fix: sync current handlers, repair relic data and restore visible launcher consoles
This commit is contained in:
1 parent
163d4433e6
commit
74f3c4411b
46 files changed
+4599
-1402
No files matched your search
@@ -0,0 +1,88 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RuntimeConfig is shared by both server processes. Deployment values belong
|
||||
// in configuration rather than in handlers or executable entry points.
|
||||
type RuntimeConfig struct {
|
||||
BattleDiagnostics BattleDiagnosticsConfig `json:"battle_diagnostics"`
|
||||
ClientVersion string `json:"client_version"`
|
||||
GameHost string `json:"game_host"`
|
||||
GamePort uint16 `json:"game_port"`
|
||||
SDKHost string `json:"sdk_host"`
|
||||
SDKPort uint16 `json:"sdk_port"`
|
||||
PublicGameHost string `json:"public_game_host"`
|
||||
PublicSDKURL string `json:"public_sdk_url"`
|
||||
}
|
||||
|
||||
// The obfuscated protobuf class name is version-specific and comes from the
|
||||
// client's stack trace. Empty disables the read-only client wire probe.
|
||||
type BattleDiagnosticsConfig struct {
|
||||
ClientBattleType string `json:"client_battle_type"`
|
||||
}
|
||||
|
||||
func LoadRuntimeConfig() (RuntimeConfig, error) {
|
||||
path := os.Getenv("GAC_CONFIG")
|
||||
if path == "" {
|
||||
path = "server.json"
|
||||
}
|
||||
var cfg RuntimeConfig
|
||||
for i, filename := range []string{path, filepath.Join(filepath.Dir(path), strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))+".local.json")} {
|
||||
raw, err := os.ReadFile(filename)
|
||||
if i == 1 && os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return cfg, fmt.Errorf("read runtime config %s: %w", filename, err)
|
||||
}
|
||||
if err := json.Unmarshal(bytes.TrimPrefix(raw, []byte{0xef, 0xbb, 0xbf}), &cfg); err != nil {
|
||||
return cfg, fmt.Errorf("parse runtime config %s: %w", filename, err)
|
||||
}
|
||||
}
|
||||
for name, dest := range map[string]*string{
|
||||
"GAC_CLIENT_VERSION": &cfg.ClientVersion, "GAC_GAME_HOST": &cfg.GameHost,
|
||||
"GAC_SDK_HOST": &cfg.SDKHost, "GAC_PUBLIC_GAME_HOST": &cfg.PublicGameHost,
|
||||
"GAC_PUBLIC_SDK_URL": &cfg.PublicSDKURL,
|
||||
} {
|
||||
if value, ok := os.LookupEnv(name); ok {
|
||||
*dest = value
|
||||
}
|
||||
}
|
||||
for name, dest := range map[string]*uint16{"GAC_GAME_PORT": &cfg.GamePort, "GAC_SDK_PORT": &cfg.SDKPort} {
|
||||
if value, ok := os.LookupEnv(name); ok {
|
||||
n, err := strconv.ParseUint(value, 10, 16)
|
||||
if err != nil || n == 0 {
|
||||
return cfg, fmt.Errorf("%s must be a port between 1 and 65535", name)
|
||||
}
|
||||
*dest = uint16(n)
|
||||
}
|
||||
}
|
||||
if cfg.GamePort == 0 || cfg.SDKPort == 0 || strings.TrimSpace(cfg.ClientVersion) == "" {
|
||||
return cfg, fmt.Errorf("runtime config requires client_version, game_port and sdk_port")
|
||||
}
|
||||
for name, host := range map[string]string{"game_host": cfg.GameHost, "sdk_host": cfg.SDKHost, "public_game_host": cfg.PublicGameHost} {
|
||||
if strings.TrimSpace(host) == "" || strings.ContainsAny(host, "/\\ \t\r\n") {
|
||||
return cfg, fmt.Errorf("invalid %s", name)
|
||||
}
|
||||
}
|
||||
u, err := url.Parse(cfg.PublicSDKURL)
|
||||
if err != nil || u.Hostname() == "" || (u.Scheme != "http" && u.Scheme != "https") || u.RawQuery != "" || u.Fragment != "" || u.User != nil {
|
||||
return cfg, fmt.Errorf("public_sdk_url must be an HTTP(S) base URL")
|
||||
}
|
||||
cfg.PublicSDKURL = strings.TrimRight(cfg.PublicSDKURL, "/")
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (c RuntimeConfig) SDKAddress() string {
|
||||
return net.JoinHostPort(c.SDKHost, strconv.Itoa(int(c.SDKPort)))
|
||||
}
|
||||
Reference in new issue
Block a user