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.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 bool Disconnect()
{
bool result = false;
try
{
result = Socket?.Send(SocketMessageType.Disconnect, "") == SocketResult.Success;
}
catch (Exception e)
{
Main.GetMessage(e.GetErrorInfo());
}
return result;
}
public void Disconnected()
{
Disconnect();
}
public void 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_IP = s[0];
Constant.Server_Port = Convert.ToInt32(s[1]);
}
}
else
{
ShowMessage.ErrorMessage("查找可用的服务器失败!");
Config.FunGame_isRetrying = false;
throw new FindServerFailedException();
}
}
catch (Exception e)
{
Main.GetMessage(e.GetErrorInfo(), TimeType.None);
}
}
public async Task Connect()
{
if (Constant.Server_IP == "" || Constant.Server_Port <= 0)
{
ShowMessage.ErrorMessage("查找可用的服务器失败!");
return ConnectResult.FindServerFailed;
}
try
{
if (Config.FunGame_isRetrying)
{
Main.GetMessage("正在连接服务器,请耐心等待。");
Config.FunGame_isRetrying = false;
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_IP, Constant.Server_Port);
if (Socket != null && Socket.Connected)
{
// 设置可复用Socket
RunTime.Socket = Socket;
// 发送连接请求
if (Socket.Send(SocketMessageType.Connect) == SocketResult.Success)
{
SocketMessageType Result = Receiving();
if (Result == SocketMessageType.Connect)
{
Main.GetMessage("连接服务器成功,请登录账号以体验FunGame。");
Main.UpdateUI(MainInvokeType.Connected);
StartReceiving();
await Task.Factory.StartNew(() =>
{
while (true)
{
if (IsReceiving)
{
break;
}
}
});
return ConnectResult.Success;
}
}
Config.FunGame_isRetrying = false;
Socket.Close();
return ConnectResult.ConnectFailed;
}
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;
return ConnectResult.ConnectFailed;
}
}
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 ConnectEventArgs(Constant.Server_IP, Constant.Server_Port));
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();
}
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:
if (!SocketHandler_Connect(ServerMessage)) return SocketMessageType.Unknown;
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 bool SocketHandler_Connect(SocketObject ServerMessage)
{
string msg = "";
Guid token = Guid.Empty;
if (ServerMessage.Parameters.Length > 0) msg = ServerMessage.GetParam(0)!;
string[] strings = msg.Split(';');
if (strings.Length != 2)
{
// 服务器拒绝连接
msg = strings[0];
Main.GetMessage(msg);
ShowMessage.ErrorMessage(msg);
return false;
}
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);
return true;
}
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
}
}