using System; using System.Data.Odbc; using System.IO; using System.Runtime; using System.Threading; using GameLogServer.Handlers; using IgniteEngine; using IgniteEngine.IO; using IgniteEngine.Networking; namespace GameLogServer { internal class Program { internal static INIFile Config; internal static NetworkServer LogServer = new NetworkServer(NetworkConnectionType.NCT_DB_GAMELOG); internal static OdbcConnection AccountLogODBC; internal static OdbcConnection GameLogODBC; private static readonly string configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{Assembly.Name}.ini"); internal static void Main() { var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); Console.Title = $"{Assembly.Name} {Assembly.Version}{(System.Diagnostics.Debugger.IsAttached ? " (Debugging)" : "")} "; Debug.Log($"Local Time: {DateTime.Now}"); Debug.Log($"System (UTC) Time: {DateTime.UtcNow}\n"); // Check application recommendations if (!Environment.Is64BitProcess) { Debug.LogWarning("The process is currently not in 64-bit mode. Performance issues may occur. Press any key to continue code execution."); Console.ReadKey(); } if (!GCSettings.IsServerGC) { Debug.LogWarning("Garbage collection is not configured to server mode."); } Debug.Log($"Loading configuration file '{Path.GetFileName(configFilePath)}'."); // Load configuration if (!File.Exists(configFilePath)) { Debug.LogError("Configuration file was not found, please make sure it exists and has the correct properties. Press any key to quit."); Console.ReadKey(); return; } Config = new INIFile(configFilePath, "Config"); Debug.Log("Configuration file loaded successfully."); Debug.Log("Launching the server...\n"); // Connect to the database InitDBConnection(); // Store handlers StoreHandlers(); // Setup networking LogServer.Listen(Config.GetString("gamelog_server_ip"), (ushort)Config.GetInt16("gamelog_server_port")); stopwatch.Stop(); Debug.Log($"Time taken to start: {stopwatch.ElapsedMilliseconds}ms\n"); // Starts the main server loop. new Thread(() => { while (true) { Update(Time.Milliseconds); Thread.Sleep(10); } }).Start(); // Handle console commands while (true) { if (Console.ReadKey(true).Key == ConsoleKey.Enter) { Console.Write("$ "); var input = Console.ReadLine(); if (input?.Length > 0) { var parts = input.Split(new[] { ' ' }, 2); if (parts.Length > 1) { HandleConsoleCommand(parts[0], parts[1].Split(' ')); continue; } HandleConsoleCommand(parts[0], null); } } } } private static void HandleConsoleCommand(string command, string[] args) { switch (command.ToLower()) { case "clear": Console.Clear(); break; case "performance": Debug.Log($"CPU: {Profiler.CPUUsage}% RAM: {Profiler.RAMUsage}MB"); break; case "clients": Debug.Log($"Log Clients: {LogServer.Connections.Count}"); break; } } private static void InitDBConnection() { try { AccountLogODBC = new OdbcConnection(Config.GetString("accountlog_odbc_connection_string")); AccountLogODBC.Open(); var accountLogStartupCommand = AccountLogODBC.CreateCommand(); accountLogStartupCommand.CommandText = Config.GetString("accountlog_odbc_startup_command"); accountLogStartupCommand.ExecuteNonQuery(); GameLogODBC = new OdbcConnection(Config.GetString("gamelog_odbc_connection_string")); GameLogODBC.Open(); var gameLogStartupCommand = GameLogODBC.CreateCommand(); gameLogStartupCommand.CommandText = Config.GetString("gamelog_odbc_startup_command"); gameLogStartupCommand.ExecuteNonQuery(); } catch (Exception e) { Debug.LogException($"Could not initialize the ODBC database connections: {e.Message}"); } } private static void StoreHandlers() { // S2S NetworkMessageHandler.Store(NetworkCommand.NC_MISC_S2SCONNECTION_REQ, MiscHandlers.NC_MISC_S2SCONNECTION_REQ); // User Logs NetworkMessageHandler.Store(NetworkCommand.NC_LOG_USER_LOGINFAIL, LogHandlers.NC_LOG_USER_LOGINFAIL); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_USER_LOGIN, LogHandlers.NC_LOG_USER_LOGIN); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_USER_LOGOUT, LogHandlers.NC_LOG_USER_LOGOUT); // Avatar Logs NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_CREATE_AVATAR, LogHandlers.NC_LOG_GAME_CREATE_AVATAR); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DELETE_AVATAR, LogHandlers.NC_LOG_GAME_DELETE_AVATAR); // Game Data Type Logs NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_0, LogHandlers.NC_LOG_GAME_DATA_TYPE_0); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_1, LogHandlers.NC_LOG_GAME_DATA_TYPE_1); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_2, LogHandlers.NC_LOG_GAME_DATA_TYPE_2); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_3, LogHandlers.NC_LOG_GAME_DATA_TYPE_3); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_4, LogHandlers.NC_LOG_GAME_DATA_TYPE_4); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_5, LogHandlers.NC_LOG_GAME_DATA_TYPE_5); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_6, LogHandlers.NC_LOG_GAME_DATA_TYPE_6); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_7, LogHandlers.NC_LOG_GAME_DATA_TYPE_7); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_8, LogHandlers.NC_LOG_GAME_DATA_TYPE_8); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_9, LogHandlers.NC_LOG_GAME_DATA_TYPE_9); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_A, LogHandlers.NC_LOG_GAME_DATA_TYPE_A); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_B, LogHandlers.NC_LOG_GAME_DATA_TYPE_B); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_C, LogHandlers.NC_LOG_GAME_DATA_TYPE_C); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_D, LogHandlers.NC_LOG_GAME_DATA_TYPE_D); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_E, LogHandlers.NC_LOG_GAME_DATA_TYPE_E); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_F, LogHandlers.NC_LOG_GAME_DATA_TYPE_F); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_G, LogHandlers.NC_LOG_GAME_DATA_TYPE_G); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_H, LogHandlers.NC_LOG_GAME_DATA_TYPE_H); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_I, LogHandlers.NC_LOG_GAME_DATA_TYPE_I); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_J, LogHandlers.NC_LOG_GAME_DATA_TYPE_J); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_K, LogHandlers.NC_LOG_GAME_DATA_TYPE_K); NetworkMessageHandler.Store(NetworkCommand.NC_LOG_GAME_DATA_TYPE_L, LogHandlers.NC_LOG_GAME_DATA_TYPE_L); } private static void Update(long now) { // Do stuff? } } }