From 0e106b2676a0528e91fd42fe48bc22dc7e176cd3 Mon Sep 17 00:00:00 2001 From: Mili Date: Sat, 11 Mar 2023 01:05:33 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E5=B0=81=E8=A3=85SocketManag?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FunGame.Core/Api/Transmittal/MailSender.cs | 19 +- FunGame.Core/Interface/Base/IClientSocket.cs | 13 + FunGame.Core/Interface/Base/ISocket.cs | 4 - .../Interface/Base}/ISocketHandler.cs | 2 +- .../Common/Architecture/BaseController.cs | 10 + .../Library/Common/Architecture/BaseModel.cs | 67 +++ .../Library/Common/Network/ClientSocket.cs | 14 +- .../Library/Common/Network/ServerSocket.cs | 17 - FunGame.Core/Library/Common/Network/Socket.cs | 14 +- .../Library/Common/Network/SocketObject.cs | 21 +- FunGame.Core/Library/Constant/General.cs | 2 + FunGame.Core/Library/Exception/Exception.cs | 10 + FunGame.Core/Service/SocketManager.cs | 39 +- FunGame.Desktop/Controller/LoginController.cs | 16 +- FunGame.Desktop/Controller/MainController.cs | 112 +---- .../Controller/RegisterController.cs | 8 +- .../Controller/RunTimeController.cs | 100 +++++ FunGame.Desktop/Library/Base/BaseLogin.cs | 8 +- .../Library/Component/GeneralForm.cs | 63 ++- FunGame.Desktop/Library/Config/RunTime.cs | 1 + FunGame.Desktop/Library/Interface/IMain.cs | 24 -- FunGame.Desktop/Model/LoginModel.cs | 89 +++- FunGame.Desktop/Model/MainModel.cs | 388 ++---------------- FunGame.Desktop/Model/RegisterModel.cs | 25 +- FunGame.Desktop/Model/RunTimeModel.cs | 301 ++++++++++++++ FunGame.Desktop/UI/Login/Login.cs | 18 +- FunGame.Desktop/UI/Main/Main.cs | 48 ++- FunGame.Desktop/UI/Register/Register.cs | 12 +- 28 files changed, 811 insertions(+), 634 deletions(-) create mode 100644 FunGame.Core/Interface/Base/IClientSocket.cs rename {FunGame.Desktop/Library/Interface => FunGame.Core/Interface/Base}/ISocketHandler.cs (76%) create mode 100644 FunGame.Core/Library/Common/Architecture/BaseController.cs create mode 100644 FunGame.Core/Library/Common/Architecture/BaseModel.cs create mode 100644 FunGame.Desktop/Controller/RunTimeController.cs delete mode 100644 FunGame.Desktop/Library/Interface/IMain.cs create mode 100644 FunGame.Desktop/Model/RunTimeModel.cs diff --git a/FunGame.Core/Api/Transmittal/MailSender.cs b/FunGame.Core/Api/Transmittal/MailSender.cs index 5819dfd..4d8bec2 100644 --- a/FunGame.Core/Api/Transmittal/MailSender.cs +++ b/FunGame.Core/Api/Transmittal/MailSender.cs @@ -34,15 +34,24 @@ namespace Milimoe.FunGame.Core.Api.Transmittal return _LastestResult; } - public bool Dispose() + private bool IsDisposed = false; + + public void Dispose() { - return MailManager.Dispose(this); + Dispose(true); + GC.SuppressFinalize(this); } - void IDisposable.Dispose() + protected void Dispose(bool Disposing) { - MailManager.Dispose(this); - GC.SuppressFinalize(this); + if (!IsDisposed) + { + if (Disposing) + { + MailManager.Dispose(this); + } + } + IsDisposed = true; } } } diff --git a/FunGame.Core/Interface/Base/IClientSocket.cs b/FunGame.Core/Interface/Base/IClientSocket.cs new file mode 100644 index 0000000..1125594 --- /dev/null +++ b/FunGame.Core/Interface/Base/IClientSocket.cs @@ -0,0 +1,13 @@ +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Core.Interface.Base +{ + public interface IClientSocket : ISocket + { + public bool Receiving { get; } + public void StartReceiving(Task t); + public SocketResult Send(SocketMessageType type, params object[] objs); + public Library.Common.Network.SocketObject Receive(); + public void BindEvent(Delegate Method, bool Remove = false); + } +} diff --git a/FunGame.Core/Interface/Base/ISocket.cs b/FunGame.Core/Interface/Base/ISocket.cs index 40cee43..1ef1d44 100644 --- a/FunGame.Core/Interface/Base/ISocket.cs +++ b/FunGame.Core/Interface/Base/ISocket.cs @@ -12,10 +12,6 @@ namespace Milimoe.FunGame.Core.Interface.Base public string ServerName { get; } public string ServerNotice { get; } public bool Connected => Instance != null && Instance.Connected; - public bool Receiving { get; } - public SocketResult Send(SocketMessageType type, params object[] objs); - public Library.Common.Network.SocketObject Receive(); public void Close(); - public void StartReceiving(Task t); } } diff --git a/FunGame.Desktop/Library/Interface/ISocketHandler.cs b/FunGame.Core/Interface/Base/ISocketHandler.cs similarity index 76% rename from FunGame.Desktop/Library/Interface/ISocketHandler.cs rename to FunGame.Core/Interface/Base/ISocketHandler.cs index 9fbca94..501e314 100644 --- a/FunGame.Desktop/Library/Interface/ISocketHandler.cs +++ b/FunGame.Core/Interface/Base/ISocketHandler.cs @@ -1,6 +1,6 @@ using Milimoe.FunGame.Core.Library.Common.Network; -namespace Milimoe.FunGame.Desktop.Library.Interface +namespace Milimoe.FunGame.Core.Interface.Base { public interface ISocketHandler { diff --git a/FunGame.Core/Library/Common/Architecture/BaseController.cs b/FunGame.Core/Library/Common/Architecture/BaseController.cs new file mode 100644 index 0000000..ee8ebf3 --- /dev/null +++ b/FunGame.Core/Library/Common/Architecture/BaseController.cs @@ -0,0 +1,10 @@ +namespace Milimoe.FunGame.Core.Library.Common.Architecture +{ + public abstract class BaseController + { + /// + /// 重写此方法并调用Model的Dispose方法,否则将无法正常将监听Socket的事件移除! + /// + public abstract void Dispose(); + } +} diff --git a/FunGame.Core/Library/Common/Architecture/BaseModel.cs b/FunGame.Core/Library/Common/Architecture/BaseModel.cs new file mode 100644 index 0000000..be2811f --- /dev/null +++ b/FunGame.Core/Library/Common/Architecture/BaseModel.cs @@ -0,0 +1,67 @@ +using Milimoe.FunGame.Core.Interface.Base; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Service; + +namespace Milimoe.FunGame.Core.Library.Common.Architecture +{ + public class BaseModel : ISocketHandler, IDisposable + { + /// + /// Socket + /// + private readonly Socket _Socket; + + /// + /// 继承请调用base构造 + /// + /// Socket + public BaseModel(Socket? socket) + { + if (socket != null) + { + _Socket = socket; + socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler)); + } + else throw new SocketCreateReceivingException(); + } + + /// + /// 继承请重写此方法 + /// + /// SocketObject + public virtual void SocketHandler(SocketObject SocketObject) + { + + } + + /// + /// 判断是否已经Disposed + /// + private bool IsDisposed = false; + + /// + /// 公开的Dispose方法 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 关闭时 + /// + /// + protected void Dispose(bool Disposing) + { + if (!IsDisposed) + { + if (Disposing) + { + _Socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler), true); + } + } + IsDisposed = true; + } + } +} diff --git a/FunGame.Core/Library/Common/Network/ClientSocket.cs b/FunGame.Core/Library/Common/Network/ClientSocket.cs index bce83d7..218b964 100644 --- a/FunGame.Core/Library/Common/Network/ClientSocket.cs +++ b/FunGame.Core/Library/Common/Network/ClientSocket.cs @@ -4,7 +4,7 @@ using Milimoe.FunGame.Core.Service; namespace Milimoe.FunGame.Core.Library.Common.Network { - public class ClientSocket : ISocket + public class ClientSocket : IClientSocket { public System.Net.Sockets.Socket Instance { get; } public int Runtime { get; } = (int)SocketRuntimeType.Server; @@ -62,6 +62,18 @@ namespace Milimoe.FunGame.Core.Library.Common.Network return SocketResult.NotSent; } + public void BindEvent(Delegate Method, bool Remove = false) + { + if (!Remove) + { + SocketManager.SocketReceive += (SocketManager.SocketReceiveHandler)Method; + } + else + { + SocketManager.SocketReceive -= (SocketManager.SocketReceiveHandler)Method; + } + } + public void StartReceiving(Task t) { _Receiving = true; diff --git a/FunGame.Core/Library/Common/Network/ServerSocket.cs b/FunGame.Core/Library/Common/Network/ServerSocket.cs index 653a73e..64ec1e0 100644 --- a/FunGame.Core/Library/Common/Network/ServerSocket.cs +++ b/FunGame.Core/Library/Common/Network/ServerSocket.cs @@ -15,12 +15,10 @@ namespace Milimoe.FunGame.Core.Library.Common.Network public string ServerName { get; } = ""; public string ServerNotice { get; } = ""; public bool Connected => Instance != null && Instance.Connected; - public bool Receiving => _Receiving; public List GetUsersList => OnlineUsers.GetList(); public int UsersCount => OnlineUsers.Count; private readonly ThreadManager OnlineUsers; - private bool _Receiving = false; private ServerSocket(System.Net.Sockets.Socket Instance, int ServerPort, int MaxConnection = 0) { @@ -72,26 +70,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Network return OnlineUsers[UserName]; } - public SocketResult Send(SocketMessageType type, params object[] objs) - { - throw new ListeningSocketCanNotSendException(); - } - - public SocketObject Receive() - { - throw new ListeningSocketCanNotSendException(); - } - public void Close() { Instance?.Close(); } - public void StartReceiving(Task t) - { - throw new ListeningSocketCanNotSendException(); - } - public static string GetTypeString(SocketMessageType type) { return Socket.GetTypeString(type); diff --git a/FunGame.Core/Library/Common/Network/Socket.cs b/FunGame.Core/Library/Common/Network/Socket.cs index a8de6d5..a9b14cc 100644 --- a/FunGame.Core/Library/Common/Network/Socket.cs +++ b/FunGame.Core/Library/Common/Network/Socket.cs @@ -4,7 +4,7 @@ using Milimoe.FunGame.Core.Service; namespace Milimoe.FunGame.Core.Library.Common.Network { - public class Socket : ISocket, ISocketHeartBeat + public class Socket : IClientSocket, ISocketHeartBeat { public System.Net.Sockets.Socket Instance { get; } public int Runtime { get; } = (int)SocketRuntimeType.Client; @@ -72,6 +72,18 @@ namespace Milimoe.FunGame.Core.Library.Common.Network } } + public void BindEvent(Delegate Method, bool Remove = false) + { + if (!Remove) + { + SocketManager.SocketReceive += (SocketManager.SocketReceiveHandler)Method; + } + else + { + SocketManager.SocketReceive -= (SocketManager.SocketReceiveHandler)Method; + } + } + public void CheckHeartBeatFaileds() { if (HeartBeatFaileds >= 3) Close(); diff --git a/FunGame.Core/Library/Common/Network/SocketObject.cs b/FunGame.Core/Library/Common/Network/SocketObject.cs index 257fb14..35d1b00 100644 --- a/FunGame.Core/Library/Common/Network/SocketObject.cs +++ b/FunGame.Core/Library/Common/Network/SocketObject.cs @@ -1,4 +1,5 @@ -using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Library.Common.Network { @@ -7,12 +8,30 @@ namespace Milimoe.FunGame.Core.Library.Common.Network public SocketMessageType SocketType { get; } = SocketMessageType.Unknown; public Guid Token { get; } = Guid.Empty; public object[] Parameters { get; } = Array.Empty(); + public int Length { get; } = 0; public SocketObject(SocketMessageType type, Guid token, params object[] parameters) { SocketType = type; Token = token; Parameters = parameters; + Length = parameters.Length; + } + + /// + /// 从参数列表中获取指定类型的参数 + /// + /// 类型 + /// 索引 + /// 类型的参数 + /// 索引超过数组上限 + public T? GetParam(int index) + { + if (index < Parameters.Length) + { + return NetworkUtility.ConvertJsonObject(Parameters[index]); + } + throw new IndexOutOfArrayLengthException(); } } } diff --git a/FunGame.Core/Library/Constant/General.cs b/FunGame.Core/Library/Constant/General.cs index 0ad0f06..baaa29c 100644 --- a/FunGame.Core/Library/Constant/General.cs +++ b/FunGame.Core/Library/Constant/General.cs @@ -14,5 +14,7 @@ namespace Milimoe.FunGame.Core.Library.Constant public const int MaxTask_1C2G = 10; public const int MaxThread_General = 20; public const int MaxTask_4C4G = 40; + + public const int SocketByteSize = 2048; } } diff --git a/FunGame.Core/Library/Exception/Exception.cs b/FunGame.Core/Library/Exception/Exception.cs index 7948380..6d93d5f 100644 --- a/FunGame.Core/Library/Exception/Exception.cs +++ b/FunGame.Core/Library/Exception/Exception.cs @@ -129,4 +129,14 @@ { public override string Message => "无法创建Smtp服务 (#10026)"; } + + public class IndexOutOfArrayLengthException : Exception + { + public override string Message => "索引超过数组长度上限 (#10027)"; + } + + public class SocketCreateReceivingException : Exception + { + public override string Message => "无法创建监听套接字 (#10027)"; + } } diff --git a/FunGame.Core/Service/SocketManager.cs b/FunGame.Core/Service/SocketManager.cs index 1058e54..3366fbf 100644 --- a/FunGame.Core/Service/SocketManager.cs +++ b/FunGame.Core/Service/SocketManager.cs @@ -162,7 +162,7 @@ namespace Milimoe.FunGame.Core.Service if (Socket != null) { // 从服务器接收消息 - byte[] buffer = new byte[2048]; + byte[] buffer = new byte[General.SocketByteSize]; int length = Socket.Receive(buffer); if (length > 0) { @@ -172,6 +172,8 @@ namespace Milimoe.FunGame.Core.Service { result = new Library.Common.Network.SocketObject(json.MessageType, json.Token, json.Parameters); } + // 客户端接收消息,广播ScoketObject到每个UIModel + OnSocketReceive(result); return result; } } @@ -189,7 +191,7 @@ namespace Milimoe.FunGame.Core.Service if (ClientSocket != null) { // 从客户端接收消息 - byte[] buffer = new byte[2048]; + byte[] buffer = new byte[General.SocketByteSize]; int length = ClientSocket.Receive(buffer); if (length > 0) { @@ -238,38 +240,23 @@ namespace Milimoe.FunGame.Core.Service #region 事件 /// - /// 异步监听事件 + /// 监听事件的委托 /// - /// 结果类 - /// 通信类型 - /// 参数 - /// 结果 - internal delegate Task SocketHandler(Library.Common.Network.SocketObject SocketObject); + /// SocketObject + internal delegate void SocketReceiveHandler(Library.Common.Network.SocketObject SocketObject); /// - /// 异步监听事件 + /// 监听事件 /// - /// 通信类型 - /// 参数 - /// 线程 - internal delegate Task SocketHandler(Library.Common.Network.SocketObject SocketObject); + internal static event SocketReceiveHandler? SocketReceive; /// - /// 监听没有返回值的事件 + /// 触发异步监听事件 /// - internal static event SocketHandler? SocketReceiveAsync; - - /// - /// 触发异步无返回值事件 - /// - /// 通信类型 - /// 参数 - internal static void OnSocketReceiveAsync(Library.Common.Network.SocketObject SocketObject) + /// SocketObject + internal static void OnSocketReceive(Library.Common.Network.SocketObject SocketObject) { - if (SocketReceiveAsync != null) - { - SocketReceiveAsync.Invoke(SocketObject); - } + SocketReceive?.Invoke(SocketObject); } #endregion diff --git a/FunGame.Desktop/Controller/LoginController.cs b/FunGame.Desktop/Controller/LoginController.cs index 7ccb183..bb7f797 100644 --- a/FunGame.Desktop/Controller/LoginController.cs +++ b/FunGame.Desktop/Controller/LoginController.cs @@ -1,12 +1,26 @@ using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; using Milimoe.FunGame.Desktop.Library; using Milimoe.FunGame.Desktop.Library.Component; using Milimoe.FunGame.Desktop.Model; +using Milimoe.FunGame.Desktop.UI; namespace Milimoe.FunGame.Desktop.Controller { - public class LoginController + public class LoginController : BaseController { + private readonly LoginModel LoginModel; + + public LoginController() + { + LoginModel = new LoginModel(); + } + + public override void Dispose() + { + LoginModel.Dispose(); + } + public static bool LoginAccount(params object[]? objs) { if (RunTime.Login?.OnBeforeLoginEvent(new GeneralEventArgs()) == Core.Library.Constant.EventResult.Fail) return false; diff --git a/FunGame.Desktop/Controller/MainController.cs b/FunGame.Desktop/Controller/MainController.cs index 0848204..dcbc4a1 100644 --- a/FunGame.Desktop/Controller/MainController.cs +++ b/FunGame.Desktop/Controller/MainController.cs @@ -1,13 +1,12 @@ using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; using Milimoe.FunGame.Core.Library.Constant; -using Milimoe.FunGame.Desktop.Library; -using Milimoe.FunGame.Desktop.Library.Interface; using Milimoe.FunGame.Desktop.Model; using Milimoe.FunGame.Desktop.UI; namespace Milimoe.FunGame.Desktop.Controller { - public class MainController : IMain + public class MainController : BaseController { public bool Connected => Do(MainInvokeType.Connected); @@ -20,6 +19,11 @@ namespace Milimoe.FunGame.Desktop.Controller MainModel = new MainModel(Main); } + public override void Dispose() + { + MainModel.Dispose(); + } + /** * 从内部去调用Model的方法,并记录日志。 */ @@ -28,58 +32,11 @@ namespace Milimoe.FunGame.Desktop.Controller object result = new(); switch(DoType) { - case MainInvokeType.GetServerConnection: - result = MainModel.GetServerConnection(); - break; - - case MainInvokeType.Connect: - result = MainModel.Connect(); - if ((ConnectResult)result != ConnectResult.Success) - { - Main.OnFailedConnectEvent(new GeneralEventArgs()); - Main.OnAfterConnectEvent(new GeneralEventArgs()); - } - break; - - case MainInvokeType.Connected: - result = MainModel.Connected; - break; - - case MainInvokeType.Disconnect: - if (Main.OnBeforeDisconnectEvent(new GeneralEventArgs()) == EventResult.Fail) return (T)result; - MainModel.Disconnect(); - break; - - case MainInvokeType.Disconnected: - break; - - case MainInvokeType.WaitConnectAndSetYellow: - break; - - case MainInvokeType.WaitLoginAndSetYellow: - break; - - case MainInvokeType.SetGreenAndPing: - break; - - case MainInvokeType.SetGreen: - break; - - case MainInvokeType.SetYellow: - break; - - case MainInvokeType.SetRed: - break; - case MainInvokeType.LogOut: if (Main.OnBeforeLogoutEvent(new GeneralEventArgs()) == EventResult.Fail) return (T)result; result = MainModel.LogOut(); break; - case MainInvokeType.Close: - result = MainModel.Close(); - break; - case MainInvokeType.IntoRoom: if (Main.OnBeforeIntoRoomEvent(new GeneralEventArgs()) == EventResult.Fail) return (T)result; result = MainModel.IntoRoom(); @@ -97,66 +54,11 @@ namespace Milimoe.FunGame.Desktop.Controller return (T)result; } - public bool GetServerConnection() - { - return Do(MainInvokeType.GetServerConnection); - } - - public ConnectResult Connect() - { - return Do(MainInvokeType.Connect); - } - - public void Disconnect() - { - Do(MainInvokeType.Disconnect); - } - - public void Disconnected() - { - Do(MainInvokeType.Disconnected); - } - - public void SetWaitConnectAndSetYellow() - { - throw new NotImplementedException(); - } - - public void SetWaitLoginAndSetYellow() - { - throw new NotImplementedException(); - } - - public void SetGreenAndPing() - { - throw new NotImplementedException(); - } - - public void SetGreen() - { - throw new NotImplementedException(); - } - - public void SetYellow() - { - throw new NotImplementedException(); - } - - public void SetRed() - { - throw new NotImplementedException(); - } - public bool LogOut() { return Do(MainInvokeType.LogOut); } - public bool Close() - { - return Do(MainInvokeType.Close); - } - public bool IntoRoom() { return Do(MainInvokeType.IntoRoom); diff --git a/FunGame.Desktop/Controller/RegisterController.cs b/FunGame.Desktop/Controller/RegisterController.cs index 48b6d20..a838b49 100644 --- a/FunGame.Desktop/Controller/RegisterController.cs +++ b/FunGame.Desktop/Controller/RegisterController.cs @@ -3,11 +3,11 @@ using Milimoe.FunGame.Desktop.Library; using Milimoe.FunGame.Desktop.Model; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Desktop.UI; -using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Library.Common.Architecture; namespace Milimoe.FunGame.Desktop.Controller { - public class RegisterController + public class RegisterController : BaseController { private readonly Register Register; private readonly RegisterModel RegModel; @@ -18,9 +18,9 @@ namespace Milimoe.FunGame.Desktop.Controller RegModel = new RegisterModel(reg); } - public void SocketHandler(SocketMessageType type, params object[]? objs) + public override void Dispose() { - RegModel.SocketHandler(type, objs); + RegModel.Dispose(); } public bool Reg(params object[]? objs) diff --git a/FunGame.Desktop/Controller/RunTimeController.cs b/FunGame.Desktop/Controller/RunTimeController.cs new file mode 100644 index 0000000..c6d99b2 --- /dev/null +++ b/FunGame.Desktop/Controller/RunTimeController.cs @@ -0,0 +1,100 @@ +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Model; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Controller +{ + public class RunTimeController + { + public bool Connected => Do(MainInvokeType.Connected); + + private RunTimeModel RunTimeModel { get; } + private Main Main { get; } + + public RunTimeController(Main Main) + { + this.Main = Main; + RunTimeModel = new RunTimeModel(Main); + } + + /** + * 从内部去调用Model的方法,并记录日志。 + */ + private T Do(MainInvokeType DoType, params object[] args) + { + object result = new(); + switch (DoType) + { + case MainInvokeType.GetServerConnection: + result = RunTimeModel.GetServerConnection(); + break; + + case MainInvokeType.Connect: + result = RunTimeModel.Connect(); + if ((ConnectResult)result != ConnectResult.Success) + { + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + } + break; + + case MainInvokeType.Connected: + result = RunTimeModel.Connected; + break; + + case MainInvokeType.Disconnect: + if (Main.OnBeforeDisconnectEvent(new GeneralEventArgs()) == EventResult.Fail) return (T)result; + RunTimeModel.Disconnect(); + break; + + case MainInvokeType.Disconnected: + break; + + case MainInvokeType.Close: + if (args != null && args.Length > 0) + { + RunTimeModel.Error((Exception)args[0]); + result = true; + } + else + result = RunTimeModel.Close(); + break; + + default: + break; + } + return (T)result; + } + + public bool GetServerConnection() + { + return Do(MainInvokeType.GetServerConnection); + } + + public ConnectResult Connect() + { + return Do(MainInvokeType.Connect); + } + + public void Disconnect() + { + Do(MainInvokeType.Disconnect); + } + + public void Disconnected() + { + Do(MainInvokeType.Disconnected); + } + + public bool Close() + { + return Do(MainInvokeType.Close); + } + + public bool Error(Exception e) + { + return Do(MainInvokeType.Close, e); + } + } +} diff --git a/FunGame.Desktop/Library/Base/BaseLogin.cs b/FunGame.Desktop/Library/Base/BaseLogin.cs index 9321586..55a7340 100644 --- a/FunGame.Desktop/Library/Base/BaseLogin.cs +++ b/FunGame.Desktop/Library/Base/BaseLogin.cs @@ -16,7 +16,7 @@ namespace Milimoe.FunGame.Desktop.Library.Base { if (AfterLogin != null) { - return AfterLogin(this, e); + return AfterLogin.Invoke(this, e); } else return EventResult.NoEventImplement; } @@ -25,7 +25,7 @@ namespace Milimoe.FunGame.Desktop.Library.Base { if (BeforeLogin != null) { - return BeforeLogin(this, e); + return BeforeLogin.Invoke(this, e); } else return EventResult.NoEventImplement; } @@ -34,7 +34,7 @@ namespace Milimoe.FunGame.Desktop.Library.Base { if (FailedLogin != null) { - return FailedLogin(this, e); + return FailedLogin.Invoke(this, e); } else return EventResult.NoEventImplement; } @@ -43,7 +43,7 @@ namespace Milimoe.FunGame.Desktop.Library.Base { if (SucceedLogin != null) { - return SucceedLogin(this, e); + return SucceedLogin.Invoke(this, e); } else return EventResult.NoEventImplement; } diff --git a/FunGame.Desktop/Library/Component/GeneralForm.cs b/FunGame.Desktop/Library/Component/GeneralForm.cs index afa7da6..a092a00 100644 --- a/FunGame.Desktop/Library/Component/GeneralForm.cs +++ b/FunGame.Desktop/Library/Component/GeneralForm.cs @@ -56,39 +56,38 @@ namespace Milimoe.FunGame.Desktop.Library.Component /// protected virtual void FormClosedEvent(object? sender, FormClosedEventArgs e) { - Dispose(); - if (GetType() == typeof(ShowMessage)) + if (GetType() != typeof(ShowMessage)) { - return; - } - Singleton.Remove(this); - if (GetType() == typeof(Main)) - { - RunTime.Main = null; - } - else if (GetType() == typeof(Login)) - { - RunTime.Login = null; - } - else if (GetType() == typeof(Register)) - { - RunTime.Register = null; - } - else if (GetType() == typeof(InventoryUI)) - { - RunTime.Inventory = null; - } - else if (GetType() == typeof(StoreUI)) - { - RunTime.Store = null; - } - else if (GetType() == typeof(RoomSetting)) - { - RunTime.RoomSetting = null; - } - else if (GetType() == typeof(UserCenter)) - { - RunTime.UserCenter = null; + Singleton.Remove(this); + if (GetType() == typeof(Main)) + { + RunTime.Main = null; + } + else if (GetType() == typeof(Login)) + { + RunTime.Login = null; + } + else if (GetType() == typeof(Register)) + { + RunTime.Register = null; + } + else if (GetType() == typeof(InventoryUI)) + { + RunTime.Inventory = null; + } + else if (GetType() == typeof(StoreUI)) + { + RunTime.Store = null; + } + else if (GetType() == typeof(RoomSetting)) + { + RunTime.RoomSetting = null; + } + else if (GetType() == typeof(UserCenter)) + { + RunTime.UserCenter = null; + } + Dispose(); } } diff --git a/FunGame.Desktop/Library/Config/RunTime.cs b/FunGame.Desktop/Library/Config/RunTime.cs index 8a94b68..b3998f1 100644 --- a/FunGame.Desktop/Library/Config/RunTime.cs +++ b/FunGame.Desktop/Library/Config/RunTime.cs @@ -7,6 +7,7 @@ public class RunTime { public static Core.Library.Common.Network.Socket? Socket { get; set; } = null; + public static Controller.RunTimeController? Connector { get; set; } = null; public static UI.Main? Main { get; set; } = null; public static UI.Login? Login { get; set; } = null; public static UI.Register? Register { get; set; } = null; diff --git a/FunGame.Desktop/Library/Interface/IMain.cs b/FunGame.Desktop/Library/Interface/IMain.cs deleted file mode 100644 index 758e47b..0000000 --- a/FunGame.Desktop/Library/Interface/IMain.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.Desktop.Library.Interface -{ - public interface IMain - { - public bool Connected { get; } - - public bool GetServerConnection(); - public ConnectResult Connect(); - public void Disconnect(); - public void Disconnected(); - public void SetWaitConnectAndSetYellow(); - public void SetWaitLoginAndSetYellow(); - public void SetGreenAndPing(); - public void SetGreen(); - public void SetYellow(); - public void SetRed(); - public bool LogOut(); - public bool Close(); - public bool IntoRoom(); - public bool Chat(string msg); - } -} diff --git a/FunGame.Desktop/Model/LoginModel.cs b/FunGame.Desktop/Model/LoginModel.cs index 3638120..c27a31f 100644 --- a/FunGame.Desktop/Model/LoginModel.cs +++ b/FunGame.Desktop/Model/LoginModel.cs @@ -1,20 +1,55 @@ using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Controller; using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.UI; namespace Milimoe.FunGame.Desktop.Model { /// /// 请不要越过Controller直接调用Model中的方法。 /// - public class LoginModel + public class LoginModel : BaseModel { + public LoginModel() : base(RunTime.Socket) + { + + } + + public override void SocketHandler(SocketObject SocketObject) + { + try + { + SocketMessageType type = SocketObject.SocketType; + object[] objs = SocketObject.Parameters; + switch (SocketObject.SocketType) + { + case SocketMessageType.Login: + SocketHandler_Login(SocketObject); + break; + + case SocketMessageType.CheckLogin: + SocketHandler_CheckLogin(SocketObject); + break; + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + } + public static bool LoginAccount(params object[]? objs) { try { - Core.Library.Common.Network.Socket? Socket = RunTime.Socket; + Socket? Socket = RunTime.Socket; if (Socket != null && objs != null) { string username = ""; @@ -41,7 +76,7 @@ namespace Milimoe.FunGame.Desktop.Model { try { - Core.Library.Common.Network.Socket? Socket = RunTime.Socket; + Socket? Socket = RunTime.Socket; if (Socket != null && objs != null) { Guid key = Guid.Empty; @@ -58,5 +93,53 @@ namespace Milimoe.FunGame.Desktop.Model } return false; } + + private void SocketHandler_Login(SocketObject SocketObject) + { + Guid key = Guid.Empty; + string? msg = ""; + // 返回一个Key,再发回去给服务器就行了 + if (SocketObject.Length > 0) key = SocketObject.GetParam(0); + if (SocketObject.Length > 1) msg = SocketObject.GetParam(1); + // 如果返回了msg,说明验证错误。 + if (msg != null && msg.Trim() != "") + { + ShowMessage.ErrorMessage(msg, "登录失败"); + RunTime.Login?.OnFailedLoginEvent(new GeneralEventArgs()); + RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); + } + else + { + if (key != Guid.Empty) + { + Config.Guid_LoginKey = key; + LoginController.CheckLogin(key); + } + else + { + ShowMessage.ErrorMessage("登录失败!!", "登录失败", 5); + RunTime.Login?.OnFailedLoginEvent(new GeneralEventArgs()); + RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); + } + } + } + + private void SocketHandler_CheckLogin(SocketObject SocketObject) + { + // 返回的objs是该Login的User对象的各个属性 + object[] objs = SocketObject.Parameters; + if (objs != null && objs.Length > 0) + { + // 创建User对象并返回到Main + RunTime.Main?.UpdateUI(MainInvokeType.SetUser, new object[] { Factory.New(objs) }); + RunTime.Login?.OnSucceedLoginEvent(new GeneralEventArgs()); + RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); + return; + } + ShowMessage.ErrorMessage("登录失败!!", "登录失败", 5); + RunTime.Login?.OnFailedLoginEvent(new GeneralEventArgs()); + RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); + } + } } diff --git a/FunGame.Desktop/Model/MainModel.cs b/FunGame.Desktop/Model/MainModel.cs index 36c2397..347b6b8 100644 --- a/FunGame.Desktop/Model/MainModel.cs +++ b/FunGame.Desktop/Model/MainModel.cs @@ -1,35 +1,25 @@ -using Milimoe.FunGame.Core.Api.Utility; -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Exception; -using Milimoe.FunGame.Desktop.Controller; using Milimoe.FunGame.Desktop.Library; using Milimoe.FunGame.Desktop.Library.Component; -using Milimoe.FunGame.Desktop.Library.Interface; using Milimoe.FunGame.Desktop.UI; -using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView; -using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace Milimoe.FunGame.Desktop.Model { - public class MainModel : IMain + public class MainModel : BaseModel { - public bool Connected => Socket != null && Socket.Connected; - private readonly Main Main; - private Task? ReceivingTask; - private Core.Library.Common.Network.Socket? Socket; - private bool IsReceiving = false; - public MainModel(Main main) + public MainModel(Main main) : base(RunTime.Socket) { Main = main; } #region 公开方法 - + public bool LogOut() { try @@ -37,7 +27,7 @@ namespace Milimoe.FunGame.Desktop.Model // 需要当时登录给的Key发回去,确定是账号本人在操作才允许登出 if (Config.Guid_LoginKey != Guid.Empty) { - if (Socket?.Send(SocketMessageType.Logout, Config.Guid_LoginKey) == SocketResult.Success) + if (RunTime.Socket?.Send(SocketMessageType.Logout, Config.Guid_LoginKey) == SocketResult.Success) { return true; } @@ -54,202 +44,11 @@ namespace Milimoe.FunGame.Desktop.Model return false; } - public void Disconnect() - { - try - { - Socket?.Send(SocketMessageType.Disconnect, ""); - } - catch (Exception e) - { - Main.GetMessage(e.GetErrorInfo()); - Main.OnFailedDisconnectEvent(new GeneralEventArgs()); - Main.OnAfterDisconnectEvent(new GeneralEventArgs()); - } - } - - public void Disconnected() - { - Disconnect(); - } - - public bool GetServerConnection() - { - try - { - // 获取服务器IP - string? ipaddress = (string?)Implement.GetFunGameImplValue(InterfaceType.IClient, InterfaceMethod.RemoteServerIP); - if (ipaddress != null) - { - string[] s = ipaddress.Split(':'); - if (s != null && s.Length > 1) - { - Constant.Server_Address = s[0]; - Constant.Server_Port = Convert.ToInt32(s[1]); - if (Connect() == ConnectResult.Success) return true; // 连接服务器 - } - } - else - { - ShowMessage.ErrorMessage("查找可用的服务器失败!"); - Config.FunGame_isRetrying = false; - throw new FindServerFailedException(); - } - } - catch (Exception e) - { - Main.GetMessage(e.GetErrorInfo(), TimeType.None); - } - - return false; - } - - public ConnectResult Connect() - { - if (Main.OnBeforeConnectEvent(new GeneralEventArgs()) == EventResult.Fail) return ConnectResult.ConnectFailed; - if (Constant.Server_Address == "" || Constant.Server_Port <= 0) - { - ShowMessage.ErrorMessage("查找可用的服务器失败!"); - Main.OnFailedConnectEvent(new GeneralEventArgs()); - Main.OnAfterConnectEvent(new GeneralEventArgs()); - return ConnectResult.FindServerFailed; - } - try - { - if (Config.FunGame_isRetrying) - { - Main.GetMessage("正在连接服务器,请耐心等待。"); - Config.FunGame_isRetrying = false; - Main.OnFailedConnectEvent(new GeneralEventArgs()); - Main.OnAfterConnectEvent(new GeneralEventArgs()); - return ConnectResult.CanNotConnect; - } - if (!Config.FunGame_isConnected) - { - Main.CurrentRetryTimes++; - if (Main.CurrentRetryTimes == 0) Main.GetMessage("开始连接服务器...", TimeType.General); - else Main.GetMessage("第" + Main.CurrentRetryTimes + "次重试连接服务器..."); - // 超过重连次数上限 - if (Main.CurrentRetryTimes + 1 > Main.MaxRetryTimes) - { - throw new CanNotConnectException(); - } - // 与服务器建立连接 - Socket?.Close(); - Config.FunGame_isRetrying = true; - Socket = Core.Library.Common.Network.Socket.Connect(Constant.Server_Address, Constant.Server_Port); - if (Socket != null && Socket.Connected) - { - // 设置可复用Socket - RunTime.Socket = Socket; - // 发送连接请求 - if (Socket.Send(SocketMessageType.Connect) == SocketResult.Success) - { - Task t = Task.Factory.StartNew(() => - { - if (Receiving() == SocketMessageType.Connect) - { - Main.GetMessage("连接服务器成功,请登录账号以体验FunGame。"); - Main.UpdateUI(MainInvokeType.Connected); - StartReceiving(); - while (true) - { - if (IsReceiving) - { - Main.OnSucceedConnectEvent(new GeneralEventArgs()); - Main.OnAfterConnectEvent(new GeneralEventArgs()); - break; - } - } - } - }); - return ConnectResult.Success; - } - Socket?.Close(); - Config.FunGame_isRetrying = false; - throw new CanNotConnectException(); - } - } - else - { - Main.GetMessage("已连接至服务器,请勿重复连接。"); - return ConnectResult.CanNotConnect; - } - } - catch (Exception e) - { - Main.GetMessage(e.GetErrorInfo(), TimeType.None); - Main.UpdateUI(MainInvokeType.SetRed); - Config.FunGame_isRetrying = false; - Task.Factory.StartNew(() => - { - Main.OnFailedConnectEvent(new GeneralEventArgs()); - Main.OnAfterConnectEvent(new GeneralEventArgs()); - }); - return ConnectResult.ConnectFailed; - } - return ConnectResult.CanNotConnect; - } - - public bool Close() - { - try - { - if (Socket != null) - { - Socket.Close(); - Socket = null; - } - if (ReceivingTask != null && !ReceivingTask.IsCompleted) - { - ReceivingTask.Wait(1); - ReceivingTask = null; - IsReceiving = false; - } - } - catch (Exception e) - { - Main.GetMessage(e.GetErrorInfo(), TimeType.None); - return false; - } - return true; - } - - public void SetWaitConnectAndSetYellow() - { - throw new NotImplementedException(); - } - - public void SetWaitLoginAndSetYellow() - { - throw new NotImplementedException(); - } - - public void SetGreenAndPing() - { - throw new NotImplementedException(); - } - - public void SetGreen() - { - throw new NotImplementedException(); - } - - public void SetYellow() - { - throw new NotImplementedException(); - } - - public void SetRed() - { - throw new NotImplementedException(); - } - public bool IntoRoom() { try { - if (Socket?.Send(SocketMessageType.IntoRoom, Config.FunGame_Roomid) == SocketResult.Success) + if (RunTime.Socket?.Send(SocketMessageType.IntoRoom, Config.FunGame_Roomid) == SocketResult.Success) return true; else throw new CanNotIntoRoomException(); } @@ -266,7 +65,7 @@ namespace Milimoe.FunGame.Desktop.Model { try { - if (Socket?.Send(SocketMessageType.Chat, msg) == SocketResult.Success) + if (RunTime.Socket?.Send(SocketMessageType.Chat, msg) == SocketResult.Success) return true; else throw new CanNotSendTalkException(); } @@ -279,89 +78,34 @@ namespace Milimoe.FunGame.Desktop.Model } } - #endregion - - #region 私有方法 - - private void StartReceiving() + public override void SocketHandler(SocketObject SocketObject) { - ReceivingTask = Task.Factory.StartNew(() => - { - Thread.Sleep(100); - IsReceiving = true; - while (Socket != null && Socket.Connected) - { - Receiving(); - } - }); - Socket?.StartReceiving(ReceivingTask); - } - - private SocketObject GetServerMessage() - { - if (Socket != null && Socket.Connected) - { - return Socket.Receive(); - } - return new SocketObject(SocketMessageType.Unknown, Guid.Empty, Array.Empty()); - } - - private SocketMessageType Receiving() - { - if (Socket is null) return SocketMessageType.Unknown; - SocketMessageType result = SocketMessageType.Unknown; try { - SocketObject ServerMessage = GetServerMessage(); - SocketMessageType type = ServerMessage.SocketType; - object[] objs = ServerMessage.Parameters; - result = type; - switch (type) + switch (SocketObject.SocketType) { - case SocketMessageType.Connect: - SocketHandler_Connect(objs); - break; - case SocketMessageType.GetNotice: - SocketHandler_GetNotice(objs); - break; - - case SocketMessageType.Login: - SocketHandler_Login(objs); - break; - - case SocketMessageType.CheckLogin: - SocketHandler_CheckLogin(objs); - RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); + SocketHandler_GetNotice(SocketObject); break; case SocketMessageType.Logout: - SocketHandler_LogOut(objs); - break; - - case SocketMessageType.Disconnect: - SocketHandler_Disconnect(objs); + SocketHandler_LogOut(SocketObject); break; case SocketMessageType.HeartBeat: - if (Socket.Connected && Usercfg.LoginUser != null) + if ((RunTime.Socket?.Connected ?? false) && Usercfg.LoginUser != null) Main.UpdateUI(MainInvokeType.SetGreenAndPing); break; case SocketMessageType.IntoRoom: - SocketHandler_IntoRoom(objs); + SocketHandler_IntoRoom(SocketObject); break; case SocketMessageType.QuitRoom: break; case SocketMessageType.Chat: - SocketHandler_Chat(objs); - break; - - case SocketMessageType.Reg: - case SocketMessageType.CheckReg: - RunTime.Register?.SocketHandler(type, objs); + SocketHandler_Chat(SocketObject); break; case SocketMessageType.Unknown: @@ -371,79 +115,26 @@ namespace Milimoe.FunGame.Desktop.Model } catch (Exception e) { - // 报错中断服务器连接 - Main.GetMessage(e.GetErrorInfo(), TimeType.None); - Main.UpdateUI(MainInvokeType.Disconnected); - Main.OnFailedConnectEvent(new GeneralEventArgs()); - Close(); + RunTime.Connector?.Error(e); } - return result; } #endregion #region SocketHandler - private void SocketHandler_Connect(object[] objs) + private void SocketHandler_GetNotice(SocketObject SocketObject) { - string msg = ""; - Guid token = Guid.Empty; - if (objs.Length > 0) msg = NetworkUtility.ConvertJsonObject(objs[0])!; - string[] strings = msg.Split(';'); - string ServerName = strings[0]; - string ServerNotice = strings[1]; - Config.FunGame_ServerName = ServerName; - Config.FunGame_Notice = ServerNotice; - if (objs.Length > 1) token = NetworkUtility.ConvertJsonObject(objs[1]); - Socket!.Token = token; - Config.Guid_Socket = token; - Main.GetMessage($"已连接服务器:{ServerName}。\n\n********** 服务器公告 **********\n\n{ServerNotice}\n\n"); - // 设置等待登录的黄灯 - Main.UpdateUI(MainInvokeType.WaitLoginAndSetYellow); + if (SocketObject.Length > 0) Config.FunGame_Notice = SocketObject.GetParam(0)!; } - private void SocketHandler_GetNotice(object[] objs) - { - if (objs.Length > 0) Config.FunGame_Notice = NetworkUtility.ConvertJsonObject(objs[0])!; - } - - private void SocketHandler_Login(object[] objs) - { - Guid key = Guid.Empty; - string? msg = ""; - // 返回一个Key,再发回去给服务器就行了 - if (objs.Length > 0) key = NetworkUtility.ConvertJsonObject(objs[0]); - if (objs.Length > 1) msg = NetworkUtility.ConvertJsonObject(objs[1]); - // 如果返回了msg,说明验证错误。 - if (msg != null && msg.Trim() != "") - { - ShowMessage.ErrorMessage(msg, "登录失败"); - RunTime.Login?.OnFailedLoginEvent(new GeneralEventArgs()); - RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); - } - else - { - if (key != Guid.Empty) - { - Config.Guid_LoginKey = key; - LoginController.CheckLogin(key); - } - else - { - ShowMessage.ErrorMessage("登录失败!!", "登录失败", 5); - RunTime.Login?.OnFailedLoginEvent(new GeneralEventArgs()); - RunTime.Login?.OnAfterLoginEvent(new GeneralEventArgs()); - } - } - } - - private void SocketHandler_LogOut(object[] objs) + private void SocketHandler_LogOut(SocketObject SocketObject) { Guid key = Guid.Empty; string? msg = ""; // 返回一个Key,如果这个Key是空的,登出失败 - if (objs != null && objs.Length > 0) key = NetworkUtility.ConvertJsonObject(objs[0]); - if (objs != null && objs.Length > 1) msg = NetworkUtility.ConvertJsonObject(objs[1]); + if (SocketObject.Parameters != null && SocketObject.Length > 0) key = SocketObject.GetParam(0); + if (SocketObject.Parameters != null && SocketObject.Length > 1) msg = SocketObject.GetParam(1); if (key != Guid.Empty) { Config.Guid_LoginKey = Guid.Empty; @@ -458,35 +149,10 @@ namespace Milimoe.FunGame.Desktop.Model Main.OnAfterLogoutEvent(new GeneralEventArgs()); } - private void SocketHandler_CheckLogin(object[] objs) - { - // 返回的objs是该Login的User对象的各个属性 - if (objs != null && objs.Length > 0) - { - // 创建User对象并返回到Main - Main.UpdateUI(MainInvokeType.SetUser, new object[] { Factory.New(objs) }); - RunTime.Login?.OnSucceedLoginEvent(new GeneralEventArgs()); - return; - } - ShowMessage.ErrorMessage("登录失败!!", "登录失败", 5); - RunTime.Login?.OnFailedLoginEvent(new GeneralEventArgs()); - } - - private void SocketHandler_Disconnect(object[] objs) - { - string msg = ""; - if (objs.Length > 0) msg = NetworkUtility.ConvertJsonObject(objs[0])!; - Main.GetMessage(msg); - Main.UpdateUI(MainInvokeType.Disconnect); - Close(); - Main.OnSucceedDisconnectEvent(new GeneralEventArgs()); - Main.OnAfterDisconnectEvent(new GeneralEventArgs()); - } - - private void SocketHandler_IntoRoom(object[] objs) + private void SocketHandler_IntoRoom(SocketObject SocketObject) { string roomid = ""; - if (objs.Length > 0) roomid = NetworkUtility.ConvertJsonObject(objs[0])!; + if (SocketObject.Length > 0) roomid = SocketObject.GetParam(0)!; if (roomid.Trim() != "" && roomid == "-1") { Main.GetMessage($"已连接至公共聊天室。"); @@ -499,12 +165,12 @@ namespace Milimoe.FunGame.Desktop.Model Main.OnAfterIntoRoomEvent(new GeneralEventArgs()); } - private void SocketHandler_Chat(object[] objs) + private void SocketHandler_Chat(SocketObject SocketObject) { - if (objs != null && objs.Length > 1) + if (SocketObject.Parameters != null && SocketObject.Length > 1) { - string user = NetworkUtility.ConvertJsonObject(objs[0])!; - string msg = NetworkUtility.ConvertJsonObject(objs[1])!; + string user = SocketObject.GetParam(0)!; + string msg = SocketObject.GetParam(1)!; if (user != Usercfg.LoginUserName) { Main.GetMessage(msg, TimeType.None); diff --git a/FunGame.Desktop/Model/RegisterModel.cs b/FunGame.Desktop/Model/RegisterModel.cs index 1f1bd46..4b9ef87 100644 --- a/FunGame.Desktop/Model/RegisterModel.cs +++ b/FunGame.Desktop/Model/RegisterModel.cs @@ -1,38 +1,41 @@ using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Exception; using Milimoe.FunGame.Desktop.Library; using Milimoe.FunGame.Desktop.Library.Component; -using Milimoe.FunGame.Desktop.Library.Interface; using Milimoe.FunGame.Desktop.UI; namespace Milimoe.FunGame.Desktop.Model { - public class RegisterModel + public class RegisterModel : BaseModel { private readonly Register Register; - public RegisterModel(Register reg) + public RegisterModel(Register reg) : base(RunTime.Socket) { Register = reg; } - public void SocketHandler(SocketMessageType type, params object[]? objs) + public override void SocketHandler(SocketObject SocketObject) { try { - switch (type) + SocketMessageType type = SocketObject.SocketType; + object[] objs = SocketObject.Parameters; + switch (SocketObject.SocketType) { case SocketMessageType.Reg: RegInvokeType invokeType = RegInvokeType.None; if (objs != null && objs.Length > 0) { - invokeType = NetworkUtility.ConvertJsonObject(objs[0]); + invokeType = SocketObject.GetParam(0); Register.UpdateUI(invokeType); } break; case SocketMessageType.CheckReg: - SocketHandler_CheckReg(objs); + SocketHandler_CheckReg(SocketObject); break; } } @@ -42,12 +45,12 @@ namespace Milimoe.FunGame.Desktop.Model } } - private void SocketHandler_CheckReg(params object[]? objs) + private void SocketHandler_CheckReg(SocketObject SocketObject) { - if (objs != null && objs.Length > 1) + if (SocketObject.Parameters != null && SocketObject.Parameters.Length > 1) { - bool successful = NetworkUtility.ConvertJsonObject(objs[0])!; - string msg = NetworkUtility.ConvertJsonObject(objs[1])!; + bool successful = SocketObject.GetParam(0)!; + string msg = SocketObject.GetParam(1)!; ShowMessage.Message(msg, "注册结果"); if (successful) { diff --git a/FunGame.Desktop/Model/RunTimeModel.cs b/FunGame.Desktop/Model/RunTimeModel.cs new file mode 100644 index 0000000..d0e61fc --- /dev/null +++ b/FunGame.Desktop/Model/RunTimeModel.cs @@ -0,0 +1,301 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Controller; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Model +{ + /// + /// 与创建关闭Socket相关的方法,使用此类 + /// + public class RunTimeModel + { + public bool Connected => Socket != null && Socket.Connected; + + private readonly Main Main; + private Task? ReceivingTask; + private Socket? Socket; + private bool IsReceiving = false; + + public RunTimeModel(Main main) + { + Main = main; + } + + #region 公开方法 + + public void Disconnect() + { + try + { + Socket?.Send(SocketMessageType.Disconnect, ""); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + Main.OnFailedDisconnectEvent(new GeneralEventArgs()); + Main.OnAfterDisconnectEvent(new GeneralEventArgs()); + } + } + + public void Disconnected() + { + Disconnect(); + } + + public bool GetServerConnection() + { + try + { + // 获取服务器IP + string? ipaddress = (string?)Implement.GetFunGameImplValue(InterfaceType.IClient, InterfaceMethod.RemoteServerIP); + if (ipaddress != null) + { + string[] s = ipaddress.Split(':'); + if (s != null && s.Length > 1) + { + Constant.Server_Address = s[0]; + Constant.Server_Port = Convert.ToInt32(s[1]); + if (Connect() == ConnectResult.Success) return true; // 连接服务器 + } + } + else + { + ShowMessage.ErrorMessage("查找可用的服务器失败!"); + Config.FunGame_isRetrying = false; + throw new FindServerFailedException(); + } + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + } + + return false; + } + + public ConnectResult Connect() + { + if (Main.OnBeforeConnectEvent(new GeneralEventArgs()) == EventResult.Fail) return ConnectResult.ConnectFailed; + if (Constant.Server_Address == "" || Constant.Server_Port <= 0) + { + ShowMessage.ErrorMessage("查找可用的服务器失败!"); + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + return ConnectResult.FindServerFailed; + } + try + { + if (Config.FunGame_isRetrying) + { + Main.GetMessage("正在连接服务器,请耐心等待。"); + Config.FunGame_isRetrying = false; + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + return ConnectResult.CanNotConnect; + } + if (!Config.FunGame_isConnected) + { + Main.CurrentRetryTimes++; + if (Main.CurrentRetryTimes == 0) Main.GetMessage("开始连接服务器...", TimeType.General); + else Main.GetMessage("第" + Main.CurrentRetryTimes + "次重试连接服务器..."); + // 超过重连次数上限 + if (Main.CurrentRetryTimes + 1 > Main.MaxRetryTimes) + { + throw new CanNotConnectException(); + } + // 与服务器建立连接 + Socket?.Close(); + Config.FunGame_isRetrying = true; + Socket = Socket.Connect(Constant.Server_Address, Constant.Server_Port); + if (Socket != null && Socket.Connected) + { + // 设置可复用Socket + RunTime.Socket = Socket; + // 发送连接请求 + if (Socket.Send(SocketMessageType.Connect) == SocketResult.Success) + { + Task t = Task.Factory.StartNew(() => + { + if (Receiving() == SocketMessageType.Connect) + { + Main.GetMessage("连接服务器成功,请登录账号以体验FunGame。"); + Main.UpdateUI(MainInvokeType.Connected); + StartReceiving(); + while (true) + { + if (IsReceiving) + { + Main.OnSucceedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + break; + } + } + } + }); + return ConnectResult.Success; + } + Socket?.Close(); + Config.FunGame_isRetrying = false; + throw new CanNotConnectException(); + } + } + else + { + Main.GetMessage("已连接至服务器,请勿重复连接。"); + return ConnectResult.CanNotConnect; + } + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + Main.UpdateUI(MainInvokeType.SetRed); + Config.FunGame_isRetrying = false; + Task.Factory.StartNew(() => + { + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + }); + return ConnectResult.ConnectFailed; + } + return ConnectResult.CanNotConnect; + } + + public bool Close() + { + try + { + if (Socket != null) + { + Socket.Close(); + Socket = null; + } + if (ReceivingTask != null && !ReceivingTask.IsCompleted) + { + ReceivingTask.Wait(1); + ReceivingTask = null; + IsReceiving = false; + } + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + return false; + } + return true; + } + + public void Error(Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + Main.UpdateUI(MainInvokeType.Disconnected); + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Close(); + } + + #endregion + + #region 私有方法 + + private void StartReceiving() + { + ReceivingTask = Task.Factory.StartNew(() => + { + Thread.Sleep(100); + IsReceiving = true; + while (Socket != null && Socket.Connected) + { + Receiving(); + } + }); + Socket?.StartReceiving(ReceivingTask); + } + + private SocketObject GetServerMessage() + { + if (Socket != null && Socket.Connected) + { + return Socket.Receive(); + } + return new SocketObject(SocketMessageType.Unknown, Guid.Empty, Array.Empty()); + } + + private SocketMessageType Receiving() + { + if (Socket is null) return SocketMessageType.Unknown; + SocketMessageType result = SocketMessageType.Unknown; + try + { + SocketObject ServerMessage = GetServerMessage(); + SocketMessageType type = ServerMessage.SocketType; + object[] objs = ServerMessage.Parameters; + result = type; + switch (type) + { + case SocketMessageType.Connect: + SocketHandler_Connect(ServerMessage); + break; + + case SocketMessageType.Disconnect: + SocketHandler_Disconnect(ServerMessage); + break; + + case SocketMessageType.HeartBeat: + if (Socket.Connected && Usercfg.LoginUser != null) + Main.UpdateUI(MainInvokeType.SetGreenAndPing); + break; + + case SocketMessageType.Unknown: + default: + break; + } + } + catch (Exception e) + { + // 报错中断服务器连接 + Error(e); + } + return result; + } + + #endregion + + #region SocketHandler + + private void SocketHandler_Connect(SocketObject ServerMessage) + { + string msg = ""; + Guid token = Guid.Empty; + if (ServerMessage.Parameters.Length > 0) msg = ServerMessage.GetParam(0)!; + string[] strings = msg.Split(';'); + string ServerName = strings[0]; + string ServerNotice = strings[1]; + Config.FunGame_ServerName = ServerName; + Config.FunGame_Notice = ServerNotice; + if (ServerMessage.Parameters.Length > 1) token = ServerMessage.GetParam(1); + Socket!.Token = token; + Config.Guid_Socket = token; + Main.GetMessage($"已连接服务器:{ServerName}。\n\n********** 服务器公告 **********\n\n{ServerNotice}\n\n"); + // 设置等待登录的黄灯 + Main.UpdateUI(MainInvokeType.WaitLoginAndSetYellow); + } + + private void SocketHandler_Disconnect(SocketObject ServerMessage) + { + string msg = ""; + if (ServerMessage.Parameters.Length > 0) msg = ServerMessage.GetParam(0)!; + Main.GetMessage(msg); + Main.UpdateUI(MainInvokeType.Disconnect); + Close(); + Main.OnSucceedDisconnectEvent(new GeneralEventArgs()); + Main.OnAfterDisconnectEvent(new GeneralEventArgs()); + } + + #endregion + } +} \ No newline at end of file diff --git a/FunGame.Desktop/UI/Login/Login.cs b/FunGame.Desktop/UI/Login/Login.cs index 1561ffc..0ea3a94 100644 --- a/FunGame.Desktop/UI/Login/Login.cs +++ b/FunGame.Desktop/UI/Login/Login.cs @@ -11,20 +11,29 @@ namespace Milimoe.FunGame.Desktop.UI { public partial class Login : BaseLogin { + private readonly LoginController LoginController; + public Login() { InitializeComponent(); + LoginController = new LoginController(); } protected override void BindEvent() { base.BindEvent(); + Disposed += Login_Disposed; BeforeLogin += BeforeLoginEvent; AfterLogin += AfterLoginEvent; FailedLogin += FailedLoginEvent; SucceedLogin += SucceedLoginEvent; } + private void Login_Disposed(object? sender, EventArgs e) + { + LoginController.Dispose(); + } + private bool Login_Handler() { try @@ -79,14 +88,19 @@ namespace Milimoe.FunGame.Desktop.UI public EventResult FailedLoginEvent(object sender, GeneralEventArgs e) { - GoToLogin.Enabled = true; + if (InvokeRequired) GoToLogin.Invoke(() => GoToLogin.Enabled = true); + else GoToLogin.Enabled = true; RunTime.Main?.OnFailedLoginEvent(e); return EventResult.Success; } private EventResult SucceedLoginEvent(object sender, GeneralEventArgs e) { - Close(); + if (!IsDisposed) + { + if (InvokeRequired) Invoke(Close); + else Close(); + } RunTime.Main?.OnSucceedLoginEvent(e); return EventResult.Success; } diff --git a/FunGame.Desktop/UI/Main/Main.cs b/FunGame.Desktop/UI/Main/Main.cs index 3e5e383..252a73b 100644 --- a/FunGame.Desktop/UI/Main/Main.cs +++ b/FunGame.Desktop/UI/Main/Main.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Library.Common.Event; @@ -8,7 +9,6 @@ using Milimoe.FunGame.Desktop.Library; using Milimoe.FunGame.Desktop.Library.Base; using Milimoe.FunGame.Desktop.Library.Component; using Milimoe.FunGame.Desktop.Utility; -using System.Diagnostics; namespace Milimoe.FunGame.Desktop.UI { @@ -39,23 +39,23 @@ namespace Milimoe.FunGame.Desktop.UI public Main() { InitializeComponent(); - Init(); + InitAsync(); } /// /// 所有自定义初始化的内容 /// - public void Init() + public async void InitAsync() { RunTime.Main = this; SetButtonEnableIfLogon(false, ClientState.WaitConnect); SetRoomid("-1"); // 房间号初始化 ShowFunGameInfo(); // 显示FunGame信息 GetFunGameConfig(); // 获取FunGame配置 - // 创建一个UI控制器 - MainController = new MainController(this); + // 创建RunTime + RunTime.Connector = new RunTimeController(this); // 窗口句柄创建后,进行委托 - Task.Factory.StartNew(() => + await Task.Factory.StartNew(() => { while (true) { @@ -64,13 +64,8 @@ namespace Milimoe.FunGame.Desktop.UI break; } } - void action() - { - if (Config.FunGame_isAutoConnect) - MainController.GetServerConnection(); - } - InvokeUpdateUI(action); }); + if (Config.FunGame_isAutoConnect) RunTime.Connector?.GetServerConnection(); } /// @@ -79,6 +74,7 @@ namespace Milimoe.FunGame.Desktop.UI protected override void BindEvent() { base.BindEvent(); + Disposed += Main_Disposed; FailedConnect += FailedConnectEvent; SucceedConnect += SucceedConnectEvent; SucceedLogin += SucceedLoginEvent; @@ -134,7 +130,7 @@ namespace Milimoe.FunGame.Desktop.UI if (MainController != null && Config.FunGame_isAutoConnect) { // 自动连接服务器 - MainController.Connect(); + RunTime.Connector?.Connect(); } break; @@ -630,7 +626,6 @@ namespace Milimoe.FunGame.Desktop.UI Login.Visible = false; Logout.Visible = true; UpdateUI(MainInvokeType.SetGreenAndPing); - RunTime.Login?.Close(); Thread.Sleep(100); string welcome = $"欢迎回来, {Usercfg.LoginUserName}!"; ShowMessage.Message(welcome, "登录成功", 5); @@ -840,11 +835,7 @@ namespace Milimoe.FunGame.Desktop.UI { if (ShowMessage.OKCancelMessage("你确定关闭游戏?", "退出") == (int)MessageResult.OK) { - if (MainController != null) - { - MainController.Close(); - MainController = null; - } + RunTime.Connector?.Close(); Environment.Exit(0); } } @@ -1174,6 +1165,11 @@ namespace Milimoe.FunGame.Desktop.UI } } + private void Main_Disposed(object? sender, EventArgs e) + { + MainController?.Dispose(); + } + /// /// 连接服务器失败后触发事件 /// @@ -1188,7 +1184,7 @@ namespace Milimoe.FunGame.Desktop.UI Task.Run(() => { Thread.Sleep(5000); - if (Config.FunGame_isConnected && Config.FunGame_isAutoRetry) MainController?.Connect(); // 再次判断是否开启自动重连 + if (Config.FunGame_isConnected && Config.FunGame_isAutoRetry) RunTime.Connector?.Connect(); // 再次判断是否开启自动重连 }); GetMessage("连接服务器失败,5秒后自动尝试重连。"); } @@ -1204,6 +1200,8 @@ namespace Milimoe.FunGame.Desktop.UI /// public EventResult SucceedConnectEvent(object sender, GeneralEventArgs e) { + // 创建MainController + MainController = new MainController(this); if (MainController != null && Config.FunGame_isAutoLogin && Config.FunGame_AutoLoginUser != "" && Config.FunGame_AutoLoginPassword != "" && Config.FunGame_AutoLoginKey != "") { // 自动登录 @@ -1305,7 +1303,7 @@ namespace Milimoe.FunGame.Desktop.UI { CurrentRetryTimes = -1; Config.FunGame_isAutoLogin = true; - MainController?.Connect(); + RunTime.Connector?.Connect(); } else WritelnGameInfo(">> 你不能在连接服务器的同时重试连接!"); @@ -1315,20 +1313,20 @@ namespace Milimoe.FunGame.Desktop.UI { CurrentRetryTimes = -1; Config.FunGame_isAutoLogin = true; - MainController?.GetServerConnection(); + RunTime.Connector?.GetServerConnection(); } break; case Constant.FunGame_Disconnect: if (Config.FunGame_isConnected && MainController != null) { // 先退出登录再断开连接 - if (MainController?.LogOut() ?? false) MainController?.Disconnect(); + if (MainController?.LogOut() ?? false) RunTime.Connector?.Disconnect(); } break; case Constant.FunGame_DisconnectWhenNotLogin: if (Config.FunGame_isConnected && MainController != null) { - MainController?.Disconnect(); + RunTime.Connector?.Disconnect(); } break; case Constant.FunGame_ConnectTo: @@ -1359,7 +1357,7 @@ namespace Milimoe.FunGame.Desktop.UI Constant.Server_Port = port; CurrentRetryTimes = -1; Config.FunGame_isAutoLogin = true; - MainController?.Connect(); + RunTime.Connector?.Connect(); } else if (ErrorType == Core.Library.Constant.ErrorType.IsNotIP) ShowMessage.ErrorMessage("这不是一个IP地址!"); else if (ErrorType == Core.Library.Constant.ErrorType.IsNotPort) ShowMessage.ErrorMessage("这不是一个端口号!\n正确范围:1~65535"); diff --git a/FunGame.Desktop/UI/Register/Register.cs b/FunGame.Desktop/UI/Register/Register.cs index 00d780e..7183988 100644 --- a/FunGame.Desktop/UI/Register/Register.cs +++ b/FunGame.Desktop/UI/Register/Register.cs @@ -6,7 +6,6 @@ using Milimoe.FunGame.Desktop.Controller; using Milimoe.FunGame.Desktop.Library; using Milimoe.FunGame.Desktop.Library.Base; using Milimoe.FunGame.Desktop.Library.Component; -using Milimoe.FunGame.Desktop.Library.Interface; namespace Milimoe.FunGame.Desktop.UI { @@ -26,9 +25,15 @@ namespace Milimoe.FunGame.Desktop.UI protected override void BindEvent() { base.BindEvent(); + Disposed += Register_Disposed; SucceedReg += SucceedRegEvent; } + private void Register_Disposed(object? sender, EventArgs e) + { + RegController.Dispose(); + } + private bool Reg_Handler() { try @@ -99,11 +104,6 @@ namespace Milimoe.FunGame.Desktop.UI return true; } - public void SocketHandler(SocketMessageType type, params object[]? objs) - { - RegController.SocketHandler(type, objs); - } - public void UpdateUI(RegInvokeType type) { try