using System.Collections; using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.SQLScript.Common; using Milimoe.FunGame.Core.Library.SQLScript.Entity; using Milimoe.FunGame.Core.Model; using Milimoe.FunGame.Server.Others; using Milimoe.FunGame.Server.Services.DataUtility; namespace Milimoe.FunGame.Server.Services { public class FunGameSystem { /// /// 服务器指令列表 /// public static Hashtable OrderList { get; } = []; /// /// 在线房间列表 /// public static RoomList RoomList { get; } = new(); /// /// Server实际安装的模组 /// public static GameModuleLoader? GameModuleLoader { get; set; } /// /// Server插件 /// public static ServerPluginLoader? ServerPluginLoader { get; set; } /// /// Web API插件 /// public static WebAPIPluginLoader? WebAPIPluginLoader { get; set; } /// /// 服务器配置 /// public static PluginConfig UserKeys { get; set; } = new("system", "user_keys"); /// /// 服务器配置 /// public static PluginConfig SQLConfig { get; set; } = new("system", "sqlconfig"); /// /// 默认的 Web API Token ID,在首次初始化数据库时生成一个 Secret Key /// public const string FunGameWebAPITokenID = "fungame_web_api"; /// /// 初始化数据库连接器 /// public static void InitSQLHelper() { try { Factory.OpenFactory.RegisterFactory(() => Config.SQLMode switch { SQLMode.MySQL => new MySQLHelper(), SQLMode.SQLite => new SQLiteHelper(), _ => null, }); if (INIHelper.ExistINIFile()) { string useMySQL = INIHelper.ReadINI("MySQL", "UseMySQL").Trim(); string useSQLite = INIHelper.ReadINI("SQLite", "UseSQLite").Trim(); // 根据配置文件选择适当的 SQLHelper 实例 SQLHelper? sqlHelper = useMySQL == "true" ? new MySQLHelper() : useSQLite == "true" ? new SQLiteHelper() : null; if (sqlHelper != null) { Config.SQLMode = sqlHelper.Mode; switch (Config.SQLMode) { case SQLMode.MySQL: ServerHelper.WriteLine("Connect -> MySQL://" + sqlHelper.ServerInfo.SQLServerIP + ":" + sqlHelper.ServerInfo.SQLServerPort); break; case SQLMode.SQLite: ServerHelper.WriteLine("Connect -> SQLite://" + sqlHelper.ServerInfo.SQLServerDataBase); break; } AfterCreateSQLService(sqlHelper); } else { Config.SQLMode = SQLMode.None; ServerHelper.WriteLine("未开启 SQL 服务,某些请求将无法处理。", InvokeMessageType.Warning); } } } catch (Exception e) { ServerHelper.Error(e); } } /// /// 初始化邮件发送器 /// public static void InitMailSender() { try { Factory.OpenFactory.RegisterFactory(SmtpHelper.GetMailSender); MailSender? sender = SmtpHelper.GetMailSender(); if (sender != null) { ServerHelper.WriteLine("SMTP 服务已启动!"); sender.Dispose(); } else { ServerHelper.WriteLine("SMTP 服务处于关闭状态", InvokeMessageType.Warning); } } catch (Exception e) { ServerHelper.Error(e); } } /// /// 加载游戏模组 /// /// public static bool GetGameModuleList() { List supported = []; // 构建AddonController Dictionary delegates = []; delegates.Add("WriteLine", new Action((name, msg, level, useLevel) => ServerHelper.WriteLine_Addons(name, msg, InvokeMessageType.GameModule, level, useLevel))); delegates.Add("Error", new Action(ServerHelper.Error)); // 读取modules目录下的模组 try { GameModuleLoader = GameModuleLoader.LoadGameModules(Config.FunGameType, delegates); foreach (GameModuleServer module in GameModuleLoader.ModuleServers.Values) { try { bool check = true; // 检查模组是否有相对应的地图 if (!GameModuleLoader.Maps.ContainsKey(module.DefaultMap)) { ServerHelper.WriteLine("GameModule Load Failed: " + module.Name + " 没有找到相对应的地图,加载失败", InvokeMessageType.Error); check = false; } if (check) { if (!module.IsAnonymous) supported.Add(module.Name); ServerHelper.WriteLine("GameModule Loaded -> " + module.Name, InvokeMessageType.Core); } } catch (Exception e) { ServerHelper.Error(e); } } } catch (Exception e2) { ServerHelper.Error(e2); } // 设置全局 Config.GameModuleSupported = [.. supported.Distinct()]; return Config.GameModuleSupported.Length > 0; } /// /// 加载服务器插件 /// public static void GetServerPlugins() { Dictionary delegates = []; delegates.Add("WriteLine", new Action((name, msg, level, useLevel) => ServerHelper.WriteLine_Addons(name, msg, InvokeMessageType.Plugin, level, useLevel))); delegates.Add("Error", new Action(ServerHelper.Error)); try { // 读取plugins目录下的插件 ServerPluginLoader = ServerPluginLoader.LoadPlugins(delegates); foreach (ServerPlugin plugin in ServerPluginLoader.Plugins.Values) { ServerHelper.WriteLine("Plugin Loaded -> " + plugin.Name, InvokeMessageType.Core); } } catch (Exception e) { ServerHelper.Error(e); } } /// /// 加载 Web API 插件 /// public static void GetWebAPIPlugins(params object[] otherobjs) { Dictionary delegates = []; delegates.Add("WriteLine", new Action((name, msg, level, useLevel) => ServerHelper.WriteLine_Addons(name, msg, InvokeMessageType.Plugin, level, useLevel))); delegates.Add("Error", new Action(ServerHelper.Error)); try { // 读取plugins目录下的插件 WebAPIPluginLoader = WebAPIPluginLoader.LoadPlugins(delegates, otherobjs); foreach (WebAPIPlugin plugin in WebAPIPluginLoader.Plugins.Values) { ServerHelper.WriteLine("Plugin Loaded -> " + plugin.Name, InvokeMessageType.Core); } } catch (Exception e) { ServerHelper.Error(e); } } /// /// 服务器启动登记 /// public static void ServerLogin(SQLHelper sqlHelper) { sqlHelper.Execute(ServerLoginLogs.Insert_ServerLoginLog(sqlHelper, Config.ServerName, Config.ServerKey)); } /// /// 重启服务器后,所有房间都会被删除 /// public static void ClearRoomList(SQLHelper sqlHelper) { sqlHelper.Execute(RoomQuery.Delete_Rooms(sqlHelper)); } /// /// 初始化用户密钥列表 /// public static void InitUserKeys() { UserKeys.LoadConfig(); UserKeys.SaveConfig(); } /// /// 获取指定用户的密钥 /// /// /// public static string GetUserKey(string username) { if (UserKeys.TryGetValue(username.ToLower(), out object? value) && value is string key) { return key; } return username; } /// /// 更新指定用户的密钥 /// /// /// public static void UpdateUserKey(string username) { UserKeys.Add(username.ToLower(), Encryption.GenerateRandomString()); UserKeys.SaveConfig(); } /// /// 检查是否存在 API Secret Key /// /// public static bool IsAPISecretKeyExist(string key) { using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); if (sql != null) { sql.ExecuteDataSet(ApiTokens.Select_GetAPISecretKey(sql, key)); if (sql.Result == SQLResult.Success) { return true; } } return false; } /// /// 获取 API Secret Key /// /// public static string GetAPISecretKey(string token) { using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper(); if (sql != null) { sql.ExecuteDataSet(ApiTokens.Select_GetAPIToken(sql, token)); if (sql.Result == SQLResult.Success) { return sql.DataSet.Tables[0].Rows[0][ApiTokens.Column_SecretKey].ToString() ?? ""; } } return ""; } /// /// 设置 API Secret Key /// /// /// /// public static void SetAPISecretKey(string token, string reference1 = "", string reference2 = "", SQLHelper? sqlHelper = null) { bool useSQLHelper = sqlHelper != null; sqlHelper ??= Factory.OpenFactory.GetSQLHelper(); string key = Encryption.GenerateRandomString(); if (sqlHelper != null) { sqlHelper.ExecuteDataSet(ApiTokens.Select_GetAPIToken(sqlHelper, token)); if (sqlHelper.Success) { sqlHelper.Execute(ApiTokens.Update_APIToken(sqlHelper, token, key, reference1, reference2)); } else { sqlHelper.Execute(ApiTokens.Insert_APIToken(sqlHelper, token, key, reference1, reference2)); } } if (!useSQLHelper) { sqlHelper?.Dispose(); } } /// /// 创建 SQL 服务后需要做的事 /// /// public static void AfterCreateSQLService(SQLHelper sqlHelper) { Config.SQLMode = sqlHelper.Mode; ServerHelper.WriteLine("正在检查数据库 . . .", InvokeMessageType.Core); if (!DatabaseExists() && !sqlHelper.DatabaseExists()) { ServerHelper.WriteLine("数据库检查失败,正在初始化数据库 . . .", InvokeMessageType.Core); if (sqlHelper is SQLiteHelper sqliteHelper) { sqliteHelper.ExecuteSqlFile(AppDomain.CurrentDomain.BaseDirectory + "fungame_sqlite.sql"); } else if (sqlHelper is MySQLHelper mysqlHelper) { mysqlHelper.ExecuteSqlFile(AppDomain.CurrentDomain.BaseDirectory + "fungame.sql"); } SetAPISecretKey(FunGameWebAPITokenID, sqlHelper: sqlHelper); sqlHelper.Execute(Configs.Insert_Config(sqlHelper, "Initialization", FunGameInfo.FunGame_Version, "SQL Service Installed.")); SQLConfig.Clear(); SQLConfig.Add("Initialized", true); SQLConfig.SaveConfig(); ServerHelper.WriteLine("数据库初始化完毕!", InvokeMessageType.Core); } else ServerHelper.WriteLine("数据库检查通过!", InvokeMessageType.Core); ServerLogin(sqlHelper); ClearRoomList(sqlHelper); sqlHelper.Dispose(); } public static bool DatabaseExists() { SQLConfig.LoadConfig(); if (SQLConfig.TryGetValue("Initialized", out object? value) && value is bool initialized) { return initialized; } return false; } /// /// 关闭服务器要做的事 /// public static void CloseServer() { if (GameModuleLoader != null) { foreach (GameModuleServer server in GameModuleLoader.ModuleServers.Values) { server.Controller.Close(); } } if (ServerPluginLoader != null) { foreach (ServerPlugin plugin in ServerPluginLoader.Plugins.Values) { plugin.Controller.Close(); } } if (WebAPIPluginLoader != null) { foreach (WebAPIPlugin plugin in WebAPIPluginLoader.Plugins.Values) { plugin.Controller.Close(); } } } } }