submit world server skeleton
This commit is contained in:
parent
68479a5f0c
commit
fe1a74aa7f
6
.gitignore
vendored
6
.gitignore
vendored
@ -19,6 +19,6 @@
|
||||
go.work
|
||||
|
||||
# Test builds
|
||||
./world_config.json
|
||||
./world_server
|
||||
./world.db
|
||||
/world_config.json
|
||||
/world_server
|
||||
/world.db
|
||||
|
213
cmd/world_server/main.go
Normal file
213
cmd/world_server/main.go
Normal file
@ -0,0 +1,213 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"eq2emu/internal/world"
|
||||
)
|
||||
|
||||
const defaultConfigFile = "world_config.json"
|
||||
|
||||
var (
|
||||
configFile = flag.String("config", defaultConfigFile, "Path to configuration file")
|
||||
listenAddr = flag.String("listen-addr", "", "Override listen address")
|
||||
listenPort = flag.Int("listen-port", 0, "Override listen port")
|
||||
webPort = flag.Int("web-port", 0, "Override web interface port")
|
||||
dbPath = flag.String("db", "", "Override database path")
|
||||
logLevel = flag.String("log-level", "", "Override log level (debug, info, warn, error)")
|
||||
serverName = flag.String("name", "", "Override server name")
|
||||
xpRate = flag.Float64("xp-rate", 0, "Override XP rate")
|
||||
showVersion = flag.Bool("version", false, "Show version and exit")
|
||||
)
|
||||
|
||||
// Version information (set at build time)
|
||||
var (
|
||||
Version = "1.0.0-dev"
|
||||
BuildTime = "unknown"
|
||||
GitCommit = "unknown"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *showVersion {
|
||||
fmt.Printf("EQ2Go World Server\n")
|
||||
fmt.Printf("Version: %s\n", Version)
|
||||
fmt.Printf("Build Time: %s\n", BuildTime)
|
||||
fmt.Printf("Git Commit: %s\n", GitCommit)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
config, err := loadConfig(*configFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load configuration: %v", err)
|
||||
}
|
||||
|
||||
// Apply command-line overrides
|
||||
applyOverrides(config)
|
||||
|
||||
// Print startup banner
|
||||
printBanner(config)
|
||||
|
||||
// Create world server
|
||||
worldServer, err := world.NewWorld(config)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create world server: %v", err)
|
||||
}
|
||||
|
||||
// Start world server
|
||||
if err := worldServer.Start(); err != nil {
|
||||
log.Fatalf("Failed to start world server: %v", err)
|
||||
}
|
||||
|
||||
// Setup signal handlers
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
// Run server in background
|
||||
go worldServer.Process()
|
||||
|
||||
// Wait for shutdown signal
|
||||
sig := <-sigChan
|
||||
fmt.Printf("\nReceived signal: %v\n", sig)
|
||||
|
||||
// Graceful shutdown
|
||||
if err := worldServer.Stop(); err != nil {
|
||||
log.Printf("Error during shutdown: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// loadConfig loads the configuration from file
|
||||
func loadConfig(filename string) (*world.WorldConfig, error) {
|
||||
// Check if config file exists
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
// Create default configuration
|
||||
config := createDefaultConfig()
|
||||
|
||||
// Save default configuration
|
||||
if err := saveConfig(filename, config); err != nil {
|
||||
return nil, fmt.Errorf("failed to save default config: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Created default configuration file: %s\n", filename)
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// Load existing configuration
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open config file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var config world.WorldConfig
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(&config); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode config: %w", err)
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// saveConfig saves the configuration to file
|
||||
func saveConfig(filename string, config *world.WorldConfig) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create config file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetIndent("", " ")
|
||||
if err := encoder.Encode(config); err != nil {
|
||||
return fmt.Errorf("failed to encode config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createDefaultConfig creates a default configuration
|
||||
func createDefaultConfig() *world.WorldConfig {
|
||||
return &world.WorldConfig{
|
||||
// Network settings
|
||||
ListenAddr: "0.0.0.0",
|
||||
ListenPort: 9000,
|
||||
MaxClients: 1000,
|
||||
|
||||
// Web interface settings
|
||||
WebAddr: "0.0.0.0",
|
||||
WebPort: 8080,
|
||||
WebCertFile: "",
|
||||
WebKeyFile: "",
|
||||
WebKeyPassword: "",
|
||||
|
||||
// Database settings
|
||||
DatabasePath: "world.db",
|
||||
|
||||
// Server settings
|
||||
ServerName: "EQ2Go World Server",
|
||||
ServerMOTD: "Welcome to EQ2Go!",
|
||||
LogLevel: "info",
|
||||
|
||||
// Game settings
|
||||
XPRate: 1.0,
|
||||
TSXPRate: 1.0,
|
||||
CoinRate: 1.0,
|
||||
LootRate: 1.0,
|
||||
|
||||
// Login server settings
|
||||
LoginServerAddr: "127.0.0.1",
|
||||
LoginServerPort: 5999,
|
||||
LoginServerKey: "",
|
||||
}
|
||||
}
|
||||
|
||||
// applyOverrides applies command-line overrides to the configuration
|
||||
func applyOverrides(config *world.WorldConfig) {
|
||||
if *listenAddr != "" {
|
||||
config.ListenAddr = *listenAddr
|
||||
}
|
||||
if *listenPort > 0 {
|
||||
config.ListenPort = *listenPort
|
||||
}
|
||||
if *webPort > 0 {
|
||||
config.WebPort = *webPort
|
||||
}
|
||||
if *dbPath != "" {
|
||||
config.DatabasePath = *dbPath
|
||||
}
|
||||
if *logLevel != "" {
|
||||
config.LogLevel = *logLevel
|
||||
}
|
||||
if *serverName != "" {
|
||||
config.ServerName = *serverName
|
||||
}
|
||||
if *xpRate > 0 {
|
||||
config.XPRate = float32(*xpRate)
|
||||
}
|
||||
}
|
||||
|
||||
// printBanner prints the server startup banner
|
||||
func printBanner(config *world.WorldConfig) {
|
||||
fmt.Println("================================================================================")
|
||||
fmt.Println(" EQ2Go World Server")
|
||||
fmt.Println("================================================================================")
|
||||
fmt.Printf("Version: %s\n", Version)
|
||||
fmt.Printf("Server Name: %s\n", config.ServerName)
|
||||
fmt.Printf("Listen Address: %s:%d\n", config.ListenAddr, config.ListenPort)
|
||||
fmt.Printf("Web Interface: %s:%d\n", config.WebAddr, config.WebPort)
|
||||
fmt.Printf("Database: %s\n", config.DatabasePath)
|
||||
fmt.Printf("Log Level: %s\n", config.LogLevel)
|
||||
fmt.Printf("XP Rate: %.1fx\n", config.XPRate)
|
||||
fmt.Printf("TS XP Rate: %.1fx\n", config.TSXPRate)
|
||||
fmt.Printf("Coin Rate: %.1fx\n", config.CoinRate)
|
||||
fmt.Printf("Loot Rate: %.1fx\n", config.LootRate)
|
||||
fmt.Println("================================================================================")
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user