mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2025-04-21 11:39:35 +08:00
为服务器统一数据访问连接 (#91)
* 重做 WebSocket 监听;为服务器统一了多种数据连接访问时的处理;统一编码为 UTF-8 * ModelManager已更名并移动到工具命名空间中 * 完成 WebSocket 消息处理系统 * 添加Socket异步接收数据流;修复TaskUtility阻塞的问题;优化心跳、房间、模组 * 添加枚举 * 删除多余字符 * 添加监听器的名称 * 修改了命名
This commit is contained in:
parent
2de1e57e0c
commit
940f8397f1
@ -13,9 +13,9 @@ namespace Milimoe.FunGame.Core.Api.Factory
|
|||||||
return RoomFactory.Create();
|
return RoomFactory.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Room Create(long Id = 0, string Roomid = "-1", DateTime? CreateTime = null, User? RoomMaster = null, RoomType RoomType = RoomType.All, string GameModule = "", string GameMap = "", RoomState RoomState = RoomState.Created, bool IsRank = false, string Password = "")
|
public static Room Create(long id = 0, string roomid = "-1", DateTime? createTime = null, User? roomMaster = null, RoomType roomType = RoomType.All, string gameModule = "", string gameMap = "", RoomState roomState = RoomState.Created, bool isRank = false, string password = "", int maxUsers = 4)
|
||||||
{
|
{
|
||||||
return new Room(Id, Roomid, CreateTime, RoomMaster, RoomType, GameModule, GameMap, RoomState, IsRank, Password);
|
return new Room(id, roomid, createTime, roomMaster, roomType, gameModule, gameMap, roomState, isRank, password, maxUsers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Service
|
namespace Milimoe.FunGame.Core.Api.Utility
|
||||||
{
|
{
|
||||||
internal class ModelManager<T> : IEnumerable<T>
|
public class ConcurrentModelList<T> : IEnumerable<T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 目前的Model数量
|
/// 目前的Model数量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal int Count => Models.Count;
|
public int Count => Models.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 最大接受的Model数量
|
/// 最大接受的Model数量
|
||||||
@ -24,7 +24,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// Init ModelManager
|
/// Init ModelManager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="MaxModel">MaxModel</param>
|
/// <param name="MaxModel">MaxModel</param>
|
||||||
internal ModelManager(int MaxModel = 0)
|
public ConcurrentModelList(int MaxModel = 0)
|
||||||
{
|
{
|
||||||
if (MaxModel <= 0)
|
if (MaxModel <= 0)
|
||||||
this.MaxModel = Library.Constant.General.MaxTask_2C2G;
|
this.MaxModel = Library.Constant.General.MaxTask_2C2G;
|
||||||
@ -39,7 +39,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">Model的Key</param>
|
/// <param name="name">Model的Key</param>
|
||||||
/// <returns>Model对象</returns>
|
/// <returns>Model对象</returns>
|
||||||
internal T this[string name] => Models[name];
|
public T this[string name] => Models[name];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 向Model管理器中添加Model
|
/// 向Model管理器中添加Model
|
||||||
@ -47,7 +47,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <param name="name">Model的Key</param>
|
/// <param name="name">Model的Key</param>
|
||||||
/// <param name="t">Model对象</param>
|
/// <param name="t">Model对象</param>
|
||||||
/// <returns>True:操作成功</returns>
|
/// <returns>True:操作成功</returns>
|
||||||
internal bool Add(string name, T t)
|
public bool Add(string name, T t)
|
||||||
{
|
{
|
||||||
if (Models.Count + 1 > MaxModel) return false;
|
if (Models.Count + 1 > MaxModel) return false;
|
||||||
return Models.TryAdd(name, t);
|
return Models.TryAdd(name, t);
|
||||||
@ -58,7 +58,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">Model的Key</param>
|
/// <param name="name">Model的Key</param>
|
||||||
/// <returns>True:操作成功</returns>
|
/// <returns>True:操作成功</returns>
|
||||||
internal bool Remove(string name)
|
public bool Remove(string name)
|
||||||
{
|
{
|
||||||
return Models.TryRemove(name, out _);
|
return Models.TryRemove(name, out _);
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <param name="name">Model的Key</param>
|
/// <param name="name">Model的Key</param>
|
||||||
/// <param name="t">Model对象</param>
|
/// <param name="t">Model对象</param>
|
||||||
/// <returns>被移除的Model</returns>
|
/// <returns>被移除的Model</returns>
|
||||||
internal bool Remove(string name, ref T? t)
|
public bool Remove(string name, ref T? t)
|
||||||
{
|
{
|
||||||
return Models.TryRemove(name, out t);
|
return Models.TryRemove(name, out t);
|
||||||
}
|
}
|
||||||
@ -79,13 +79,13 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">Model的Key</param>
|
/// <param name="name">Model的Key</param>
|
||||||
/// <returns>被移除的Model</returns>
|
/// <returns>被移除的Model</returns>
|
||||||
internal T? RemoveAndGet(string name)
|
public T? RemoveAndGet(string name)
|
||||||
{
|
{
|
||||||
Models.TryRemove(name, out T? result);
|
Models.TryRemove(name, out T? result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ContainsKey(string name)
|
public bool ContainsKey(string name)
|
||||||
{
|
{
|
||||||
return Models.ContainsKey(name);
|
return Models.ContainsKey(name);
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 清空Model管理器
|
/// 清空Model管理器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
Models.Clear();
|
Models.Clear();
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取Model对象的列表
|
/// 获取Model对象的列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal List<T> GetList()
|
public List<T> GetList()
|
||||||
{
|
{
|
||||||
return [.. Models.Values];
|
return [.. Models.Values];
|
||||||
}
|
}
|
@ -64,44 +64,46 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取房间实例
|
/// 获取房间实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Id">房间内部序列号</param>
|
/// <param name="id">房间内部序列号</param>
|
||||||
/// <param name="Roomid">房间号</param>
|
/// <param name="roomid">房间号</param>
|
||||||
/// <param name="CreateTime">创建时间</param>
|
/// <param name="createTime">创建时间</param>
|
||||||
/// <param name="RoomMaster">房主</param>
|
/// <param name="roomMaster">房主</param>
|
||||||
/// <param name="RoomType">房间类型</param>
|
/// <param name="roomType">房间类型</param>
|
||||||
/// <param name="GameModule">游戏模组</param>
|
/// <param name="gameModule">游戏模组</param>
|
||||||
/// <param name="GameMap"></param>
|
/// <param name="gameMap"></param>
|
||||||
/// <param name="RoomState">房间状态</param>
|
/// <param name="roomState">房间状态</param>
|
||||||
/// <param name="IsRank"></param>
|
/// <param name="isRank"></param>
|
||||||
/// <param name="Password">房间密码</param>
|
/// <param name="password">房间密码</param>
|
||||||
|
/// <param name="maxUsers">人数上限</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Room GetRoom(long Id = 0, string Roomid = "-1", DateTime? CreateTime = null, User? RoomMaster = null, RoomType RoomType = RoomType.All, string GameModule = "", string GameMap = "", RoomState RoomState = RoomState.Created, bool IsRank = false, string Password = "")
|
public static Room GetRoom(long id = 0, string roomid = "-1", DateTime? createTime = null, User? roomMaster = null, RoomType roomType = RoomType.All, string gameModule = "", string gameMap = "", RoomState roomState = RoomState.Created, bool isRank = false, string password = "", int maxUsers = 4)
|
||||||
{
|
{
|
||||||
return RoomFactory.Create(Id, Roomid, CreateTime, RoomMaster, RoomType, GameModule, GameMap, RoomState, IsRank, Password);
|
return RoomFactory.Create(id, roomid, createTime, roomMaster, roomType, gameModule, gameMap, roomState, isRank, password, maxUsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过DataSet获取房间实例
|
/// 通过DataSet获取房间实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="DrRoom"></param>
|
/// <param name="drRoom"></param>
|
||||||
/// <param name="User"></param>
|
/// <param name="user"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Room GetRoom(DataRow DrRoom, User User)
|
public static Room GetRoom(DataRow drRoom, User user)
|
||||||
{
|
{
|
||||||
Room room = General.HallInstance;
|
Room room = General.HallInstance;
|
||||||
if (DrRoom != null)
|
if (drRoom != null)
|
||||||
{
|
{
|
||||||
long Id = (long)DrRoom[RoomQuery.Column_ID];
|
long id = (long)drRoom[RoomQuery.Column_ID];
|
||||||
string Roomid = (string)DrRoom[RoomQuery.Column_RoomID];
|
string roomid = (string)drRoom[RoomQuery.Column_RoomID];
|
||||||
DateTime CreateTime = (DateTime)DrRoom[RoomQuery.Column_CreateTime];
|
DateTime createTime = (DateTime)drRoom[RoomQuery.Column_CreateTime];
|
||||||
User RoomMaster = User;
|
User roomMaster = user;
|
||||||
RoomType RoomType = (RoomType)Convert.ToInt32(DrRoom[RoomQuery.Column_RoomType]);
|
RoomType roomType = (RoomType)Convert.ToInt32(drRoom[RoomQuery.Column_RoomType]);
|
||||||
string GameModule = (string)DrRoom[RoomQuery.Column_GameModule];
|
string gameModule = (string)drRoom[RoomQuery.Column_GameModule];
|
||||||
string GameMap = (string)DrRoom[RoomQuery.Column_GameMap];
|
string gameMap = (string)drRoom[RoomQuery.Column_GameMap];
|
||||||
RoomState RoomState = (RoomState)Convert.ToInt32(DrRoom[RoomQuery.Column_RoomState]);
|
RoomState roomState = (RoomState)Convert.ToInt32(drRoom[RoomQuery.Column_RoomState]);
|
||||||
bool IsRank = Convert.ToInt32(DrRoom[RoomQuery.Column_IsRank]) == 1;
|
bool isRank = Convert.ToInt32(drRoom[RoomQuery.Column_IsRank]) == 1;
|
||||||
string Password = (string)DrRoom[RoomQuery.Column_Password];
|
string password = (string)drRoom[RoomQuery.Column_Password];
|
||||||
room = GetRoom(Id, Roomid, CreateTime, RoomMaster, RoomType, GameModule, GameMap, RoomState, IsRank, Password);
|
int maxUsers = (int)drRoom[RoomQuery.Column_MaxUsers];
|
||||||
|
room = GetRoom(id, roomid, createTime, roomMaster, roomType, gameModule, gameMap, roomState, isRank, password, maxUsers);
|
||||||
}
|
}
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
@ -109,38 +111,38 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过DataSet获取房间列表
|
/// 通过DataSet获取房间列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="DsRoom"></param>
|
/// <param name="dsRoom"></param>
|
||||||
/// <param name="DsUser"></param>
|
/// <param name="dsUser"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static List<Room> GetRooms(DataSet DsRoom, DataSet DsUser)
|
public static List<Room> GetRooms(DataSet dsRoom, DataSet dsUser)
|
||||||
{
|
{
|
||||||
List<Room> list =
|
List<Room> list =
|
||||||
[
|
[
|
||||||
General.HallInstance
|
General.HallInstance
|
||||||
];
|
];
|
||||||
if (DsRoom != null && DsRoom.Tables[0].Rows.Count > 0)
|
if (dsRoom != null && dsRoom.Tables[0].Rows.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (DataRow DrRoom in DsRoom.Tables[0].Rows)
|
foreach (DataRow drRoom in dsRoom.Tables[0].Rows)
|
||||||
{
|
{
|
||||||
long Id = (long)DrRoom[RoomQuery.Column_ID];
|
long Id = (long)drRoom[RoomQuery.Column_ID];
|
||||||
string Roomid = (string)DrRoom[RoomQuery.Column_RoomID];
|
string Roomid = (string)drRoom[RoomQuery.Column_RoomID];
|
||||||
DateTime CreateTime = (DateTime)DrRoom[RoomQuery.Column_CreateTime];
|
DateTime createTime = (DateTime)drRoom[RoomQuery.Column_CreateTime];
|
||||||
User RoomMaster = General.UnknownUserInstance;
|
User roomMaster = General.UnknownUserInstance;
|
||||||
if (DsUser != null && DsUser.Tables.Count > 0)
|
if (dsUser != null && dsUser.Tables.Count > 0)
|
||||||
{
|
{
|
||||||
DataRow[] rows = DsUser.Tables[0].Select($"{UserQuery.Column_UID} = {(long)DrRoom[RoomQuery.Column_RoomMaster]}");
|
DataRow[] rows = dsUser.Tables[0].Select($"{UserQuery.Column_UID} = {(long)drRoom[RoomQuery.Column_RoomMaster]}");
|
||||||
if (rows.Length > 0)
|
if (rows.Length > 0)
|
||||||
{
|
{
|
||||||
RoomMaster = GetUser(rows[0]);
|
roomMaster = GetUser(rows[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RoomType RoomType = (RoomType)Convert.ToInt32(DrRoom[RoomQuery.Column_RoomType]);
|
RoomType roomType = (RoomType)Convert.ToInt32(drRoom[RoomQuery.Column_RoomType]);
|
||||||
string GameModule = (string)DrRoom[RoomQuery.Column_GameModule];
|
string gameModule = (string)drRoom[RoomQuery.Column_GameModule];
|
||||||
string GameMap = (string)DrRoom[RoomQuery.Column_GameMap];
|
string gameMap = (string)drRoom[RoomQuery.Column_GameMap];
|
||||||
RoomState RoomState = (RoomState)Convert.ToInt32(DrRoom[RoomQuery.Column_RoomState]);
|
RoomState roomState = (RoomState)Convert.ToInt32(drRoom[RoomQuery.Column_RoomState]);
|
||||||
bool IsRank = Convert.ToInt32(DrRoom[RoomQuery.Column_IsRank]) == 1;
|
bool isRank = Convert.ToInt32(drRoom[RoomQuery.Column_IsRank]) == 1;
|
||||||
string Password = (string)DrRoom[RoomQuery.Column_Password];
|
string password = (string)drRoom[RoomQuery.Column_Password];
|
||||||
list.Add(GetRoom(Id, Roomid, CreateTime, RoomMaster, RoomType, GameModule, GameMap, RoomState, IsRank, Password));
|
list.Add(GetRoom(Id, Roomid, createTime, roomMaster, roomType, gameModule, gameMap, roomState, isRank, password));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Milimoe.FunGame.Core.Library.Common.Architecture;
|
using Milimoe.FunGame.Core.Library.Common.Architecture;
|
||||||
@ -282,7 +281,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async Task<T?> HttpPost<T>(string url, string json)
|
public static async Task<T?> HttpPost<T>(string url, string json)
|
||||||
{
|
{
|
||||||
HttpContent content = new StringContent(json, Encoding.UTF8, "application/json");
|
HttpContent content = new StringContent(json, General.DefaultEncoding, "application/json");
|
||||||
HttpResponseMessage response = await client.PostAsync(url, content);
|
HttpResponseMessage response = await client.PostAsync(url, content);
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
@ -431,7 +430,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string RSAEncrypt(string plain_text, string plublic_key)
|
public static string RSAEncrypt(string plain_text, string plublic_key)
|
||||||
{
|
{
|
||||||
byte[] plain = Encoding.UTF8.GetBytes(plain_text);
|
byte[] plain = General.DefaultEncoding.GetBytes(plain_text);
|
||||||
using RSACryptoServiceProvider rsa = new();
|
using RSACryptoServiceProvider rsa = new();
|
||||||
rsa.FromXmlString(plublic_key);
|
rsa.FromXmlString(plublic_key);
|
||||||
byte[] encrypted = rsa.Encrypt(plain, false);
|
byte[] encrypted = rsa.Encrypt(plain, false);
|
||||||
@ -450,7 +449,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
using RSACryptoServiceProvider rsa = new();
|
using RSACryptoServiceProvider rsa = new();
|
||||||
rsa.FromXmlString(private_key);
|
rsa.FromXmlString(private_key);
|
||||||
byte[] decrypted = rsa.Decrypt(secret, false);
|
byte[] decrypted = rsa.Decrypt(secret, false);
|
||||||
return Encoding.UTF8.GetString(decrypted);
|
return General.DefaultEncoding.GetString(decrypted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,15 +57,12 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Init(FunGameInfo.FunGame FunGameType)
|
public static void Init(FunGameInfo.FunGame FunGameType)
|
||||||
{
|
{
|
||||||
StreamWriter writer = new(DefaultFileName, false, General.DefaultEncoding);
|
|
||||||
switch (FunGameType)
|
switch (FunGameType)
|
||||||
{
|
{
|
||||||
case FunGameInfo.FunGame.FunGame_Core:
|
case FunGameInfo.FunGame.FunGame_Core:
|
||||||
case FunGameInfo.FunGame.FunGame_Core_Api:
|
case FunGameInfo.FunGame.FunGame_Core_Api:
|
||||||
case FunGameInfo.FunGame.FunGame_Console:
|
case FunGameInfo.FunGame.FunGame_Console:
|
||||||
case FunGameInfo.FunGame.FunGame_Desktop:
|
case FunGameInfo.FunGame.FunGame_Desktop:
|
||||||
writer.Write("[Config]");
|
|
||||||
writer.Close();
|
|
||||||
/**
|
/**
|
||||||
* Config
|
* Config
|
||||||
*/
|
*/
|
||||||
@ -79,8 +76,6 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
WriteINI("Account", "AutoKey", "");
|
WriteINI("Account", "AutoKey", "");
|
||||||
break;
|
break;
|
||||||
case FunGameInfo.FunGame.FunGame_Server:
|
case FunGameInfo.FunGame.FunGame_Server:
|
||||||
writer.Write("[Server]");
|
|
||||||
writer.Close();
|
|
||||||
/**
|
/**
|
||||||
* Server
|
* Server
|
||||||
*/
|
*/
|
||||||
@ -100,6 +95,11 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
* Socket
|
* Socket
|
||||||
*/
|
*/
|
||||||
WriteINI("Socket", "Port", "22222");
|
WriteINI("Socket", "Port", "22222");
|
||||||
|
WriteINI("Socket", "UseWebSocket", "false");
|
||||||
|
WriteINI("Socket", "WebSocketAddress", "*");
|
||||||
|
WriteINI("Socket", "WebSocketPort", "22223");
|
||||||
|
WriteINI("Socket", "WebSocketSubUrl", "ws");
|
||||||
|
WriteINI("Socket", "WebSocketSSL", "false");
|
||||||
WriteINI("Socket", "MaxPlayer", "20");
|
WriteINI("Socket", "MaxPlayer", "20");
|
||||||
WriteINI("Socket", "MaxConnectFailed", "0");
|
WriteINI("Socket", "MaxConnectFailed", "0");
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using Milimoe.FunGame.Core.Interface.Sockets;
|
using Milimoe.FunGame.Core.Interface.Sockets;
|
||||||
using Milimoe.FunGame.Core.Library.Common.Architecture;
|
using Milimoe.FunGame.Core.Library.Common.Architecture;
|
||||||
using Milimoe.FunGame.Core.Library.Common.Network;
|
using Milimoe.FunGame.Core.Library.Common.Network;
|
||||||
using Milimoe.FunGame.Core.Service;
|
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Controller
|
namespace Milimoe.FunGame.Core.Controller
|
||||||
{
|
{
|
||||||
@ -37,7 +36,7 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
if (socket != null)
|
if (socket != null)
|
||||||
{
|
{
|
||||||
_Socket = socket;
|
_Socket = socket;
|
||||||
socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler));
|
socket.AddSocketObjectHandler(SocketHandler);
|
||||||
}
|
}
|
||||||
else throw new SocketCreateReceivingException();
|
else throw new SocketCreateReceivingException();
|
||||||
}
|
}
|
||||||
@ -51,7 +50,7 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
if (websocket != null)
|
if (websocket != null)
|
||||||
{
|
{
|
||||||
_WebSocket = websocket;
|
_WebSocket = websocket;
|
||||||
websocket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler));
|
websocket.AddSocketObjectHandler(SocketHandler);
|
||||||
}
|
}
|
||||||
else throw new SocketCreateReceivingException();
|
else throw new SocketCreateReceivingException();
|
||||||
}
|
}
|
||||||
@ -90,8 +89,8 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
{
|
{
|
||||||
if (Disposing)
|
if (Disposing)
|
||||||
{
|
{
|
||||||
_Socket?.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler), true);
|
_Socket?.RemoveSocketObjectHandler(SocketHandler);
|
||||||
_WebSocket?.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler), true);
|
_WebSocket?.RemoveSocketObjectHandler(SocketHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
@ -8,15 +8,15 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
{
|
{
|
||||||
public long Id => User.Id;
|
public long Id => User.Id;
|
||||||
public User User { get; }
|
public User User { get; }
|
||||||
public Dictionary<long, double> DamageStats { get; } = new();
|
public Dictionary<long, double> DamageStats { get; } = [];
|
||||||
public Dictionary<long, double> PhysicalDamageStats { get; } = new();
|
public Dictionary<long, double> PhysicalDamageStats { get; } = [];
|
||||||
public Dictionary<long, double> MagicDamageStats { get; } = new();
|
public Dictionary<long, double> MagicDamageStats { get; } = [];
|
||||||
public Dictionary<long, double> RealDamageStats { get; } = new();
|
public Dictionary<long, double> RealDamageStats { get; } = [];
|
||||||
public Dictionary<long, double> AvgDamageStats
|
public Dictionary<long, double> AvgDamageStats
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Dictionary<long, double> avgdamage = new();
|
Dictionary<long, double> avgdamage = [];
|
||||||
foreach (long key in Plays.Keys)
|
foreach (long key in Plays.Keys)
|
||||||
{
|
{
|
||||||
long plays = Plays[key];
|
long plays = Plays[key];
|
||||||
@ -34,7 +34,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Dictionary<long, double> avgdamage = new();
|
Dictionary<long, double> avgdamage = [];
|
||||||
foreach (long key in Plays.Keys)
|
foreach (long key in Plays.Keys)
|
||||||
{
|
{
|
||||||
long plays = Plays[key];
|
long plays = Plays[key];
|
||||||
@ -52,7 +52,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Dictionary<long, double> avgdamage = new();
|
Dictionary<long, double> avgdamage = [];
|
||||||
foreach (long key in Plays.Keys)
|
foreach (long key in Plays.Keys)
|
||||||
{
|
{
|
||||||
long plays = Plays[key];
|
long plays = Plays[key];
|
||||||
@ -70,7 +70,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Dictionary<long, double> avgdamage = new();
|
Dictionary<long, double> avgdamage = [];
|
||||||
foreach (long key in Plays.Keys)
|
foreach (long key in Plays.Keys)
|
||||||
{
|
{
|
||||||
long plays = Plays[key];
|
long plays = Plays[key];
|
||||||
@ -84,17 +84,17 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
return avgdamage;
|
return avgdamage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Dictionary<long, long> Kills { get; } = new();
|
public Dictionary<long, long> Kills { get; } = [];
|
||||||
public Dictionary<long, long> Deaths { get; } = new();
|
public Dictionary<long, long> Deaths { get; } = [];
|
||||||
public Dictionary<long, long> Assists { get; } = new();
|
public Dictionary<long, long> Assists { get; } = [];
|
||||||
public Dictionary<long, long> Plays { get; } = new();
|
public Dictionary<long, long> Plays { get; } = [];
|
||||||
public Dictionary<long, long> Wins { get; } = new();
|
public Dictionary<long, long> Wins { get; } = [];
|
||||||
public Dictionary<long, long> Loses { get; } = new();
|
public Dictionary<long, long> Loses { get; } = [];
|
||||||
public Dictionary<long, double> Winrates
|
public Dictionary<long, double> Winrates
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Dictionary<long, double> winrates = new();
|
Dictionary<long, double> winrates = [];
|
||||||
foreach (long key in Plays.Keys)
|
foreach (long key in Plays.Keys)
|
||||||
{
|
{
|
||||||
long plays = Plays[key];
|
long plays = Plays[key];
|
||||||
@ -108,15 +108,15 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
return winrates;
|
return winrates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Dictionary<long, double> RatingStats { get; } = new();
|
public Dictionary<long, double> RatingStats { get; } = [];
|
||||||
public Dictionary<long, double> EloStats { get; } = new();
|
public Dictionary<long, double> EloStats { get; } = [];
|
||||||
public Dictionary<long, string> RankStats { get; } = new();
|
public Dictionary<long, string> RankStats { get; } = [];
|
||||||
|
|
||||||
public string GetWinrate(long season)
|
public string GetWinrate(long season)
|
||||||
{
|
{
|
||||||
if (Winrates.ContainsKey(season))
|
if (Winrates.TryGetValue(season, out double value))
|
||||||
{
|
{
|
||||||
return Winrates[season].ToString("0.##%");
|
return value.ToString("0.##%");
|
||||||
}
|
}
|
||||||
return "0%";
|
return "0%";
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
public bool IsRank { get; set; } = false;
|
public bool IsRank { get; set; } = false;
|
||||||
public bool HasPass => Password.Trim() != "";
|
public bool HasPass => Password.Trim() != "";
|
||||||
public string Password { get; set; } = "";
|
public string Password { get; set; } = "";
|
||||||
|
public int MaxUsers { get; set; } = 0;
|
||||||
|
public Dictionary<User, bool> UserAndIsReady { get; } = [];
|
||||||
public GameStatistics Statistics { get; set; }
|
public GameStatistics Statistics { get; set; }
|
||||||
|
|
||||||
internal Room()
|
internal Room()
|
||||||
@ -24,18 +26,19 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
Statistics = new(this);
|
Statistics = new(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Room(long Id = 0, string Roomid = "-1", DateTime? CreateTime = null, User? RoomMaster = null, RoomType RoomType = RoomType.All, string GameModule = "", string GameMap = "", RoomState RoomState = RoomState.Created, bool IsRank = false, string Password = "")
|
internal Room(long id = 0, string roomid = "-1", DateTime? createTime = null, User? roomMaster = null, RoomType roomType = RoomType.All, string gameModule = "", string gameMap = "", RoomState roomState = RoomState.Created, bool isRank = false, string password = "", int maxUsers = 4)
|
||||||
{
|
{
|
||||||
this.Id = Id;
|
Id = id;
|
||||||
this.Roomid = Roomid;
|
Roomid = roomid;
|
||||||
this.CreateTime = CreateTime ?? General.DefaultTime;
|
CreateTime = createTime ?? General.DefaultTime;
|
||||||
this.RoomMaster = RoomMaster ?? General.UnknownUserInstance;
|
RoomMaster = roomMaster ?? General.UnknownUserInstance;
|
||||||
this.RoomType = RoomType;
|
RoomType = roomType;
|
||||||
this.GameModule = GameModule;
|
GameModule = gameModule;
|
||||||
this.GameMap = GameMap;
|
GameMap = gameMap;
|
||||||
this.RoomState = RoomState;
|
RoomState = roomState;
|
||||||
this.IsRank = IsRank;
|
IsRank = isRank;
|
||||||
this.Password = Password;
|
Password = password;
|
||||||
|
MaxUsers = maxUsers;
|
||||||
Statistics = new(this);
|
Statistics = new(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
Entity/System/Season.cs
Normal file
9
Entity/System/Season.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Milimoe.FunGame.Core.Entity.System
|
||||||
|
{
|
||||||
|
public class Season(long id, string name, string description)
|
||||||
|
{
|
||||||
|
public long Id { get; } = id;
|
||||||
|
public string Name { get; } = name;
|
||||||
|
public string Description { get; } = description;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,6 @@ namespace Milimoe.FunGame.Core.Interface.Addons
|
|||||||
{
|
{
|
||||||
public bool StartServer(string GameModule, Room Room, List<User> Users, IServerModel RoomMasterServerModel, Dictionary<string, IServerModel> ServerModels, params object[] args);
|
public bool StartServer(string GameModule, Room Room, List<User> Users, IServerModel RoomMasterServerModel, Dictionary<string, IServerModel> ServerModels, params object[] args);
|
||||||
|
|
||||||
public Dictionary<string, object> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data);
|
public Task<Dictionary<string, object>> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,10 @@ namespace Milimoe.FunGame.Core.Interface.HTTP
|
|||||||
{
|
{
|
||||||
public interface IHTTPClient : IBaseSocket
|
public interface IHTTPClient : IBaseSocket
|
||||||
{
|
{
|
||||||
|
public bool Receiving { get; }
|
||||||
|
public Task Receive();
|
||||||
public Task<SocketResult> Send(SocketMessageType type, params object[] objs);
|
public Task<SocketResult> Send(SocketMessageType type, params object[] objs);
|
||||||
public SocketObject SocketObject_Handler(SocketObject objs);
|
public void AddSocketObjectHandler(Action<SocketObject> method);
|
||||||
public void BindEvent(Delegate method, bool remove = false);
|
public void RemoveSocketObjectHandler(Action<SocketObject> method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Milimoe.FunGame.Core.Entity;
|
using Milimoe.FunGame.Core.Api.Transmittal;
|
||||||
|
using Milimoe.FunGame.Core.Entity;
|
||||||
using Milimoe.FunGame.Core.Library.Common.Addon;
|
using Milimoe.FunGame.Core.Library.Common.Addon;
|
||||||
using Milimoe.FunGame.Core.Library.Common.Network;
|
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Interface.Base
|
namespace Milimoe.FunGame.Core.Interface.Base
|
||||||
@ -10,28 +10,43 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务器实例是否在运行
|
/// 服务器实例是否在运行
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract bool Running { get; }
|
public bool Running { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户端的套接字实例
|
/// 客户端的套接字实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract ISocketMessageProcessor? Socket { get; }
|
public ISocketMessageProcessor? Socket { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端的数据库连接实例
|
||||||
|
/// </summary>
|
||||||
|
public SQLHelper? SQLHelper { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端的邮件服务实例
|
||||||
|
/// </summary>
|
||||||
|
public MailSender? MailSender { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户端的用户实例,在用户登录后有效
|
/// 客户端的用户实例,在用户登录后有效
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract User User { get; }
|
public User User { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户端的名称,默认是客户端的IP地址
|
/// 客户端的名称,默认是客户端的IP地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract string ClientName { get; }
|
public string ClientName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户端是否启动了开发者模式
|
/// 客户端是否启动了开发者模式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDebugMode { get; }
|
public bool IsDebugMode { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端所在的房间
|
||||||
|
/// </summary>
|
||||||
|
public Room InRoom { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户端的游戏模组服务器
|
/// 客户端的游戏模组服务器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -40,11 +55,10 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 向客户端发送消息
|
/// 向客户端发送消息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="socket"></param>
|
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="objs"></param>
|
/// <param name="objs"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool Send(ISocketMessageProcessor socket, SocketMessageType type, params object[] objs);
|
public Task<bool> Send(SocketMessageType type, params object[] objs);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 向客户端发送系统消息
|
/// 向客户端发送系统消息
|
||||||
@ -61,19 +75,5 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string GetClientName();
|
public string GetClientName();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开始接收客户端消息
|
|
||||||
/// <para>请勿在 <see cref="GameModuleServer"/> 中调用此方法</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="socket"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Read(ISocketMessageProcessor socket);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 启动对客户端的监听
|
|
||||||
/// <para>请勿在 <see cref="GameModuleServer"/> 中调用此方法</para>
|
|
||||||
/// </summary>
|
|
||||||
public void Start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
Interface/Base/ISocketListener.cs
Normal file
32
Interface/Base/ISocketListener.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
|
|
||||||
|
namespace Milimoe.FunGame.Core.Interface.Base
|
||||||
|
{
|
||||||
|
public interface ISocketListener<T> where T : ISocketMessageProcessor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 监听器的名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已连接的客户端列表
|
||||||
|
/// </summary>
|
||||||
|
public ConcurrentModelList<IServerModel> ClientList { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已登录的用户列表
|
||||||
|
/// </summary>
|
||||||
|
public ConcurrentModelList<IServerModel> UserList { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 黑名单IP地址列表
|
||||||
|
/// </summary>
|
||||||
|
public List<string> BannedList { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭监听
|
||||||
|
/// </summary>
|
||||||
|
public void Close();
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,20 @@
|
|||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Common.Network;
|
||||||
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Interface.Base
|
namespace Milimoe.FunGame.Core.Interface.Base
|
||||||
{
|
{
|
||||||
public interface ISocketMessageProcessor
|
public interface ISocketMessageProcessor
|
||||||
{
|
{
|
||||||
public Type InstanceType { get; }
|
public Type InstanceType { get; }
|
||||||
|
public Guid Token { get; }
|
||||||
public string ClientIP { get; }
|
public string ClientIP { get; }
|
||||||
public string ClientName { get; }
|
public string ClientName { get; }
|
||||||
|
|
||||||
|
public SocketObject[] Receive();
|
||||||
|
public Task<SocketObject[]> ReceiveAsync();
|
||||||
public SocketResult Send(SocketMessageType type, params object[] objs);
|
public SocketResult Send(SocketMessageType type, params object[] objs);
|
||||||
public Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs);
|
public Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs);
|
||||||
public void Close();
|
public void Close();
|
||||||
|
public Task CloseAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Common.Network;
|
||||||
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Interface.Sockets
|
namespace Milimoe.FunGame.Core.Interface.Sockets
|
||||||
{
|
{
|
||||||
@ -6,8 +7,10 @@ namespace Milimoe.FunGame.Core.Interface.Sockets
|
|||||||
{
|
{
|
||||||
public bool Receiving { get; }
|
public bool Receiving { get; }
|
||||||
public void StartReceiving(Task t);
|
public void StartReceiving(Task t);
|
||||||
|
public void StopReceiving();
|
||||||
public SocketResult Send(SocketMessageType type, params object[] objs);
|
public SocketResult Send(SocketMessageType type, params object[] objs);
|
||||||
public Library.Common.Network.SocketObject[] Receive();
|
public SocketObject[] Receive();
|
||||||
public void BindEvent(Delegate method, bool remove = false);
|
public void AddSocketObjectHandler(Action<SocketObject> method);
|
||||||
|
public void RemoveSocketObjectHandler(Action<SocketObject> method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
Interface/Base/Sockets/IClientWebSocket.cs
Normal file
16
Interface/Base/Sockets/IClientWebSocket.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Milimoe.FunGame.Core.Interface.Base;
|
||||||
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
|
||||||
|
namespace Milimoe.FunGame.Core.Interface.Sockets
|
||||||
|
{
|
||||||
|
public interface IClientWebSocket : IBaseSocket
|
||||||
|
{
|
||||||
|
public System.Net.WebSockets.WebSocket Instance { get; }
|
||||||
|
public bool Connected => Instance != null && Instance.State == System.Net.WebSockets.WebSocketState.Open;
|
||||||
|
public bool Receiving { get; }
|
||||||
|
public void StartReceiving(Task t);
|
||||||
|
public void StopReceiving();
|
||||||
|
public Task<Library.Common.Network.SocketObject[]> ReceiveAsync();
|
||||||
|
public Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs);
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
using Milimoe.FunGame.Core.Interface.Base;
|
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Interface.Sockets
|
|
||||||
{
|
|
||||||
public interface IWebSocket : IBaseSocket
|
|
||||||
{
|
|
||||||
public System.Net.WebSockets.WebSocket Instance { get; }
|
|
||||||
public bool Connected => Instance != null && Instance.State == System.Net.WebSockets.WebSocketState.Open;
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,6 +48,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
|
|||||||
|
|
||||||
public override RoomType RoomType => RoomType.Mix;
|
public override RoomType RoomType => RoomType.Mix;
|
||||||
|
|
||||||
|
public override int MaxUsers => 8;
|
||||||
|
|
||||||
public override bool HideMain => false;
|
public override bool HideMain => false;
|
||||||
|
|
||||||
public ExampleGameModule()
|
public ExampleGameModule()
|
||||||
@ -175,7 +177,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
|
|||||||
UserData[username].Add("connect_token", token);
|
UserData[username].Add("connect_token", token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SendGamingMessage(All.Values, GamingType.UpdateInfo, data);
|
await SendGamingMessage(All.Values, GamingType.UpdateInfo, data);
|
||||||
|
|
||||||
// 新建一个线程等待所有玩家确认
|
// 新建一个线程等待所有玩家确认
|
||||||
while (true)
|
while (true)
|
||||||
@ -187,7 +189,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
|
|||||||
Controller.WriteLine("所有玩家都已经连接。");
|
Controller.WriteLine("所有玩家都已经连接。");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Dictionary<string, object> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data)
|
public override async Task<Dictionary<string, object>> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> result = [];
|
Dictionary<string, object> result = [];
|
||||||
|
|
||||||
@ -205,6 +207,9 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
|
|||||||
}
|
}
|
||||||
else Controller.WriteLine(username + " 确认连接失败!");
|
else Controller.WriteLine(username + " 确认连接失败!");
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
await Task.Delay(1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -44,6 +44,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract RoomType RoomType { get; }
|
public abstract RoomType RoomType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模组的容纳人数
|
||||||
|
/// </summary>
|
||||||
|
public abstract int MaxUsers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否隐藏主界面
|
/// 是否隐藏主界面
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -72,7 +72,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
|||||||
/// <param name="type">消息类型</param>
|
/// <param name="type">消息类型</param>
|
||||||
/// <param name="data">消息参数</param>
|
/// <param name="data">消息参数</param>
|
||||||
/// <returns>底层会将字典中的数据发送给客户端</returns>
|
/// <returns>底层会将字典中的数据发送给客户端</returns>
|
||||||
public abstract Dictionary<string, object> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data);
|
public abstract Task<Dictionary<string, object>> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加载标记
|
/// 加载标记
|
||||||
@ -120,15 +120,12 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
|||||||
/// <param name="clients"></param>
|
/// <param name="clients"></param>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
protected virtual void SendGamingMessage(IEnumerable<IServerModel> clients, GamingType type, Dictionary<string, object> data)
|
protected virtual async Task SendGamingMessage(IEnumerable<IServerModel> clients, GamingType type, Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
// 发送局内消息
|
// 发送局内消息
|
||||||
foreach (IServerModel s in clients)
|
foreach (IServerModel s in clients)
|
||||||
{
|
{
|
||||||
if (s != null && s.Socket != null)
|
await s.Send(SocketMessageType.Gaming, type, data);
|
||||||
{
|
|
||||||
s.Send(s.Socket, SocketMessageType.Gaming, type, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,15 +135,12 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
|||||||
/// <param name="clients"></param>
|
/// <param name="clients"></param>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
protected virtual void Send(IEnumerable<IServerModel> clients, SocketMessageType type, params object[] args)
|
protected virtual async Task Send(IEnumerable<IServerModel> clients, SocketMessageType type, params object[] args)
|
||||||
{
|
{
|
||||||
// 发送消息
|
// 发送消息
|
||||||
foreach (IServerModel s in clients)
|
foreach (IServerModel s in clients)
|
||||||
{
|
{
|
||||||
if (s != null && s.Socket != null)
|
await s.Send(type, args);
|
||||||
{
|
|
||||||
s.Send(s.Socket, type, args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
|
|
||||||
private Task? SendingHeartBeatTask;
|
private Task? SendingHeartBeatTask;
|
||||||
private bool _SendingHeartBeat = false;
|
private bool _SendingHeartBeat = false;
|
||||||
|
private bool _LastHeartbeatReceived = false;
|
||||||
private int _HeartBeatFaileds = 0;
|
private int _HeartBeatFaileds = 0;
|
||||||
|
|
||||||
private readonly Socket? _Socket = null;
|
private readonly Socket? _Socket = null;
|
||||||
@ -20,13 +21,13 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
public HeartBeat(Socket socket)
|
public HeartBeat(Socket socket)
|
||||||
{
|
{
|
||||||
_Socket = socket;
|
_Socket = socket;
|
||||||
this.TransmittalType = TransmittalType.Socket;
|
TransmittalType = TransmittalType.Socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeartBeat(HTTPClient client)
|
public HeartBeat(HTTPClient client)
|
||||||
{
|
{
|
||||||
_HTTPClient = client;
|
_HTTPClient = client;
|
||||||
this.TransmittalType = TransmittalType.WebSocket;
|
TransmittalType = TransmittalType.WebSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartSendingHeartBeat()
|
public void StartSendingHeartBeat()
|
||||||
@ -34,6 +35,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
if (!FunGameInfo.FunGame_DebugMode)
|
if (!FunGameInfo.FunGame_DebugMode)
|
||||||
{
|
{
|
||||||
_SendingHeartBeat = true;
|
_SendingHeartBeat = true;
|
||||||
|
_Socket?.AddSocketObjectHandler(SocketObject_Handler);
|
||||||
|
_HTTPClient?.AddSocketObjectHandler(SocketObject_Handler);
|
||||||
SendingHeartBeatTask = Task.Factory.StartNew(SendHeartBeat);
|
SendingHeartBeatTask = Task.Factory.StartNew(SendHeartBeat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,6 +46,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
_SendingHeartBeat = false;
|
_SendingHeartBeat = false;
|
||||||
SendingHeartBeatTask?.Wait(1);
|
SendingHeartBeatTask?.Wait(1);
|
||||||
SendingHeartBeatTask = null;
|
SendingHeartBeatTask = null;
|
||||||
|
_Socket?.RemoveSocketObjectHandler(SocketObject_Handler);
|
||||||
|
_HTTPClient?.RemoveSocketObjectHandler(SocketObject_Handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendHeartBeat()
|
private async Task SendHeartBeat()
|
||||||
@ -54,13 +59,14 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
{
|
{
|
||||||
if (!SendingHeartBeat) _SendingHeartBeat = true;
|
if (!SendingHeartBeat) _SendingHeartBeat = true;
|
||||||
// 发送心跳包
|
// 发送心跳包
|
||||||
|
_LastHeartbeatReceived = false;
|
||||||
if (_Socket.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
|
if (_Socket.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
|
||||||
{
|
{
|
||||||
await Task.Delay(4 * 000);
|
await Task.Delay(4 * 1000);
|
||||||
AddHeartBeatFaileds();
|
if (!_LastHeartbeatReceived) AddHeartBeatFaileds();
|
||||||
}
|
}
|
||||||
else AddHeartBeatFaileds();
|
else AddHeartBeatFaileds();
|
||||||
await Task.Delay(20 * 000);
|
await Task.Delay(20 * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_HTTPClient != null)
|
else if (_HTTPClient != null)
|
||||||
@ -71,11 +77,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
// 发送心跳包
|
// 发送心跳包
|
||||||
if (await _HTTPClient.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
|
if (await _HTTPClient.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
|
||||||
{
|
{
|
||||||
await Task.Delay(4 * 000);
|
await Task.Delay(4 * 1000);
|
||||||
AddHeartBeatFaileds();
|
AddHeartBeatFaileds();
|
||||||
}
|
}
|
||||||
else AddHeartBeatFaileds();
|
else AddHeartBeatFaileds();
|
||||||
await Task.Delay(20 * 000);
|
await Task.Delay(20 * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SendingHeartBeat = false;
|
_SendingHeartBeat = false;
|
||||||
@ -85,7 +91,20 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
{
|
{
|
||||||
// 超过三次没回应心跳,服务器连接失败。
|
// 超过三次没回应心跳,服务器连接失败。
|
||||||
if (_HeartBeatFaileds++ >= 3)
|
if (_HeartBeatFaileds++ >= 3)
|
||||||
|
{
|
||||||
|
_Socket?.Close();
|
||||||
|
_HTTPClient?.Close();
|
||||||
throw new LostConnectException();
|
throw new LostConnectException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SocketObject_Handler(SocketObject obj)
|
||||||
|
{
|
||||||
|
if (obj.SocketType == SocketMessageType.HeartBeat)
|
||||||
|
{
|
||||||
|
_LastHeartbeatReceived = true;
|
||||||
|
_HeartBeatFaileds = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Event
|
|||||||
RoomType = type;
|
RoomType = type;
|
||||||
RoomTypeString = RoomSet.GetTypeString(type);
|
RoomTypeString = RoomSet.GetTypeString(type);
|
||||||
Password = password;
|
Password = password;
|
||||||
Room = Factory.GetRoom(RoomType: RoomType, Password: Password);
|
Room = Factory.GetRoom(roomType: RoomType, password: Password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoomEventArgs(Room room)
|
public RoomEventArgs(Room room)
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
using Milimoe.FunGame.Core.Interface.Base;
|
|
||||||
using Milimoe.FunGame.Core.Interface.Sockets;
|
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
|
||||||
using Milimoe.FunGame.Core.Service;
|
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Library.Common.Network
|
|
||||||
{
|
|
||||||
public class ClientSocket(System.Net.Sockets.Socket instance, string clientIP, string clientName, Guid token) : IClientSocket, ISocketMessageProcessor
|
|
||||||
{
|
|
||||||
public System.Net.Sockets.Socket Instance { get; } = instance;
|
|
||||||
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
|
||||||
public Guid Token { get; } = token;
|
|
||||||
public string ClientIP { get; } = clientIP;
|
|
||||||
public string ClientName => _ClientName;
|
|
||||||
public bool Connected => Instance != null && Instance.Connected;
|
|
||||||
public bool Receiving => _Receiving;
|
|
||||||
public Type InstanceType => typeof(ClientSocket);
|
|
||||||
|
|
||||||
private Task? ReceivingTask;
|
|
||||||
|
|
||||||
private bool _Receiving;
|
|
||||||
private readonly string _ClientName = clientName;
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
StopReceiving();
|
|
||||||
Instance?.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketObject[] Receive()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return SocketManager.Receive(Instance);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw new SocketWrongInfoException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketResult Send(SocketMessageType type, params object[] objs)
|
|
||||||
{
|
|
||||||
if (Instance != null)
|
|
||||||
{
|
|
||||||
if (SocketManager.Send(Instance, new(type, Token, objs)) == SocketResult.Success)
|
|
||||||
{
|
|
||||||
return SocketResult.Success;
|
|
||||||
}
|
|
||||||
else return SocketResult.Fail;
|
|
||||||
}
|
|
||||||
return SocketResult.NotSent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs)
|
|
||||||
{
|
|
||||||
if (Instance != null)
|
|
||||||
{
|
|
||||||
if (await SocketManager.SendAsync(Instance, new(type, Token, objs)) == SocketResult.Success)
|
|
||||||
{
|
|
||||||
return SocketResult.Success;
|
|
||||||
}
|
|
||||||
else return SocketResult.Fail;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
ReceivingTask = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopReceiving()
|
|
||||||
{
|
|
||||||
_Receiving = false;
|
|
||||||
ReceivingTask?.Wait(1);
|
|
||||||
ReceivingTask = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
using System.Net.WebSockets;
|
|
||||||
using Milimoe.FunGame.Core.Api.Utility;
|
|
||||||
using Milimoe.FunGame.Core.Interface.Base;
|
|
||||||
using Milimoe.FunGame.Core.Interface.Sockets;
|
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
|
||||||
using Milimoe.FunGame.Core.Service;
|
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Library.Common.Network
|
|
||||||
{
|
|
||||||
public class ClientWebSocket(HTTPListener listener, WebSocket instance, string clientIP, string clientName, Guid token) : IWebSocket, ISocketMessageProcessor
|
|
||||||
{
|
|
||||||
public HTTPListener Listener => listener;
|
|
||||||
public WebSocket Instance => instance;
|
|
||||||
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
|
||||||
public Guid Token => token;
|
|
||||||
public string ClientIP => clientIP;
|
|
||||||
public string ClientName => clientName;
|
|
||||||
public Type InstanceType => typeof(ClientWebSocket);
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
TaskUtility.NewTask(async () =>
|
|
||||||
{
|
|
||||||
if (Instance.State == WebSocketState.Open)
|
|
||||||
{
|
|
||||||
// 安全关闭 WebSocket 连接
|
|
||||||
await Instance.CloseAsync(WebSocketCloseStatus.NormalClosure, "服务器正在关闭,断开连接!", CancellationToken.None);
|
|
||||||
Listener.ClientSockets.Remove(Token);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketResult Send(SocketMessageType type, params object[] objs)
|
|
||||||
{
|
|
||||||
throw new AsyncSendException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs)
|
|
||||||
{
|
|
||||||
return await HTTPManager.Send(Instance, new(type, token, objs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,53 +11,44 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
{
|
{
|
||||||
public System.Net.WebSockets.ClientWebSocket? Instance { get; } = null;
|
public System.Net.WebSockets.ClientWebSocket? Instance { get; } = null;
|
||||||
public SocketRuntimeType Runtime => SocketRuntimeType.Client;
|
public SocketRuntimeType Runtime => SocketRuntimeType.Client;
|
||||||
public Guid Token { get; } = Guid.Empty;
|
public Guid Token { get; set; } = Guid.Empty;
|
||||||
public string ServerAddress { get; } = "";
|
public string ServerAddress { get; } = "";
|
||||||
public int ServerPort { get; } = 0;
|
public int ServerPort { get; } = 0;
|
||||||
public string ServerName { get; } = "";
|
public string ServerName { get; } = "";
|
||||||
public string ServerNotice { get; } = "";
|
public string ServerNotice { get; } = "";
|
||||||
|
public bool Connected => Instance != null && Instance.State == WebSocketState.Open;
|
||||||
|
public bool Receiving => _receiving;
|
||||||
|
private HeartBeat HeartBeat { get; }
|
||||||
|
|
||||||
private bool _Listening = false;
|
private bool _receiving = false;
|
||||||
private readonly HeartBeat HeartBeat;
|
private readonly HashSet<Action<SocketObject>> _boundEvents = [];
|
||||||
|
|
||||||
private HTTPClient(System.Net.WebSockets.ClientWebSocket Instance, string ServerAddress, int ServerPort, params object[] args)
|
private HTTPClient(System.Net.WebSockets.ClientWebSocket instance, string serverAddress, int serverPort, params object[] args)
|
||||||
{
|
{
|
||||||
this.Instance = Instance;
|
Instance = instance;
|
||||||
this.ServerAddress = ServerAddress;
|
ServerAddress = serverAddress;
|
||||||
this.ServerPort = ServerPort;
|
ServerPort = serverPort;
|
||||||
HeartBeat = new(this);
|
HeartBeat = new(this);
|
||||||
HeartBeat.StartSendingHeartBeat();
|
HeartBeat.StartSendingHeartBeat();
|
||||||
Task.Factory.StartNew(async () => await StartListening(args));
|
Task.Factory.StartNew(async () => await StartListening(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<HTTPClient> Connect(string ServerAddress, int ServerPort, bool SSL, string SubDirectory = "", params object[] args)
|
public static async Task<HTTPClient> Connect(string serverAddress, int serverPort, bool ssl, string subUrl = "", params object[] args)
|
||||||
{
|
{
|
||||||
string ServerIP = Api.Utility.NetworkUtility.GetIPAddress(ServerAddress);
|
string ServerIP = Api.Utility.NetworkUtility.GetIPAddress(serverAddress);
|
||||||
Uri uri = new((SSL ? "wss://" : "ws://") + ServerIP + ":" + ServerPort + "/" + SubDirectory);
|
Uri uri = new((ssl ? "wss://" : "ws://") + ServerIP + ":" + serverPort + "/" + subUrl.Trim('/') + "/");
|
||||||
System.Net.WebSockets.ClientWebSocket? socket = await HTTPManager.Connect(uri);
|
System.Net.WebSockets.ClientWebSocket? socket = await HTTPManager.Connect(uri);
|
||||||
if (socket != null && socket.State == WebSocketState.Open)
|
if (socket != null && socket.State == WebSocketState.Open)
|
||||||
{
|
{
|
||||||
HTTPClient client = new(socket, ServerAddress, ServerPort, args);
|
HTTPClient client = new(socket, serverAddress, serverPort, args);
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
throw new CanNotConnectException();
|
throw new CanNotConnectException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartListening(params object[] args)
|
|
||||||
{
|
|
||||||
if (Instance != null && Instance.State == WebSocketState.Open)
|
|
||||||
{
|
|
||||||
if (await HTTPManager.Send(Instance, new(SocketMessageType.Connect, Guid.Empty, args)) == SocketResult.Success && await HTTPManager.ReceiveMessage(this))
|
|
||||||
{
|
|
||||||
_Listening = true;
|
|
||||||
await Receive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Receive()
|
public async Task Receive()
|
||||||
{
|
{
|
||||||
while (_Listening)
|
while (_receiving)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -81,29 +72,42 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
return SocketResult.NotSent;
|
return SocketResult.NotSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual SocketObject SocketObject_Handler(SocketObject objs)
|
public void AddSocketObjectHandler(Action<SocketObject> method)
|
||||||
{
|
{
|
||||||
return new(SocketMessageType.Unknown, Guid.Empty);
|
if (_boundEvents.Add(method))
|
||||||
|
{
|
||||||
|
SocketManager.SocketReceive += new SocketManager.SocketReceiveHandler(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BindEvent(Delegate method, bool remove = false)
|
public void RemoveSocketObjectHandler(Action<SocketObject> method)
|
||||||
{
|
{
|
||||||
if (!remove)
|
_boundEvents.Remove(method);
|
||||||
{
|
SocketManager.SocketReceive -= new SocketManager.SocketReceiveHandler(method);
|
||||||
SocketManager.SocketReceive += (SocketManager.SocketReceiveHandler)method;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SocketManager.SocketReceive -= (SocketManager.SocketReceiveHandler)method;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
_Listening = false;
|
_receiving = false;
|
||||||
HeartBeat.StopSendingHeartBeat();
|
HeartBeat.StopSendingHeartBeat();
|
||||||
Instance?.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
Instance?.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
||||||
Instance?.Dispose();
|
Instance?.Dispose();
|
||||||
|
foreach (Action<SocketObject> method in _boundEvents.ToList())
|
||||||
|
{
|
||||||
|
RemoveSocketObjectHandler(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task StartListening(params object[] args)
|
||||||
|
{
|
||||||
|
if (Instance != null && Instance.State == WebSocketState.Open)
|
||||||
|
{
|
||||||
|
if (await HTTPManager.Send(Instance, new(SocketMessageType.Connect, Guid.Empty, args)) == SocketResult.Success && await HTTPManager.ReceiveMessage(this))
|
||||||
|
{
|
||||||
|
_receiving = true;
|
||||||
|
await Receive();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using Milimoe.FunGame.Core.Api.Utility;
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Base;
|
||||||
using Milimoe.FunGame.Core.Interface.HTTP;
|
using Milimoe.FunGame.Core.Interface.HTTP;
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
using Milimoe.FunGame.Core.Service;
|
using Milimoe.FunGame.Core.Service;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Library.Common.Network
|
namespace Milimoe.FunGame.Core.Library.Common.Network
|
||||||
{
|
{
|
||||||
public class HTTPListener : IHTTPListener
|
public class HTTPListener : IHTTPListener, ISocketListener<ServerWebSocket>
|
||||||
{
|
{
|
||||||
public HttpListener Instance { get; }
|
public HttpListener Instance { get; }
|
||||||
|
public string Name => "HTTPListener";
|
||||||
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
||||||
public Guid Token { get; } = Guid.Empty;
|
public Guid Token { get; } = Guid.Empty;
|
||||||
public Dictionary<Guid, WebSocket> ClientSockets { get; } = [];
|
public ConcurrentModelList<IServerModel> ClientList { get; } = [];
|
||||||
|
public ConcurrentModelList<IServerModel> UserList { get; } = [];
|
||||||
|
public List<string> BannedList { get; } = [];
|
||||||
|
|
||||||
private HTTPListener(HttpListener instance)
|
private HTTPListener(HttpListener instance)
|
||||||
{
|
{
|
||||||
@ -20,24 +24,27 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
Token = Guid.NewGuid();
|
Token = Guid.NewGuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HTTPListener StartListening(int port, bool ssl = false)
|
public static HTTPListener StartListening(string address = "*", int port = 22223, string subUrl = "ws", bool ssl = false)
|
||||||
{
|
{
|
||||||
HttpListener? socket = HTTPManager.StartListening(port, ssl);
|
HttpListener? socket = HTTPManager.StartListening(address, port, subUrl, ssl);
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
{
|
{
|
||||||
HTTPListener instance = new(socket);
|
HTTPListener instance = new(socket);
|
||||||
Task t = Task.Run(async () => await HTTPManager.Receiving(instance));
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
else throw new SocketCreateListenException();
|
else throw new SocketCreateListenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendMessage(Guid token, SocketObject obj)
|
public async Task<ServerWebSocket> Accept(Guid token)
|
||||||
{
|
{
|
||||||
if (ClientSockets.TryGetValue(token, out WebSocket? socket) && socket != null)
|
object[] result = await HTTPManager.Accept();
|
||||||
|
if (result != null && result.Length == 2)
|
||||||
{
|
{
|
||||||
await HTTPManager.Send(socket, obj);
|
string clientIP = (string)result[0];
|
||||||
|
WebSocket client = (WebSocket)result[1];
|
||||||
|
return new ServerWebSocket(this, client, clientIP, clientIP, token);
|
||||||
}
|
}
|
||||||
|
throw new SocketGetClientException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool CheckClientConnection(SocketObject objs)
|
public virtual bool CheckClientConnection(SocketObject objs)
|
||||||
@ -52,27 +59,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
bool closing = true;
|
|
||||||
TaskUtility.NewTask(async () =>
|
|
||||||
{
|
|
||||||
// 关闭所有 WebSocket 连接
|
|
||||||
foreach (WebSocket socket in ClientSockets.Values)
|
|
||||||
{
|
|
||||||
if (socket.State == WebSocketState.Open)
|
|
||||||
{
|
|
||||||
// 安全关闭 WebSocket 连接
|
|
||||||
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "服务器正在关闭,断开连接!", CancellationToken.None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClientSockets.Clear();
|
|
||||||
Instance?.Close();
|
Instance?.Close();
|
||||||
closing = true;
|
|
||||||
});
|
|
||||||
while (closing)
|
|
||||||
{
|
|
||||||
if (!closing) break;
|
|
||||||
Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,109 +5,109 @@ using Milimoe.FunGame.Core.Service;
|
|||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Library.Common.Network
|
namespace Milimoe.FunGame.Core.Library.Common.Network
|
||||||
{
|
{
|
||||||
public class ServerSocket : ISocket
|
public class ServerSocket(SocketListener listener, System.Net.Sockets.Socket instance, string clientIP, string clientName, Guid token) : IClientSocket, ISocketMessageProcessor
|
||||||
{
|
{
|
||||||
public System.Net.Sockets.Socket Instance { get; }
|
public SocketListener Listener { get; } = listener;
|
||||||
|
public System.Net.Sockets.Socket Instance { get; } = instance;
|
||||||
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
||||||
public Guid Token { get; } = Guid.Empty;
|
public Guid Token { get; } = token;
|
||||||
|
public string ClientIP { get; } = clientIP;
|
||||||
|
public string ClientName => clientName;
|
||||||
public bool Connected => Instance != null && Instance.Connected;
|
public bool Connected => Instance != null && Instance.Connected;
|
||||||
public List<IServerModel> ClientList => OnlineClients.GetList();
|
public bool Receiving => _receiving;
|
||||||
public List<IServerModel> UserList => OnlineUsers.GetList();
|
public Type InstanceType => typeof(ServerSocket);
|
||||||
public List<string> BannedList { get; } = [];
|
|
||||||
public int ClientCount => OnlineClients.Count;
|
|
||||||
public int UserCount => OnlineUsers.Count;
|
|
||||||
public int BannedCount => BannedList.Count;
|
|
||||||
|
|
||||||
private readonly ModelManager<IServerModel> OnlineClients;
|
private Task? _receivingTask;
|
||||||
private readonly ModelManager<IServerModel> OnlineUsers;
|
private bool _receiving;
|
||||||
|
private readonly HashSet<Action<SocketObject>> _boundEvents = [];
|
||||||
private ServerSocket(System.Net.Sockets.Socket instance, int maxConnection = 0)
|
|
||||||
{
|
|
||||||
Token = Guid.NewGuid();
|
|
||||||
Instance = instance;
|
|
||||||
if (maxConnection <= 0)
|
|
||||||
{
|
|
||||||
OnlineClients = [];
|
|
||||||
OnlineUsers = [];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OnlineClients = new(maxConnection);
|
|
||||||
OnlineUsers = new(maxConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ServerSocket StartListening(int port = 22222, int maxConnection = 0)
|
|
||||||
{
|
|
||||||
if (maxConnection <= 0) maxConnection = SocketSet.MaxConnection_2C2G;
|
|
||||||
System.Net.Sockets.Socket? socket = SocketManager.StartListening(port, maxConnection);
|
|
||||||
if (socket != null) return new ServerSocket(socket, port);
|
|
||||||
else throw new SocketCreateListenException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClientSocket Accept(Guid token)
|
|
||||||
{
|
|
||||||
object[] result = SocketManager.Accept();
|
|
||||||
if (result != null && result.Length == 2)
|
|
||||||
{
|
|
||||||
string clientIP = (string)result[0];
|
|
||||||
System.Net.Sockets.Socket client = (System.Net.Sockets.Socket)result[1];
|
|
||||||
return new ClientSocket(client, clientIP, clientIP, token);
|
|
||||||
}
|
|
||||||
throw new SocketGetClientException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddClient(string name, IServerModel t)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineClients.Add(name, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveClient(string name)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineClients.Remove(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContainsClient(string name)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineClients.ContainsKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IServerModel GetClient(string name)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineClients[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddUser(string name, IServerModel t)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineUsers.Add(name, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveUser(string name)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineUsers.Remove(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContainsUser(string name)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineUsers.ContainsKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IServerModel GetUser(string name)
|
|
||||||
{
|
|
||||||
name = name.ToLower();
|
|
||||||
return OnlineUsers[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Instance?.Close();
|
StopReceiving();
|
||||||
|
Instance.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CloseAsync()
|
||||||
|
{
|
||||||
|
StopReceiving();
|
||||||
|
await Task.Run(() => Instance?.Close());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketObject[] Receive()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return SocketManager.Receive(Instance);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new SocketWrongInfoException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SocketObject[]> ReceiveAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await SocketManager.ReceiveAsync(Instance);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new SocketWrongInfoException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketResult Send(SocketMessageType type, params object[] objs)
|
||||||
|
{
|
||||||
|
if (Instance != null)
|
||||||
|
{
|
||||||
|
if (SocketManager.Send(Instance, new(type, Token, objs)) == SocketResult.Success)
|
||||||
|
{
|
||||||
|
return SocketResult.Success;
|
||||||
|
}
|
||||||
|
else return SocketResult.Fail;
|
||||||
|
}
|
||||||
|
return SocketResult.NotSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs)
|
||||||
|
{
|
||||||
|
if (Instance != null)
|
||||||
|
{
|
||||||
|
if (await SocketManager.SendAsync(Instance, new(type, Token, objs)) == SocketResult.Success)
|
||||||
|
{
|
||||||
|
return SocketResult.Success;
|
||||||
|
}
|
||||||
|
else return SocketResult.Fail;
|
||||||
|
}
|
||||||
|
return SocketResult.NotSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSocketObjectHandler(Action<SocketObject> method)
|
||||||
|
{
|
||||||
|
if (_boundEvents.Add(method))
|
||||||
|
{
|
||||||
|
SocketManager.SocketReceive += new SocketManager.SocketReceiveHandler(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveSocketObjectHandler(Action<SocketObject> method)
|
||||||
|
{
|
||||||
|
_boundEvents.Remove(method);
|
||||||
|
SocketManager.SocketReceive -= new SocketManager.SocketReceiveHandler(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartReceiving(Task t)
|
||||||
|
{
|
||||||
|
_receiving = true;
|
||||||
|
_receivingTask = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopReceiving()
|
||||||
|
{
|
||||||
|
_receiving = false;
|
||||||
|
_receivingTask?.Wait(1);
|
||||||
|
_receivingTask = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
77
Library/Common/Network/ServerWebSocket.cs
Normal file
77
Library/Common/Network/ServerWebSocket.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using System.Net.WebSockets;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Base;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Sockets;
|
||||||
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
using Milimoe.FunGame.Core.Service;
|
||||||
|
|
||||||
|
namespace Milimoe.FunGame.Core.Library.Common.Network
|
||||||
|
{
|
||||||
|
public class ServerWebSocket(ISocketListener<ServerWebSocket> listener, WebSocket instance, string clientIP, string clientName, Guid token) : IClientWebSocket, ISocketMessageProcessor
|
||||||
|
{
|
||||||
|
public ISocketListener<ServerWebSocket> Listener => listener;
|
||||||
|
public WebSocket Instance => instance;
|
||||||
|
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
||||||
|
public Guid Token => token;
|
||||||
|
public string ClientIP => clientIP;
|
||||||
|
public string ClientName => clientName;
|
||||||
|
public Type InstanceType => typeof(ServerWebSocket);
|
||||||
|
public bool Receiving => _receiving;
|
||||||
|
|
||||||
|
private Task? _receivingTask;
|
||||||
|
private bool _receiving = false;
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
throw new AsyncSendException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CloseAsync()
|
||||||
|
{
|
||||||
|
if (Instance.State == WebSocketState.Open)
|
||||||
|
{
|
||||||
|
// 安全关闭 WebSocket 连接
|
||||||
|
await Instance.CloseAsync(WebSocketCloseStatus.NormalClosure, "服务器正在关闭,断开连接!", CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketObject[] Receive()
|
||||||
|
{
|
||||||
|
throw new AsyncReadException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SocketObject[]> ReceiveAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await HTTPManager.Receive(Instance);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new SocketWrongInfoException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketResult Send(SocketMessageType type, params object[] objs)
|
||||||
|
{
|
||||||
|
throw new AsyncSendException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SocketResult> SendAsync(SocketMessageType type, params object[] objs)
|
||||||
|
{
|
||||||
|
return await HTTPManager.Send(Instance, new(type, token, objs));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartReceiving(Task t)
|
||||||
|
{
|
||||||
|
_receiving = true;
|
||||||
|
_receivingTask = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopReceiving()
|
||||||
|
{
|
||||||
|
_receiving = false;
|
||||||
|
_receivingTask?.Wait(1);
|
||||||
|
_receivingTask = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,11 +16,12 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
public string ServerName { get; } = "";
|
public string ServerName { get; } = "";
|
||||||
public string ServerNotice { get; } = "";
|
public string ServerNotice { get; } = "";
|
||||||
public bool Connected => Instance != null && Instance.Connected;
|
public bool Connected => Instance != null && Instance.Connected;
|
||||||
public bool Receiving => _Receiving;
|
public bool Receiving => _receiving;
|
||||||
|
private HeartBeat HeartBeat { get; }
|
||||||
|
|
||||||
private Task? ReceivingTask;
|
private Task? _receivingTask;
|
||||||
private readonly HeartBeat HeartBeat;
|
private bool _receiving = false;
|
||||||
private bool _Receiving = false;
|
private readonly HashSet<Action<SocketObject>> _boundEvents = [];
|
||||||
|
|
||||||
private Socket(System.Net.Sockets.Socket instance, string serverAddress, int serverPort)
|
private Socket(System.Net.Sockets.Socket instance, string serverAddress, int serverPort)
|
||||||
{
|
{
|
||||||
@ -65,16 +66,18 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BindEvent(Delegate method, bool remove = false)
|
public void AddSocketObjectHandler(Action<SocketObject> method)
|
||||||
{
|
{
|
||||||
if (!remove)
|
if (_boundEvents.Add(method))
|
||||||
{
|
{
|
||||||
SocketManager.SocketReceive += (SocketManager.SocketReceiveHandler)method;
|
SocketManager.SocketReceive += new SocketManager.SocketReceiveHandler(method);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
SocketManager.SocketReceive -= (SocketManager.SocketReceiveHandler)method;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveSocketObjectHandler(Action<SocketObject> method)
|
||||||
|
{
|
||||||
|
_boundEvents.Remove(method);
|
||||||
|
SocketManager.SocketReceive -= new SocketManager.SocketReceiveHandler(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
@ -82,19 +85,23 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
HeartBeat.StopSendingHeartBeat();
|
HeartBeat.StopSendingHeartBeat();
|
||||||
StopReceiving();
|
StopReceiving();
|
||||||
Instance?.Close();
|
Instance?.Close();
|
||||||
|
foreach (Action<SocketObject> method in _boundEvents.ToList())
|
||||||
|
{
|
||||||
|
RemoveSocketObjectHandler(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartReceiving(Task t)
|
public void StartReceiving(Task t)
|
||||||
{
|
{
|
||||||
_Receiving = true;
|
_receiving = true;
|
||||||
ReceivingTask = t;
|
_receivingTask = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopReceiving()
|
public void StopReceiving()
|
||||||
{
|
{
|
||||||
_Receiving = false;
|
_receiving = false;
|
||||||
ReceivingTask?.Wait(1);
|
_receivingTask?.Wait(1);
|
||||||
ReceivingTask = null;
|
_receivingTask = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
51
Library/Common/Network/SocketListener.cs
Normal file
51
Library/Common/Network/SocketListener.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Base;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Sockets;
|
||||||
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
using Milimoe.FunGame.Core.Service;
|
||||||
|
|
||||||
|
namespace Milimoe.FunGame.Core.Library.Common.Network
|
||||||
|
{
|
||||||
|
public class SocketListener : ISocket, ISocketListener<ServerSocket>
|
||||||
|
{
|
||||||
|
public System.Net.Sockets.Socket Instance { get; }
|
||||||
|
public string Name => "SocketListener";
|
||||||
|
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
|
||||||
|
public Guid Token { get; } = Guid.Empty;
|
||||||
|
public bool Connected => Instance != null && Instance.Connected;
|
||||||
|
public ConcurrentModelList<IServerModel> ClientList { get; } = [];
|
||||||
|
public ConcurrentModelList<IServerModel> UserList { get; } = [];
|
||||||
|
public List<string> BannedList { get; } = [];
|
||||||
|
|
||||||
|
private SocketListener(System.Net.Sockets.Socket instance)
|
||||||
|
{
|
||||||
|
Token = Guid.NewGuid();
|
||||||
|
Instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SocketListener StartListening(int port = 22222, int maxConnection = 0)
|
||||||
|
{
|
||||||
|
if (maxConnection <= 0) maxConnection = SocketSet.MaxConnection_2C2G;
|
||||||
|
System.Net.Sockets.Socket? socket = SocketManager.StartListening(port, maxConnection);
|
||||||
|
if (socket != null) return new SocketListener(socket);
|
||||||
|
else throw new SocketCreateListenException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerSocket Accept(Guid token)
|
||||||
|
{
|
||||||
|
object[] result = SocketManager.Accept();
|
||||||
|
if (result != null && result.Length == 2)
|
||||||
|
{
|
||||||
|
string clientIP = (string)result[0];
|
||||||
|
System.Net.Sockets.Socket client = (System.Net.Sockets.Socket)result[1];
|
||||||
|
return new ServerSocket(this, client, clientIP, clientIP, token);
|
||||||
|
}
|
||||||
|
throw new SocketGetClientException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
Instance?.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,11 +27,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
}
|
}
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public SocketObject(SocketMessageType SocketType, Guid Token, params object[] Parameters)
|
public SocketObject(SocketMessageType type, Guid token, params object[] args)
|
||||||
{
|
{
|
||||||
this.SocketType = SocketType;
|
SocketType = type;
|
||||||
this.Token = Token;
|
Token = token;
|
||||||
if (Parameters != null && Parameters.Length > 0) this.Parameters = Parameters;
|
if (args != null && args.Length > 0) Parameters = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -102,7 +102,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
|||||||
/**
|
/**
|
||||||
* Register
|
* Register
|
||||||
*/
|
*/
|
||||||
public const string Reg_GetRegVerifyCode = "Reg::GetRegVerifyCode";
|
public const string Reg_Reg = "Reg::Reg";
|
||||||
/**
|
/**
|
||||||
* Login
|
* Login
|
||||||
*/
|
*/
|
||||||
@ -140,7 +140,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
|||||||
DataRequestType.Main_Ready => Main_Ready,
|
DataRequestType.Main_Ready => Main_Ready,
|
||||||
DataRequestType.Main_CancelReady => Main_CancelReady,
|
DataRequestType.Main_CancelReady => Main_CancelReady,
|
||||||
DataRequestType.Main_StartGame => Main_StartGame,
|
DataRequestType.Main_StartGame => Main_StartGame,
|
||||||
DataRequestType.Reg_GetRegVerifyCode => Reg_GetRegVerifyCode,
|
DataRequestType.Reg_Reg => Reg_Reg,
|
||||||
DataRequestType.Login_Login => Login_Login,
|
DataRequestType.Login_Login => Login_Login,
|
||||||
DataRequestType.Login_GetFindPasswordVerifyCode => Login_GetFindPasswordVerifyCode,
|
DataRequestType.Login_GetFindPasswordVerifyCode => Login_GetFindPasswordVerifyCode,
|
||||||
DataRequestType.Login_UpdatePassword => Login_UpdatePassword,
|
DataRequestType.Login_UpdatePassword => Login_UpdatePassword,
|
||||||
|
@ -38,7 +38,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认的字符编码
|
/// 默认的字符编码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Encoding DefaultEncoding => Encoding.Unicode;
|
public static Encoding DefaultEncoding => Encoding.UTF8;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认的时间格式 yyyy-MM-dd HH:mm:ss.fff
|
/// 默认的时间格式 yyyy-MM-dd HH:mm:ss.fff
|
||||||
|
@ -97,7 +97,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
|||||||
Main_Ready,
|
Main_Ready,
|
||||||
Main_CancelReady,
|
Main_CancelReady,
|
||||||
Main_StartGame,
|
Main_StartGame,
|
||||||
Reg_GetRegVerifyCode,
|
Reg_Reg,
|
||||||
Login_Login,
|
Login_Login,
|
||||||
Login_GetFindPasswordVerifyCode,
|
Login_GetFindPasswordVerifyCode,
|
||||||
Login_UpdatePassword,
|
Login_UpdatePassword,
|
||||||
@ -843,7 +843,8 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
|||||||
Interface,
|
Interface,
|
||||||
DataRequest,
|
DataRequest,
|
||||||
Plugin,
|
Plugin,
|
||||||
GameModule
|
GameModule,
|
||||||
|
Warning
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SQLMode
|
public enum SQLMode
|
||||||
|
@ -165,13 +165,18 @@
|
|||||||
public override string Message => "试图在不支持的类中创建数据请求 (#10033)";
|
public override string Message => "试图在不支持的类中创建数据请求 (#10033)";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AsyncSendException : Exception
|
|
||||||
{
|
|
||||||
public override string Message => "必须以异步方式发送数据 (#10034)";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SQLServiceException : Exception
|
public class SQLServiceException : Exception
|
||||||
{
|
{
|
||||||
public override string Message => "SQL服务遇到错误,请检查SQL配置 (#10035)";
|
public override string Message => "SQL服务遇到错误,请检查SQL配置 (#10034)";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AsyncSendException : Exception
|
||||||
|
{
|
||||||
|
public override string Message => "必须以异步方式发送数据 (#10035)";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AsyncReadException : Exception
|
||||||
|
{
|
||||||
|
public override string Message => "必须以异步方式读取数据 (#10036)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,17 @@
|
|||||||
public const string Column_IsRank = "IsRank";
|
public const string Column_IsRank = "IsRank";
|
||||||
public const string Column_HasPass = "HasPass";
|
public const string Column_HasPass = "HasPass";
|
||||||
public const string Column_Password = "Password";
|
public const string Column_Password = "Password";
|
||||||
|
public const string Column_MaxUsers = "MaxUsers";
|
||||||
public const string Select_Rooms = $"{Command_Select} {TableName}.{Command_All}, {UserQuery.TableName}.{UserQuery.Column_Username} {Command_As} {Column_RoomMasterName} " +
|
public const string Select_Rooms = $"{Command_Select} {TableName}.{Command_All}, {UserQuery.TableName}.{UserQuery.Column_Username} {Command_As} {Column_RoomMasterName} " +
|
||||||
$"{Command_From} {TableName} {Command_LeftJoin} {UserQuery.TableName} {Command_On} {UserQuery.TableName}.{UserQuery.Column_UID} = {TableName}.{Column_RoomMaster}";
|
$"{Command_From} {TableName} {Command_LeftJoin} {UserQuery.TableName} {Command_On} {UserQuery.TableName}.{UserQuery.Column_UID} = {TableName}.{Column_RoomMaster}";
|
||||||
|
|
||||||
public static string Insert_CreateRoom(string RoomID, long RoomMaster, Library.Constant.RoomType RoomType, string GameModule, string GameMap, bool IsRank, string Password)
|
public static string Insert_CreateRoom(string roomid, long roomMaster, Library.Constant.RoomType roomType, string gameModule, string gameMap, bool isRank, string password, int maxUsers)
|
||||||
{
|
{
|
||||||
Library.Constant.RoomState RoomState = Library.Constant.RoomState.Created;
|
Library.Constant.RoomState RoomState = Library.Constant.RoomState.Created;
|
||||||
DateTime NowTime = DateTime.Now;
|
DateTime NowTime = DateTime.Now;
|
||||||
bool HasPass = Password.Trim() != "";
|
bool HasPass = password.Trim() != "";
|
||||||
return $"{Command_Insert} {Command_Into} {TableName} ({Column_RoomID}, {Column_CreateTime}, {Column_RoomMaster}, {Column_RoomType}, {Column_GameModule}, {Column_GameMap}, {Column_RoomState}, {Column_IsRank}, {Column_HasPass}, {Column_Password})" +
|
return $"{Command_Insert} {Command_Into} {TableName} ({Column_RoomID}, {Column_CreateTime}, {Column_RoomMaster}, {Column_RoomType}, {Column_GameModule}, {Column_GameMap}, {Column_RoomState}, {Column_IsRank}, {Column_HasPass}, {Column_Password}, {Column_MaxUsers})" +
|
||||||
$" {Command_Values} ('{RoomID}', '{NowTime}', {RoomMaster}, {(int)RoomType}, '{GameModule}', '{GameMap}', {(int)RoomState}, {(IsRank ? 1 : 0)}, {(HasPass ? 1 : 0)}, '{Password}')";
|
$" {Command_Values} ('{roomid}', '{NowTime}', {roomMaster}, {(int)roomType}, '{gameModule}', '{gameMap}', {(int)RoomState}, {(isRank ? 1 : 0)}, {(HasPass ? 1 : 0)}, '{password}', {maxUsers})";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Delete_Rooms(params string[] roomids)
|
public static string Delete_Rooms(params string[] roomids)
|
||||||
@ -37,19 +38,19 @@
|
|||||||
return $"{Command_Delete} {Command_From} {TableName}";
|
return $"{Command_Delete} {Command_From} {TableName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Delete_QuitRoom(string RoomID, long RoomMaster)
|
public static string Delete_QuitRoom(string roomID, long roomMaster)
|
||||||
{
|
{
|
||||||
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_RoomID} = '{RoomID}' {Command_And} {Column_RoomMaster} = {RoomMaster}";
|
return $"{Command_Delete} {Command_From} {TableName} {Command_Where} {Column_RoomID} = '{roomID}' {Command_And} {Column_RoomMaster} = {roomMaster}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Update_QuitRoom(string RoomID, long OldRoomMaster, long NewRoomMaster)
|
public static string Update_QuitRoom(string roomid, long oldRoomMaster, long newRoomMaster)
|
||||||
{
|
{
|
||||||
return $"{Command_Update} {TableName} {Command_Set} {Column_RoomMaster} = {NewRoomMaster} {Command_Where} {Column_RoomID} = '{RoomID}' {Command_And} {Column_RoomMaster} = {OldRoomMaster}";
|
return $"{Command_Update} {TableName} {Command_Set} {Column_RoomMaster} = {newRoomMaster} {Command_Where} {Column_RoomID} = '{roomid}' {Command_And} {Column_RoomMaster} = {oldRoomMaster}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Select_IsExistRoom(string RoomID)
|
public static string Select_IsExistRoom(string roomid)
|
||||||
{
|
{
|
||||||
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_RoomID} = '{RoomID}'";
|
return $"{Command_Select} {Command_All} {Command_From} {TableName} {Command_Where} {Column_RoomID} = '{roomid}'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
public static string Select_Users_Where(string Where)
|
public static string Select_Users_Where(string Where)
|
||||||
{
|
{
|
||||||
return $"{Select_Users} {Command_Where} {Where}'";
|
return $"{Select_Users} {Command_Where} {Where}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Select_CheckAutoKey(string Username, string AutoKey)
|
public static string Select_CheckAutoKey(string Username, string AutoKey)
|
||||||
|
@ -7,39 +7,41 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
public class RoomList : IEnumerable<Room>
|
public class RoomList : IEnumerable<Room>
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, Room> _List = [];
|
private readonly Dictionary<string, Room> _List = [];
|
||||||
private readonly Dictionary<string, List<User>> _PlayerList = [];
|
private readonly Dictionary<string, List<User>> _UserList = [];
|
||||||
private readonly Dictionary<string, List<User>> _ReadyPlayerList = [];
|
private readonly Dictionary<string, List<User>> _ReadyUserList = [];
|
||||||
|
|
||||||
public Room this[string roomid] => GetRoom(roomid);
|
public Room this[string roomid] => GetRoom(roomid);
|
||||||
|
|
||||||
public int Count => _List.Count;
|
public int Count => _List.Count;
|
||||||
|
|
||||||
public int GetPlayerCount(string roomid) => GetPlayerList(roomid).Count;
|
public int GetUserCount(string roomid) => this[roomid].UserAndIsReady.Count;
|
||||||
|
|
||||||
public int GetReadyPlayerCount(string roomid) => GetReadyPlayerList(roomid).Count;
|
public int GetReadyUserCount(string roomid) => GetReadyUserList(roomid).Count;
|
||||||
|
|
||||||
public List<Room> ListRoom => [.. _List.Values];
|
public List<Room> ListRoom => [.. _List.Values];
|
||||||
|
|
||||||
public List<string> ListRoomID => [.. _List.Keys];
|
public List<string> ListRoomID => [.. _List.Keys];
|
||||||
|
|
||||||
public List<User> GetPlayerList(string roomid) => _PlayerList.TryGetValue(roomid, out List<User>? user) ? user : [];
|
public User GetRoomMaster(string roomid) => this[roomid].RoomMaster;
|
||||||
|
|
||||||
public List<User> GetReadyPlayerList(string roomid) => _ReadyPlayerList.TryGetValue(roomid, out List<User>? user) ? user : [];
|
public List<User> GetUsers(string roomid) => [.. this[roomid].UserAndIsReady.Keys];
|
||||||
|
|
||||||
public List<User> GetNotReadyPlayerList(string roomid) => _PlayerList.TryGetValue(roomid, out List<User>? user) ? user.Except(GetReadyPlayerList(roomid)).Except([this[roomid].RoomMaster]).ToList() : [];
|
public List<User> GetReadyUserList(string roomid) => this[roomid].UserAndIsReady.Where(kv => kv.Value && kv.Key.Id != GetRoomMaster(roomid).Id).Select(kv => kv.Key).ToList();
|
||||||
|
|
||||||
|
public List<User> GetNotReadyUserList(string roomid) => this[roomid].UserAndIsReady.Where(kv => !kv.Value && kv.Key.Id != GetRoomMaster(roomid).Id).Select(kv => kv.Key).ToList();
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_List.Clear();
|
_List.Clear();
|
||||||
_PlayerList.Clear();
|
_UserList.Clear();
|
||||||
_ReadyPlayerList.Clear();
|
_ReadyUserList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRoom(Room room)
|
public void AddRoom(Room room)
|
||||||
{
|
{
|
||||||
_List.Add(room.Roomid, room);
|
_List.Add(room.Roomid, room);
|
||||||
_PlayerList.Add(room.Roomid, []);
|
_UserList.Add(room.Roomid, []);
|
||||||
_ReadyPlayerList.Add(room.Roomid, []);
|
_ReadyUserList.Add(room.Roomid, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRooms(List<Room> rooms)
|
public void AddRooms(List<Room> rooms)
|
||||||
@ -53,8 +55,8 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
public void RemoveRoom(string roomid)
|
public void RemoveRoom(string roomid)
|
||||||
{
|
{
|
||||||
_List.Remove(roomid);
|
_List.Remove(roomid);
|
||||||
_PlayerList.Remove(roomid);
|
_UserList.Remove(roomid);
|
||||||
_ReadyPlayerList.Remove(roomid);
|
_ReadyUserList.Remove(roomid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRoom(Room room) => RemoveRoom(room.Roomid);
|
public void RemoveRoom(Room room) => RemoveRoom(room.Roomid);
|
||||||
@ -63,7 +65,10 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
if (roomid != "-1" && user.Id != 0)
|
if (roomid != "-1" && user.Id != 0)
|
||||||
{
|
{
|
||||||
GetPlayerList(roomid).Add(user);
|
if (!this[roomid].UserAndIsReady.TryAdd(user, false))
|
||||||
|
{
|
||||||
|
this[roomid].UserAndIsReady[user] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,23 +76,23 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
if (roomid != "-1" && user.Id != 0)
|
if (roomid != "-1" && user.Id != 0)
|
||||||
{
|
{
|
||||||
GetPlayerList(roomid).Remove(user);
|
this[roomid].UserAndIsReady.Remove(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetReady(string roomid, User user)
|
public void SetReady(string roomid, User user)
|
||||||
{
|
{
|
||||||
if (roomid != "-1" && user.Id != 0)
|
if (roomid != "-1" && user.Id != 0 && this[roomid].UserAndIsReady.ContainsKey(user))
|
||||||
{
|
{
|
||||||
GetReadyPlayerList(roomid).Add(user);
|
this[roomid].UserAndIsReady[user] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CancelReady(string roomid, User user)
|
public void CancelReady(string roomid, User user)
|
||||||
{
|
{
|
||||||
if (roomid != "-1" && user.Id != 0)
|
if (roomid != "-1" && user.Id != 0 && this[roomid].UserAndIsReady.ContainsKey(user))
|
||||||
{
|
{
|
||||||
GetReadyPlayerList(roomid).Remove(user);
|
this[roomid].UserAndIsReady[user] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,15 +100,6 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
public bool IsExist(string roomid) => _List.ContainsKey(roomid);
|
public bool IsExist(string roomid) => _List.ContainsKey(roomid);
|
||||||
|
|
||||||
public User GetRoomMaster(string roomid)
|
|
||||||
{
|
|
||||||
foreach (Room room in ListRoom.Where(r => r.Roomid == roomid && r.RoomMaster != null))
|
|
||||||
{
|
|
||||||
return room.RoomMaster;
|
|
||||||
}
|
|
||||||
return General.UnknownUserInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetRoomMaster(string roomid, User user)
|
public void SetRoomMaster(string roomid, User user)
|
||||||
{
|
{
|
||||||
if (roomid != "-1" && user.Id != 0)
|
if (roomid != "-1" && user.Id != 0)
|
||||||
|
@ -10,17 +10,34 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
{
|
{
|
||||||
internal class HTTPManager
|
internal class HTTPManager
|
||||||
{
|
{
|
||||||
internal static HttpListener? ServerSocket => _ServerSocket;
|
/// <summary>
|
||||||
private static HttpListener? _ServerSocket = null;
|
/// 实际的 <see cref="System.Net.HttpListener"/> 监听实例 [ 单例 ]
|
||||||
|
/// </summary>
|
||||||
|
internal static HttpListener? HttpListener => _HttpListener;
|
||||||
|
private static HttpListener? _HttpListener = null;
|
||||||
|
|
||||||
internal static HttpListener StartListening(int port = 22227, bool ssl = false)
|
/// <summary>
|
||||||
|
/// 开始监听
|
||||||
|
/// 当 <paramref name="address"/> = "*" 时,需要管理员权限
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address"></param>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <param name="subUrl"></param>
|
||||||
|
/// <param name="ssl"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static HttpListener StartListening(string address = "*", int port = 22223, string subUrl = "ws", bool ssl = false)
|
||||||
{
|
{
|
||||||
HttpListener listener = new();
|
_HttpListener = new();
|
||||||
listener.Prefixes.Add((ssl ? "https://" : "http://") + "localhost:" + port + "/ws");
|
_HttpListener.Prefixes.Add((ssl ? "https://" : "http://") + address + ":" + port + "/" + subUrl.Trim('/') + "/");
|
||||||
listener.Start();
|
_HttpListener.Start();
|
||||||
return listener;
|
return _HttpListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端连接远程 WebSocket 服务器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uri"></param>
|
||||||
|
/// <returns></returns>
|
||||||
internal static async Task<System.Net.WebSockets.ClientWebSocket?> Connect(Uri uri)
|
internal static async Task<System.Net.WebSockets.ClientWebSocket?> Connect(Uri uri)
|
||||||
{
|
{
|
||||||
System.Net.WebSockets.ClientWebSocket socket = new();
|
System.Net.WebSockets.ClientWebSocket socket = new();
|
||||||
@ -32,6 +49,12 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端向服务器发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socket"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <returns></returns>
|
||||||
internal static async Task<SocketResult> Send(System.Net.WebSockets.ClientWebSocket socket, SocketObject obj)
|
internal static async Task<SocketResult> Send(System.Net.WebSockets.ClientWebSocket socket, SocketObject obj)
|
||||||
{
|
{
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
@ -50,6 +73,12 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
return SocketResult.NotSent;
|
return SocketResult.NotSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器向客户端发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socket"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <returns></returns>
|
||||||
internal static async Task<SocketResult> Send(WebSocket socket, SocketObject obj)
|
internal static async Task<SocketResult> Send(WebSocket socket, SocketObject obj)
|
||||||
{
|
{
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
@ -68,18 +97,22 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
return SocketResult.NotSent;
|
return SocketResult.NotSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task Receiving(HTTPListener listener)
|
/// <summary>
|
||||||
{
|
/// 服务器接受一个 HTTP 的 WebSocket 升级请求
|
||||||
if (ServerSocket != null)
|
/// </summary>
|
||||||
|
/// <returns>[0]客户端IP地址;[1]客户端的WebSocket实例</returns>
|
||||||
|
internal static async Task<object[]> Accept()
|
||||||
{
|
{
|
||||||
|
if (HttpListener is null) return [];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (true)
|
HttpListenerContext context = await HttpListener.GetContextAsync();
|
||||||
{
|
|
||||||
HttpListenerContext context = await ServerSocket.GetContextAsync();
|
|
||||||
if (context.Request.IsWebSocketRequest)
|
if (context.Request.IsWebSocketRequest)
|
||||||
{
|
{
|
||||||
TaskUtility.NewTask(async () => await AddClientWebSocket(listener, context));
|
HttpListenerWebSocketContext socketContext = await context.AcceptWebSocketAsync(null);
|
||||||
|
WebSocket socket = socketContext.WebSocket;
|
||||||
|
string ip = context.Request.RemoteEndPoint.ToString();
|
||||||
|
return [ip, socket];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -87,26 +120,72 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
context.Response.Close();
|
context.Response.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
_ServerSocket = null;
|
HttpListener?.Close();
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器接收客户端消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socket"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static async Task<SocketObject[]> Receive(WebSocket socket)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<SocketObject> objs = [];
|
||||||
|
if (socket != null)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[General.SocketByteSize];
|
||||||
|
WebSocketReceiveResult result;
|
||||||
|
StringBuilder builder = new();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||||
|
builder.Append(General.DefaultEncoding.GetString(buffer, 0, result.Count).Replace("\0", "").Trim());
|
||||||
|
}
|
||||||
|
while (!result.EndOfMessage);
|
||||||
|
|
||||||
|
string msg = builder.ToString();
|
||||||
|
|
||||||
|
if (JsonManager.IsCompleteJson<SocketObject>(msg))
|
||||||
|
{
|
||||||
|
foreach (SocketObject obj in JsonManager.GetObjects<SocketObject>(msg))
|
||||||
|
{
|
||||||
|
objs.Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [.. objs];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端接收服务器消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <returns></returns>
|
||||||
internal static async Task<bool> ReceiveMessage(HTTPClient client)
|
internal static async Task<bool> ReceiveMessage(HTTPClient client)
|
||||||
{
|
{
|
||||||
if (client.Instance is null) return false;
|
if (client.Instance is null) return false;
|
||||||
|
|
||||||
byte[] buffer = new byte[General.SocketByteSize];
|
byte[] buffer = new byte[General.SocketByteSize];
|
||||||
WebSocketReceiveResult result = await client.Instance.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
WebSocketReceiveResult result = await client.Instance.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||||
string msg = Encoding.UTF8.GetString(buffer).Replace("\0", "").Trim();
|
string msg = General.DefaultEncoding.GetString(buffer).Replace("\0", "").Trim();
|
||||||
SocketObject[] objs = await GetSocketObjects(client.Instance, result, msg);
|
SocketObject[] objs = await GetSocketObjects(client.Instance, result, msg);
|
||||||
|
|
||||||
foreach (SocketObject obj in objs)
|
foreach (SocketObject obj in objs)
|
||||||
{
|
{
|
||||||
SocketObject sendobject = client.SocketObject_Handler(obj);
|
SocketManager.OnSocketReceive(obj);
|
||||||
if (obj.SocketType == SocketMessageType.Connect)
|
if (obj.SocketType == SocketMessageType.Connect)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -116,81 +195,18 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
await client.Instance.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, result.CloseStatusDescription, CancellationToken.None);
|
await client.Instance.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, result.CloseStatusDescription, CancellationToken.None);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
await Send(client.Instance, sendobject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task AddClientWebSocket(HTTPListener listener, HttpListenerContext context)
|
/// <summary>
|
||||||
{
|
/// 将收到的消息反序列为 <see cref="SocketObject"/>
|
||||||
HttpListenerWebSocketContext socketContext = await context.AcceptWebSocketAsync(null);
|
/// </summary>
|
||||||
WebSocket socket = socketContext.WebSocket;
|
/// <param name="socket"></param>
|
||||||
|
/// <param name="result"></param>
|
||||||
byte[] buffer = new byte[General.SocketByteSize];
|
/// <param name="msg"></param>
|
||||||
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
/// <returns></returns>
|
||||||
string msg = Encoding.UTF8.GetString(buffer).Replace("\0", "").Trim();
|
|
||||||
|
|
||||||
SocketObject sendobject = new(SocketMessageType.Unknown, Guid.Empty);
|
|
||||||
SocketObject[] objs = await GetSocketObjects(socket, result, msg);
|
|
||||||
bool isConnect = false;
|
|
||||||
|
|
||||||
foreach (SocketObject obj in objs)
|
|
||||||
{
|
|
||||||
if (obj.SocketType == SocketMessageType.Connect)
|
|
||||||
{
|
|
||||||
isConnect = listener.CheckClientConnection(obj);
|
|
||||||
}
|
|
||||||
else if (listener.ClientSockets.ContainsKey(obj.Token))
|
|
||||||
{
|
|
||||||
sendobject = listener.SocketObject_Handler(obj);
|
|
||||||
isConnect = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isConnect)
|
|
||||||
{
|
|
||||||
Guid token = Guid.NewGuid();
|
|
||||||
listener.ClientSockets.TryAdd(token, socket);
|
|
||||||
await Send(socket, sendobject);
|
|
||||||
|
|
||||||
while (socket.State == WebSocketState.Open)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
buffer = new byte[General.SocketByteSize];
|
|
||||||
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|
||||||
|
|
||||||
if (result.CloseStatus.HasValue)
|
|
||||||
{
|
|
||||||
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = Encoding.UTF8.GetString(buffer).Replace("\0", "").Trim();
|
|
||||||
objs = await GetSocketObjects(socket, result, msg);
|
|
||||||
foreach (SocketObject obj in objs)
|
|
||||||
{
|
|
||||||
sendobject = listener.SocketObject_Handler(obj);
|
|
||||||
if (obj.SocketType == SocketMessageType.Disconnect)
|
|
||||||
{
|
|
||||||
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Disconnect received", CancellationToken.None);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await Send(socket, sendobject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// 处理其他异常
|
|
||||||
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
|
||||||
await socket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Server Error", CancellationToken.None);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<SocketObject[]> GetSocketObjects(WebSocket socket, WebSocketReceiveResult result, string msg)
|
private static async Task<SocketObject[]> GetSocketObjects(WebSocket socket, WebSocketReceiveResult result, string msg)
|
||||||
{
|
{
|
||||||
List<SocketObject> objs = [];
|
List<SocketObject> objs = [];
|
||||||
|
@ -67,10 +67,10 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
MailMessage Msg = new()
|
MailMessage Msg = new()
|
||||||
{
|
{
|
||||||
Subject = Mail.Subject,
|
Subject = Mail.Subject,
|
||||||
SubjectEncoding = System.Text.Encoding.UTF8,
|
SubjectEncoding = General.DefaultEncoding,
|
||||||
Body = Mail.Body,
|
Body = Mail.Body,
|
||||||
BodyEncoding = System.Text.Encoding.UTF8,
|
BodyEncoding = General.DefaultEncoding,
|
||||||
From = new MailAddress(Mail.Sender, Mail.SenderName, System.Text.Encoding.UTF8),
|
From = new MailAddress(Mail.Sender, Mail.SenderName, General.DefaultEncoding),
|
||||||
IsBodyHtml = Mail.HTML,
|
IsBodyHtml = Mail.HTML,
|
||||||
Priority = Mail.Priority
|
Priority = Mail.Priority
|
||||||
};
|
};
|
||||||
|
@ -30,18 +30,18 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建服务器监听Socket
|
/// 创建服务器监听Socket
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Port">监听端口号</param>
|
/// <param name="port">监听端口号</param>
|
||||||
/// <param name="MaxConnection">最大连接数量</param>
|
/// <param name="maxConnection">最大连接数量</param>
|
||||||
/// <returns>服务器端专用Socket</returns>
|
/// <returns>服务器端专用Socket</returns>
|
||||||
internal static Socket? StartListening(int Port = 22222, int MaxConnection = 0)
|
internal static Socket? StartListening(int port = 22222, int maxConnection = 0)
|
||||||
{
|
{
|
||||||
if (MaxConnection <= 0) MaxConnection = SocketSet.MaxConnection_2C2G;
|
if (maxConnection <= 0) maxConnection = SocketSet.MaxConnection_2C2G;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_ServerSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
_ServerSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
IPEndPoint ServerEndPoint = new(IPAddress.Any, Port);
|
IPEndPoint ServerEndPoint = new(IPAddress.Any, port);
|
||||||
_ServerSocket.Bind(ServerEndPoint);
|
_ServerSocket.Bind(ServerEndPoint);
|
||||||
_ServerSocket.Listen(MaxConnection);
|
_ServerSocket.Listen(maxConnection);
|
||||||
_ServerSocket.NoDelay = true;
|
_ServerSocket.NoDelay = true;
|
||||||
return _ServerSocket;
|
return _ServerSocket;
|
||||||
}
|
}
|
||||||
@ -65,8 +65,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
{
|
{
|
||||||
Client = ServerSocket.Accept();
|
Client = ServerSocket.Accept();
|
||||||
Client.NoDelay = true;
|
Client.NoDelay = true;
|
||||||
IPEndPoint? ClientIPEndPoint = (IPEndPoint?)Client.RemoteEndPoint;
|
ClientIP = Client.RemoteEndPoint?.ToString() ?? "Unknown";
|
||||||
ClientIP = (ClientIPEndPoint != null) ? ClientIPEndPoint.ToString() : "Unknown";
|
|
||||||
return [ClientIP, Client];
|
return [ClientIP, Client];
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -79,17 +78,17 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建客户端Socket
|
/// 创建客户端Socket
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Address">服务器IP地址</param>
|
/// <param name="address">服务器IP地址</param>
|
||||||
/// <param name="Port">服务器监听端口</param>
|
/// <param name="port">服务器监听端口</param>
|
||||||
/// <returns>客户端专用Socket</returns>
|
/// <returns>客户端专用Socket</returns>
|
||||||
internal static Socket? Connect(string Address, int Port = 22222)
|
internal static Socket? Connect(string address, int port = 22222)
|
||||||
{
|
{
|
||||||
Socket? ClientSocket;
|
Socket? ClientSocket;
|
||||||
EndPoint ServerEndPoint;
|
EndPoint ServerEndPoint;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string IP = Api.Utility.NetworkUtility.GetIPAddress(Address);
|
string IP = NetworkUtility.GetIPAddress(address);
|
||||||
ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
|
ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
|
||||||
if (ServerEndPoint != null)
|
if (ServerEndPoint != null)
|
||||||
{
|
{
|
||||||
ClientSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
ClientSocket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
@ -131,14 +130,14 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于服务器端向客户端Socket发送信息
|
/// 用于服务器端向客户端Socket发送信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ClientSocket">客户端Socket</param>
|
/// <param name="clientSocket">客户端Socket</param>
|
||||||
/// <param name="SocketObject">Socket信息容器</param>
|
/// <param name="obj">Socket信息容器</param>
|
||||||
/// <returns>通信结果</returns>
|
/// <returns>通信结果</returns>
|
||||||
internal static SocketResult Send(Socket ClientSocket, Library.Common.Network.SocketObject SocketObject)
|
internal static SocketResult Send(Socket clientSocket, Library.Common.Network.SocketObject obj)
|
||||||
{
|
{
|
||||||
if (ClientSocket != null)
|
if (clientSocket != null)
|
||||||
{
|
{
|
||||||
if (ClientSocket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0)
|
if (clientSocket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0)
|
||||||
{
|
{
|
||||||
return SocketResult.Success;
|
return SocketResult.Success;
|
||||||
}
|
}
|
||||||
@ -150,14 +149,14 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于服务器端向客户端Socket发送信息 [ 异步版 ]
|
/// 用于服务器端向客户端Socket发送信息 [ 异步版 ]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ClientSocket">客户端Socket</param>
|
/// <param name="clientSocket">客户端Socket</param>
|
||||||
/// <param name="SocketObject">Socket信息容器</param>
|
/// <param name="obj">Socket信息容器</param>
|
||||||
/// <returns>通信结果</returns>
|
/// <returns>通信结果</returns>
|
||||||
internal static async Task<SocketResult> SendAsync(Socket ClientSocket, Library.Common.Network.SocketObject SocketObject)
|
internal static async Task<SocketResult> SendAsync(Socket clientSocket, Library.Common.Network.SocketObject obj)
|
||||||
{
|
{
|
||||||
if (ClientSocket != null)
|
if (clientSocket != null)
|
||||||
{
|
{
|
||||||
if (await ClientSocket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0)
|
if (await clientSocket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0)
|
||||||
{
|
{
|
||||||
return SocketResult.Success;
|
return SocketResult.Success;
|
||||||
}
|
}
|
||||||
@ -169,13 +168,13 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于客户端向服务器Socket发送信息
|
/// 用于客户端向服务器Socket发送信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="SocketObject">Socket信息容器</param>
|
/// <param name="obj">Socket信息容器</param>
|
||||||
/// <returns>通信结果</returns>
|
/// <returns>通信结果</returns>
|
||||||
internal static SocketResult Send(Library.Common.Network.SocketObject SocketObject)
|
internal static SocketResult Send(Library.Common.Network.SocketObject obj)
|
||||||
{
|
{
|
||||||
if (Socket != null)
|
if (Socket != null)
|
||||||
{
|
{
|
||||||
if (Socket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0)
|
if (Socket.Send(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0)
|
||||||
{
|
{
|
||||||
return SocketResult.Success;
|
return SocketResult.Success;
|
||||||
}
|
}
|
||||||
@ -187,13 +186,13 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于客户端向服务器Socket发送信息 [ 异步版 ]
|
/// 用于客户端向服务器Socket发送信息 [ 异步版 ]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="SocketObject">Socket信息容器</param>
|
/// <param name="obj">Socket信息容器</param>
|
||||||
/// <returns>通信结果</returns>
|
/// <returns>通信结果</returns>
|
||||||
internal static async Task<SocketResult> SendAsync(Library.Common.Network.SocketObject SocketObject)
|
internal static async Task<SocketResult> SendAsync(Library.Common.Network.SocketObject obj)
|
||||||
{
|
{
|
||||||
if (Socket != null)
|
if (Socket != null)
|
||||||
{
|
{
|
||||||
if (await Socket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0)
|
if (await Socket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(obj))) > 0)
|
||||||
{
|
{
|
||||||
return SocketResult.Success;
|
return SocketResult.Success;
|
||||||
}
|
}
|
||||||
@ -204,16 +203,16 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 接收数据流中的信息
|
/// 接收数据流中的信息
|
||||||
/// <para/>如果是服务器接收信息需要传入客户端Socket <paramref name="ClientSocket"/>
|
/// <para/>如果是服务器接收信息需要传入客户端Socket <paramref name="clientSocket"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ClientSocket">如果是服务器接收信息需要传入客户端Socket</param>
|
/// <param name="clientSocket">如果是服务器接收信息需要传入客户端Socket</param>
|
||||||
/// <returns>SocketObjects</returns>
|
/// <returns>SocketObjects</returns>
|
||||||
internal static Library.Common.Network.SocketObject[] Receive(Socket? ClientSocket = null)
|
internal static Library.Common.Network.SocketObject[] Receive(Socket? clientSocket = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Library.Common.Network.SocketObject> result = [];
|
List<Library.Common.Network.SocketObject> result = [];
|
||||||
Socket? tempSocket = ClientSocket is null ? Socket : ClientSocket;
|
Socket? tempSocket = clientSocket is null ? Socket : clientSocket;
|
||||||
if (tempSocket != null)
|
if (tempSocket != null)
|
||||||
{
|
{
|
||||||
// 从服务器接收消息
|
// 从服务器接收消息
|
||||||
@ -229,7 +228,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
{
|
{
|
||||||
result.Add(obj);
|
result.Add(obj);
|
||||||
// 客户端接收消息,广播ScoketObject到每个UIModel
|
// 客户端接收消息,广播ScoketObject到每个UIModel
|
||||||
if (ClientSocket is null) OnSocketReceive(obj);
|
if (clientSocket is null) OnSocketReceive(obj);
|
||||||
}
|
}
|
||||||
return [.. result];
|
return [.. result];
|
||||||
}
|
}
|
||||||
@ -256,7 +255,73 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
{
|
{
|
||||||
result.Add(obj);
|
result.Add(obj);
|
||||||
// 客户端接收消息,广播ScoketObject到每个UIModel
|
// 客户端接收消息,广播ScoketObject到每个UIModel
|
||||||
if (ClientSocket is null) OnSocketReceive(obj);
|
if (clientSocket is null) OnSocketReceive(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [.. result];
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接收数据流中的信息 [ 异步版 ]
|
||||||
|
/// <para/>如果是服务器接收信息需要传入客户端Socket <paramref name="clientSocket"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="clientSocket">如果是服务器接收信息需要传入客户端Socket</param>
|
||||||
|
/// <returns>SocketObjects</returns>
|
||||||
|
internal static async Task<Library.Common.Network.SocketObject[]> ReceiveAsync(Socket? clientSocket = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<Library.Common.Network.SocketObject> result = [];
|
||||||
|
Socket? tempSocket = clientSocket is null ? Socket : clientSocket;
|
||||||
|
if (tempSocket != null)
|
||||||
|
{
|
||||||
|
// 从服务器接收消息
|
||||||
|
byte[] buffer = new byte[General.SocketByteSize];
|
||||||
|
int length = await tempSocket.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None);
|
||||||
|
string msg = "";
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
msg = General.DefaultEncoding.GetString(buffer, 0, length);
|
||||||
|
if (JsonManager.IsCompleteJson<Library.Common.Network.SocketObject>(msg))
|
||||||
|
{
|
||||||
|
foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects<Library.Common.Network.SocketObject>(msg))
|
||||||
|
{
|
||||||
|
result.Add(obj);
|
||||||
|
// 客户端接收消息,广播ScoketObject到每个UIModel
|
||||||
|
if (clientSocket is null) OnSocketReceive(obj);
|
||||||
|
}
|
||||||
|
return [.. result];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread.Sleep(20);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (tempSocket.Available > 0)
|
||||||
|
{
|
||||||
|
length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None);
|
||||||
|
msg += General.DefaultEncoding.GetString(buffer, 0, length);
|
||||||
|
if (JsonManager.IsCompleteJson<Library.Common.Network.SocketObject>(msg))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.Sleep(20);
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects<Library.Common.Network.SocketObject>(msg))
|
||||||
|
{
|
||||||
|
result.Add(obj);
|
||||||
|
// 客户端接收消息,广播ScoketObject到每个UIModel
|
||||||
|
if (clientSocket is null) OnSocketReceive(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [.. result];
|
return [.. result];
|
||||||
@ -275,8 +340,8 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 监听事件的委托
|
/// 监听事件的委托
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="SocketObject">SocketObject</param>
|
/// <param name="obj">SocketObject</param>
|
||||||
internal delegate void SocketReceiveHandler(Library.Common.Network.SocketObject SocketObject);
|
internal delegate void SocketReceiveHandler(Library.Common.Network.SocketObject obj);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 监听事件
|
/// 监听事件
|
||||||
@ -286,10 +351,10 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 触发异步监听事件
|
/// 触发异步监听事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="SocketObject">SocketObject</param>
|
/// <param name="obj">SocketObject</param>
|
||||||
internal static void OnSocketReceive(Library.Common.Network.SocketObject SocketObject)
|
internal static void OnSocketReceive(Library.Common.Network.SocketObject obj)
|
||||||
{
|
{
|
||||||
SocketReceive?.Invoke(SocketObject);
|
SocketReceive?.Invoke(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -34,9 +34,9 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
private bool _IsCompleted = false;
|
private bool _IsCompleted = false;
|
||||||
private Exception _Exception = new();
|
private Exception _Exception = new();
|
||||||
|
|
||||||
internal TaskAwaiter(Action action) => _ = Worker(action);
|
internal TaskAwaiter(Action action) => Worker(action);
|
||||||
|
|
||||||
internal TaskAwaiter(Func<Task> function) => _ = Worker(function);
|
internal TaskAwaiter(Func<Task> function) => Worker(function);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回ITaskAwaiter可以进一步调用方法<para/>
|
/// 返回ITaskAwaiter可以进一步调用方法<para/>
|
||||||
@ -63,7 +63,9 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Worker(Action action)
|
private void Worker(Action action)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -76,9 +78,12 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
_Exception = e;
|
_Exception = e;
|
||||||
Error?.Invoke(e);
|
Error?.Invoke(e);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Worker(Func<Task> function)
|
private void Worker(Func<Task> function)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -91,6 +96,7 @@ namespace Milimoe.FunGame.Core.Service
|
|||||||
_Exception = e;
|
_Exception = e;
|
||||||
Error?.Invoke(e);
|
Error?.Invoke(e);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user