package main import ( "encoding/json" "flag" "fmt" "log" "os" "os/signal" "syscall" "eq2emu/internal/login" ) const defaultConfigFile = "login_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") logLevel = flag.String("log-level", "", "Override log level (debug, info, warn, error)") serverName = flag.String("name", "", "Override server name") 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 Login 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 login server loginServer, err := login.NewServer(config) if err != nil { log.Fatalf("Failed to create login server: %v", err) } // Start login server if err := loginServer.Start(); err != nil { log.Fatalf("Failed to start login server: %v", err) } // Setup signal handlers sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // Run server in background go loginServer.Process() // Wait for shutdown signal sig := <-sigChan fmt.Printf("\nReceived signal: %v\n", sig) // Graceful shutdown if err := loginServer.Stop(); err != nil { log.Printf("Error during shutdown: %v", err) } } // loadConfig loads the configuration from file func loadConfig(filename string) (*login.ServerConfig, 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 login.ServerConfig 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 *login.ServerConfig) 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() *login.ServerConfig { return &login.ServerConfig{ // Network settings ListenAddr: "0.0.0.0", ListenPort: 5999, MaxClients: 1000, // Web interface settings WebAddr: "0.0.0.0", WebPort: 8081, WebCertFile: "", WebKeyFile: "", WebKeyPassword: "", WebUser: "", WebPassword: "", // Database settings DatabaseType: "sqlite", DatabaseDSN: "login.db", // Server settings ServerName: "EQ2Go Login Server", LogLevel: "info", // World servers WorldServers: []login.WorldServerInfo{}, } } // applyOverrides applies command-line overrides to the configuration func applyOverrides(config *login.ServerConfig) { if *listenAddr != "" { config.ListenAddr = *listenAddr } if *listenPort > 0 { config.ListenPort = *listenPort } if *webPort > 0 { config.WebPort = *webPort } if *logLevel != "" { config.LogLevel = *logLevel } if *serverName != "" { config.ServerName = *serverName } } // printBanner prints the server startup banner func printBanner(config *login.ServerConfig) { fmt.Println("================================================================================") fmt.Println(" EQ2Go Login 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 %s\n", config.DatabaseType, config.DatabaseDSN) fmt.Printf("Log Level: %s\n", config.LogLevel) fmt.Printf("World Servers: %d configured\n", len(config.WorldServers)) fmt.Println("================================================================================") }