This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files

161 lines
4.5 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
type Config struct {
Login LoginSettings `json:"login"`
Client ClientConfig `json:"client"`
Network NetworkConfig `json:"network"`
Admin AdminConfig `json:"admin"`
Player PlayerConfig `json:"player"`
World WorldConfig `json:"world"`
}
type ClientConfig struct {
Version int `json:"version"`
ArtifactVersion string `json:"artifactVersion"`
ServerID int `json:"serverId"`
Aid int `json:"aid"`
RpcMd5 string `json:"rpcMd5"`
NoMoreHotfixPatchError uint32 `json:"noMoreHotfixPatchError"`
}
type NetworkConfig struct {
BindHost string `json:"bindHost"`
AdvertisedHost string `json:"advertisedHost"`
LoginPorts []int `json:"loginPorts"`
GamePort int `json:"gamePort"`
SocketHeartbeatMs int `json:"socketHeartbeatMs"`
WriteTimeoutMs int `json:"writeTimeoutMs"`
Proxy ProxyConfig `json:"proxy"`
}
type ProxyConfig struct {
HttpsPort int `json:"httpsPort"`
HttpPort int `json:"httpPort"`
LoginListPort int `json:"loginListPort"`
LoginTcpPort int `json:"loginTcpPort"`
GameTcpPort int `json:"gameTcpPort"`
SceneSubPort int `json:"sceneSubPort"`
FastPatchPort int `json:"fastPatchPort"`
UpdateHost string `json:"updateHost"`
CertificatePassphrase string `json:"certificatePassphrase"`
}
type AdminConfig struct {
Enabled bool `json:"enabled"`
Host string `json:"host"`
Port int `json:"port"`
}
type PlayerConfig struct {
Pid uint64 `json:"pid"`
InitialUnitId uint64 `json:"initialUnitId"`
InitialSpiritTemplateId uint32 `json:"initialSpiritTemplateId"`
AccountId string `json:"accountId"`
UserName string `json:"userName"`
DisplayName string `json:"displayName"`
LoginToken string `json:"loginToken"`
GameToken string `json:"gameToken"`
LoginUniverseId uint32 `json:"loginUniverseId"`
ShareToken string `json:"shareToken"`
FpPassToken string `json:"fpPassToken"`
Skey string `json:"skey"`
}
type Vec3 struct {
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
}
type WorldConfig struct {
RaidId uint32 `json:"raidId"`
SceneInstanceId uint64 `json:"sceneInstanceId"`
UniverseId uint32 `json:"universeId"`
Spawn Vec3 `json:"spawn"`
Facing float32 `json:"facing"`
EntryOpeningEnabled bool `json:"entryOpeningEnabled"`
}
// LoadConfig reads and parses private-server.json from the specified path or standard locations.
func LoadConfig(path string) (*Config, error) {
if path == "" {
candidates := []string{
"config/private-server.json",
"../config/private-server.json",
"../../config/private-server.json",
}
for _, c := range candidates {
if _, err := os.Stat(c); err == nil {
path = c
break
}
}
}
if path == "" {
return nil, fmt.Errorf("config/private-server.json not found")
}
absPath, err := filepath.Abs(path)
if err != nil {
absPath = path
}
data, err := os.ReadFile(absPath)
if err != nil {
return nil, fmt.Errorf("failed to read config from %s: %w", absPath, err)
}
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("failed to parse json config from %s: %w", absPath, err)
}
if cfg.Login.RoleListMode == "" {
cfg.Login.RoleListMode = "list"
}
// Apply default values if omitted
if cfg.Network.BindHost == "" {
cfg.Network.BindHost = "0.0.0.0"
}
if cfg.Network.AdvertisedHost == "" {
cfg.Network.AdvertisedHost = "127.0.0.1"
}
if len(cfg.Network.LoginPorts) == 0 {
cfg.Network.LoginPorts = []int{5200, 5201}
}
if cfg.Network.GamePort == 0 {
cfg.Network.GamePort = 5202
}
if cfg.Network.Proxy.HttpsPort == 0 {
cfg.Network.Proxy.HttpsPort = 443
}
if cfg.Network.Proxy.HttpPort == 0 {
cfg.Network.Proxy.HttpPort = 80
}
if cfg.Network.Proxy.LoginListPort == 0 {
cfg.Network.Proxy.LoginListPort = 5801
}
if cfg.Admin.Port == 0 {
cfg.Admin.Port = 17888
}
if cfg.Player.Pid == 0 {
cfg.Player.Pid = 100
}
if cfg.Player.InitialUnitId == 0 {
cfg.Player.InitialUnitId = 100000000000
}
if cfg.Player.InitialSpiritTemplateId == 0 {
cfg.Player.InitialSpiritTemplateId = 15020967 // Default character
}
return &cfg, nil
}