From 7a6b40800d38b6ad005b5521b8f8bddb22f9e9ae Mon Sep 17 00:00:00 2001 From: milimoe <110188673+milimoe@users.noreply.github.com> Date: Thu, 14 Sep 2023 22:15:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9E=B6=E6=9E=84=20(#24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加ServerController;DataRequest添加GetNotice * DataRequest添加Reg * 添加RoomS * 修改架构之Connect * 迁移其他的Socket业务至DataRequest * 更新连接服务器的逻辑 * 修改架构之Login * 更新Core * 修复IntoRoom Bug * 修复ForceLogOut Bug * 修复CreateRoom QuitRoom IntoRoom * 修复QuitRoom Bug和进入房间的广播 * 添加查看列表指令,完善kick和forcelogout * 数量显示错误 * 修复QuitRoom ConnectingCount Bug --- .../Controllers/DataRequestController.cs | 476 +++++++++++++++- FunGame.Server/Main.cs | 112 ++-- FunGame.Server/Models/ConsoleModel.cs | 86 +++ FunGame.Server/Models/ServerModel.cs | 514 +++++------------- FunGame.Server/Models/SocketMessageHandler.cs | 7 - FunGame.Server/Others/Config.cs | 4 +- FunGame.Server/Others/OrderDictionary.cs | 6 + FunGame.Server/Utilities/General.cs | 11 +- FunGame.Server/Utilities/MySQLManager.cs | 2 - 9 files changed, 753 insertions(+), 465 deletions(-) create mode 100644 FunGame.Server/Models/ConsoleModel.cs delete mode 100644 FunGame.Server/Models/SocketMessageHandler.cs diff --git a/FunGame.Server/Controllers/DataRequestController.cs b/FunGame.Server/Controllers/DataRequestController.cs index 4a213f7..677012e 100644 --- a/FunGame.Server/Controllers/DataRequestController.cs +++ b/FunGame.Server/Controllers/DataRequestController.cs @@ -1,6 +1,8 @@ using System.Collections; +using System.Data; using Milimoe.FunGame.Core.Api.Transmittal; 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.SQLScript.Common; @@ -16,8 +18,11 @@ namespace Milimoe.FunGame.Server.Controller public ServerModel Server { get; } public MySQLHelper SQLHelper => Server.SQLHelper; public MailSender? MailSender => Server.MailSender; + public DataRequestType LastRequest => _LastRequest; private string ForgetVerify = ""; + private string RegVerify = ""; + private DataRequestType _LastRequest = DataRequestType.UnKnown; public DataRequestController(ServerModel server) { @@ -27,12 +32,52 @@ namespace Milimoe.FunGame.Server.Controller public Hashtable GetResultData(DataRequestType type, Hashtable data) { Hashtable result = new(); + _LastRequest = type; switch (type) { case DataRequestType.UnKnown: break; + + case DataRequestType.RunTime_Logout: + LogOut(data, result); + break; + + case DataRequestType.Main_GetNotice: + GetServerNotice(result); + break; + case DataRequestType.Main_CreateRoom: + CreateRoom(data, result); + break; + + case DataRequestType.Main_UpdateRoom: + UpdateRoom(result); + break; + + case DataRequestType.Main_IntoRoom: + IntoRoom(data, result); + break; + + case DataRequestType.Main_QuitRoom: + QuitRoom(data, result); + break; + + case DataRequestType.Main_MatchRoom: + break; + + case DataRequestType.Main_Chat: + Chat(data); + break; + + case DataRequestType.Reg_GetRegVerifyCode: + Reg(data, result); + break; + + case DataRequestType.Login_Login: + Login(data, result); + break; + case DataRequestType.Login_GetFindPasswordVerifyCode: ForgetPassword(data, result); break; @@ -40,20 +85,425 @@ namespace Milimoe.FunGame.Server.Controller case DataRequestType.Login_UpdatePassword: UpdatePassword(data, result); break; + + case DataRequestType.Room_GetRoomSettings: + break; + + case DataRequestType.Room_GetRoomPlayerCount: + GetRoomPlayerCount(data, result); + break; + + case DataRequestType.Room_UpdateRoomMaster: + break; + + default: + break; } return result; } + #region RunTime + + /// + /// 退出登录 + /// + /// + /// + private void LogOut(Hashtable RequestData, Hashtable ResultData) + { + string msg = ""; + Guid key = Guid.Empty; + if (RequestData.Count >= 1) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> LogOut"); + key = DataRequest.GetHashtableJsonObject(RequestData, "key"); + if (Server.IsLoginKey(key)) + { + Server.LogOut(); + msg = "你已成功退出登录! "; + } + } + ResultData.Add("msg", msg); + ResultData.Add("key", key); + } + + #endregion + + #region Main + + /// + /// 获取公告 + /// + /// + private void GetServerNotice(Hashtable ResultData) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> GetNotice"); + _LastRequest = DataRequestType.Main_GetNotice; + ResultData.Add("notice", Config.ServerNotice); + } + + /// + /// 创建房间 + /// + /// + /// + private void CreateRoom(Hashtable RequestData, Hashtable ResultData) + { + string roomid = "-1"; + if (RequestData.Count >= 3) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> CreateRoom"); + string roomtype_string = DataRequest.GetHashtableJsonObject(RequestData, "roomtype") ?? GameMode.GameMode_All; + User user = DataRequest.GetHashtableJsonObject(RequestData, "master") ?? Factory.GetUser(); + string password = DataRequest.GetHashtableJsonObject(RequestData, "password") ?? ""; + + if (!string.IsNullOrWhiteSpace(roomtype_string) && user.Id != 0) + { + RoomType roomtype = roomtype_string switch + { + GameMode.GameMode_Mix => RoomType.Mix, + GameMode.GameMode_Team => RoomType.Team, + GameMode.GameMode_MixHasPass => RoomType.MixHasPass, + GameMode.GameMode_TeamHasPass => RoomType.TeamHasPass, + _ => RoomType.All + }; + roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7).ToUpper(); + SQLHelper.Execute(RoomQuery.Insert_CreateRoom(roomid, user.Id, roomtype, password ?? "")); + if (SQLHelper.Result == SQLResult.Success) + { + ServerHelper.WriteLine("[CreateRoom] Master: " + user.Username + " RoomID: " + roomid); + } + } + } + ResultData.Add("roomid", roomid); + } + + /// + /// 更新房间列表 + /// + /// + private void UpdateRoom(Hashtable ResultData) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> UpdateRoom"); + Config.RoomList ??= new(); + Config.RoomList.Clear(); + DataSet DsRoomTemp = SQLHelper.ExecuteDataSet(RoomQuery.Select_Rooms); + DataSet DsUserTemp = SQLHelper.ExecuteDataSet(UserQuery.Select_Users); + List rooms = Factory.GetRooms(DsRoomTemp, DsUserTemp); + Config.RoomList.AddRooms(rooms); // 更新服务器中的房间列表 + ResultData.Add("rooms", rooms); // 传RoomList + } + + /// + /// 退出房间,并更新房主 + /// + /// + /// + private void QuitRoom(Hashtable RequestData, Hashtable ResultData) + { + bool result = false; + if (RequestData.Count >= 2) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> QuitRoom"); + string roomid = DataRequest.GetHashtableJsonObject(RequestData, "roomid") ?? "-1"; + bool isMaster = DataRequest.GetHashtableJsonObject(RequestData, "isMaster"); + + if (roomid != "-1") + { + Config.RoomList.QuitRoom(roomid, Server.User); + Room Room = Config.RoomList[roomid] ?? General.HallInstance; + // 是否是房主 + if (isMaster) + { + List users = Config.RoomList.GetPlayerList(roomid); + if (users.Count > 0) // 如果此时房间还有人,更新房主 + { + User NewMaster = users[0]; + Room.RoomMaster = NewMaster; + SQLHelper.Execute(RoomQuery.Update_QuitRoom(roomid, Server.User.Id, NewMaster.Id)); + if (SQLHelper.Result == SQLResult.Success) + { + Server.Room = General.HallInstance; + Server.UpdateRoomMaster(Room, true); + result = true; + } + } + else // 没人了就解散房间 + { + Config.RoomList.RemoveRoom(roomid); + SQLHelper.Execute(RoomQuery.Delete_QuitRoom(roomid, Server.User.Id)); + if (SQLHelper.Result == SQLResult.Success) + { + Server.Room = General.HallInstance; + ServerHelper.WriteLine("[ " + Server.GetClientName() + " ] 解散了房间 " + roomid); + result = true; + } + } + } + // 不是房主直接退出房间 + else + { + Server.Room = General.HallInstance; + Server.UpdateRoomMaster(Room); + result = true; + } + } + } + ResultData.Add("result", result); + } + + /// + /// 进入房间 + /// + /// + /// + private void IntoRoom(Hashtable RequestData, Hashtable ResultData) + { + bool result = false; + if (RequestData.Count >= 1) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> IntoRoom"); + string roomid = DataRequest.GetHashtableJsonObject(RequestData, "roomid") ?? "-1"; + + if (roomid != "-1") + { + Config.RoomList.IntoRoom(roomid, Server.User); + Server.IntoRoom(roomid); + result = true; + } + } + ResultData.Add("result", result); + } + + /// + /// 发送聊天消息 + /// + /// + private void Chat(Hashtable RequestData) + { + if (RequestData.Count >= 1) + { + string msg = DataRequest.GetHashtableJsonObject(RequestData, "msg") ?? ""; + if (msg.Trim() != "") Server.Chat(msg); + } + } + + #endregion + + #region Reg + + /// + /// 接收并验证注册验证码 + /// + /// + /// + private void Reg(Hashtable RequestData, Hashtable ResultData) + { + string msg = ""; + RegInvokeType returnType = RegInvokeType.None; + bool success = false; + if (RequestData.Count >= 4) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> Reg"); + string username = DataRequest.GetHashtableJsonObject(RequestData, "username") ?? ""; + string password = DataRequest.GetHashtableJsonObject(RequestData, "password") ?? ""; + string email = DataRequest.GetHashtableJsonObject(RequestData, "email") ?? ""; + string verifycode = DataRequest.GetHashtableJsonObject(RequestData, "verifycode") ?? ""; + + // 如果没发验证码,就生成验证码 + if (verifycode.Trim() == "") + { + // 先检查账号是否重复 + SQLHelper.ExecuteDataSet(UserQuery.Select_IsExistUsername(username)); + if (SQLHelper.Result == SQLResult.Success) + { + ServerHelper.WriteLine(Server.GetClientName() + " 账号已被注册"); + msg = "此账号名已被使用!"; + returnType = RegInvokeType.DuplicateUserName; + } + else + { + // 检查邮箱是否重复 + SQLHelper.ExecuteDataSet(UserQuery.Select_IsExistEmail(email)); + if (SQLHelper.Result == SQLResult.Success) + { + ServerHelper.WriteLine(Server.GetClientName() + " 邮箱已被注册"); + msg = "此邮箱已被注册!"; + returnType = RegInvokeType.DuplicateEmail; + } + else + { + // 检查验证码是否发送过 + SQLHelper.ExecuteDataSet(RegVerifyCodes.Select_HasSentRegVerifyCode(username, email)); + if (SQLHelper.Result == SQLResult.Success) + { + DateTime RegTime = (DateTime)SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegTime]; + string RegVerifyCode = (string)SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegVerifyCode]; + if ((DateTime.Now - RegTime).TotalMinutes < 10) + { + ServerHelper.WriteLine(Server.GetClientName() + $" 十分钟内已向{email}发送过验证码:{RegVerifyCode}"); + } + returnType = RegInvokeType.InputVerifyCode; + } + else + { + // 发送验证码,需要先删除之前过期的验证码 + SQLHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(username, email)); + RegVerify = Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 6); + SQLHelper.Execute(RegVerifyCodes.Insert_RegVerifyCode(username, email, RegVerify)); + if (SQLHelper.Result == SQLResult.Success) + { + if (MailSender != null) + { + // 发送验证码 + string ServerName = Config.ServerName; + string Subject = $"[{ServerName}] FunGame 注册验证码"; + string Body = $"亲爱的 {username},
感谢您注册[{ServerName}],您的验证码是 {RegVerify} ,10分钟内有效,请及时输入!

{ServerName}
{DateTimeUtility.GetDateTimeToString(TimeType.DateOnly)}"; + string[] To = new string[] { email }; + if (MailSender.Send(MailSender.CreateMail(Subject, Body, System.Net.Mail.MailPriority.Normal, true, To)) == MailSendResult.Success) + { + ServerHelper.WriteLine(Server.GetClientName() + $" 已向{email}发送验证码:{RegVerify}"); + } + else + { + ServerHelper.WriteLine(Server.GetClientName() + " 无法发送验证码"); + ServerHelper.WriteLine(MailSender.ErrorMsg); + } + } + else // 不使用MailSender的情况 + { + ServerHelper.WriteLine(Server.GetClientName() + $" 验证码为:{RegVerify},请服务器管理员告知此用户"); + } + returnType = RegInvokeType.InputVerifyCode; + } + } + } + } + } + else + { + // 先检查验证码 + SQLHelper.ExecuteDataSet(RegVerifyCodes.Select_RegVerifyCode(username, email, verifycode)); + if (SQLHelper.Result == SQLResult.Success) + { + // 检查验证码是否过期 + DateTime RegTime = (DateTime)SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegTime]; + if ((DateTime.Now - RegTime).TotalMinutes >= 10) + { + ServerHelper.WriteLine(Server.GetClientName() + " 验证码已过期"); + msg = "此验证码已过期,请重新注册。"; + SQLHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(username, email)); + } + else + { + // 注册 + if (RegVerify.Equals(SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegVerifyCode])) + { + ServerHelper.WriteLine("[Reg] UserName: " + username + " Email: " + email); + SQLHelper.Execute(UserQuery.Insert_Register(username, password, email, Server.Socket?.ClientIP ?? "")); + if (SQLHelper.Result == SQLResult.Success) + { + success = true; + msg = "注册成功!请牢记您的账号与密码!"; + SQLHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(username, email)); + } + else + { + msg = "服务器无法处理您的注册,注册失败!"; + } + } + else msg = "验证码不正确,请重新输入!"; + } + } + else if (SQLHelper.Result == SQLResult.NotFound) msg = "验证码不正确,请重新输入!"; + else msg = "服务器无法处理您的注册,注册失败!"; + } + } + ResultData.Add("msg", msg); + ResultData.Add("type", returnType); + ResultData.Add("success", success); + } + + #endregion + + #region Login + + /// + /// 登录 + /// + /// + /// + private void Login(Hashtable RequestData, Hashtable ResultData) + { + string msg = ""; + User user = Factory.GetUser(); + if (RequestData.Count >= 4) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> Login"); + string username = DataRequest.GetHashtableJsonObject(RequestData, "username") ?? ""; + string password = DataRequest.GetHashtableJsonObject(RequestData, "password") ?? ""; + string autokey = DataRequest.GetHashtableJsonObject(RequestData, "autokey") ?? ""; + Guid key = DataRequest.GetHashtableJsonObject(RequestData, "key"); + + // CheckLogin的情况 + if (key != Guid.Empty) + { + if (Server.IsLoginKey(key)) + { + Server.CheckLogin(); + user = Server.User; + } + else ServerHelper.WriteLine("客户端发送了错误的秘钥,不允许本次登录。"); + } + else + { + // 验证登录 + if (username != null && password != null) + { + ServerHelper.WriteLine("[" + DataRequest.GetTypeString(DataRequestType.Login_Login) + "] UserName: " + username); + SQLHelper.ExecuteDataSet(UserQuery.Select_Users_LoginQuery(username, password)); + if (SQLHelper.Result == SQLResult.Success) + { + DataSet DsUser = SQLHelper.DataSet; + if (autokey.Trim() != "") + { + SQLHelper.ExecuteDataSet(UserQuery.Select_CheckAutoKey(username, autokey)); + if (SQLHelper.Result == SQLResult.Success) + { + ServerHelper.WriteLine("[" + DataRequest.GetTypeString(DataRequestType.Login_Login) + "] AutoKey: 已确认"); + } + else + { + msg = "AutoKey不正确,拒绝自动登录!"; + ServerHelper.WriteLine("[" + DataRequest.GetTypeString(DataRequestType.Login_Login) + "] " + msg); + } + } + key = Guid.NewGuid(); + Server.PreLogin(DsUser, username, key); + ResultData.Add("key", key); + } + else + { + msg = "用户名或密码不正确。"; + ServerHelper.WriteLine(msg); + } + } + } + } + ResultData.Add("msg", msg); + ResultData.Add("user", user); + } + /// /// 接收并验证找回密码时的验证码 /// /// /// - public void ForgetPassword(Hashtable RequestData, Hashtable ResultData) + private void ForgetPassword(Hashtable RequestData, Hashtable ResultData) { string msg = "无法找回您的密码,请稍后再试。"; // 返回的验证信息 - if (RequestData.Count >= 2) + if (RequestData.Count >= 3) { ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> ForgetPassword"); string username = DataRequest.GetHashtableJsonObject(RequestData, ForgetVerifyCodes.Column_Username) ?? ""; @@ -172,5 +622,27 @@ namespace Milimoe.FunGame.Server.Controller } ResultData.Add("msg", msg); } + + #endregion + + #region Room + + /// + /// 获取房间内玩家数量 + /// + /// + /// + private void GetRoomPlayerCount(Hashtable RequestData, Hashtable ResultData) + { + string roomid = "-1"; + if (RequestData.Count >= 1) + { + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + Server.GetClientName() + " -> GetRoomPlayerCount"); + roomid = DataRequest.GetHashtableJsonObject(RequestData, "roomid") ?? "-1"; + } + ResultData.Add("count", Config.RoomList.GetPlayerCount(roomid)); + } + + #endregion } } diff --git a/FunGame.Server/Main.cs b/FunGame.Server/Main.cs index 5e5b264..90fc639 100644 --- a/FunGame.Server/Main.cs +++ b/FunGame.Server/Main.cs @@ -3,7 +3,6 @@ using Milimoe.FunGame.Core.Api.Utility; 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.Model; using Milimoe.FunGame.Server.Others; using Milimoe.FunGame.Server.Utility; @@ -18,11 +17,11 @@ StartServer(); while (Running) { - string? order = ""; - order = Console.ReadLine(); + string order = Console.ReadLine() ?? ""; ServerHelper.Type(); - if (order != null && !order.Equals("") && Running) + if (order != "" && Running) { + order = order.ToLower(); switch (order) { case OrderDictionary.Quit: @@ -30,17 +29,16 @@ while (Running) case OrderDictionary.Close: Running = false; break; - case OrderDictionary.Help: - ServerHelper.WriteLine("Milimoe -> 帮助"); - break; case OrderDictionary.Restart: if (ListeningSocket == null) { ServerHelper.WriteLine("重启服务器"); StartServer(); } - else - ServerHelper.WriteLine("服务器正在运行,拒绝重启!"); + else ServerHelper.WriteLine("服务器正在运行,拒绝重启!"); + break; + default: + ConsoleModel.Order(ListeningSocket, order); break; } } @@ -98,44 +96,33 @@ void StartServer() while (Running) { ClientSocket socket; - string ClientIPAddress = ""; + string clientip = ""; try { - Guid Token = Guid.NewGuid(); - socket = ListeningSocket.Accept(Token); - ClientIPAddress = socket.ClientIP; - if (Config.ConnectingPlayersCount + Config.OnlinePlayersCount + 1 > Config.MaxPlayers) - { - SendRefuseConnect(socket, "服务器可接受的连接数量已上限!"); - ServerHelper.WriteLine("服务器可接受的连接数量已上限!"); - continue; - } - Config.ConnectingPlayersCount++; - ServerHelper.WriteLine(ServerHelper.MakeClientName(ClientIPAddress) + " 正在连接服务器 . . ."); - if (IsIPBanned(ListeningSocket, ClientIPAddress)) - { - SendRefuseConnect(socket, "服务器已拒绝黑名单用户连接。"); - ServerHelper.WriteLine("检测到 " + ServerHelper.MakeClientName(ClientIPAddress) + " 为黑名单用户,已禁止其连接!"); - Config.ConnectingPlayersCount--; - continue; - } - if (Read(socket) && Send(socket, Token)) + Guid token = Guid.NewGuid(); + socket = ListeningSocket.Accept(token); + clientip = socket.ClientIP; + Config.ConnectingPlayerCount++; + // 开始处理客户端连接请求 + if (Connect(socket, token, clientip)) { ServerModel ClientModel = new(ListeningSocket, socket, Running); Task t = Task.Factory.StartNew(() => { ClientModel.Start(); }); - ClientModel.SetTaskAndClientName(t, ClientIPAddress); + ClientModel.SetTaskAndClientName(t, clientip); } else - ServerHelper.WriteLine(ServerHelper.MakeClientName(ClientIPAddress) + " 连接失败。"); - Config.ConnectingPlayersCount--; + { + ServerHelper.WriteLine(ServerHelper.MakeClientName(clientip) + " 连接失败。"); + } + Config.ConnectingPlayerCount--; } catch (Exception e) { - if (--Config.ConnectingPlayersCount < 0) Config.ConnectingPlayersCount = 0; - ServerHelper.WriteLine(ServerHelper.MakeClientName(ClientIPAddress) + " 断开连接!"); + if (--Config.ConnectingPlayerCount < 0) Config.ConnectingPlayerCount = 0; + ServerHelper.WriteLine(ServerHelper.MakeClientName(clientip) + " 中断连接!"); ServerHelper.Error(e); } } @@ -160,25 +147,42 @@ void StartServer() ListeningSocket = null; } } - }); } -bool Read(ClientSocket socket) +bool Connect(ClientSocket socket, Guid token, string clientip) { // 接收客户端消息 foreach (SocketObject read in socket.ReceiveArray()) { - SocketMessageType type = read.SocketType; - if (type == SocketMessageType.RunTime_Connect) + if (read.SocketType == SocketMessageType.Connect) { - if (read.Parameters.Length > 0) + if (Config.ConnectingPlayerCount + Config.OnlinePlayerCount > Config.MaxPlayers) { - string str = (read.GetParam(0) ?? "").Trim(); - if (str != "") ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] " + ServerHelper.MakeClientName(socket.ClientIP) + " -> " + str); + SendRefuseConnect(socket, "服务器可接受的连接数量已上限!"); + ServerHelper.WriteLine("服务器可接受的连接数量已上限!"); + return false; + } + ServerHelper.WriteLine(ServerHelper.MakeClientName(clientip) + " 正在连接服务器 . . ."); + if (IsIPBanned(ListeningSocket, clientip)) + { + SendRefuseConnect(socket, "服务器已拒绝黑名单用户连接。"); + ServerHelper.WriteLine("检测到 " + ServerHelper.MakeClientName(clientip) + " 为黑名单用户,已禁止其连接!"); + return false; + } + + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(read.SocketType) + "] " + ServerHelper.MakeClientName(socket.ClientIP)); + + if (socket.Send(SocketMessageType.Connect, true, "", token, Config.ServerName, Config.ServerNotice) == SocketResult.Success) + { + ServerHelper.WriteLine(ServerHelper.MakeClientName(socket.ClientIP) + " <- " + "已确认连接"); + return true; + } + else + { + ServerHelper.WriteLine("无法传输数据,与客户端的连接可能丢失。"); + return false; } - else ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] " + ServerHelper.MakeClientName(socket.ClientIP)); - return true; } } @@ -186,32 +190,20 @@ bool Read(ClientSocket socket) return false; } -bool Send(ClientSocket socket, Guid Token) -{ - // 发送消息给客户端 - string msg = Config.ServerName + ";" + Config.ServerNotice; - if (socket.Send(SocketMessageType.RunTime_Connect, msg, Token) == SocketResult.Success) - { - ServerHelper.WriteLine(ServerHelper.MakeClientName(socket.ClientIP) + " <- " + "已确认连接"); - return true; - } - else - ServerHelper.WriteLine("无法传输数据,与客户端的连接可能丢失。"); - return false; -} - bool SendRefuseConnect(ClientSocket socket, string msg) { // 发送消息给客户端 - msg = $"连接被拒绝,如有疑问请联系服务器管理员:{msg}"; - if (socket.Send(SocketMessageType.RunTime_Connect, msg) == SocketResult.Success) + msg = "连接被拒绝,如有疑问请联系服务器管理员:" + msg; + if (socket.Send(SocketMessageType.Connect, false, msg) == SocketResult.Success) { ServerHelper.WriteLine(ServerHelper.MakeClientName(socket.ClientIP) + " <- " + "已拒绝连接"); return true; } else + { ServerHelper.WriteLine("无法传输数据,与客户端的连接可能丢失。"); - return false; + return false; + } } SQLResult TestSQLConnection() diff --git a/FunGame.Server/Models/ConsoleModel.cs b/FunGame.Server/Models/ConsoleModel.cs new file mode 100644 index 0000000..9a75398 --- /dev/null +++ b/FunGame.Server/Models/ConsoleModel.cs @@ -0,0 +1,86 @@ +using Milimoe.FunGame.Core.Interface; +using Milimoe.FunGame.Core.Interface.Base; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Server.Others; +using Milimoe.FunGame.Server.Utility; + +namespace Milimoe.FunGame.Server.Model +{ + public class ConsoleModel + { + public static void Order(ServerSocket? server, string order) + { + try + { + switch (order) + { + case OrderDictionary.Kick: + { + ServerHelper.Write("输入需要踢出的客户端名称:"); + string client = Console.ReadLine() ?? ""; + if (client != "" && server != null) + { + ((ServerModel)server.GetClient(client))?.Kick("您已被服务器管理员踢出此服务器。"); + } + break; + } + case OrderDictionary.Logout: + { + ServerHelper.Write("输入需要强制下线的玩家ID:"); + string user = Console.ReadLine() ?? ""; + if (user != "" && server != null) + { + ((ServerModel)server.GetUser(user))?.ForceLogOut("您已被服务器管理员强制下线。"); + } + break; + } + case OrderDictionary.ShowList: + ShowClients(server); + ShowUsers(server); + break; + case OrderDictionary.ShowClients1: + case OrderDictionary.ShowClients2: + ShowClients(server); + break; + case OrderDictionary.ShowUsers1: + case OrderDictionary.ShowUsers2: + ShowUsers(server); + break; + case OrderDictionary.Help: + ServerHelper.WriteLine("Milimoe -> 帮助"); + break; + } + } + catch (Exception e) + { + ServerHelper.Error(e); + } + } + + private static void ShowClients(ServerSocket? server) + { + if (server != null) + { + ServerHelper.WriteLine("显示在线客户端列表"); + int index = 1; + foreach (IServerModel client in server.ClientList) + { + ServerHelper.WriteLine(index++ + ". " + client.ClientName + (client.User.Id != 0 ? " (已登录为:" + client.User.Username + ")" : "")); + } + } + } + + private static void ShowUsers(ServerSocket? server) + { + if (server != null) + { + ServerHelper.WriteLine("显示在线玩家列表"); + int index = 1; + foreach (IServerModel user in server.UserList.Where(u => u.User.Id != 0)) + { + ServerHelper.WriteLine(index++ + ". " + (user.User.Username) + " (客户端:" + user.ClientName + ")"); + } + } + } + } +} diff --git a/FunGame.Server/Models/ServerModel.cs b/FunGame.Server/Models/ServerModel.cs index 7d3e8dd..84953cb 100644 --- a/FunGame.Server/Models/ServerModel.cs +++ b/FunGame.Server/Models/ServerModel.cs @@ -6,7 +6,6 @@ using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Interface.Base; 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; @@ -14,7 +13,7 @@ using Milimoe.FunGame.Server.Utility; namespace Milimoe.FunGame.Server.Model { - public partial class ServerModel : IServerModel + public class ServerModel : IServerModel { /** * Public @@ -24,6 +23,11 @@ namespace Milimoe.FunGame.Server.Model public Task? Task => _Task; public string ClientName => _ClientName; public User User => _User; + public Room Room + { + get => _Room; + set => _Room = value; + } public MySQLHelper SQLHelper { get; } public MailSender? MailSender { get; } @@ -33,15 +37,14 @@ namespace Milimoe.FunGame.Server.Model private ClientSocket? _Socket = null; private bool _Running = false; private User _User = General.UnknownUserInstance; + private Room _Room = General.HallInstance; private Task? _Task = null; private string _ClientName = ""; private Guid CheckLoginKey = Guid.Empty; - private string RegVerify = ""; private int FailedTimes = 0; // 超过一定次数断开连接 private string UserName = ""; private DataSet DsUser = new(); - private string RoomID = ""; private readonly Guid Token; private readonly ServerSocket Server; private readonly DataRequestController DataRequestController; @@ -57,8 +60,6 @@ namespace Milimoe.FunGame.Server.Model SQLHelper = new(this); MailSender = SmtpHelper.GetMailSender(); DataRequestController = new(this); - Config.OnlinePlayersCount++; - GetUsersCount(); } public bool Read(ClientSocket socket) @@ -73,7 +74,7 @@ namespace Milimoe.FunGame.Server.Model string msg = ""; // 验证Token - if (type != SocketMessageType.RunTime_HeartBeat && token != Token) + if (type != SocketMessageType.HeartBeat && token != Token) { ServerHelper.WriteLine(GetClientName() + " 使用了非法方式传输消息,服务器拒绝回应 -> [" + ServerSocket.GetTypeString(type) + "] "); return false; @@ -84,378 +85,17 @@ namespace Milimoe.FunGame.Server.Model return DataRequestHandler(socket, SocketObject); } - // 如果不等于这些Type,就不会输出一行记录。这些Type有特定的输出。 - SocketMessageType[] IgnoreType = new SocketMessageType[] { SocketMessageType.RunTime_HeartBeat, SocketMessageType.RunTime_Login, SocketMessageType.Main_IntoRoom, - SocketMessageType.Main_Chat}; - if (!IgnoreType.Contains(type)) + if (type == SocketMessageType.HeartBeat) { - if (msg.Trim() == "") - ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] " + GetClientName()); - else - ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] " + GetClientName() + " -> " + msg); + return HeartBeat(socket); } switch (type) { - case SocketMessageType.Main_GetNotice: - msg = Config.ServerNotice; - break; - - case SocketMessageType.RunTime_Login: - CheckLoginKey = Guid.Empty; - if (args != null) - { - string? username = "", password = "", autokey = ""; - if (args.Length > 0) username = SocketObject.GetParam(0); - if (args.Length > 1) password = SocketObject.GetParam(1); - if (args.Length > 2) autokey = SocketObject.GetParam(2); - if (username != null && password != null) - { - ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] UserName: " + username); - SQLHelper.ExecuteDataSet(UserQuery.Select_Users_LoginQuery(username, password)); - if (SQLHelper.Result == SQLResult.Success) - { - DsUser = SQLHelper.DataSet; - if (autokey != null && autokey.Trim() != "") - { - SQLHelper.ExecuteDataSet(UserQuery.Select_CheckAutoKey(username, autokey)); - if (SQLHelper.Result == SQLResult.Success) - { - ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] AutoKey: 已确认"); - } - else - { - msg = "AutoKey不正确,拒绝自动登录!"; - ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] " + msg); - return Send(socket, type, CheckLoginKey, msg); - } - } - UserName = username; - CheckLoginKey = Guid.NewGuid(); - return Send(socket, type, CheckLoginKey); - } - msg = "用户名或密码不正确。"; - ServerHelper.WriteLine(msg); - } - } - return Send(socket, type, CheckLoginKey, msg); - - case SocketMessageType.RunTime_CheckLogin: - if (args != null && args.Length > 0) - { - Guid checkloginkey = SocketObject.GetParam(0); - if (CheckLoginKey.Equals(checkloginkey)) - { - // 创建User对象 - _User = Factory.GetUser(DsUser); - // 检查有没有重复登录的情况 - KickUser(); - // 添加至玩家列表 - AddUser(); - GetUsersCount(); - // CheckLogin - LoginTime = DateTime.Now.Ticks; - SQLHelper.Execute(UserQuery.Update_CheckLogin(UserName, socket.ClientIP.Split(':')[0])); - return Send(socket, type, _User); - } - ServerHelper.WriteLine("客户端发送了错误的秘钥,不允许本次登录。"); - } - return Send(socket, type, CheckLoginKey.ToString()); - - case SocketMessageType.RunTime_Logout: - Guid checklogoutkey = Guid.Empty; - if (args != null && args.Length > 0) - { - checklogoutkey = SocketObject.GetParam(0); - if (CheckLoginKey.Equals(checklogoutkey)) - { - // 从玩家列表移除 - RemoveUser(); - GetUsersCount(); - CheckLoginKey = Guid.Empty; - msg = "你已成功退出登录! "; - return Send(socket, type, checklogoutkey, msg); - } - } - ServerHelper.WriteLine("客户端发送了错误的秘钥,不允许本次登出。"); - return Send(socket, type, checklogoutkey); - - case SocketMessageType.RunTime_Disconnect: + case SocketMessageType.Disconnect: + ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(SocketMessageType.DataRequest) + "] " + GetClientName() + " -> Disconnect"); msg = "你已成功断开与服务器的连接: " + Config.ServerName + "。 "; break; - - case SocketMessageType.RunTime_HeartBeat: - msg = ""; - break; - - case SocketMessageType.Main_IntoRoom: - msg = "-1"; - if (args != null && args.Length > 0) msg = SocketObject.GetParam(0)!; - RoomID = msg; - Config.RoomList.IntoRoom(RoomID, User); - if (RoomID != "-1") - { - // 昭告天下 - foreach (ServerModel Client in Server.GetUsersList.Cast()) - { - if (RoomID == Client.RoomID) - { - if (Client != null && User.Id != 0) - { - Client.Send(Client.Socket!, SocketMessageType.Main_Chat, User.Username, DateTimeUtility.GetNowShortTime() + " [ " + User.Username + " ] 进入了房间。"); - } - } - } - } - break; - - case SocketMessageType.Main_Chat: - if (args != null && args.Length > 0) msg = SocketObject.GetParam(0)!; - ServerHelper.WriteLine(msg); - foreach (ServerModel Client in Server.GetUsersList.Cast()) - { - if (RoomID == Client.RoomID) - { - if (Client != null && User.Id != 0) - { - Client.Send(Client.Socket!, SocketMessageType.Main_Chat, User.Username, DateTimeUtility.GetNowShortTime() + msg); - } - } - } - return true; - - case SocketMessageType.RunTime_Reg: - if (args != null) - { - string? username = "", email = ""; - if (args.Length > 0) username = SocketObject.GetParam(0); - if (args.Length > 1) email = SocketObject.GetParam(1); - if (username != null && email != null) - { - // 先检查账号是否重复 - SQLHelper.ExecuteDataSet(UserQuery.Select_IsExistUsername(username)); - if (SQLHelper.Result == SQLResult.Success) - { - ServerHelper.WriteLine(GetClientName() + " 账号已被注册"); - return Send(socket, type, RegInvokeType.DuplicateUserName); - } - // 检查邮箱是否重复 - SQLHelper.ExecuteDataSet(UserQuery.Select_IsExistEmail(email)); - if (SQLHelper.Result == SQLResult.Success) - { - ServerHelper.WriteLine(GetClientName() + " 邮箱已被注册"); - return Send(socket, type, RegInvokeType.DuplicateEmail); - } - // 检查验证码是否发送过 - SQLHelper.ExecuteDataSet(RegVerifyCodes.Select_HasSentRegVerifyCode(username, email)); - if (SQLHelper.Result == SQLResult.Success) - { - DateTime RegTime = (DateTime)SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegTime]; - string RegVerifyCode = (string)SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegVerifyCode]; - if ((DateTime.Now - RegTime).TotalMinutes < 10) - { - ServerHelper.WriteLine(GetClientName() + $" 十分钟内已向{email}发送过验证码:{RegVerifyCode}"); - } - return Send(socket, type, RegInvokeType.InputVerifyCode); - } - // 发送验证码,需要先删除之前过期的验证码 - SQLHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(username, email)); - RegVerify = Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 6); - SQLHelper.Execute(RegVerifyCodes.Insert_RegVerifyCode(username, email, RegVerify)); - if (SQLHelper.Result == SQLResult.Success) - { - if (MailSender != null) - { - // 发送验证码 - string ServerName = Config.ServerName; - string Subject = $"[{ServerName}] FunGame 注册验证码"; - string Body = $"亲爱的 {username},
感谢您注册[{ServerName}],您的验证码是 {RegVerify} ,10分钟内有效,请及时输入!

{ServerName}
{DateTimeUtility.GetDateTimeToString(TimeType.DateOnly)}"; - string[] To = new string[] { email }; - if (MailSender.Send(MailSender.CreateMail(Subject, Body, System.Net.Mail.MailPriority.Normal, true, To)) == MailSendResult.Success) - { - ServerHelper.WriteLine(GetClientName() + $" 已向{email}发送验证码:{RegVerify}"); - } - else - { - ServerHelper.WriteLine(GetClientName() + " 无法发送验证码"); - ServerHelper.WriteLine(MailSender.ErrorMsg); - } - } - else // 不使用MailSender的情况 - { - ServerHelper.WriteLine(GetClientName() + $" 验证码为:{RegVerify},请服务器管理员告知此用户"); - } - return Send(socket, type, RegInvokeType.InputVerifyCode); - } - } - } - return true; - - case SocketMessageType.RunTime_CheckReg: - if (args != null) - { - string? username = "", password = "", email = "", verifycode = ""; - if (args.Length > 0) username = SocketObject.GetParam(0); - if (args.Length > 1) password = SocketObject.GetParam(1); - if (args.Length > 2) email = SocketObject.GetParam(2); - if (args.Length > 3) verifycode = SocketObject.GetParam(3); - if (username != null && password != null && email != null && verifycode != null) - { - // 先检查验证码 - SQLHelper.ExecuteDataSet(RegVerifyCodes.Select_RegVerifyCode(username, email, verifycode)); - if (SQLHelper.Result == SQLResult.Success) - { - // 检查验证码是否过期 - DateTime RegTime = (DateTime)SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegTime]; - if ((DateTime.Now - RegTime).TotalMinutes >= 10) - { - ServerHelper.WriteLine(GetClientName() + " 验证码已过期"); - msg = "此验证码已过期,请重新注册。"; - SQLHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(username, email)); - return Send(socket, type, false, msg); - } - // 注册 - if (RegVerify.Equals(SQLHelper.DataSet.Tables[0].Rows[0][RegVerifyCodes.Column_RegVerifyCode])) - { - ServerHelper.WriteLine("[" + ServerSocket.GetTypeString(type) + "] UserName: " + username + " Email: " + email); - SQLHelper.NewTransaction(); - SQLHelper.Execute(UserQuery.Insert_Register(username, password, email, socket.ClientIP)); - if (SQLHelper.Result == SQLResult.Success) - { - msg = "注册成功!请牢记您的账号与密码!"; - SQLHelper.Execute(RegVerifyCodes.Delete_RegVerifyCode(username, email)); - SQLHelper.Commit(); - return Send(socket, type, true, msg); - } - else - { - msg = "服务器无法处理您的注册,注册失败!"; - SQLHelper.Rollback(); - } - } - else msg = "验证码不正确,请重新输入!"; - } - else if (SQLHelper.Result == SQLResult.NotFound) msg = "验证码不正确,请重新输入!"; - else msg = "服务器无法处理您的注册,注册失败!"; - } - } - else msg = "注册失败!"; - return Send(socket, type, false, msg); - - case SocketMessageType.Main_UpdateRoom: - Config.RoomList ??= new(); - Config.RoomList.Clear(); - DataSet DsRoomTemp = new(), DsUserTemp = new(); - DsRoomTemp = SQLHelper.ExecuteDataSet(RoomQuery.Select_Rooms); - DsUserTemp = SQLHelper.ExecuteDataSet(UserQuery.Select_Users); - List rooms = Factory.GetRooms(DsRoomTemp, DsUserTemp); - Config.RoomList.AddRooms(rooms); // 更新服务器中的房间列表 - return Send(socket, type, rooms); // 传RoomList - - case SocketMessageType.Main_CreateRoom: - msg = "-1"; - if (args != null) - { - string? roomtype_string = ""; - long userid = 0; - string? password = ""; - if (args.Length > 0) roomtype_string = SocketObject.GetParam(0); - if (args.Length > 1) userid = SocketObject.GetParam(1); - if (args.Length > 2) password = SocketObject.GetParam(2); - if (!string.IsNullOrWhiteSpace(roomtype_string) && userid != 0) - { - RoomType roomtype = roomtype_string switch - { - GameMode.GameMode_Mix => RoomType.Mix, - GameMode.GameMode_Team => RoomType.Team, - GameMode.GameMode_MixHasPass => RoomType.MixHasPass, - GameMode.GameMode_TeamHasPass => RoomType.TeamHasPass, - _ => RoomType.All - }; - string roomid = Verification.CreateVerifyCode(VerifyCodeType.MixVerifyCode, 7).ToUpper(); - SQLHelper.Execute(RoomQuery.Insert_CreateRoom(roomid, userid, roomtype, password ?? "")); - if (SQLHelper.Result == SQLResult.Success) - { - msg = roomid; - } - } - } - break; - - case SocketMessageType.Main_QuitRoom: - if (args != null) - { - string? roomid = ""; - bool isMaster = false; - if (args.Length > 0) roomid = SocketObject.GetParam(0); - if (args.Length > 1) isMaster = SocketObject.GetParam(1); - if (roomid != null && roomid.Trim() != "") - { - Config.RoomList.QuitRoom(roomid, User); - Room Room = Config.RoomList[roomid] ?? General.HallInstance; - User UpdateRoomMaster = General.UnknownUserInstance; - DataSet DsUser = new(), DsRoom = new(); - // 是否是房主 - if (isMaster) - { - List users = GetRoomPlayerList(roomid); - if (users.Count > 0) // 如果此时房间还有人,更新房主 - { - UpdateRoomMaster = users[0]; - Room.RoomMaster = UpdateRoomMaster; - SQLHelper.Execute(RoomQuery.Update_QuitRoom(roomid, User.Id, UpdateRoomMaster.Id)); - DsUser = SQLHelper.ExecuteDataSet(UserQuery.Select_IsExistUsername(UpdateRoomMaster.Username)); - DsRoom = SQLHelper.ExecuteDataSet(RoomQuery.Select_IsExistRoom(roomid)); - } - else // 没人了就解散房间 - { - Config.RoomList.RemoveRoom(roomid); - SQLHelper.Execute(RoomQuery.Delete_QuitRoom(roomid, User.Id)); - if (SQLHelper.Result == SQLResult.Success) - { - ServerHelper.WriteLine(GetClientName() + " 解散了房间 " + roomid); - } - } - } - // 昭告天下 - foreach (ServerModel Client in Server.GetUsersList.Cast()) - { - if (roomid == Client.RoomID) - { - if (Client != null && User.Id != 0) - { - Client.Send(Client.Socket!, SocketMessageType.Main_Chat, User.Username, DateTimeUtility.GetNowShortTime() + " [ " + User.Username + " ] 离开了房间。"); - if (UpdateRoomMaster.Id != 0 && Room.Roomid != "-1") - { - Client.Send(Client.Socket!, SocketMessageType.Room_UpdateRoomMaster, User, Room); - } - } - } - } - RoomID = "-1"; - return Send(socket, type, true); - } - } - return Send(socket, type, false); - - case SocketMessageType.Main_MatchRoom: - break; - - case SocketMessageType.Room_ChangeRoomSetting: - break; - - case SocketMessageType.Room_GetRoomPlayerCount: - if (args != null) - { - string? roomid = "-1"; - if (args.Length > 0) roomid = SocketObject.GetParam(0); - if (roomid != null && roomid != "-1") - { - int count = GetRoomPlayerCount(roomid); - return Send(socket, type, count); - } - } - return Send(socket, type, 0); } return Send(socket, type, msg); } @@ -503,14 +143,14 @@ namespace Milimoe.FunGame.Server.Model { switch (type) { - case SocketMessageType.RunTime_Logout: + case SocketMessageType.ForceLogout: RemoveUser(); break; - case SocketMessageType.RunTime_Disconnect: + case SocketMessageType.Disconnect: RemoveUser(); Close(); break; - case SocketMessageType.Main_Chat: + case SocketMessageType.Chat: return true; } object obj = objs[0]; @@ -538,6 +178,10 @@ namespace Milimoe.FunGame.Server.Model { _Task = t; _ClientName = ClientName; + // 添加客户端到列表中 + Server.AddClient(_ClientName, this); + Config.OnlinePlayerCount++; + GetUsersCount(); } public string GetClientName() @@ -545,6 +189,108 @@ namespace Milimoe.FunGame.Server.Model return ServerHelper.MakeClientName(ClientName, User); } + public void PreLogin(DataSet dsuser, string username, Guid checkloginkey) + { + DsUser = dsuser; + UserName = username; + CheckLoginKey = checkloginkey; + } + + public void CheckLogin() + { + // 创建User对象 + _User = Factory.GetUser(DsUser); + // 检查有没有重复登录的情况 + KickUser(); + // 添加至玩家列表 + AddUser(); + GetUsersCount(); + // CheckLogin + LoginTime = DateTime.Now.Ticks; + SQLHelper.Execute(UserQuery.Update_CheckLogin(UserName, _Socket?.ClientIP.Split(':')[0] ?? "127.0.0.1")); + } + + public bool IsLoginKey(Guid key) + { + return key == CheckLoginKey; + } + + public void LogOut() + { + // 从玩家列表移除 + RemoveUser(); + GetUsersCount(); + CheckLoginKey = Guid.Empty; + } + + public void ForceLogOut(string msg, string username = "") + { + ServerModel serverTask = (ServerModel)Server.GetUser(username == "" ? UserName : username); + if (serverTask.Socket != null) + { + serverTask.Send(serverTask.Socket, SocketMessageType.ForceLogout, msg); + } + } + + public void Kick(string msg, string clientname = "") + { + // 将客户端踢出服务器 + RemoveUser(); + ServerModel serverTask = (ServerModel)Server.GetClient(clientname == "" ? ClientName : clientname); + if (serverTask.Socket != null) + { + serverTask.Send(serverTask.Socket, SocketMessageType.Disconnect, msg); + } + Close(); + } + + public void Chat(string msg) + { + ServerHelper.WriteLine(msg); + foreach (ServerModel Client in Server.ClientList.Cast()) + { + if (Room.Roomid == Client.Room.Roomid) + { + if (Client != null && User.Id != 0) + { + Client.Send(Client.Socket!, SocketMessageType.Chat, User.Username, DateTimeUtility.GetNowShortTime() + msg); + } + } + } + } + + public void IntoRoom(string roomid) + { + Room = Config.RoomList[roomid]; + foreach (ServerModel Client in Server.ClientList.Cast().Where(c => c != null && c.Socket != null && roomid == c.Room.Roomid)) + { + if (User.Id != 0) + { + Client.Send(Client.Socket!, SocketMessageType.Chat, User.Username, DateTimeUtility.GetNowShortTime() + " [ " + User.Username + " ] 进入了房间。"); + } + } + } + + public void UpdateRoomMaster(Room Room, bool bolIsUpdateRoomMaster = false) + { + foreach (ServerModel Client in Server.ClientList.Cast().Where(c => c != null && c.Socket != null && Room.Roomid == c.Room.Roomid)) + { + if (User.Id != 0) + { + Client.Send(Client.Socket!, SocketMessageType.Chat, User.Username, DateTimeUtility.GetNowShortTime() + " [ " + User.Username + " ] 离开了房间。"); + if (bolIsUpdateRoomMaster && Room.RoomMaster?.Id != 0 && Room.Roomid != "-1") + { + Client.Send(Client.Socket!, SocketMessageType.UpdateRoomMaster, Room); + } + } + } + } + + public bool HeartBeat(ClientSocket socket) + { + return Send(socket, SocketMessageType.HeartBeat, ""); + } + private void KickUser() { if (User.Id != 0) @@ -553,8 +299,7 @@ namespace Milimoe.FunGame.Server.Model if (Server.ContainsUser(user)) { ServerHelper.WriteLine("OnlinePlayers: 玩家 " + user + " 重复登录!"); - ServerModel serverTask = (ServerModel)Server.GetUser(user); - serverTask?.Send(serverTask.Socket!, SocketMessageType.RunTime_ForceLogout, serverTask.CheckLoginKey, "您的账号在别处登录,已强制下线。"); + ForceLogOut("您的账号在别处登录,已强制下线。"); } } } @@ -595,7 +340,7 @@ namespace Milimoe.FunGame.Server.Model private void GetUsersCount() { - ServerHelper.WriteLine($"目前在线客户端数量: {Config.OnlinePlayersCount}(已登录的玩家数量:{Server.UsersCount})"); + ServerHelper.WriteLine($"目前在线客户端数量: {Server.ClientCount}(已登录的玩家数量:{Server.UserCount})"); } private void CreateStreamReader() @@ -652,7 +397,8 @@ namespace Milimoe.FunGame.Server.Model Socket?.Close(); _Socket = null; _Running = false; - Config.OnlinePlayersCount--; + Server.RemoveClient(ClientName); + Config.OnlinePlayerCount--; GetUsersCount(); } catch (Exception e) @@ -660,15 +406,5 @@ namespace Milimoe.FunGame.Server.Model ServerHelper.Error(e); } } - - private static int GetRoomPlayerCount(string roomid) - { - return Config.RoomList.GetPlayerCount(roomid); - } - - private static List GetRoomPlayerList(string roomid) - { - return Config.RoomList.GetPlayerList(roomid); - } } } diff --git a/FunGame.Server/Models/SocketMessageHandler.cs b/FunGame.Server/Models/SocketMessageHandler.cs deleted file mode 100644 index 7ecfa5c..0000000 --- a/FunGame.Server/Models/SocketMessageHandler.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Milimoe.FunGame.Server.Model -{ - public partial class ServerModel - { - - } -} diff --git a/FunGame.Server/Others/Config.cs b/FunGame.Server/Others/Config.cs index 9607398..5564bed 100644 --- a/FunGame.Server/Others/Config.cs +++ b/FunGame.Server/Others/Config.cs @@ -17,8 +17,8 @@ namespace Milimoe.FunGame.Server.Others public static string ServerBannedList { get; set; } = ""; // 禁止连接的黑名单 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 int OnlinePlayerCount { get; set; } = 0; // 已连接的玩家数量 + public static int ConnectingPlayerCount { 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(); diff --git a/FunGame.Server/Others/OrderDictionary.cs b/FunGame.Server/Others/OrderDictionary.cs index 9a6384f..2761b1a 100644 --- a/FunGame.Server/Others/OrderDictionary.cs +++ b/FunGame.Server/Others/OrderDictionary.cs @@ -12,5 +12,11 @@ public const string RemoveBanned1 = "ban -remove"; public const string RemoveBanned2 = "ban -r"; public const string Kick = "kick"; + public const string Logout = "logout"; + public const string ShowList = "showlist"; + public const string ShowClients1 = "showclients"; + public const string ShowClients2 = "clients"; + public const string ShowUsers1 = "showusers"; + public const string ShowUsers2 = "users"; } } diff --git a/FunGame.Server/Utilities/General.cs b/FunGame.Server/Utilities/General.cs index 5931351..b345c66 100644 --- a/FunGame.Server/Utilities/General.cs +++ b/FunGame.Server/Utilities/General.cs @@ -19,9 +19,14 @@ namespace Milimoe.FunGame.Server.Utility Console.Write("\r" + GetPrefix() + e.Message + "\n" + e.StackTrace + "\n\r> "); } - public static void WriteLine(string? msg) + public static void Write(string msg) { - Console.Write("\r" + GetPrefix() + msg + "\n\r> "); + if (msg.Trim() != "") Console.Write("\r" + GetPrefix() + msg + "> "); + } + + public static void WriteLine(string msg) + { + if (msg.Trim() != "") Console.Write("\r" + GetPrefix() + msg + "\n\r> "); } public static void Type() @@ -100,7 +105,7 @@ namespace Milimoe.FunGame.Server.Utility } catch (Exception e) { - ServerHelper.WriteLine(e.StackTrace); + ServerHelper.WriteLine(e.StackTrace ?? ""); } } diff --git a/FunGame.Server/Utilities/MySQLManager.cs b/FunGame.Server/Utilities/MySQLManager.cs index 38469c5..26119a2 100644 --- a/FunGame.Server/Utilities/MySQLManager.cs +++ b/FunGame.Server/Utilities/MySQLManager.cs @@ -20,7 +20,6 @@ namespace Milimoe.FunGame.Server.Utility try { PrepareCommand(Helper, cmd); - Helper.NewTransaction(); updaterow = cmd.ExecuteNonQuery(); if (updaterow > 0) @@ -91,7 +90,6 @@ namespace Milimoe.FunGame.Server.Utility try { PrepareCommand(Helper, cmd); - Helper.NewTransaction(); updaterow = cmd.ExecuteNonQuery(); if (updaterow > 0)