diff --git a/FunGame.Server/Main.cs b/FunGame.Server/Main.cs index 191e3da..1c7582c 100644 --- a/FunGame.Server/Main.cs +++ b/FunGame.Server/Main.cs @@ -66,19 +66,19 @@ void StartServer() ServerHelper.InitOrderList(); // 创建全局SQLHelper - Config.InitSQLHelper(); + FunGameSystem.InitSQLHelper(); // 创建全局MailSender - Config.InitMailSender(); + FunGameSystem.InitMailSender(); // 读取游戏模组 - if (!Config.GetGameModuleList()) + if (!FunGameSystem.GetGameModuleList()) { ServerHelper.WriteLine("服务器似乎未安装任何游戏模组,请检查是否正确安装它们。"); } // 读取Server插件 - Config.GetServerPlugins(); + FunGameSystem.GetServerPlugins(); // 检查是否存在配置文件 if (!INIHelper.ExistINIFile()) @@ -95,6 +95,8 @@ void StartServer() } ServerHelper.WriteLine("请输入 help 来获取帮助,输入 quit 关闭服务器。"); + ServerHelper.PrintFunGameTitle(); + // 使用Socket还是WebSocket bool useWebSocket = Config.UseWebSocket; diff --git a/FunGame.Server/Models/ServerModel.cs b/FunGame.Server/Models/ServerModel.cs index 4c25ba6..2b6d57e 100644 --- a/FunGame.Server/Models/ServerModel.cs +++ b/FunGame.Server/Models/ServerModel.cs @@ -6,6 +6,7 @@ using Milimoe.FunGame.Core.Interface.Base; using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.SQLScript.Common; using Milimoe.FunGame.Core.Library.SQLScript.Entity; using Milimoe.FunGame.Server.Controller; using Milimoe.FunGame.Server.Others; @@ -49,11 +50,8 @@ namespace Milimoe.FunGame.Server.Model Socket = socket; DataRequestController = new(this); IsDebugMode = isDebugMode; - if (Config.SQLMode != SQLMode.None) - { - _sqlHelper = Config.SQLHelper; - } - _mailer = Config.MailSender; + _sqlHelper = Factory.OpenFactory.GetSQLHelper(); + _mailer = SmtpHelper.GetMailSender(); } public virtual async Task SocketMessageHandler(ISocketMessageProcessor socket, SocketObject obj) @@ -465,6 +463,33 @@ namespace Milimoe.FunGame.Server.Model protected async Task CreateStreamReader() { + CancellationTokenSource cts = new(); + Task sqlPolling = Task.Run(async () => + { + await Task.Delay(30); + ServerHelper.WriteLine("Creating: SQLPolling -> " + GetClientName() + " ...OK"); + while (Running) + { + if (cts.Token.IsCancellationRequested) + { + break; + } + // 每两小时触发一次SQL服务器的心跳查询,防止SQL服务器掉线 + try + { + await Task.Delay(2 * 1000 * 3600); + SQLHelper?.ExecuteDataSet(ServerLoginLogs.Select_GetLastLoginTime()); + } + catch (OperationCanceledException) + { + break; + } + catch (Exception e) + { + ServerHelper.Error(e); + } + } + }, cts.Token); await Task.Delay(20); ServerHelper.WriteLine("Creating: StreamReader -> " + GetClientName() + " ...OK"); while (Running) @@ -494,6 +519,9 @@ namespace Milimoe.FunGame.Server.Model break; } } + cts.Cancel(); + await sqlPolling; + cts.Dispose(); } protected async Task Close() diff --git a/FunGame.Server/Others/Config.cs b/FunGame.Server/Others/Config.cs index d709bb3..afd1848 100644 --- a/FunGame.Server/Others/Config.cs +++ b/FunGame.Server/Others/Config.cs @@ -1,14 +1,8 @@ using System.Collections; using System.Text; -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.Utility; -using Milimoe.FunGame.Server.Utility.DataUtility; namespace Milimoe.FunGame.Server.Others { @@ -143,213 +137,6 @@ namespace Milimoe.FunGame.Server.Others /// 未Loadmodules时,此属性表示至少需要安装的模组 /// public static string[] GameModuleSupported { get; set; } = []; - - /// - /// 全局数据库连接器 - /// - public static SQLHelper SQLHelper - { - get - { - if (_SQLHelper is null) throw new SQLServiceException(); - return _SQLHelper; - } - } - - /// - /// 全局邮件发送器 - /// - public static MailSender? MailSender => _MailSender; - - private static SQLHelper? _SQLHelper; - private static MailSender? _MailSender; - - /// - /// 初始化数据库连接器 - /// - public static void InitSQLHelper() - { - try - { - if (INIHelper.ExistINIFile()) - { - if (INIHelper.ReadINI("MySQL", "UseMySQL").Trim() == "true") - { - _SQLHelper = new MySQLHelper("", false); - if (((MySQLHelper)_SQLHelper).Connection != null) - { - AfterCreateSQLService(_SQLHelper); - } - } - else if (INIHelper.ReadINI("SQLite", "UseSQLite").Trim() == "true") - { - _SQLHelper = new SQLiteHelper(); - AfterCreateSQLService(_SQLHelper); - } - else - { - SQLMode = SQLMode.None; - ServerHelper.WriteLine("未开启 SQL 服务,某些请求将无法处理。", InvokeMessageType.Warning); - } - } - } - catch (Exception e) - { - ServerHelper.Error(e); - } - } - - /// - /// 初始化邮件发送器 - /// - public static void InitMailSender() - { - try - { - _MailSender = SmtpHelper.GetMailSender(); - } - catch (Exception e) - { - ServerHelper.Error(e); - } - if (_MailSender != null) - { - Singleton.AddOrUpdate(_MailSender); - } - } - - public static bool GetGameModuleList() - { - List supported = []; - // 构建AddonController - Dictionary delegates = []; - delegates.Add("WriteLine", new Action(msg => ServerHelper.WriteLine(msg, InvokeMessageType.GameModule))); - delegates.Add("Error", new Action(ServerHelper.Error)); - // 读取modules目录下的模组 - try - { - GameModuleLoader = GameModuleLoader.LoadGameModules(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 + " 没有找到相对应的地图,加载失败", InvokeMessageType.Error); - check = false; - } - if (check) - { - supported.Add(module.Name); - } - } - catch (Exception e) - { - ServerHelper.Error(e); - } - } - } - catch (Exception e2) - { - ServerHelper.Error(e2); - } - // 设置全局 - GameModuleSupported = supported.Distinct().ToArray(); - foreach (string modename in GameModuleSupported) - { - ServerHelper.WriteLine("Loaded: " + modename, InvokeMessageType.GameModule); - } - - return GameModuleSupported.Length > 0; - } - - public static void GetServerPlugins() - { - Dictionary delegates = []; - delegates.Add("WriteLine", new Action(msg => ServerHelper.WriteLine(msg, InvokeMessageType.Plugin))); - delegates.Add("Error", new Action(ServerHelper.Error)); - try - { - // 读取plugins目录下的插件 - ServerPluginLoader = ServerPluginLoader.LoadPlugins(delegates); - foreach (ServerPlugin plugin in ServerPluginLoader.Plugins.Values) - { - ServerHelper.WriteLine("Loaded: " + plugin.Name, InvokeMessageType.Plugin); - } - } - catch (Exception e) - { - ServerHelper.Error(e); - } - } - - public static void GetWebAPIPlugins() - { - Dictionary delegates = []; - delegates.Add("WriteLine", new Action(msg => ServerHelper.WriteLine(msg, InvokeMessageType.Plugin))); - delegates.Add("Error", new Action(ServerHelper.Error)); - try - { - // 读取plugins目录下的插件 - WebAPIPluginLoader = WebAPIPluginLoader.LoadPlugins(delegates); - foreach (WebAPIPlugin plugin in WebAPIPluginLoader.Plugins.Values) - { - ServerHelper.WriteLine("Loaded: " + plugin.Name, InvokeMessageType.Plugin); - } - } - catch (Exception e) - { - ServerHelper.Error(e); - } - } - - /// - /// 服务器启动登记 - /// - public static void ServerLogin() - { - if (SQLMode != SQLMode.None) - { - SQLHelper.Execute(ServerLoginLogs.Insert_ServerLoginLogs(ServerName, ServerKey)); - } - } - - /// - /// 重启服务器后,所有房间都会被删除 - /// - public static void ClearRoomList() - { - if (SQLMode != SQLMode.None) - { - SQLHelper.Execute(RoomQuery.Delete_Rooms()); - } - } - - public static void AfterCreateSQLService(SQLHelper sqlHelper) - { - SQLMode = sqlHelper.Mode; - Singleton.AddOrUpdate(sqlHelper, true); - ServerLogin(); - ClearRoomList(); - Task t = Task.Run(async () => - { - while (true) - { - // 每两小时触发一次SQL服务器的心跳查询,防止SQL服务器掉线 - try - { - await Task.Delay(2 * 1000 * 3600); - SQLHelper?.ExecuteDataSet(ServerLoginLogs.Select_GetLastLoginTime()); - } - catch (Exception e) - { - ServerHelper.Error(e); - } - } - }); - } } /// diff --git a/FunGame.Server/Others/FunGameSystem.cs b/FunGame.Server/Others/FunGameSystem.cs new file mode 100644 index 0000000..ed4040e --- /dev/null +++ b/FunGame.Server/Others/FunGameSystem.cs @@ -0,0 +1,198 @@ +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.Server.Utility; +using Milimoe.FunGame.Server.Utility.DataUtility; + +namespace Milimoe.FunGame.Server.Others +{ + public class FunGameSystem + { + /// + /// 初始化数据库连接器 + /// + 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() + { + MailSender? sender = null; + try + { + 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(msg => ServerHelper.WriteLine(msg, InvokeMessageType.GameModule))); + delegates.Add("Error", new Action(ServerHelper.Error)); + // 读取modules目录下的模组 + try + { + Config.GameModuleLoader = GameModuleLoader.LoadGameModules(Config.FunGameType, delegates); + foreach (GameModuleServer module in Config.GameModuleLoader.ModuleServers.Values) + { + try + { + bool check = true; + // 检查模组是否有相对应的地图 + if (!Config.GameModuleLoader.Maps.ContainsKey(module.DefaultMap)) + { + ServerHelper.WriteLine("GameModule Load Failed: " + module + " 没有找到相对应的地图,加载失败", InvokeMessageType.Error); + check = false; + } + if (check) + { + supported.Add(module.Name); + } + } + catch (Exception e) + { + ServerHelper.Error(e); + } + } + } + catch (Exception e2) + { + ServerHelper.Error(e2); + } + // 设置全局 + Config.GameModuleSupported = supported.Distinct().ToArray(); + foreach (string modename in Config.GameModuleSupported) + { + ServerHelper.WriteLine("Loaded: " + modename, InvokeMessageType.GameModule); + } + + return Config.GameModuleSupported.Length > 0; + } + + public static void GetServerPlugins() + { + Dictionary delegates = []; + delegates.Add("WriteLine", new Action(msg => ServerHelper.WriteLine(msg, InvokeMessageType.Plugin))); + delegates.Add("Error", new Action(ServerHelper.Error)); + try + { + // 读取plugins目录下的插件 + Config.ServerPluginLoader = ServerPluginLoader.LoadPlugins(delegates); + foreach (ServerPlugin plugin in Config.ServerPluginLoader.Plugins.Values) + { + ServerHelper.WriteLine("Loaded: " + plugin.Name, InvokeMessageType.Plugin); + } + } + catch (Exception e) + { + ServerHelper.Error(e); + } + } + + public static void GetWebAPIPlugins() + { + Dictionary delegates = []; + delegates.Add("WriteLine", new Action(msg => ServerHelper.WriteLine(msg, InvokeMessageType.Plugin))); + delegates.Add("Error", new Action(ServerHelper.Error)); + try + { + // 读取plugins目录下的插件 + Config.WebAPIPluginLoader = WebAPIPluginLoader.LoadPlugins(delegates); + foreach (WebAPIPlugin plugin in Config.WebAPIPluginLoader.Plugins.Values) + { + ServerHelper.WriteLine("Loaded: " + plugin.Name, InvokeMessageType.Plugin); + } + } + catch (Exception e) + { + ServerHelper.Error(e); + } + } + + /// + /// 服务器启动登记 + /// + public static void ServerLogin(SQLHelper sqlHelper) + { + sqlHelper.Execute(ServerLoginLogs.Insert_ServerLoginLogs(Config.ServerName, Config.ServerKey)); + } + + /// + /// 重启服务器后,所有房间都会被删除 + /// + public static void ClearRoomList(SQLHelper sqlHelper) + { + sqlHelper.Execute(RoomQuery.Delete_Rooms()); + } + + public static void AfterCreateSQLService(SQLHelper sqlHelper) + { + Config.SQLMode = sqlHelper.Mode; + ServerLogin(sqlHelper); + ClearRoomList(sqlHelper); + sqlHelper.Dispose(); + } + } +} diff --git a/FunGame.Server/Utilities/General.cs b/FunGame.Server/Utilities/General.cs index f197ae2..6ad9cbe 100644 --- a/FunGame.Server/Utilities/General.cs +++ b/FunGame.Server/Utilities/General.cs @@ -9,6 +9,14 @@ namespace Milimoe.FunGame.Server.Utility { public class ServerHelper { + public static void PrintFunGameTitle() + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("\r "); + Console.WriteLine(FunGameInfo.FunGameServerTitle); + Console.ResetColor(); + } + public static string GetPrefix(InvokeMessageType type) { string prefix; @@ -191,7 +199,7 @@ namespace Milimoe.FunGame.Server.Utility public static string SenderPassword { get; set; } = ""; public static string SmtpHost { get; set; } = ""; public static int SmtpPort { get; set; } = 587; - public static bool OpenSSL { get; set; } = true; + public static bool SSL { get; set; } = true; public static MailSender? GetMailSender() { @@ -211,21 +219,19 @@ namespace Milimoe.FunGame.Server.Utility SmtpHost = INIHelper.ReadINI("Mailer", "Host"); if (int.TryParse(INIHelper.ReadINI("Mailer", "Port"), out int Port)) SmtpPort = Port; - if (bool.TryParse(INIHelper.ReadINI("Mailer", "OpenSSL").ToLower(), out bool SSL)) - OpenSSL = SSL; + if (bool.TryParse(INIHelper.ReadINI("Mailer", "SSL").ToLower(), out bool ssl)) + SSL = ssl; if (SmtpPort > 0) { - ServerHelper.WriteLine("SMTP 服务已启动!"); - return new MailSender(SenderMailAddress, SenderName, SenderPassword, SmtpHost, SmtpPort, OpenSSL); + return new MailSender(SenderMailAddress, SenderName, SenderPassword, SmtpHost, SmtpPort, SSL); } } } - ServerHelper.WriteLine("SMTP 服务处于关闭状态", InvokeMessageType.Warning); return null; } throw new SmtpHelperException(); } - return new MailSender(SenderMailAddress, SenderName, SenderPassword, SmtpHost, SmtpPort, OpenSSL); + return new MailSender(SenderMailAddress, SenderName, SenderPassword, SmtpHost, SmtpPort, SSL); } catch (Exception e) { diff --git a/FunGame.Server/Utilities/MySQL/MySQLConnection.cs b/FunGame.Server/Utilities/MySQL/MySQLConnection.cs deleted file mode 100644 index 79fe54c..0000000 --- a/FunGame.Server/Utilities/MySQL/MySQLConnection.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Milimoe.FunGame.Core.Model; -using MySql.Data.MySqlClient; - -namespace Milimoe.FunGame.Server.Utility.DataUtility -{ - public class MySQLConnection - { - public MySqlConnection? Connection - { - get - { - return _Connection; - } - } - public SQLServerInfo ServerInfo - { - get - { - return _ServerInfo ?? SQLServerInfo.Create(); - } - } - - private MySqlConnection? _Connection; - private SQLServerInfo? _ServerInfo; - - /// - /// 创建SQL连接 - /// - /// - public MySQLConnection(out SQLServerInfo? serverInfo) - { - _Connection = Connect(out serverInfo); - } - - /// - /// 关闭连接 - /// - public void Close() - { - if (_Connection != null && _Connection.State == System.Data.ConnectionState.Open) - { - _Connection.Close(); - } - _Connection = null; - } - - /// - /// 连接MySQL服务器 - /// - /// 服务器信息 - /// 连接对象 - /// MySQL服务启动失败:无法找到MySQL配置文件 - private MySqlConnection? Connect(out SQLServerInfo? serverInfo) - { - try - { - string connectionString = ConnectProperties.GetConnectPropertiesForMySQL(); - if (connectionString != null) - { - string[] strings = connectionString.Split(";"); - if (strings.Length > 1 && strings[0].Length > 14 && strings[1].Length > 8) - { - ServerHelper.WriteLine("Connect -> MySQL://" + strings[0][14..] + ":" + strings[1][8..]); - } - _Connection = new MySqlConnection(connectionString); - _Connection.Open(); - if (_Connection.State == System.Data.ConnectionState.Open) - { - _ServerInfo = SQLServerInfo.Create(ConnectProperties.Name, ConnectProperties.DataSource, ConnectProperties.Port, ConnectProperties.DataBase, ConnectProperties.User, ConnectProperties.Password); - ServerHelper.WriteLine("Connected: MySQL服务器连接成功"); - } - } - else - { - throw new MySQLConfigException(); - } - } - catch (Exception e) - { - ServerHelper.Error(e); - } - - serverInfo = _ServerInfo; - return _Connection; - } - } -} diff --git a/FunGame.Server/Utilities/MySQL/MySQLHelper.cs b/FunGame.Server/Utilities/MySQL/MySQLHelper.cs index 7db2d5f..da5c40e 100644 --- a/FunGame.Server/Utilities/MySQL/MySQLHelper.cs +++ b/FunGame.Server/Utilities/MySQL/MySQLHelper.cs @@ -1,136 +1,170 @@ using System.Data; using Milimoe.FunGame.Core.Api.Transmittal; -using Milimoe.FunGame.Core.Interface.Base; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Model; -using Milimoe.FunGame.Server.Others; -using Milimoe.FunGame.Server.Utility.DataUtility; using MySql.Data.MySqlClient; -namespace Milimoe.FunGame.Server.Utility +namespace Milimoe.FunGame.Server.Utility.DataUtility { public class MySQLHelper : SQLHelper { - public override FunGameInfo.FunGame FunGameType => Config.FunGameType; - public override SQLMode Mode => SQLMode.MySQL; + public override FunGameInfo.FunGame FunGameType { get; } = FunGameInfo.FunGame.FunGame_Server; + public override SQLMode Mode { get; } = SQLMode.MySQL; public override string Script { get; set; } = ""; public override CommandType CommandType { get; set; } = CommandType.Text; - public override SQLResult Result => _Result; - public override SQLServerInfo ServerInfo => _ServerInfo ?? SQLServerInfo.Create(); - public override int UpdateRows => _UpdateRows; - public override DataSet DataSet => _DataSet; - public MySqlParameter[] Parameters { get; set; } - public MySQLConnection? Connection => _Connection; + public override SQLResult Result => _result; + public override SQLServerInfo ServerInfo => _serverInfo ?? SQLServerInfo.Create(); + public override int UpdateRows => _updateRows; + public override DataSet DataSet => _dataSet; - private SQLResult _Result = SQLResult.Success; - private SQLServerInfo? _ServerInfo; - private int _UpdateRows = 0; - private DataSet _DataSet = new(); - private MySQLConnection? _Connection; - private MySqlTransaction? _Transaction; - private readonly IServerModel? ServerModel; - private readonly bool _IsOneTime = false; + private readonly string _connectionString = ""; + private MySqlConnection? _connection; + private MySqlTransaction? _transaction; + private DataSet _dataSet = new(); + private SQLResult _result = SQLResult.NotFound; + private readonly SQLServerInfo? _serverInfo; + private int _updateRows = 0; + + public MySQLHelper(string script = "", CommandType type = CommandType.Text) + { + Script = script; + CommandType = type; + _connectionString = ConnectProperties.GetConnectPropertiesForMySQL(); + string[] strings = _connectionString.Split(";"); + if (strings.Length > 1 && strings[0].Length > 14 && strings[1].Length > 8) + { + string ip = strings[0][14..]; + string port = strings[1][8..]; + _serverInfo = SQLServerInfo.Create(ip: ip, port: port); + } + } + + /// + /// 打开数据库连接 + /// + private void OpenConnection() + { + _connection ??= new MySqlConnection(_connectionString); + if (_connection.State != ConnectionState.Open) + { + _connection.Open(); + } + } + + /// + /// 关闭数据库连接 + /// + public override void Close() + { + _transaction?.Dispose(); + _transaction = null; + if (_connection?.State != ConnectionState.Closed) + { + _connection?.Close(); + } + _connection?.Dispose(); + _connection = null; + } /// /// 执行一个命令 /// - /// 执行结果 - /// 影响的行数 + /// public override int Execute() { - // _IsOneTime = true需要手动创建连接和关闭 - ServerHelper.WriteLine("SQLQuery -> " + Script, InvokeMessageType.Api); - _DataSet = new DataSet(); - _UpdateRows = MySQLManager.Execute(this, out _Result); - if (_IsOneTime) Close(); - return _UpdateRows; + return Execute(Script); } /// /// 执行一个指定的命令 /// - /// 命令 - /// 执行结果 - /// 影响的行数 - public override int Execute(string Script) + /// + /// + /// + public override int Execute(string script) { - // _IsOneTime = true需要手动创建连接和关闭 - ServerHelper.WriteLine("SQLQuery -> " + Script, InvokeMessageType.Api); - this.Script = Script; - _DataSet = new DataSet(); - _UpdateRows = MySQLManager.Execute(this, out _Result); - if (_IsOneTime) Close(); - return _UpdateRows; + bool localTransaction = _transaction == null; + + try + { + if (localTransaction) + { + NewTransaction(); + } + OpenConnection(); + ServerHelper.WriteLine("SQLQuery -> " + script, InvokeMessageType.Api); + using MySqlCommand command = new(script, _connection); + command.CommandType = CommandType; + if (_transaction != null) command.Transaction = _transaction; + + _updateRows = command.ExecuteNonQuery(); + _result = SQLResult.Success; + if (localTransaction) Commit(); + } + catch (Exception e) + { + if (localTransaction) Rollback(); + _result = SQLResult.Fail; + ServerHelper.Error(e); + } + finally + { + if (localTransaction) Close(); + } + return UpdateRows; } /// /// 查询DataSet /// - /// 执行结果 - /// 结果集 + /// public override DataSet ExecuteDataSet() { - // _IsOneTime = true需要手动创建连接和关闭 - ServerHelper.WriteLine("SQLQuery -> " + Script, InvokeMessageType.Api); - _DataSet = MySQLManager.ExecuteDataSet(this, out _Result, out _UpdateRows); - if (_IsOneTime) Close(); - return DataSet; + return ExecuteDataSet(Script); } /// /// 执行指定的命令查询DataSet /// - /// 命令 - /// 执行结果 - /// 结果集 - public override DataSet ExecuteDataSet(string Script) + /// + /// + public override DataSet ExecuteDataSet(string script) { - // _IsOneTime = true需要手动创建连接和关闭 - ServerHelper.WriteLine("SQLQuery -> " + Script, InvokeMessageType.Api); - this.Script = Script; - _DataSet = MySQLManager.ExecuteDataSet(this, out _Result, out _UpdateRows); - if (_IsOneTime) Close(); - return DataSet; - } + bool localTransaction = _transaction == null; - /// - /// 关闭连接 如有事务会自动提交事务 - /// - public override void Close() - { - // _IsOneTime = false需要手动调用此方法 - Commit(); - _Connection?.Close(); - ServerHelper.WriteLine($"{(GetClientName() == string.Empty ? "" : GetClientName())}已释放MySQL连接"); - } + try + { + if (localTransaction) + { + NewTransaction(); + } + OpenConnection(); + ServerHelper.WriteLine("SQLQuery -> " + script, InvokeMessageType.Api); - /// - /// 创建SQLHelper - /// - /// 是否是单次使用(执行完毕会自动Close连接) - /// 存储过程名称或者script语句 - /// 存储过程, 文本, 等等 - /// 执行命令所用参数的集合 - public MySQLHelper(string script = "", bool IsOneTime = true, CommandType type = CommandType.Text, params MySqlParameter[] parameters) - { - Script = script; - _IsOneTime = IsOneTime; - CommandType = type; - Parameters = parameters; - _Connection = new MySQLConnection(out _ServerInfo); - } + using MySqlCommand command = new(script, _connection) + { + CommandType = CommandType + }; - /// - /// 创建为SocketModel服务的SQLHelper - /// - /// SocketModel - public MySQLHelper(IServerModel ServerModel) - { - this.ServerModel = ServerModel; - Script = ""; - CommandType = CommandType.Text; - Parameters = []; - _Connection = new MySQLConnection(out _ServerInfo); + MySqlDataAdapter adapter = new() + { + SelectCommand = command + }; + adapter.Fill(_dataSet); + + if (localTransaction) Commit(); + } + catch (Exception e) + { + if (localTransaction) Rollback(); + _result = SQLResult.Fail; + ServerHelper.Error(e); + } + finally + { + if (localTransaction) Close(); + } + return _dataSet; } /// @@ -138,7 +172,11 @@ namespace Milimoe.FunGame.Server.Utility /// public override void NewTransaction() { - _Transaction ??= _Connection?.Connection?.BeginTransaction(); + OpenConnection(); + if (_connection != null) + { + _transaction = _connection.BeginTransaction(); + } } /// @@ -146,8 +184,16 @@ namespace Milimoe.FunGame.Server.Utility /// public override void Commit() { - _Transaction?.Commit(); - _Transaction = null; + try + { + _transaction?.Commit(); + _result = SQLResult.Success; + } + catch (Exception e) + { + _result = SQLResult.Fail; + ServerHelper.Error(e); + } } /// @@ -155,17 +201,43 @@ namespace Milimoe.FunGame.Server.Utility /// public override void Rollback() { - _Transaction?.Rollback(); - _Transaction = null; + try + { + _transaction?.Rollback(); + _result = SQLResult.Success; + } + catch (Exception e) + { + _result = SQLResult.Fail; + ServerHelper.Error(e); + } } + private bool _isDisposed = false; + /// - /// 获取客户端名称 + /// 资源清理 /// - /// - private string GetClientName() + public void Dispose(bool disposing) { - return ServerModel?.GetClientName() ?? string.Empty; + if (!_isDisposed) + { + if (disposing) + { + _transaction?.Dispose(); + _transaction = null; + _connection?.Close(); + _connection?.Dispose(); + _connection = null; + } + } + _isDisposed = true; + } + + public override void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); } } } diff --git a/FunGame.Server/Utilities/MySQL/MySQLManager.cs b/FunGame.Server/Utilities/MySQL/MySQLManager.cs deleted file mode 100644 index bccbd55..0000000 --- a/FunGame.Server/Utilities/MySQL/MySQLManager.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System.Data; -using Milimoe.FunGame.Core.Library.Constant; -using MySql.Data.MySqlClient; - -namespace Milimoe.FunGame.Server.Utility -{ - public class MySQLManager - { - /// - /// 执行Script命令 - /// - /// MySQLHelper - /// 执行结果 - /// 影响的行数 - public static int Execute(MySQLHelper Helper, out SQLResult Result) - { - MySqlCommand cmd = new(); - int updaterow; - - try - { - PrepareCommand(Helper, cmd); - - updaterow = cmd.ExecuteNonQuery(); - if (updaterow > 0) - { - Result = SQLResult.Success; - } - else Result = SQLResult.NotFound; - } - catch (Exception e) - { - ServerHelper.Error(e); - updaterow = -1; - Result = SQLResult.Fail; - } - - return updaterow; - } - - /// - /// 返回DataSet - /// - /// MySQLHelper - /// 执行结果 - /// 结果集 - public static DataSet ExecuteDataSet(MySQLHelper Helper, out SQLResult Result, out int Rows) - { - MySqlCommand cmd = new(); - DataSet ds = new(); - Rows = 0; - - try - { - PrepareCommand(Helper, cmd); - - MySqlDataAdapter adapter = new() - { - SelectCommand = cmd - }; - adapter.Fill(ds); - - //清除参数 - cmd.Parameters.Clear(); - - Rows = ds.Tables[0].Rows.Count; - if (Rows > 0) Result = SQLResult.Success; - else Result = SQLResult.NotFound; - } - catch (Exception e) - { - ServerHelper.Error(e); - Result = SQLResult.Fail; - } - - return ds; - } - - /// - /// 返回插入值ID - /// - /// MySQLHelper - /// 执行结果 - /// 插入值ID - public static long ExecuteAndGetLastInsertedID(MySQLHelper Helper, out SQLResult Result) - { - MySqlCommand cmd = new(); - int updaterow; - - try - { - PrepareCommand(Helper, cmd); - - updaterow = cmd.ExecuteNonQuery(); - if (updaterow > 0) - { - Result = SQLResult.Success; - } - else Result = SQLResult.NotFound; - } - catch (Exception e) - { - ServerHelper.Error(e); - Result = SQLResult.Fail; - } - - return cmd.LastInsertedId; - } - - /// - /// 准备执行一个命令 - /// - /// MySQLHelper - /// 命令对象 - public static void PrepareCommand(MySQLHelper Helper, MySqlCommand cmd) - { - if (Helper.Connection != null) - { - MySqlConnection? conn = Helper.Connection.Connection; - - if (conn != null) - { - if (conn.State != ConnectionState.Open) conn.Open(); - - cmd.Connection = conn; - cmd.CommandText = Helper.Script; - cmd.CommandType = Helper.CommandType; - - if (Helper.Parameters != null) - { - foreach (MySqlParameter parm in Helper.Parameters) - { - cmd.Parameters.Add(parm); - } - } - } - } - } - } -} diff --git a/FunGame.Server/Utilities/SQLite/SQLiteHelper.cs b/FunGame.Server/Utilities/SQLite/SQLiteHelper.cs index 9b0ca92..d628713 100644 --- a/FunGame.Server/Utilities/SQLite/SQLiteHelper.cs +++ b/FunGame.Server/Utilities/SQLite/SQLiteHelper.cs @@ -17,13 +17,13 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility public override int UpdateRows => _updateRows; public override DataSet DataSet => _dataSet; - private readonly SqliteConnection _connection; + private readonly string _connectionString = ""; + private SqliteConnection? _connection; private SqliteTransaction? _transaction; private DataSet _dataSet = new(); private SQLResult _result = SQLResult.NotFound; private readonly SQLServerInfo? _serverInfo; private int _updateRows = 0; - private readonly string _connectionString = ""; public SQLiteHelper(string script = "", CommandType type = CommandType.Text) { @@ -33,10 +33,8 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility string[] strings = _connectionString.Split("="); if (strings.Length > 1) { - ServerHelper.WriteLine("Connect -> SQLite://" + strings[1]); _serverInfo = SQLServerInfo.Create(database: strings[1]); } - _connection = new SqliteConnection(_connectionString); } /// @@ -44,6 +42,7 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility /// private void OpenConnection() { + _connection ??= new SqliteConnection(_connectionString); if (_connection.State != ConnectionState.Open) { _connection.Open(); @@ -56,10 +55,13 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility public override void Close() { _transaction?.Dispose(); - if (_connection.State != ConnectionState.Closed) + _transaction = null; + if (_connection?.State != ConnectionState.Closed) { - _connection.Close(); + _connection?.Close(); } + _connection?.Dispose(); + _connection = null; } /// @@ -79,27 +81,35 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility /// public override int Execute(string script) { + bool localTransaction = _transaction == null; + try { + if (localTransaction) + { + NewTransaction(); + } OpenConnection(); ServerHelper.WriteLine("SQLQuery -> " + script, InvokeMessageType.Api); using SqliteCommand command = new(script, _connection); command.CommandType = CommandType; - if (_transaction != null) - { - command.Transaction = _transaction; - } + if (_transaction != null) command.Transaction = _transaction; _updateRows = command.ExecuteNonQuery(); _result = SQLResult.Success; - Close(); - return UpdateRows; + if (localTransaction) Commit(); } - catch (Exception ex) + catch (Exception e) { + if (localTransaction) Rollback(); _result = SQLResult.Fail; - throw new Exception($"SQL execution failed: {ex.Message}", ex); + ServerHelper.Error(e); } + finally + { + if (localTransaction) Close(); + } + return UpdateRows; } /// @@ -119,8 +129,14 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility /// public override DataSet ExecuteDataSet(string script) { + bool localTransaction = _transaction == null; + try { + if (localTransaction) + { + NewTransaction(); + } OpenConnection(); ServerHelper.WriteLine("SQLQuery -> " + script, InvokeMessageType.Api); using SqliteCommand command = new(script, _connection) @@ -132,42 +148,19 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility DataTable table = new(); table.Load(reader); _dataSet.Tables.Add(table); - Close(); - return _dataSet; + if (localTransaction) Commit(); } - catch (Exception ex) + catch (Exception e) { + if (localTransaction) Rollback(); _result = SQLResult.Fail; - throw new Exception($"SQL execution failed: {ex.Message}", ex); + ServerHelper.Error(e); } - } - - /// - /// 执行指定的命令查询DataRow - /// - /// - public override DataRow? ExecuteDataRow() - { - return ExecuteDataRow(Script); - } - - /// - /// 执行指定的命令查询DataRow - /// - /// - /// - public override DataRow? ExecuteDataRow(string script) - { - OpenConnection(); - ServerHelper.WriteLine("SQLQuery -> " + script, InvokeMessageType.Api); - DataSet dataSet = ExecuteDataSet(script); - if (dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0) + finally { - Close(); - return dataSet.Tables[0].Rows[0]; + if (localTransaction) Close(); } - Close(); - return null; + return _dataSet; } /// @@ -176,7 +169,10 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility public override void NewTransaction() { OpenConnection(); - _transaction = _connection.BeginTransaction(); + if (_connection != null) + { + _transaction = _connection.BeginTransaction(); + } } /// @@ -188,13 +184,12 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility try { _transaction?.Commit(); - Close(); _result = SQLResult.Success; } - catch (Exception ex) + catch (Exception e) { _result = SQLResult.Fail; - throw new Exception($"Transaction commit failed: {ex.Message}", ex); + ServerHelper.Error(e); } } @@ -207,23 +202,40 @@ namespace Milimoe.FunGame.Server.Utility.DataUtility try { _transaction?.Rollback(); - Close(); _result = SQLResult.Success; } - catch (Exception ex) + catch (Exception e) { _result = SQLResult.Fail; - throw new Exception($"Transaction rollback failed: {ex.Message}", ex); + ServerHelper.Error(e); } } + private bool _isDisposed = false; + /// /// 资源清理 /// - public void Dispose() + public void Dispose(bool disposing) { - _transaction?.Dispose(); - _connection.Dispose(); + if (!_isDisposed) + { + if (disposing) + { + _transaction?.Dispose(); + _transaction = null; + _connection?.Close(); + _connection?.Dispose(); + _connection = null; + } + } + _isDisposed = true; + } + + public override void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); } } } diff --git a/FunGame.WebAPI/Program.cs b/FunGame.WebAPI/Program.cs index 5fe6bd1..9ae6c34 100644 --- a/FunGame.WebAPI/Program.cs +++ b/FunGame.WebAPI/Program.cs @@ -33,22 +33,22 @@ try ServerHelper.InitOrderList(); // ȫSQLHelper - Config.InitSQLHelper(); + FunGameSystem.InitSQLHelper(); // ȫMailSender - Config.InitMailSender(); + FunGameSystem.InitMailSender(); // ȡϷģ - if (!Config.GetGameModuleList()) + if (!FunGameSystem.GetGameModuleList()) { ServerHelper.WriteLine("ƺδװκϷģ飬Ƿȷװǡ"); } // ȡServer - Config.GetServerPlugins(); + FunGameSystem.GetServerPlugins(); // ȡWeb API - Config.GetWebAPIPlugins(); + FunGameSystem.GetWebAPIPlugins(); // Ƿļ if (!INIHelper.ExistINIFile()) @@ -70,6 +70,8 @@ try ServerHelper.WriteLine(" help ȡ quit رշ"); + ServerHelper.PrintFunGameTitle(); + if (Config.ServerNotice != "") Console.WriteLine("\r \n********** **********\n\n" + Config.ServerNotice + "\n"); else