diff --git a/FunGame.Server/Main.cs b/FunGame.Server/Main.cs index 9986b4b..57dde2d 100644 --- a/FunGame.Server/Main.cs +++ b/FunGame.Server/Main.cs @@ -6,7 +6,7 @@ using Milimoe.FunGame.Server.Model; using Milimoe.FunGame.Server.Others; using Milimoe.FunGame.Server.Utility; -Console.Title = Config.SERVER_NAME; +Console.Title = Config.ServerName; Console.WriteLine(FunGameInfo.GetInfo((FunGameInfo.FunGame)Config.FunGameType)); bool Running = true; @@ -68,7 +68,7 @@ void StartServer() else { ServerHelper.GetServerSettings(); - Console.Title = Config.SERVER_NAME + " - FunGame Server Port: " + Config.SERVER_PORT; + Console.Title = Config.ServerName + " - FunGame Server Port: " + Config.ServerPort; } ServerHelper.WriteLine("请输入 help 来获取帮助,输入 quit 关闭服务器。"); @@ -83,11 +83,11 @@ void StartServer() ListeningSocket = ServerSocket.StartListening(); // 开始监听连接 - ServerHelper.WriteLine("Listen -> " + Config.SERVER_PORT); + ServerHelper.WriteLine("Listen -> " + Config.ServerPort); ServerHelper.WriteLine("服务器启动成功,开始监听 . . ."); - if (Config.SERVER_NOTICE != "") - ServerHelper.WriteLine("\n\n********** 服务器公告 **********\n\n" + Config.SERVER_NOTICE + "\n"); + if (Config.ServerNotice != "") + ServerHelper.WriteLine("\n\n********** 服务器公告 **********\n\n" + Config.ServerNotice + "\n"); else ServerHelper.WriteLine("无法读取服务器公告"); @@ -102,13 +102,12 @@ void StartServer() ServerHelper.WriteLine(SocketHelper.MakeClientName(ClientIPAddress) + " 正在连接服务器 . . ."); if (Read(socket) && Send(socket)) { - ServerModel ClientModel = new(socket, Running); + ServerModel ClientModel = new(ListeningSocket, socket, Running); Task t = Task.Factory.StartNew(() => { ClientModel.Start(); }); - ClientModel.Task = t; - ClientModel.ClientName = ClientIPAddress; + ClientModel.SetTaskAndClientName(t, ClientIPAddress); if (!Config.OnlineClients.ContainsKey(ClientIPAddress)) Config.OnlineClients.Add(ClientIPAddress, ClientIPAddress); } else @@ -167,9 +166,9 @@ bool Read(ClientSocket socket) bool Send(ClientSocket socket) { // 发送消息给客户端 - string msg = Config.SERVER_NAME + ";" + Config.SERVER_NOTICE; + string msg = Config.ServerName + ";" + Config.ServerNotice; byte[] buffer = new byte[2048]; - buffer = Config.DEFAULT_ENCODING.GetBytes($"1;{msg}"); + buffer = Config.DefaultEncoding.GetBytes($"1;{msg}"); if (socket.Send(SocketMessageType.Connect, msg, Guid.NewGuid()) == SocketResult.Success) { ServerHelper.WriteLine(SocketHelper.MakeClientName(socket.ClientIP) + " <- " + "已确认连接"); @@ -182,6 +181,6 @@ bool Send(ClientSocket socket) SQLResult TestSQLConnection() { - new MySQLHelper(true, SQLConstant.Insert_ServerLoginLogs(Config.SERVER_NAME, Config.SERVER_KEY)).Execute(out SQLResult TestResult); + new MySQLHelper(SQLConstant.Insert_ServerLoginLogs(Config.ServerName, Config.ServerKey)).Execute(out SQLResult TestResult); return TestResult; } \ No newline at end of file diff --git a/FunGame.Server/Model/ServerModel.cs b/FunGame.Server/Model/ServerModel.cs index 44d49dd..11ef458 100644 --- a/FunGame.Server/Model/ServerModel.cs +++ b/FunGame.Server/Model/ServerModel.cs @@ -1,12 +1,11 @@ -using Milimoe.FunGame.Core.Api.Utility; +using System.Data; +using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; -using Milimoe.FunGame.Core.Library.Exception; using Milimoe.FunGame.Core.Library.Server; using Milimoe.FunGame.Server.Others; using Milimoe.FunGame.Server.Utility; -using System.Data; namespace Milimoe.FunGame.Server.Model { @@ -15,26 +14,35 @@ namespace Milimoe.FunGame.Server.Model /** * Public */ - public new bool Running = false; - public new ClientSocket? Socket = null; - public new Task? Task = null; - public new string ClientName = ""; + public override bool Running => _Running; + public override ClientSocket? Socket => _Socket; + public override Task? Task => _Task; + public override string ClientName => _ClientName; + public override User? User => _User; /** * Private */ - private User? User = null; + private ClientSocket? _Socket = null; + private bool _Running = false; + private User? _User = null; + private Task? _Task = null; + private string _ClientName = ""; + private Guid CheckLoginKey = Guid.Empty; + private int FailedTimes = 0; // 超过一定次数断开连接 private string UserName = ""; private string Password = ""; - private int FailedTimes = 0; // 超过一定次数断开连接 + private string RoomID = ""; + private readonly ServerSocket Server; private readonly MySQLHelper SQLHelper; - public ServerModel(ClientSocket socket, bool running) + public ServerModel(ServerSocket server, ClientSocket socket, bool running) { - Socket = socket; - Running = running; - SQLHelper = new(SocketHelper.MakeClientName(socket.ClientIP)); + Server = server; + _Socket = socket; + _Running = running; + SQLHelper = new(this); } public override bool Read(ClientSocket socket) @@ -49,8 +57,7 @@ namespace Milimoe.FunGame.Server.Model string msg = ""; // 如果不等于这些Type,就不会输出一行记录。这些Type有特定的输出。 - SocketMessageType ignoreType = SocketMessageType.HeartBeat | SocketMessageType.Login; - if ((type & ignoreType) == 0) + if (type != SocketMessageType.HeartBeat && type != SocketMessageType.Login) { if (msg.Trim() == "") ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] " + SocketHelper.MakeClientName(ClientName, User)); @@ -61,7 +68,7 @@ namespace Milimoe.FunGame.Server.Model switch (type) { case SocketMessageType.GetNotice: - msg = Config.SERVER_NOTICE; + msg = Config.ServerNotice; break; case SocketMessageType.Login: @@ -77,7 +84,7 @@ namespace Milimoe.FunGame.Server.Model ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] UserName: " + username); SQLHelper.Script = $"{SQLConstant.Select_Users} {SQLConstant.Command_Where} Username = '{username}' And Password = '{password}'"; SQLHelper.ExecuteDataSet(out SQLResult result); - if (result == SQLResult.Success && SQLHelper.UpdateRows > 0) + if (result == SQLResult.Success) { DataRow UserRow = SQLHelper.DataSet.Tables[0].Rows[0]; if (autokey != null && autokey.Trim() != "") @@ -100,12 +107,12 @@ namespace Milimoe.FunGame.Server.Model if (CheckLoginKey.Equals(checkloginkey)) { // 创建User对象 - User = Factory.New(UserName, Password); + _User = Factory.New(UserName, Password); // 检查有没有重复登录的情况 KickUser(); // 添加至玩家列表 AddUser(); - GetUserCount(); + GetUsersCount(); return Send(socket, type, UserName, Password); } ServerHelper.WriteLine("客户端发送了错误的秘钥,不允许本次登录。"); @@ -121,18 +128,18 @@ namespace Milimoe.FunGame.Server.Model { // 从玩家列表移除 RemoveUser(); - GetUserCount(); + GetUsersCount(); CheckLoginKey = Guid.Empty; msg = "你已成功退出登录! "; - return Send(socket, type, checklogoutkey, msg); + return Send(socket, type, checklogoutkey, msg); } } ServerHelper.WriteLine("客户端发送了错误的秘钥,不允许本次登出。"); return Send(socket, type, checklogoutkey); case SocketMessageType.Disconnect: - msg = "你已成功断开与服务器的连接: " + Config.SERVER_NAME + "。 "; - GetUserCount(); + msg = "你已成功断开与服务器的连接: " + Config.ServerName + "。 "; + GetUsersCount(); break; case SocketMessageType.HeartBeat: @@ -142,7 +149,23 @@ namespace Milimoe.FunGame.Server.Model case SocketMessageType.IntoRoom: msg = "-1"; if (args != null && args.Length > 0) msg = NetworkUtility.ConvertJsonObject(args[0])!; + RoomID = msg; break; + + case SocketMessageType.Chat: + if (args != null && args.Length > 0) msg = NetworkUtility.ConvertJsonObject(args[0])!; + ServerHelper.WriteLine(msg); + foreach (ServerModel Client in Server.GetUsersList.Cast()) + { + if (RoomID == Client.RoomID) + { + if (Client != null && User != null) + { + Client.Send(Client.Socket!, SocketMessageType.Chat, User.Username, msg); + } + } + } + return true; } return Send(socket, type, msg); } @@ -161,15 +184,17 @@ namespace Milimoe.FunGame.Server.Model { if (socket.Send(type, objs) == SocketResult.Success) { - // Logout和Disconnect需要移除User与其线程 - if (type == SocketMessageType.Logout) + switch (type) { - RemoveUser(); - } - if (type == SocketMessageType.Disconnect) - { - RemoveUser(); - Close(); + case SocketMessageType.Logout: + RemoveUser(); + break; + case SocketMessageType.Disconnect: + RemoveUser(); + Close(); + break; + case SocketMessageType.Chat: + return true; } object obj = objs[0]; if (obj.GetType() == typeof(string) && (string)obj != "") @@ -194,38 +219,45 @@ namespace Milimoe.FunGame.Server.Model }); } + public void SetTaskAndClientName(Task t, string ClientName) + { + _Task = t; + _ClientName = ClientName; + } + private void KickUser() { - if (User != null && Config.OnlinePlayers.ContainsKey(User.Username)) + if (User != null) { - ServerHelper.WriteLine("OnlinePlayers: 玩家 " + User.Username + " 重复登录!"); - Config.OnlinePlayers.TryGetValue(User.Username, out ServerModel? serverTask); - serverTask?.Send(serverTask.Socket!, SocketMessageType.Logout, serverTask.CheckLoginKey, "您的账号在别处登录,已强制下线。"); + string user = User.Username; + if (Server.ContainsUser(user)) + { + ServerHelper.WriteLine("OnlinePlayers: 玩家 " + user + " 重复登录!"); + ServerModel serverTask = (ServerModel)Server.GetUser(user); + serverTask?.Send(serverTask.Socket!, SocketMessageType.Logout, serverTask.CheckLoginKey, "您的账号在别处登录,已强制下线。"); + } } } private bool AddUser() { - if (User != null) + if (User != null && this != null) { - if (this != null) - { - Config.OnlinePlayers.AddOrUpdate(User.Username, this, (key, value) => value); - ServerHelper.WriteLine("OnlinePlayers: 玩家 " + User.Username + " 已添加"); - return true; - } + Server.AddUser(User.Username, this); + ServerHelper.WriteLine("OnlinePlayers: 玩家 " + User.Username + " 已添加"); + return true; } return false; } private bool RemoveUser() { - if (this != null && User != null) + if (User != null && this != null) { - if (Config.OnlinePlayers.TryRemove(User.Username, out _)) + if (Server.RemoveUser(User.Username)) { ServerHelper.WriteLine("OnlinePlayers: 玩家 " + User.Username + " 已移除"); - User = null; + _User = null; return true; } else ServerHelper.WriteLine("OnlinePlayers: 移除玩家 " + User.Username + " 失败"); @@ -233,9 +265,9 @@ namespace Milimoe.FunGame.Server.Model return false; } - private void GetUserCount() + private void GetUsersCount() { - ServerHelper.WriteLine("目前在线玩家数量: " + Config.OnlinePlayers.Count); + ServerHelper.WriteLine("目前在线玩家数量: " + Server.UsersCount); } private void CreateStreamReader() @@ -249,10 +281,11 @@ namespace Milimoe.FunGame.Server.Model if (!Read(Socket)) { FailedTimes++; - if (FailedTimes >= Config.MAX_CONNECTFAILED) + if (FailedTimes >= Config.MaxConnectionFaileds) { RemoveUser(); - GetUserCount(); + Close(); + GetUsersCount(); ServerHelper.WriteLine(SocketHelper.MakeClientName(ClientName, User) + " Error -> Too Many Faileds."); ServerHelper.WriteLine(SocketHelper.MakeClientName(ClientName, User) + " Close -> StreamReader is Closed."); break; @@ -263,7 +296,8 @@ namespace Milimoe.FunGame.Server.Model else { RemoveUser(); - GetUserCount(); + Close(); + GetUsersCount(); ServerHelper.WriteLine(SocketHelper.MakeClientName(ClientName, User) + " Error -> Socket is Closed."); ServerHelper.WriteLine(SocketHelper.MakeClientName(ClientName, User) + " Close -> StringStream is Closed."); break; @@ -279,9 +313,9 @@ namespace Milimoe.FunGame.Server.Model if (Socket != null) { Socket.Close(); - Socket = null; + _Socket = null; } - Running = false; + _Running = false; } catch (Exception e) { diff --git a/FunGame.Server/Others/Config.cs b/FunGame.Server/Others/Config.cs index 8073962..947e8d3 100644 --- a/FunGame.Server/Others/Config.cs +++ b/FunGame.Server/Others/Config.cs @@ -1,42 +1,25 @@ -using System.Collections; -using System.Collections.Concurrent; -using System.Text; +using System.Text; +using System.Collections; using Milimoe.FunGame.Core.Library.Constant; -using Milimoe.FunGame.Server.Model; namespace Milimoe.FunGame.Server.Others { public static class Config { - public static string SERVER_NAME { get; set; } = "FunGame Server"; // 服务器名称 - public static int SERVER_PORT { get; set; } = 22222; // 默认端口 - public static int SERVER_STATUS { get; set; } = 1; // 默认状态:1可连接 0不可连接 -1不可用 - public static string SERVER_NOTICE { get; set; } = ""; // 服务器的公告 - public static string SERVER_PASSWORD { get; set; } = ""; // 服务器的密码 - public static string SERVER_DESCRIBE { get; set; } = ""; // 服务器的描述 - public static string SERVER_KEY { get; set; } = ""; // 注册社区服务器的Key - public static int MAX_PLAYERS { get; set; } = 20; // 最多接受连接的玩家数量 - public static int MAX_CONNECTFAILED { get; set; } = 5; // 最大连接失败次数 - public static int ONLINE_PLAYERS { get; set; } = 0; // 已连接的玩家数量 - public static int CONNECTING_PLAYERS { get; set; } = 0; // 正在连接的玩家数量 - public static Encoding DEFAULT_ENCODING { get; } = General.DefaultEncoding; // 默认传输字符集 - public static int FunGameType { get; } = (int)FunGameInfo.FunGame.FunGame_Server; - + public static string ServerName { get; set; } = "FunGame Server"; // 服务器名称 + public static int ServerPort { get; set; } = 22222; // 默认端口 + public static int ServerStatus { get; set; } = 1; // 默认状态:1可连接 0不可连接 -1不可用 + public static string ServerNotice { get; set; } = ""; // 服务器的公告 + public static string ServerPassword { get; set; } = ""; // 服务器的密码 + public static string ServerDescription { get; set; } = ""; // 服务器的描述 + public static string ServerKey { get; set; } = ""; // 注册社区服务器的Key + public static int MaxPlayers { get; set; } = 20; // 最多接受连接的玩家数量 + public static int MaxConnectionFaileds { get; set; } = 5; // 最大连接失败次数 + public static int OnlinePlayersCount { get; set; } = 0; // 已连接的玩家数量 + public static int ConnectingPlayersCount { get; set; } = 0; // 正在连接的玩家数量 + public static Encoding DefaultEncoding { get; } = General.DefaultEncoding; // 默认传输字符集 + public static FunGameInfo.FunGame FunGameType { get; } = FunGameInfo.FunGame.FunGame_Server; public static Hashtable OrderList { get; } = new(); - public static Hashtable OnlineClients { get; } = new Hashtable(); - - /// - /// string: 玩家标识ID - /// Task:玩家线程 - /// - public static ConcurrentDictionary OnlinePlayers { get; } = new ConcurrentDictionary(); - - /** - * string:房间号 - * Task:玩家线程 - */ - public static ConcurrentDictionary PlayingPlayers { get; } = new ConcurrentDictionary(); - } } diff --git a/FunGame.Server/Utility/DataUtility/MySQLHelper.cs b/FunGame.Server/Utility/DataUtility/MySQLHelper.cs index fb1d29f..594c539 100644 --- a/FunGame.Server/Utility/DataUtility/MySQLHelper.cs +++ b/FunGame.Server/Utility/DataUtility/MySQLHelper.cs @@ -4,11 +4,14 @@ using Milimoe.FunGame.Core.Api.Data; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Server; using Milimoe.FunGame.Server.Utility.DataUtility; +using Milimoe.FunGame.Server.Others; +using Milimoe.FunGame.Server.Model; namespace Milimoe.FunGame.Server.Utility { public class MySQLHelper : SQLHelper { + public override FunGameInfo.FunGame FunGameType => Config.FunGameType; public override string Script { get; set; } = ""; public override CommandType CommandType { get; set; } = CommandType.Text; public override SQLResult Result => _Result; @@ -23,8 +26,8 @@ namespace Milimoe.FunGame.Server.Utility private int _UpdateRows = 0; private DataSet _DataSet = new(); private MySQLConnection? _Connection; - private bool _IsOneTime = false; - private string _ClientName = ""; + private readonly ServerModel? ServerModel; + private readonly bool _IsOneTime = false; /// /// 执行一个命令 @@ -64,40 +67,40 @@ namespace Milimoe.FunGame.Server.Utility { // _IsOneTime = false需要手动调用此方法 _Connection?.Close(); - ServerHelper.WriteLine($"{(_ClientName != "" ? _ClientName : "")} 已释放MySQL连接"); + ServerHelper.WriteLine($"{GetClientName()} 已释放MySQL连接"); } /// - /// 创建SQLHelper + /// 创建单次使用的SQLHelper(执行完毕会自动Close连接) /// - /// 是否是单次使用的(执行完毕会自动Close连接) /// 存储过程名称或者script语句 /// 存储过程, 文本, 等等 /// 执行命令所用参数的集合 - public MySQLHelper(bool IsOneTime = false, string script = "", CommandType type = CommandType.Text, params MySqlParameter[] parameters) + public MySQLHelper(string script = "", CommandType type = CommandType.Text, params MySqlParameter[] parameters) { - _IsOneTime = IsOneTime; + _IsOneTime = true; Script = script; CommandType = type; Parameters = parameters; - if (!IsOneTime) - { - _Connection = new MySQLConnection(out _ServerInfo); - } } /// /// 创建为SocketModel服务的SQLHelper /// - /// Socket客户端名称 - public MySQLHelper(string ClientName) + /// SocketModel + public MySQLHelper(ServerModel ServerModel) { - _ClientName = ClientName; - _IsOneTime = false; + this.ServerModel = ServerModel; Script = ""; CommandType = CommandType.Text; - Parameters = new MySqlParameter[] { }; + Parameters = Array.Empty(); _Connection = new MySQLConnection(out _ServerInfo); } + + private string GetClientName() + { + if (ServerModel is null) return ""; + return SocketHelper.MakeClientName(ServerModel.ClientName, ServerModel.User); + } } } diff --git a/FunGame.Server/Utility/Utility.cs b/FunGame.Server/Utility/Utility.cs index 8cecf00..c9a55c8 100644 --- a/FunGame.Server/Utility/Utility.cs +++ b/FunGame.Server/Utility/Utility.cs @@ -11,7 +11,7 @@ namespace Milimoe.FunGame.Server.Utility public static string GetPrefix() { DateTime now = System.DateTime.Now; - return now.AddMilliseconds(-now.Millisecond).ToString() + " " + Config.SERVER_NAME + ":"; + return now.AddMilliseconds(-now.Millisecond).ToString() + " " + Config.ServerName + ":"; } public static void Error(Exception e) @@ -59,19 +59,19 @@ namespace Milimoe.FunGame.Server.Utility string? Describe = (string?)settings["Describe"]; string? Notice = (string?)settings["Notice"]; string? Key = (string?)settings["Key"]; - if (Name != null) Config.SERVER_NAME = Name; - if (Password != null) Config.SERVER_PASSWORD = Password; - if (Describe != null) Config.SERVER_DESCRIBE = Describe; - if (Notice != null) Config.SERVER_NOTICE = Notice; - if (Key != null) Config.SERVER_KEY = Key; + if (Name != null) Config.ServerName = Name; + if (Password != null) Config.ServerPassword = Password; + if (Describe != null) Config.ServerDescription = Describe; + if (Notice != null) Config.ServerNotice = Notice; + if (Key != null) Config.ServerKey = Key; int? Status = (int?)settings["Status"]; int? Port = (int?)settings["Port"]; int? MaxPlayer = (int?)settings["MaxPlayer"]; int? MaxConnectFailed = (int?)settings["MaxConnectFailed"]; - if (Status != null) Config.SERVER_STATUS = (int)Status; - if (Port != null) Config.SERVER_PORT = (int)Port; - if (MaxPlayer != null) Config.MAX_PLAYERS = (int)MaxPlayer; - if (MaxConnectFailed != null) Config.MAX_CONNECTFAILED = (int)MaxConnectFailed; + if (Status != null) Config.ServerStatus = (int)Status; + if (Port != null) Config.ServerPort = (int)Port; + if (MaxPlayer != null) Config.MaxPlayers = (int)MaxPlayer; + if (MaxConnectFailed != null) Config.MaxConnectionFaileds = (int)MaxConnectFailed; } } catch (Exception e)