diff --git a/Api/Transmittal/DataRequest.cs b/Api/Transmittal/DataRequest.cs
index 1377317..90b1a5b 100644
--- a/Api/Transmittal/DataRequest.cs
+++ b/Api/Transmittal/DataRequest.cs
@@ -1,5 +1,4 @@
-using System.Collections;
-using Milimoe.FunGame.Core.Controller;
+using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Library.Common.Network;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.Exception;
@@ -37,7 +36,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
}
set
{
- AddRequestData(key, value);
+ if (value != null) AddRequestData(key, value);
}
}
@@ -114,17 +113,15 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
///
///
///
- public void AddRequestData(string key, object? value)
+ public void AddRequestData(string key, object value)
{
if (Worker != null)
{
- if (Worker.RequestData.ContainsKey(key)) Worker.RequestData[key] = value;
- else Worker.RequestData.Add(key, value);
+ if (!Worker.RequestData.TryAdd(key, value)) Worker.RequestData[key] = value;
}
else if (GamingWorker != null)
{
- if (GamingWorker.RequestData.ContainsKey(key)) GamingWorker.RequestData[key] = value;
- else GamingWorker.RequestData.Add(key, value);
+ if (!GamingWorker.RequestData.TryAdd(key, value)) GamingWorker.RequestData[key] = value;
}
}
@@ -142,7 +139,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// 警告: 调用此方法将抛出异常。请调用并等待
///
///
- ///
+ ///
public RequestResult SendRequest()
{
Worker?.SendRequest();
@@ -177,11 +174,11 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
{
if (Worker != null)
{
- return GetHashtableJsonObject(Worker.ResultData, key);
+ return GetDictionaryJsonObject(Worker.ResultData, key);
}
else if (GamingWorker != null)
{
- return GetHashtableJsonObject(GamingWorker.ResultData, key);
+ return GetDictionaryJsonObject(GamingWorker.ResultData, key);
}
return default;
}
@@ -191,8 +188,8 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
///
private class SocketRequest : SocketHandlerController
{
- public Hashtable RequestData { get; } = [];
- public Hashtable ResultData => _ResultData;
+ public Dictionary RequestData { get; } = [];
+ public Dictionary ResultData => _ResultData;
public RequestResult Result => _Result;
public string Error => _Error;
@@ -202,7 +199,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
private readonly Guid RequestID = Guid.Empty;
private readonly bool IsLongRunning = false;
private readonly SocketRuntimeType RuntimeType = SocketRuntimeType.Client;
- private Hashtable _ResultData = [];
+ private Dictionary _ResultData = [];
private RequestResult _Result = RequestResult.Missing;
private string _Error = "";
@@ -229,7 +226,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
try
{
SetWorking();
- if (RuntimeType == SocketRuntimeType.Addon || RuntimeType == SocketRuntimeType.Addon)
+ if (RuntimeType == SocketRuntimeType.Addon)
{
if (RequestData.ContainsKey(SocketSet.Plugins_Mark)) RequestData[SocketSet.Plugins_Mark] = "true";
else RequestData.Add(SocketSet.Plugins_Mark, true);
@@ -241,7 +238,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
}
else if (WebSocket != null)
{
- throw new AsyncRequestException();
+ throw new AsyncSendException();
}
else throw new ConnectFailedException();
}
@@ -258,7 +255,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
try
{
SetWorking();
- if (RuntimeType == SocketRuntimeType.Addon || RuntimeType == SocketRuntimeType.Addon)
+ if (RuntimeType == SocketRuntimeType.Addon)
{
if (RequestData.ContainsKey(SocketSet.Plugins_Mark)) RequestData[SocketSet.Plugins_Mark] = "true";
else RequestData.Add(SocketSet.Plugins_Mark, true);
@@ -295,7 +292,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
if (!IsLongRunning) Dispose();
Work = SocketObject;
Working = false;
- _ResultData = SocketObject.GetParam(2) ?? [];
+ _ResultData = SocketObject.GetParam>(2) ?? [];
_Result = RequestResult.Success;
}
}
@@ -314,8 +311,8 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
///
private class GamingRequest : SocketHandlerController
{
- public Hashtable RequestData { get; } = [];
- public Hashtable ResultData => _ResultData;
+ public Dictionary RequestData { get; } = [];
+ public Dictionary ResultData => _ResultData;
public RequestResult Result => _Result;
public string Error => _Error;
@@ -325,7 +322,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
private readonly Guid RequestID = Guid.Empty;
private readonly bool IsLongRunning = false;
private readonly SocketRuntimeType RuntimeType = SocketRuntimeType.Client;
- private Hashtable _ResultData = [];
+ private Dictionary _ResultData = [];
private RequestResult _Result = RequestResult.Missing;
private string _Error = "";
@@ -352,19 +349,19 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
try
{
SetWorking();
- if (RuntimeType == SocketRuntimeType.Addon || RuntimeType == SocketRuntimeType.Addon)
+ if (RuntimeType == SocketRuntimeType.Addon)
{
if (RequestData.ContainsKey(SocketSet.Plugins_Mark)) RequestData[SocketSet.Plugins_Mark] = "true";
else RequestData.Add(SocketSet.Plugins_Mark, true);
}
else RequestData.Remove(SocketSet.Plugins_Mark);
- if (Socket != null && Socket.Send(SocketMessageType.DataRequest, GamingType, RequestID, RequestData) == SocketResult.Success)
+ if (Socket != null && Socket.Send(SocketMessageType.GamingRequest, GamingType, RequestID, RequestData) == SocketResult.Success)
{
WaitForWorkDone();
}
else if (WebSocket != null)
{
- throw new AsyncRequestException();
+ throw new AsyncSendException();
}
else throw new ConnectFailedException();
}
@@ -381,17 +378,17 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
try
{
SetWorking();
- if (RuntimeType == SocketRuntimeType.Addon || RuntimeType == SocketRuntimeType.Addon)
+ if (RuntimeType == SocketRuntimeType.Addon)
{
if (RequestData.ContainsKey(SocketSet.Plugins_Mark)) RequestData[SocketSet.Plugins_Mark] = "true";
else RequestData.Add(SocketSet.Plugins_Mark, true);
}
else RequestData.Remove(SocketSet.Plugins_Mark);
- if (Socket != null && Socket.Send(SocketMessageType.DataRequest, GamingType, RequestID, RequestData) == SocketResult.Success)
+ if (Socket != null && Socket.Send(SocketMessageType.GamingRequest, GamingType, RequestID, RequestData) == SocketResult.Success)
{
await WaitForWorkDoneAsync();
}
- else if (WebSocket != null && await WebSocket.Send(SocketMessageType.DataRequest, GamingType, RequestID, RequestData) == SocketResult.Success)
+ else if (WebSocket != null && await WebSocket.Send(SocketMessageType.GamingRequest, GamingType, RequestID, RequestData) == SocketResult.Success)
{
await WaitForWorkDoneAsync();
}
@@ -409,7 +406,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
{
try
{
- if (SocketObject.SocketType == SocketMessageType.DataRequest)
+ if (SocketObject.SocketType == SocketMessageType.GamingRequest)
{
GamingType type = SocketObject.GetParam(0);
Guid id = SocketObject.GetParam(1);
@@ -418,7 +415,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
if (!IsLongRunning) Dispose();
Work = SocketObject;
Working = false;
- _ResultData = SocketObject.GetParam(2) ?? [];
+ _ResultData = SocketObject.GetParam>(2) ?? [];
_Result = RequestResult.Success;
}
}
@@ -433,15 +430,15 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
}
///
- /// 反序列化Hashtable中的Json对象
+ /// 反序列化Dictionary中的Json对象
///
///
- ///
+ ///
///
///
- public static T? GetHashtableJsonObject(Hashtable hashtable, string key)
+ public static T? GetDictionaryJsonObject(Dictionary dict, string key)
{
- return Service.JsonManager.GetObject(hashtable, key);
+ return Service.JsonManager.GetObject(dict, key);
}
}
}
diff --git a/Api/Transmittal/SQLHelper.cs b/Api/Transmittal/SQLHelper.cs
index 5c69dc0..3aa15ec 100644
--- a/Api/Transmittal/SQLHelper.cs
+++ b/Api/Transmittal/SQLHelper.cs
@@ -11,6 +11,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
public abstract class SQLHelper : ISQLHelper
{
public abstract FunGameInfo.FunGame FunGameType { get; }
+ public abstract SQLMode Mode { get; }
public abstract string Script { get; set; }
public abstract CommandType CommandType { get; set; }
public abstract SQLResult Result { get; }
diff --git a/Api/Utility/ActionQueue.cs b/Api/Utility/ActionQueue.cs
index d892b7c..5d56639 100644
--- a/Api/Utility/ActionQueue.cs
+++ b/Api/Utility/ActionQueue.cs
@@ -17,7 +17,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// 当前的行动顺序
///
public List Queue => _queue;
-
+
///
/// 当前已死亡的角色顺序(第一个是最早死的)
///
@@ -342,7 +342,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
// 技能列表
List skills = [.. character.Skills.Where(s => s.Level > 0 && s.SkillType != SkillType.Passive && s.Enable && !s.IsInEffect && s.CurrentCD == 0 &&
(((s.SkillType == SkillType.SuperSkill || s.SkillType == SkillType.Skill) && s.RealEPCost <= character.EP) || (s.SkillType == SkillType.Magic && s.RealMPCost <= character.MP)))];
-
+
// 物品列表
List- items = [.. character.Items.Where(i => i.IsActive && i.Skills.Active != null && i.Enable && i.IsInGameItem &&
i.Skills.Active.SkillType == SkillType.Item && i.Skills.Active.Enable && !i.Skills.Active.IsInEffect && i.Skills.Active.CurrentCD == 0 && i.Skills.Active.RealMPCost <= character.MP && i.Skills.Active.RealEPCost <= character.EP)];
@@ -1260,7 +1260,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
{
return CharacterActionType.PreCastSkill;
}
-
+
if (rand < pUseItem + pCastSkill + pNormalAttack)
{
return CharacterActionType.NormalAttack;
diff --git a/Api/Utility/GameModuleLoader.cs b/Api/Utility/GameModuleLoader.cs
index 323a928..a64c030 100644
--- a/Api/Utility/GameModuleLoader.cs
+++ b/Api/Utility/GameModuleLoader.cs
@@ -15,7 +15,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
///
/// 适用于服务器的模组集
///
- public Dictionary ServerModules { get; } = [];
+ public Dictionary ModuleServers { get; } = [];
///
/// 游戏地图集
@@ -37,11 +37,6 @@ namespace Milimoe.FunGame.Core.Api.Utility
///
public Dictionary Items { get; } = [];
- ///
- /// 客户端模组与服务器模组的关联字典
- ///
- public Dictionary AssociatedServers { get; } = [];
-
///
/// 已加载的模组DLL名称对应的路径
///
@@ -52,7 +47,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
///
/// 传入 类型来创建指定端的模组读取器
/// runtime = 时,仅读取
- /// runtime = 时,都会读取,并且生成关联字典
+ /// runtime = 时,仅读取
/// 都会读取
///
/// 传入 类型来创建指定端的模组读取器
@@ -66,20 +61,23 @@ namespace Milimoe.FunGame.Core.Api.Utility
{
AddonManager.LoadGameModules(loader.Modules, loader.Characters, loader.Skills, loader.Items, delegates, otherobjs);
AddonManager.LoadGameMaps(loader.Maps, otherobjs);
+ foreach (GameModule module in loader.Modules.Values)
+ {
+ // 读取模组的依赖集合
+ module.GameModuleDepend.GetDependencies(loader);
+ // 如果模组加载后需要执行代码,请重写AfterLoad方法
+ module.AfterLoad(runtime, loader);
+ }
}
else if (runtime == FunGameInfo.FunGame.FunGame_Server)
{
- AddonManager.LoadGameModulesForServer(loader.Modules, loader.ServerModules, loader.Characters, loader.Skills, loader.Items, delegates, otherobjs);
- foreach (GameModule module in loader.Modules.Values)
- {
- // AssociatedServerModuleName 已经存包含 IsConnectToOtherServerModule 的判断,因此无需重复判断
- if (loader.ServerModules.TryGetValue(module.AssociatedServerModuleName, out GameModuleServer? server) && server != null)
- {
- loader.AssociatedServers.Add(module, server);
- }
- else loader.AssociatedServers.Add(module, null); // 服务器获取GameModuleServer时需要判断是否存在模组。
- }
+ AddonManager.LoadGameModulesForServer(loader.ModuleServers, loader.Characters, loader.Skills, loader.Items, delegates, otherobjs);
AddonManager.LoadGameMaps(loader.Maps, otherobjs);
+ foreach (GameModuleServer server in loader.ModuleServers.Values)
+ {
+ server.GameModuleDepend.GetDependencies(loader);
+ server.AfterLoad(loader);
+ }
}
return loader;
}
@@ -109,7 +107,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
///
public GameModuleServer GetServerMode(string name)
{
- return ServerModules[name];
+ return ModuleServers[name];
}
///
diff --git a/Api/Utility/General.cs b/Api/Utility/General.cs
index 058971a..935d3c1 100644
--- a/Api/Utility/General.cs
+++ b/Api/Utility/General.cs
@@ -217,6 +217,15 @@ namespace Milimoe.FunGame.Core.Api.Utility
///
public static T? JsonDeserializeFromHashtable(Hashtable hashtable, string key) => Service.JsonManager.GetObject(hashtable, key);
+ ///
+ /// 反序列化Dictionary中的Json对象
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static T? JsonDeserializeFromDictionary(Dictionary dict, string key) => Service.JsonManager.GetObject(dict, key);
+
///
/// 反序列化IEnumerable中的Json对象
///
diff --git a/Api/Utility/JsonTool.cs b/Api/Utility/JsonTool.cs
index d0059d7..e3f2479 100644
--- a/Api/Utility/JsonTool.cs
+++ b/Api/Utility/JsonTool.cs
@@ -75,6 +75,15 @@ namespace Milimoe.FunGame.Core.Api.Utility
///
public T? GetObject(Hashtable table, string key) => JsonManager.GetObject(table, key, options);
+ ///
+ /// 反序列化Dictionary中Key对应的Json对象
+ ///
+ ///
+ ///
+ ///
+ ///
+ public T? GetObject(Dictionary dict, string key) => JsonManager.GetObject(dict, key, options);
+
///
/// 反序列化IEnumerable中的Json对象 可指定反序列化选项
///
@@ -100,7 +109,8 @@ namespace Milimoe.FunGame.Core.Api.Utility
{
WriteIndented = true,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
- Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter() }
+ Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(),
+ new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter() }
};
}
}
diff --git a/Api/Utility/TextReader.cs b/Api/Utility/TextReader.cs
index 21832f5..e7d8f88 100644
--- a/Api/Utility/TextReader.cs
+++ b/Api/Utility/TextReader.cs
@@ -105,11 +105,17 @@ namespace Milimoe.FunGame.Core.Api.Utility
/**
* MySQL
*/
+ WriteINI("MySQL", "UseMySQL", "false");
WriteINI("MySQL", "DBServer", "localhost");
WriteINI("MySQL", "DBPort", "3306");
WriteINI("MySQL", "DBName", "fungame");
WriteINI("MySQL", "DBUser", "root");
WriteINI("MySQL", "DBPassword", "pass");
+ /**
+ * SQLite
+ */
+ WriteINI("SQLite", "UseSQLite", "true");
+ WriteINI("SQLite", "DataSource", "FunGameDB");
/**
* Mailer
*/
diff --git a/Entity/Character/Character.cs b/Entity/Character/Character.cs
index 12d3a85..5b8b20f 100644
--- a/Entity/Character/Character.cs
+++ b/Entity/Character/Character.cs
@@ -1006,7 +1006,7 @@ namespace Milimoe.FunGame.Core.Entity
}
return str;
}
-
+
///
/// 获取角色实例的名字、昵称
///
@@ -1122,7 +1122,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.Append(skill.ToString());
}
}
-
+
if (EquipSlot.Any())
{
builder.AppendLine("== 装备栏 ==");
diff --git a/Entity/Item/Item.cs b/Entity/Item/Item.cs
index d4846dd..b71deac 100644
--- a/Entity/Item/Item.cs
+++ b/Entity/Item/Item.cs
@@ -20,7 +20,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 物品的通用描述
///
public virtual string GeneralDescription { get; set; } = "";
-
+
///
/// 物品的背景故事
///
@@ -45,7 +45,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 装备槽位
///
public virtual EquipSlotType EquipSlotType { get; set; } = EquipSlotType.None;
-
+
///
/// 武器类型(如果是武器)
///
@@ -65,7 +65,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 是否可用(涉及冷却和禁用等)
///
public bool Enable { get; set; } = true;
-
+
///
/// 是否是局内使用的物品(局内是指对角色生效的物品)
///
@@ -95,7 +95,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 是否允许交易
///
public bool IsTradable { get; set; } = true;
-
+
///
/// 下次可交易的时间
///
@@ -160,7 +160,7 @@ namespace Milimoe.FunGame.Core.Entity
}
if (Character != null) OnItemEquipped(Character, this, type);
}
-
+
///
/// 当取消装备物品时
///
@@ -236,7 +236,7 @@ namespace Milimoe.FunGame.Core.Entity
{
}
-
+
///
/// 当物品被玩家使用时
///
diff --git a/Entity/Skill/Skill.cs b/Entity/Skill/Skill.cs
index ab25ba4..147e630 100644
--- a/Entity/Skill/Skill.cs
+++ b/Entity/Skill/Skill.cs
@@ -19,7 +19,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 技能描述
///
public virtual string Description { get; set; } = "";
-
+
///
/// 技能的通用描述
///
@@ -145,7 +145,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 游戏中的行动顺序表实例,在技能效果被触发时,此实例会获得赋值,使用时需要判断其是否存在
///
public ActionQueue? ActionQueue { get; set; } = null;
-
+
///
/// 技能是否属于某个物品
///
@@ -302,7 +302,7 @@ namespace Milimoe.FunGame.Core.Entity
{
return Id + "." + Name;
}
-
+
///
/// 判断两个技能是否相同 检查Id.Name
///
diff --git a/FunGame.Core.csproj b/FunGame.Core.csproj
index 832f0b0..c452b13 100644
--- a/FunGame.Core.csproj
+++ b/FunGame.Core.csproj
@@ -21,12 +21,12 @@
embedded
- 1701;1702;CS1591;CS1587
+ 1701;1702;CS1591;CS1587;IDE0130
embedded
- 1701;1702;CS1591;CS1587
+ 1701;1702;CS1591;CS1587;IDE0130
diff --git a/Interface/Base/Addons/IGameModule.cs b/Interface/Base/Addons/IGameModule.cs
index fde6564..866ba17 100644
--- a/Interface/Base/Addons/IGameModule.cs
+++ b/Interface/Base/Addons/IGameModule.cs
@@ -6,7 +6,8 @@ namespace Milimoe.FunGame.Core.Interface.Addons
IGamingRandomEventHandler, IGamingRoundEventHandler, IGamingLevelUpEventHandler, IGamingMoveEventHandler, IGamingAttackEventHandler, IGamingSkillEventHandler, IGamingItemEventHandler, IGamingMagicEventHandler,
IGamingBuyEventHandler, IGamingSuperSkillEventHandler, IGamingPauseEventHandler, IGamingUnpauseEventHandler, IGamingSurrenderEventHandler, IGamingUpdateInfoEventHandler, IGamingPunishEventHandler, IGameModuleDepend
{
- public abstract void StartGame(Gaming instance, params object[] args);
- public abstract void StartUI(params object[] args);
+ public bool HideMain { get; }
+ public void StartGame(Gaming instance, params object[] args);
+ public void StartUI(params object[] args);
}
}
diff --git a/Interface/Base/Addons/IGameModuleServer.cs b/Interface/Base/Addons/IGameModuleServer.cs
index 4fdce63..1c4ad41 100644
--- a/Interface/Base/Addons/IGameModuleServer.cs
+++ b/Interface/Base/Addons/IGameModuleServer.cs
@@ -1,5 +1,4 @@
-using System.Collections;
-using Milimoe.FunGame.Core.Entity;
+using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
@@ -9,6 +8,6 @@ namespace Milimoe.FunGame.Core.Interface.Addons
{
public bool StartServer(string GameModule, Room Room, List Users, IServerModel RoomMasterServerModel, Dictionary ServerModels, params object[] args);
- public Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data);
+ public Dictionary GamingMessageHandler(string username, GamingType type, Dictionary data);
}
}
diff --git a/Interface/Base/IBaseSocket.cs b/Interface/Base/IBaseSocket.cs
index 8b93c4f..6eb6718 100644
--- a/Interface/Base/IBaseSocket.cs
+++ b/Interface/Base/IBaseSocket.cs
@@ -6,10 +6,6 @@ namespace Milimoe.FunGame.Core.Interface.Base
{
public SocketRuntimeType Runtime { get; }
public Guid Token { get; }
- public string ServerAddress { get; }
- public int ServerPort { get; }
- public string ServerName { get; }
- public string ServerNotice { get; }
public void Close();
}
}
diff --git a/Interface/Base/IServerModel.cs b/Interface/Base/IServerModel.cs
index d993e9d..8ac4c31 100644
--- a/Interface/Base/IServerModel.cs
+++ b/Interface/Base/IServerModel.cs
@@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Entity;
+using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Common.Network;
using Milimoe.FunGame.Core.Library.Constant;
@@ -14,7 +15,7 @@ namespace Milimoe.FunGame.Core.Interface.Base
///
/// 客户端的套接字实例
///
- public abstract ClientSocket? Socket { get; }
+ public abstract ISocketMessageProcessor? Socket { get; }
///
/// 客户端的用户实例,在用户登录后有效
@@ -31,6 +32,11 @@ namespace Milimoe.FunGame.Core.Interface.Base
///
public bool IsDebugMode { get; }
+ ///
+ /// 客户端的游戏模组服务器
+ ///
+ public GameModuleServer? NowGamingServer { get; set; }
+
///
/// 向客户端发送消息
///
@@ -38,7 +44,7 @@ namespace Milimoe.FunGame.Core.Interface.Base
///
///
///
- public bool Send(ClientSocket socket, SocketMessageType type, params object[] objs);
+ public bool Send(ISocketMessageProcessor socket, SocketMessageType type, params object[] objs);
///
/// 向客户端发送系统消息
@@ -58,15 +64,15 @@ namespace Milimoe.FunGame.Core.Interface.Base
///
/// 开始接收客户端消息
- /// 请勿在 中调用此方法
+ /// 请勿在 中调用此方法
///
///
///
- public bool Read(ClientSocket socket);
+ public bool Read(ISocketMessageProcessor socket);
///
/// 启动对客户端的监听
- /// 请勿在 中调用此方法
+ /// 请勿在 中调用此方法
///
public void Start();
}
diff --git a/Interface/Base/ISocketMessageProcessor.cs b/Interface/Base/ISocketMessageProcessor.cs
new file mode 100644
index 0000000..d9e212f
--- /dev/null
+++ b/Interface/Base/ISocketMessageProcessor.cs
@@ -0,0 +1,15 @@
+using Milimoe.FunGame.Core.Library.Constant;
+
+namespace Milimoe.FunGame.Core.Interface.Base
+{
+ public interface ISocketMessageProcessor
+ {
+ public Type InstanceType { get; }
+ public string ClientIP { get; }
+ public string ClientName { get; }
+
+ public SocketResult Send(SocketMessageType type, params object[] objs);
+ public Task SendAsync(SocketMessageType type, params object[] objs);
+ public void Close();
+ }
+}
diff --git a/Interface/Base/Sockets/IWebSocket.cs b/Interface/Base/Sockets/IWebSocket.cs
new file mode 100644
index 0000000..07ab29b
--- /dev/null
+++ b/Interface/Base/Sockets/IWebSocket.cs
@@ -0,0 +1,10 @@
+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;
+ }
+}
diff --git a/Interface/Event/GamingEventHandlers.cs b/Interface/Event/GamingEventHandlers.cs
index 2f885f5..71156ba 100644
--- a/Interface/Event/GamingEventHandlers.cs
+++ b/Interface/Event/GamingEventHandlers.cs
@@ -1,5 +1,4 @@
-using System.Collections;
-using Milimoe.FunGame.Core.Library.Common.Addon;
+using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Common.Event;
namespace Milimoe.FunGame.Core.Interface
@@ -9,146 +8,146 @@ namespace Milimoe.FunGame.Core.Interface
///
public interface IGamingEventHandler
{
- public delegate void GamingEventHandler(object sender, GamingEventArgs e, Hashtable data);
+ public delegate void GamingEventHandler(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingConnectEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingConnect;
- public void OnGamingConnectEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingConnectEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingDisconnectEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingDisconnect;
- public void OnGamingDisconnectEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingDisconnectEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingReconnectEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingReconnect;
- public void OnGamingReconnectEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingReconnectEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingBanCharacterEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingBanCharacter;
- public void OnGamingBanCharacterEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingBanCharacterEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingPickCharacterEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingPickCharacter;
- public void OnGamingPickCharacterEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingPickCharacterEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingRandomEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingRandom;
- public void OnGamingRandomEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingRandomEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingRoundEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingRound;
- public void OnGamingRoundEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingRoundEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingLevelUpEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingLevelUp;
- public void OnGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingLevelUpEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingMoveEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingMove;
- public void OnGamingMoveEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingMoveEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingAttackEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingAttack;
- public void OnGamingAttackEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingAttackEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingSkillEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingSkill;
- public void OnGamingSkillEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingSkillEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingItemEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingItem;
- public void OnGamingItemEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingItemEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingMagicEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingMagic;
- public void OnGamingMagicEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingMagicEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingBuyEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingBuy;
- public void OnGamingBuyEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingBuyEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingSuperSkillEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingSuperSkill;
- public void OnGamingSuperSkillEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingSuperSkillEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingPauseEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingPause;
- public void OnGamingPauseEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingPauseEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingUnpauseEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingUnpause;
- public void OnGamingUnpauseEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingUnpauseEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingSurrenderEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingSurrender;
- public void OnGamingSurrenderEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingSurrenderEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingUpdateInfoEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingUpdateInfo;
- public void OnGamingUpdateInfoEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingPunishEventHandler : IGamingEventHandler
{
public event GamingEventHandler? GamingPunish;
- public void OnGamingPunishEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void OnGamingPunishEvent(object sender, GamingEventArgs e, Dictionary data);
}
}
diff --git a/Interface/Event/GamingEvents.cs b/Interface/Event/GamingEvents.cs
index 4061ae8..9d291a6 100644
--- a/Interface/Event/GamingEvents.cs
+++ b/Interface/Event/GamingEvents.cs
@@ -1,106 +1,105 @@
-using System.Collections;
-using Milimoe.FunGame.Core.Library.Common.Event;
+using Milimoe.FunGame.Core.Library.Common.Event;
// 模组需要实现什么事件就继承什么接口
namespace Milimoe.FunGame.Core.Interface
{
public interface IGamingConnectEvent
{
- public void GamingConnectEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingConnectEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingDisconnectEvent
{
- public void GamingDisconnectEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingDisconnectEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingReconnectEvent
{
- public void GamingReconnectEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingReconnectEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingBanCharacterEvent
{
- public void GamingBanCharacterEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingBanCharacterEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingPickCharacterEvent
{
- public void GamingPickCharacterEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingPickCharacterEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingRandomEvent
{
- public void GamingRandomEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingRandomEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingRoundEvent
{
- public void GamingRoundEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingRoundEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingLevelUpEvent
{
- public void GamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingLevelUpEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingMoveEvent
{
- public void GamingMoveEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingMoveEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingAttackEvent
{
- public void GamingAttackEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingAttackEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingSkillEvent
{
- public void GamingSkillEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingSkillEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingItemEvent
{
- public void GamingItemEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingItemEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingMagicEvent
{
- public void GamingMagicEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingMagicEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingBuyEvent
{
- public void GamingBuyEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingBuyEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingSuperSkillEvent
{
- public void GamingSuperSkillEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingSuperSkillEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingPauseEvent
{
- public void GamingPauseEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingPauseEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingUnpauseEvent
{
- public void GamingUnpauseEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingUnpauseEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingSurrenderEvent
{
- public void GamingSurrenderEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingSurrenderEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingUpdateInfoEvent
{
- public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary data);
}
public interface IGamingPunishEvent
{
- public void GamingPunishEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void GamingPunishEvent(object sender, GamingEventArgs e, Dictionary data);
}
}
diff --git a/Library/Common/Addon/Example/ExampleGameModule.cs b/Library/Common/Addon/Example/ExampleGameModule.cs
index 0ecc9ff..986dfd8 100644
--- a/Library/Common/Addon/Example/ExampleGameModule.cs
+++ b/Library/Common/Addon/Example/ExampleGameModule.cs
@@ -1,4 +1,3 @@
-using System.Collections;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
@@ -49,6 +48,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public override RoomType RoomType => RoomType.Mix;
+ public override bool HideMain => false;
+
public ExampleGameModule()
{
// 构造函数中可以指定模组连接到哪个模组服务器。
@@ -78,16 +79,16 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
// 如果没有,则不需要重写此方法
}
- public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary data)
{
// 在下方的Server示例中,服务器发来的data中,包含check字符串,因此客户端要主动发起确认连接的请求。
if (data.ContainsKey("info_type"))
{
// 反序列化得到指定key的值
- string info_type = DataRequest.GetHashtableJsonObject(data, "info_type") ?? "";
+ string info_type = DataRequest.GetDictionaryJsonObject(data, "info_type") ?? "";
if (info_type == "check")
{
- Guid token = DataRequest.GetHashtableJsonObject(data, "connect_token");
+ Guid token = DataRequest.GetDictionaryJsonObject(data, "connect_token");
// 发起连接确认请求
DataRequest request = Controller.NewDataRequest(GamingType.Connect);
// 传递参数
@@ -143,7 +144,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
}
private readonly List ConnectedUser = [];
- private readonly Dictionary UserData = [];
+ private readonly Dictionary> UserData = [];
private async Task Test()
{
@@ -154,7 +155,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
// 在FunGame项目中,建议永远使用客户端主动发起请求,因为服务器主动发起的实现难度较高
// 下面的演示基于综合的两种情况:服务器主动发送通知,客户端收到后,发起确认
// UpdateInfo是一个灵活的类型。如果发送check字符串,意味着服务器要求客户端发送确认
- Hashtable data = [];
+ Dictionary data = [];
data.Add("info_type", "check");
// 进阶示例:传递一个token,让客户端返回
@@ -164,7 +165,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
// 我们保存到字典UserData中,这样可以方便跨方法检查变量
foreach (string username in Users.Select(u => u.Username).Distinct())
{
- if (UserData.TryGetValue(username, out Hashtable? value))
+ if (UserData.TryGetValue(username, out Dictionary? value))
{
value.Add("connect_token", token);
}
@@ -174,7 +175,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
UserData[username].Add("connect_token", token);
}
}
- SendAllGamingMessage(GamingType.UpdateInfo, data);
+ SendGamingMessage(All.Values, GamingType.UpdateInfo, data);
// 新建一个线程等待所有玩家确认
while (true)
@@ -186,18 +187,18 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
Controller.WriteLine("所有玩家都已经连接。");
}
- public override Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data)
+ public override Dictionary GamingMessageHandler(string username, GamingType type, Dictionary data)
{
- Hashtable result = [];
+ Dictionary result = [];
switch (type)
{
case GamingType.Connect:
// 编写处理“连接”命令的逻辑
// 如果需要处理客户端传递的参数:获取与客户端约定好的参数key对应的值
- string un = NetworkUtility.JsonDeserializeFromHashtable(data, "username") ?? "";
- Guid token = NetworkUtility.JsonDeserializeFromHashtable(data, "connect_token");
- if (un == username && UserData.TryGetValue(username, out Hashtable? value) && value != null && (value["connect_token"]?.Equals(token) ?? false))
+ string un = NetworkUtility.JsonDeserializeFromDictionary(data, "username") ?? "";
+ Guid token = NetworkUtility.JsonDeserializeFromDictionary(data, "connect_token");
+ if (un == username && UserData.TryGetValue(username, out Dictionary? value) && value != null && (value["connect_token"]?.Equals(token) ?? false))
{
ConnectedUser.Add(Users.Where(u => u.Username == username).First());
Controller.WriteLine(username + " 已经连接。");
@@ -208,52 +209,6 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
return result;
}
-
- // === 下面是一些常用的工具方法,用于服务器给客户端发送消息,可以直接添加到你的项目中 === //
-
- protected void SendAllGamingMessage(GamingType type, Hashtable data)
- {
- // 循环服务线程,向所有玩家发送局内消息
- foreach (IServerModel s in All.Values)
- {
- if (s != null && s.Socket != null)
- {
- s.Send(s.Socket, SocketMessageType.Gaming, type, data);
- }
- }
- }
-
- protected void SendGamingMessage(string username, GamingType type, Hashtable data)
- {
- // 向指定玩家发送局内消息
- IServerModel s = All[username];
- if (s != null && s.Socket != null)
- {
- s.Send(s.Socket, SocketMessageType.Gaming, type, data);
- }
- }
-
- protected void SendAll(SocketMessageType type, params object[] args)
- {
- // 循环服务线程,向所有玩家发送消息
- foreach (IServerModel s in All.Values)
- {
- if (s != null && s.Socket != null)
- {
- s.Send(s.Socket, type, args);
- }
- }
- }
-
- protected void Send(string username, SocketMessageType type, params object[] args)
- {
- // 向指定玩家发送消息
- IServerModel s = All[username];
- if (s != null && s.Socket != null)
- {
- s.Send(s.Socket, type, args);
- }
- }
}
///
diff --git a/Library/Common/Addon/GameModule.cs b/Library/Common/Addon/GameModule.cs
index e6d42f0..64fb782 100644
--- a/Library/Common/Addon/GameModule.cs
+++ b/Library/Common/Addon/GameModule.cs
@@ -1,4 +1,3 @@
-using System.Collections;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface;
using Milimoe.FunGame.Core.Interface.Addons;
@@ -45,6 +44,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
///
public abstract RoomType RoomType { get; }
+ ///
+ /// 是否隐藏主界面
+ ///
+ public abstract bool HideMain { get; }
+
///
/// 是否连接其他的服务器模组
///
@@ -116,7 +120,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
return false;
}
// BeforeLoad可以阻止加载此模组
- if (BeforeLoad())
+ if (BeforeLoad(objs))
{
// 模组加载后,不允许再次加载此模组
IsLoaded = true;
@@ -124,16 +128,14 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
Init(objs);
// 触发绑定事件
BindEvent();
- // 如果加载后需要执行代码,请重写AfterLoad方法
- AfterLoad();
}
return IsLoaded;
}
///
- /// 模组加载后需要做的事
+ /// 模组完全加载后需要做的事
///
- protected virtual void AfterLoad()
+ public virtual void AfterLoad(params object[] args)
{
// override
}
@@ -142,7 +144,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// 允许返回false来阻止加载此模组
///
///
- protected virtual bool BeforeLoad()
+ protected virtual bool BeforeLoad(params object[] objs)
{
return true;
}
@@ -318,102 +320,102 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
public event IGamingEventHandler.GamingEventHandler? GamingUpdateInfo;
public event IGamingEventHandler.GamingEventHandler? GamingPunish;
- public void OnGamingConnectEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingConnectEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingConnect?.Invoke(sender, e, data);
}
- public void OnGamingDisconnectEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingDisconnectEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingDisconnect?.Invoke(sender, e, data);
}
- public void OnGamingReconnectEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingReconnectEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingReconnect?.Invoke(sender, e, data);
}
- public void OnGamingBanCharacterEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingBanCharacterEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingBanCharacter?.Invoke(sender, e, data);
}
- public void OnGamingPickCharacterEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingPickCharacterEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingPickCharacter?.Invoke(sender, e, data);
}
- public void OnGamingRandomEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingRandomEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingRandom?.Invoke(sender, e, data);
}
- public void OnGamingRoundEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingRoundEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingRound?.Invoke(sender, e, data);
}
- public void OnGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingLevelUpEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingLevelUp?.Invoke(sender, e, data);
}
- public void OnGamingMoveEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingMoveEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingMove?.Invoke(sender, e, data);
}
- public void OnGamingAttackEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingAttackEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingAttack?.Invoke(sender, e, data);
}
- public void OnGamingSkillEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingSkillEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingSkill?.Invoke(sender, e, data);
}
- public void OnGamingItemEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingItemEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingItem?.Invoke(sender, e, data);
}
- public void OnGamingMagicEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingMagicEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingMagic?.Invoke(sender, e, data);
}
- public void OnGamingBuyEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingBuyEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingBuy?.Invoke(sender, e, data);
}
- public void OnGamingSuperSkillEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingSuperSkillEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingSuperSkill?.Invoke(sender, e, data);
}
- public void OnGamingPauseEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingPauseEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingPause?.Invoke(sender, e, data);
}
- public void OnGamingUnpauseEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingUnpauseEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingUnpause?.Invoke(sender, e, data);
}
- public void OnGamingSurrenderEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingSurrenderEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingSurrender?.Invoke(sender, e, data);
}
- public void OnGamingUpdateInfoEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingUpdateInfo?.Invoke(sender, e, data);
}
- public void OnGamingPunishEvent(object sender, GamingEventArgs e, Hashtable data)
+ public void OnGamingPunishEvent(object sender, GamingEventArgs e, Dictionary data)
{
GamingPunish?.Invoke(sender, e, data);
}
diff --git a/Library/Common/Addon/GameModuleServer.cs b/Library/Common/Addon/GameModuleServer.cs
index 731ea82..97aa741 100644
--- a/Library/Common/Addon/GameModuleServer.cs
+++ b/Library/Common/Addon/GameModuleServer.cs
@@ -1,4 +1,3 @@
-using System.Collections;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Addons;
@@ -72,8 +71,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// 发送此消息的账号
/// 消息类型
/// 消息参数
- /// 底层会将哈希表中的数据发送给客户端
- public abstract Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data);
+ /// 底层会将字典中的数据发送给客户端
+ public abstract Dictionary GamingMessageHandler(string username, GamingType type, Dictionary data);
///
/// 加载标记
@@ -94,16 +93,14 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
{
// 模组加载后,不允许再次加载此模组
IsLoaded = true;
- // 如果加载后需要执行代码,请重写AfterLoad方法
- AfterLoad();
}
return IsLoaded;
}
///
- /// 模组加载后需要做的事
+ /// 模组完全加载后需要做的事
///
- protected virtual void AfterLoad()
+ public virtual void AfterLoad(params object[] args)
{
// override
}
@@ -116,5 +113,41 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
{
return true;
}
+
+ ///
+ /// 给客户端发送局内消息
+ ///
+ ///
+ ///
+ ///
+ protected virtual void SendGamingMessage(IEnumerable clients, GamingType type, Dictionary data)
+ {
+ // 发送局内消息
+ foreach (IServerModel s in clients)
+ {
+ if (s != null && s.Socket != null)
+ {
+ s.Send(s.Socket, SocketMessageType.Gaming, type, data);
+ }
+ }
+ }
+
+ ///
+ /// 给客户端发送消息
+ ///
+ ///
+ ///
+ ///
+ protected virtual void Send(IEnumerable clients, SocketMessageType type, params object[] args)
+ {
+ // 发送消息
+ foreach (IServerModel s in clients)
+ {
+ if (s != null && s.Socket != null)
+ {
+ s.Send(s.Socket, type, args);
+ }
+ }
+ }
}
}
diff --git a/Library/Common/JsonConverter/CharacterConverter.cs b/Library/Common/JsonConverter/CharacterConverter.cs
index d8c0841..983af79 100644
--- a/Library/Common/JsonConverter/CharacterConverter.cs
+++ b/Library/Common/JsonConverter/CharacterConverter.cs
@@ -17,6 +17,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
{
switch (propertyName)
{
+ case nameof(Character.Id):
+ result.Id = reader.GetInt64();
+ break;
case nameof(Character.Name):
result.Name = reader.GetString() ?? "";
break;
@@ -190,6 +193,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
public override void Write(Utf8JsonWriter writer, Character value, JsonSerializerOptions options)
{
writer.WriteStartObject();
+ writer.WriteNumber(nameof(Character.Id), value.Id);
writer.WriteString(nameof(Character.Name), value.Name);
writer.WriteString(nameof(Character.FirstName), value.FirstName);
writer.WriteString(nameof(Character.NickName), value.NickName);
diff --git a/Library/Common/JsonConverter/ItemConverter.cs b/Library/Common/JsonConverter/ItemConverter.cs
index 28f943e..ce45eb2 100644
--- a/Library/Common/JsonConverter/ItemConverter.cs
+++ b/Library/Common/JsonConverter/ItemConverter.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Text.Json;
+using System.Text.Json;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Architecture;
diff --git a/Library/Common/Network/ClientSocket.cs b/Library/Common/Network/ClientSocket.cs
index bac6577..6be9172 100644
--- a/Library/Common/Network/ClientSocket.cs
+++ b/Library/Common/Network/ClientSocket.cs
@@ -1,27 +1,25 @@
-using Milimoe.FunGame.Core.Interface.Sockets;
+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, int ServerPort, string ClientIP, string ClientName, Guid Token) : IClientSocket
+ 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 System.Net.Sockets.Socket Instance { get; } = instance;
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
- public Guid Token { get; } = Token;
- public string ServerAddress { get; } = "";
- public int ServerPort { get; } = ServerPort;
- public string ServerName { get; } = "";
- public string ServerNotice { get; } = "";
- public string ClientIP { get; } = ClientIP;
+ 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;
+ private readonly string _ClientName = clientName;
public void Close()
{
@@ -54,6 +52,19 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
return SocketResult.NotSent;
}
+ public async Task 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)
diff --git a/Library/Common/Network/ClientWebSocket.cs b/Library/Common/Network/ClientWebSocket.cs
new file mode 100644
index 0000000..c72736c
--- /dev/null
+++ b/Library/Common/Network/ClientWebSocket.cs
@@ -0,0 +1,43 @@
+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 SendAsync(SocketMessageType type, params object[] objs)
+ {
+ return await HTTPManager.Send(Instance, new(type, token, objs));
+ }
+ }
+}
diff --git a/Library/Common/Network/HTTPClient.cs b/Library/Common/Network/HTTPClient.cs
index 8b77099..5ed0b49 100644
--- a/Library/Common/Network/HTTPClient.cs
+++ b/Library/Common/Network/HTTPClient.cs
@@ -9,7 +9,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
{
public class HTTPClient : IHTTPClient
{
- public ClientWebSocket? Instance { get; } = null;
+ public System.Net.WebSockets.ClientWebSocket? Instance { get; } = null;
public SocketRuntimeType Runtime => SocketRuntimeType.Client;
public Guid Token { get; } = Guid.Empty;
public string ServerAddress { get; } = "";
@@ -20,7 +20,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
private bool _Listening = false;
private readonly HeartBeat HeartBeat;
- private HTTPClient(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;
this.ServerAddress = ServerAddress;
@@ -34,7 +34,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
{
string ServerIP = Api.Utility.NetworkUtility.GetIPAddress(ServerAddress);
Uri uri = new((SSL ? "wss://" : "ws://") + ServerIP + ":" + ServerPort + "/" + SubDirectory);
- ClientWebSocket? socket = await HTTPManager.Connect(uri);
+ System.Net.WebSockets.ClientWebSocket? socket = await HTTPManager.Connect(uri);
if (socket != null && socket.State == WebSocketState.Open)
{
HTTPClient client = new(socket, ServerAddress, ServerPort, args);
diff --git a/Library/Common/Network/HTTPListener.cs b/Library/Common/Network/HTTPListener.cs
index b911480..d9d8fb4 100644
--- a/Library/Common/Network/HTTPListener.cs
+++ b/Library/Common/Network/HTTPListener.cs
@@ -1,5 +1,6 @@
using System.Net;
using System.Net.WebSockets;
+using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.HTTP;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Service;
@@ -11,24 +12,20 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public HttpListener Instance { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
public Guid Token { get; } = Guid.Empty;
- public string ServerAddress { get; } = "";
- public int ServerPort { get; } = 0;
- public string ServerName { get; } = "";
- public string ServerNotice { get; } = "";
public Dictionary ClientSockets { get; } = [];
- private HTTPListener(HttpListener Instance, int ServerPort)
+ private HTTPListener(HttpListener instance)
{
- this.Instance = Instance;
- this.ServerPort = ServerPort;
+ Instance = instance;
+ Token = Guid.NewGuid();
}
- public static HTTPListener StartListening(int Port, bool SSL = false)
+ public static HTTPListener StartListening(int port, bool ssl = false)
{
- HttpListener? socket = HTTPManager.StartListening(Port, SSL);
+ HttpListener? socket = HTTPManager.StartListening(port, ssl);
if (socket != null)
{
- HTTPListener instance = new(socket, Port);
+ HTTPListener instance = new(socket);
Task t = Task.Run(async () => await HTTPManager.Receiving(instance));
return instance;
}
@@ -55,7 +52,27 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public void Close()
{
- Instance?.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();
+ closing = true;
+ });
+ while (closing)
+ {
+ if (!closing) break;
+ Thread.Sleep(100);
+ }
}
}
}
diff --git a/Library/Common/Network/ServerSocket.cs b/Library/Common/Network/ServerSocket.cs
index 7c604b2..d5e86ae 100644
--- a/Library/Common/Network/ServerSocket.cs
+++ b/Library/Common/Network/ServerSocket.cs
@@ -10,10 +10,6 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public System.Net.Sockets.Socket Instance { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Server;
public Guid Token { get; } = Guid.Empty;
- public string ServerAddress { get; } = "";
- public int ServerPort { get; } = 0;
- public string ServerName { get; } = "";
- public string ServerNotice { get; } = "";
public bool Connected => Instance != null && Instance.Connected;
public List ClientList => OnlineClients.GetList();
public List UserList => OnlineUsers.GetList();
@@ -25,38 +21,38 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
private readonly ModelManager OnlineClients;
private readonly ModelManager OnlineUsers;
- private ServerSocket(System.Net.Sockets.Socket Instance, int ServerPort, int MaxConnection = 0)
+ private ServerSocket(System.Net.Sockets.Socket instance, int maxConnection = 0)
{
- this.Instance = Instance;
- this.ServerPort = ServerPort;
- if (MaxConnection <= 0)
+ Token = Guid.NewGuid();
+ Instance = instance;
+ if (maxConnection <= 0)
{
OnlineClients = [];
OnlineUsers = [];
}
else
{
- OnlineClients = new(MaxConnection);
- OnlineUsers = new(MaxConnection);
+ OnlineClients = new(maxConnection);
+ OnlineUsers = new(maxConnection);
}
}
- public static ServerSocket StartListening(int Port = 22222, int MaxConnection = 0)
+ 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);
+ 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 ClientSocket Accept(Guid Token)
+ 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, ServerPort, ClientIP, ClientIP, Token);
+ 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();
}
diff --git a/Library/Common/Network/Socket.cs b/Library/Common/Network/Socket.cs
index a3a32b6..e769e5e 100644
--- a/Library/Common/Network/Socket.cs
+++ b/Library/Common/Network/Socket.cs
@@ -22,19 +22,19 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
private readonly HeartBeat HeartBeat;
private bool _Receiving = false;
- private Socket(System.Net.Sockets.Socket Instance, string ServerAddress, int ServerPort)
+ private Socket(System.Net.Sockets.Socket instance, string serverAddress, int serverPort)
{
- this.Instance = Instance;
- this.ServerAddress = ServerAddress;
- this.ServerPort = ServerPort;
+ this.Instance = instance;
+ this.ServerAddress = serverAddress;
+ this.ServerPort = serverPort;
HeartBeat = new(this);
HeartBeat.StartSendingHeartBeat();
}
- public static Socket Connect(string Address, int Port = 22222)
+ public static Socket Connect(string address, int port = 22222)
{
- System.Net.Sockets.Socket? socket = SocketManager.Connect(Address, Port);
- if (socket != null) return new Socket(socket, Address, Port);
+ System.Net.Sockets.Socket? socket = SocketManager.Connect(address, port);
+ if (socket != null) return new Socket(socket, address, port);
else throw new ConnectFailedException();
}
diff --git a/Library/Constant/ConstantSet.cs b/Library/Constant/ConstantSet.cs
index f0abee3..9519dee 100644
--- a/Library/Constant/ConstantSet.cs
+++ b/Library/Constant/ConstantSet.cs
@@ -37,6 +37,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
public const string Socket = "Socket";
public const string Unknown = "Unknown";
public const string DataRequest = "DataRequest";
+ public const string GamingRequest = "GamingRequest";
public const string Connect = "Connect";
public const string Disconnect = "Disconnect";
public const string System = "System";
diff --git a/Library/Constant/General.cs b/Library/Constant/General.cs
index 4229a5f..6821e29 100644
--- a/Library/Constant/General.cs
+++ b/Library/Constant/General.cs
@@ -44,7 +44,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
/// 默认的时间格式 yyyy-MM-dd HH:mm:ss.fff
///
public static string GeneralDateTimeFormat => "yyyy-MM-dd HH:mm:ss.fff";
-
+
///
/// yyyy年MM月dd日 HH:mm:ss
///
diff --git a/Library/Constant/TypeEnum.cs b/Library/Constant/TypeEnum.cs
index 4cb38b2..4090910 100644
--- a/Library/Constant/TypeEnum.cs
+++ b/Library/Constant/TypeEnum.cs
@@ -66,6 +66,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
{
Unknown,
DataRequest,
+ GamingRequest,
Connect,
Disconnect,
System,
@@ -217,7 +218,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
/// 无特殊效果
///
None,
-
+
///
/// 这是来自装备的特效
///
@@ -844,4 +845,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
Plugin,
GameModule
}
+
+ public enum SQLMode
+ {
+ None,
+ MySQL,
+ SQLite
+ }
}
diff --git a/Library/Exception/Exception.cs b/Library/Exception/Exception.cs
index 4f283ea..1c7d0ba 100644
--- a/Library/Exception/Exception.cs
+++ b/Library/Exception/Exception.cs
@@ -165,8 +165,13 @@
public override string Message => "试图在不支持的类中创建数据请求 (#10033)";
}
- public class AsyncRequestException : Exception
+ public class AsyncSendException : Exception
{
- public override string Message => "数据请求必须以异步方式发送 (#10034)";
+ public override string Message => "必须以异步方式发送数据 (#10034)";
+ }
+
+ public class SQLServiceException : Exception
+ {
+ public override string Message => "SQL服务遇到错误,请检查SQL配置 (#10035)";
}
}
diff --git a/Model/Gaming.cs b/Model/Gaming.cs
index e4dfd84..845aae9 100644
--- a/Model/Gaming.cs
+++ b/Model/Gaming.cs
@@ -1,5 +1,4 @@
-using System.Collections;
-using Milimoe.FunGame.Core.Api.Utility;
+using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Common.Event;
@@ -51,10 +50,7 @@ namespace Milimoe.FunGame.Core.Model
// 读取模组的依赖集合
module.GameModuleDepend.GetDependencies(loader);
// 新建线程来启动模组的界面
- TaskUtility.NewTask(() =>
- {
- module.StartUI();
- });
+ TaskUtility.NewTask(() => module.StartUI());
// 启动模组主线程
module.StartGame(instance, args);
return instance;
@@ -67,7 +63,7 @@ namespace Milimoe.FunGame.Core.Model
///
/// 消息类型
/// 接收到的数据
- public void GamingHandler(GamingType type, Hashtable data)
+ public void GamingHandler(GamingType type, Dictionary data)
{
switch (type)
{
@@ -137,102 +133,102 @@ namespace Milimoe.FunGame.Core.Model
}
}
- private void Connect(Hashtable data)
+ private void Connect(Dictionary data)
{
GameModule.OnGamingConnectEvent(this, EventArgs, data);
}
- private void Disconnect(Hashtable data)
+ private void Disconnect(Dictionary data)
{
GameModule.OnGamingDisconnectEvent(this, EventArgs, data);
}
- private void Reconnect(Hashtable data)
+ private void Reconnect(Dictionary data)
{
GameModule.OnGamingReconnectEvent(this, EventArgs, data);
}
- private void BanCharacter(Hashtable data)
+ private void BanCharacter(Dictionary data)
{
GameModule.OnGamingBanCharacterEvent(this, EventArgs, data);
}
- private void PickCharacter(Hashtable data)
+ private void PickCharacter(Dictionary data)
{
GameModule.OnGamingPickCharacterEvent(this, EventArgs, data);
}
- private void Random(Hashtable data)
+ private void Random(Dictionary data)
{
GameModule.OnGamingRandomEvent(this, EventArgs, data);
}
- private void Round(Hashtable data)
+ private void Round(Dictionary data)
{
GameModule.OnGamingRoundEvent(this, EventArgs, data);
}
- private void LevelUp(Hashtable data)
+ private void LevelUp(Dictionary data)
{
GameModule.OnGamingLevelUpEvent(this, EventArgs, data);
}
- private void Move(Hashtable data)
+ private void Move(Dictionary data)
{
GameModule.OnGamingMoveEvent(this, EventArgs, data);
}
- private void Attack(Hashtable data)
+ private void Attack(Dictionary data)
{
GameModule.OnGamingAttackEvent(this, EventArgs, data);
}
- private void Skill(Hashtable data)
+ private void Skill(Dictionary data)
{
GameModule.OnGamingSkillEvent(this, EventArgs, data);
}
- private void Item(Hashtable data)
+ private void Item(Dictionary data)
{
GameModule.OnGamingItemEvent(this, EventArgs, data);
}
- private void Magic(Hashtable data)
+ private void Magic(Dictionary data)
{
GameModule.OnGamingMagicEvent(this, EventArgs, data);
}
- private void Buy(Hashtable data)
+ private void Buy(Dictionary data)
{
GameModule.OnGamingBuyEvent(this, EventArgs, data);
}
- private void SuperSkill(Hashtable data)
+ private void SuperSkill(Dictionary data)
{
GameModule.OnGamingSuperSkillEvent(this, EventArgs, data);
}
- private void Pause(Hashtable data)
+ private void Pause(Dictionary data)
{
GameModule.OnGamingPauseEvent(this, EventArgs, data);
}
- private void Unpause(Hashtable data)
+ private void Unpause(Dictionary data)
{
GameModule.OnGamingUnpauseEvent(this, EventArgs, data);
}
- private void Surrender(Hashtable data)
+ private void Surrender(Dictionary data)
{
GameModule.OnGamingSurrenderEvent(this, EventArgs, data);
}
- private void UpdateInfo(Hashtable data)
+ private void UpdateInfo(Dictionary data)
{
GameModule.OnGamingUpdateInfoEvent(this, EventArgs, data);
}
- private void Punish(Hashtable data)
+ private void Punish(Dictionary data)
{
GameModule.OnGamingPunishEvent(this, EventArgs, data);
}
diff --git a/Service/AddonManager.cs b/Service/AddonManager.cs
index 62b86d8..21f453b 100644
--- a/Service/AddonManager.cs
+++ b/Service/AddonManager.cs
@@ -118,7 +118,6 @@ namespace Milimoe.FunGame.Core.Service
///
/// 从modules目录加载所有适用于服务器的模组
///
- ///
///
///
///
@@ -126,7 +125,7 @@ namespace Milimoe.FunGame.Core.Service
///
///
///
- internal static Dictionary LoadGameModulesForServer(Dictionary modules, Dictionary servers, Dictionary characters, Dictionary skills, Dictionary items, Hashtable delegates, params object[] otherobjs)
+ internal static Dictionary LoadGameModulesForServer(Dictionary servers, Dictionary characters, Dictionary skills, Dictionary items, Hashtable delegates, params object[] otherobjs)
{
if (!Directory.Exists(ReflectionSet.GameModuleFolderPath)) return servers;
@@ -140,19 +139,7 @@ namespace Milimoe.FunGame.Core.Service
{
bool isAdded = false;
- if (type.IsSubclassOf(typeof(GameModule)))
- {
- isAdded = AddAddonInstances(type, modules, (instance) =>
- {
- if (instance.Load(otherobjs))
- {
- instance.Controller = new(instance, delegates);
- return true;
- }
- return false;
- });
- }
- else if (type.IsSubclassOf(typeof(GameModuleServer)))
+ if (type.IsSubclassOf(typeof(GameModuleServer)))
{
isAdded = AddAddonInstances(type, servers, (instance) =>
{
diff --git a/Service/HTTPManager.cs b/Service/HTTPManager.cs
index 3ec263a..7e692a6 100644
--- a/Service/HTTPManager.cs
+++ b/Service/HTTPManager.cs
@@ -13,17 +13,17 @@ namespace Milimoe.FunGame.Core.Service
internal static HttpListener? ServerSocket => _ServerSocket;
private static HttpListener? _ServerSocket = null;
- internal static HttpListener StartListening(int Port = 22227, bool SSL = false)
+ internal static HttpListener StartListening(int port = 22227, bool ssl = false)
{
HttpListener listener = new();
- listener.Prefixes.Add((SSL ? "https://" : "http://") + "localhost:" + Port + "/");
+ listener.Prefixes.Add((ssl ? "https://" : "http://") + "localhost:" + port + "/ws");
listener.Start();
return listener;
}
- internal static async Task Connect(Uri uri)
+ internal static async Task Connect(Uri uri)
{
- ClientWebSocket socket = new();
+ System.Net.WebSockets.ClientWebSocket socket = new();
await socket.ConnectAsync(uri, CancellationToken.None);
if (socket.State == WebSocketState.Open)
{
@@ -32,7 +32,7 @@ namespace Milimoe.FunGame.Core.Service
return null;
}
- internal static async Task Send(ClientWebSocket socket, SocketObject obj)
+ internal static async Task Send(System.Net.WebSockets.ClientWebSocket socket, SocketObject obj)
{
if (socket != null)
{
@@ -79,7 +79,7 @@ namespace Milimoe.FunGame.Core.Service
HttpListenerContext context = await ServerSocket.GetContextAsync();
if (context.Request.IsWebSocketRequest)
{
- await AddClientWebSocket(listener, context);
+ TaskUtility.NewTask(async () => await AddClientWebSocket(listener, context));
}
else
{
@@ -154,12 +154,19 @@ namespace Milimoe.FunGame.Core.Service
listener.ClientSockets.TryAdd(token, socket);
await Send(socket, sendobject);
- while (!result.CloseStatus.HasValue)
+ while (socket.State == WebSocketState.Open)
{
try
{
buffer = new byte[General.SocketByteSize];
result = await socket.ReceiveAsync(new ArraySegment(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)
@@ -167,7 +174,7 @@ namespace Milimoe.FunGame.Core.Service
sendobject = listener.SocketObject_Handler(obj);
if (obj.SocketType == SocketMessageType.Disconnect)
{
- await socket.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, result.CloseStatusDescription, CancellationToken.None);
+ await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Disconnect received", CancellationToken.None);
return;
}
await Send(socket, sendobject);
@@ -175,8 +182,10 @@ namespace Milimoe.FunGame.Core.Service
}
catch (Exception e)
{
+ // 处理其他异常
TXTHelper.AppendErrorLog(e.GetErrorInfo());
- await socket.CloseAsync(WebSocketCloseStatus.InternalServerError, result.CloseStatusDescription, CancellationToken.None);
+ await socket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Server Error", CancellationToken.None);
+ return;
}
}
}
diff --git a/Service/JsonManager.cs b/Service/JsonManager.cs
index c582ac7..a32c62e 100644
--- a/Service/JsonManager.cs
+++ b/Service/JsonManager.cs
@@ -138,6 +138,27 @@ namespace Milimoe.FunGame.Core.Service
return default;
}
+ ///
+ /// 反序列化Dictionary中Key对应的Json对象
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static T? GetObject(Dictionary dict, string key)
+ {
+ if (dict.TryGetValue(key, out object? value))
+ {
+ JsonElement? element = (JsonElement?)value;
+ if (element != null)
+ {
+ T? result = ((JsonElement)element).Deserialize(GeneralOptions);
+ return result;
+ }
+ }
+ return default;
+ }
+
///
/// 反序列化IEnumerable中的Json对象
///
@@ -205,6 +226,28 @@ namespace Milimoe.FunGame.Core.Service
return default;
}
+ ///
+ /// 反序列化Dictionary中Key对应的Json对象
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static T? GetObject(Dictionary dict, string key, JsonSerializerOptions options)
+ {
+ if (dict.TryGetValue(key, out object? value))
+ {
+ JsonElement? element = (JsonElement?)value;
+ if (element != null)
+ {
+ T? result = ((JsonElement)element).Deserialize(options);
+ return result;
+ }
+ }
+ return default;
+ }
+
///
/// 反序列化多个Json对象
/// 注意必须是相同的Json对象才可以使用此方法解析
diff --git a/Service/SocketManager.cs b/Service/SocketManager.cs
index 36aee0a..4bee11d 100644
--- a/Service/SocketManager.cs
+++ b/Service/SocketManager.cs
@@ -1,6 +1,8 @@
using System.Net;
using System.Net.Sockets;
+using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Library.Constant;
+using Milimoe.FunGame.Core.Library.Exception;
namespace Milimoe.FunGame.Core.Service
{
@@ -145,6 +147,25 @@ namespace Milimoe.FunGame.Core.Service
return SocketResult.NotSent;
}
+ ///
+ /// 用于服务器端向客户端Socket发送信息 [ 异步版 ]
+ ///
+ /// 客户端Socket
+ /// Socket信息容器
+ /// 通信结果
+ internal static async Task SendAsync(Socket ClientSocket, Library.Common.Network.SocketObject SocketObject)
+ {
+ if (ClientSocket != null)
+ {
+ if (await ClientSocket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0)
+ {
+ return SocketResult.Success;
+ }
+ else return SocketResult.Fail;
+ }
+ return SocketResult.NotSent;
+ }
+
///
/// 用于客户端向服务器Socket发送信息
///
@@ -163,6 +184,24 @@ namespace Milimoe.FunGame.Core.Service
return SocketResult.NotSent;
}
+ ///
+ /// 用于客户端向服务器Socket发送信息 [ 异步版 ]
+ ///
+ /// Socket信息容器
+ /// 通信结果
+ internal static async Task SendAsync(Library.Common.Network.SocketObject SocketObject)
+ {
+ if (Socket != null)
+ {
+ if (await Socket.SendAsync(General.DefaultEncoding.GetBytes(JsonManager.GetString(SocketObject))) > 0)
+ {
+ return SocketResult.Success;
+ }
+ else return SocketResult.Fail;
+ }
+ return SocketResult.NotSent;
+ }
+
///
/// 接收数据流中的信息
/// 如果是服务器接收信息需要传入客户端Socket
@@ -171,54 +210,62 @@ namespace Milimoe.FunGame.Core.Service
/// SocketObjects
internal static Library.Common.Network.SocketObject[] Receive(Socket? ClientSocket = null)
{
- List result = [];
- Socket? tempSocket = ClientSocket is null ? Socket : ClientSocket;
- if (tempSocket != null)
+ try
{
- // 从服务器接收消息
- byte[] buffer = new byte[General.SocketByteSize];
- int length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None);
- string msg = "";
- if (length > 0)
+ List result = [];
+ Socket? tempSocket = ClientSocket is null ? Socket : ClientSocket;
+ if (tempSocket != null)
{
- msg = General.DefaultEncoding.GetString(buffer, 0, length);
- if (JsonManager.IsCompleteJson(msg))
+ // 从服务器接收消息
+ byte[] buffer = new byte[General.SocketByteSize];
+ int length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None);
+ string msg = "";
+ if (length > 0)
{
- foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg))
+ msg = General.DefaultEncoding.GetString(buffer, 0, length);
+ if (JsonManager.IsCompleteJson(msg))
{
- result.Add(obj);
- // 客户端接收消息,广播ScoketObject到每个UIModel
- if (ClientSocket is null) OnSocketReceive(obj);
- }
- return [.. result];
- }
- else
- {
- Thread.Sleep(20);
- while (true)
- {
- if (tempSocket.Available > 0)
+ foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg))
{
- length = tempSocket.Receive(buffer, buffer.Length, SocketFlags.None);
- msg += General.DefaultEncoding.GetString(buffer, 0, length);
- if (JsonManager.IsCompleteJson(msg))
- {
- break;
- }
- Thread.Sleep(20);
+ 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(msg))
+ {
+ break;
+ }
+ Thread.Sleep(20);
+ }
+ else break;
}
- else break;
}
}
+ foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg))
+ {
+ result.Add(obj);
+ // 客户端接收消息,广播ScoketObject到每个UIModel
+ if (ClientSocket is null) OnSocketReceive(obj);
+ }
}
- foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects(msg))
- {
- result.Add(obj);
- // 客户端接收消息,广播ScoketObject到每个UIModel
- if (ClientSocket is null) OnSocketReceive(obj);
- }
+ return [.. result];
+ }
+ catch (Exception e)
+ {
+ TXTHelper.AppendErrorLog(e.GetErrorInfo());
+ return [];
}
- return [.. result];
}
#endregion