mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2025-04-21 19:49:34 +08:00
针对服务器端的新功能支持与改进 (#90)
* 添加SQLite模式 * 将Hashtable转为Dictionary<string, object>,因为它具有性能优势 * 添加GamingRequest用于区分Gaming * 模组中AfterLoad方法现已移动至加载器完全加载完毕后触发 * 删除了服务器对GameModule的加载,现在只会加载GameModuleServer
This commit is contained in:
parent
622dbeb765
commit
2de1e57e0c
@ -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
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
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
|
||||
/// <para/>警告:<see cref="HTTPClient"/> 调用此方法将抛出异常。请调用并等待 <see cref="SendRequestAsync"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="AsyncRequestException"></exception>
|
||||
/// <exception cref="AsyncSendException"></exception>
|
||||
public RequestResult SendRequest()
|
||||
{
|
||||
Worker?.SendRequest();
|
||||
@ -177,11 +174,11 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
|
||||
{
|
||||
if (Worker != null)
|
||||
{
|
||||
return GetHashtableJsonObject<T>(Worker.ResultData, key);
|
||||
return GetDictionaryJsonObject<T>(Worker.ResultData, key);
|
||||
}
|
||||
else if (GamingWorker != null)
|
||||
{
|
||||
return GetHashtableJsonObject<T>(GamingWorker.ResultData, key);
|
||||
return GetDictionaryJsonObject<T>(GamingWorker.ResultData, key);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
@ -191,8 +188,8 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
|
||||
/// </summary>
|
||||
private class SocketRequest : SocketHandlerController
|
||||
{
|
||||
public Hashtable RequestData { get; } = [];
|
||||
public Hashtable ResultData => _ResultData;
|
||||
public Dictionary<string, object> RequestData { get; } = [];
|
||||
public Dictionary<string, object> 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<string, object> _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<Hashtable>(2) ?? [];
|
||||
_ResultData = SocketObject.GetParam<Dictionary<string, object>>(2) ?? [];
|
||||
_Result = RequestResult.Success;
|
||||
}
|
||||
}
|
||||
@ -314,8 +311,8 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
|
||||
/// </summary>
|
||||
private class GamingRequest : SocketHandlerController
|
||||
{
|
||||
public Hashtable RequestData { get; } = [];
|
||||
public Hashtable ResultData => _ResultData;
|
||||
public Dictionary<string, object> RequestData { get; } = [];
|
||||
public Dictionary<string, object> 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<string, object> _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<GamingType>(0);
|
||||
Guid id = SocketObject.GetParam<Guid>(1);
|
||||
@ -418,7 +415,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
|
||||
if (!IsLongRunning) Dispose();
|
||||
Work = SocketObject;
|
||||
Working = false;
|
||||
_ResultData = SocketObject.GetParam<Hashtable>(2) ?? [];
|
||||
_ResultData = SocketObject.GetParam<Dictionary<string, object>>(2) ?? [];
|
||||
_Result = RequestResult.Success;
|
||||
}
|
||||
}
|
||||
@ -433,15 +430,15 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化Hashtable中的Json对象
|
||||
/// 反序列化Dictionary中的Json对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="hashtable"></param>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static T? GetHashtableJsonObject<T>(Hashtable hashtable, string key)
|
||||
public static T? GetDictionaryJsonObject<T>(Dictionary<string, object> dict, string key)
|
||||
{
|
||||
return Service.JsonManager.GetObject<T>(hashtable, key);
|
||||
return Service.JsonManager.GetObject<T>(dict, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -17,7 +17,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
/// 当前的行动顺序
|
||||
/// </summary>
|
||||
public List<Character> Queue => _queue;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前已死亡的角色顺序(第一个是最早死的)
|
||||
/// </summary>
|
||||
@ -342,7 +342,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
// 技能列表
|
||||
List<Skill> 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<Item> 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;
|
||||
|
@ -15,7 +15,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
/// <summary>
|
||||
/// 适用于服务器的模组集
|
||||
/// </summary>
|
||||
public Dictionary<string, GameModuleServer> ServerModules { get; } = [];
|
||||
public Dictionary<string, GameModuleServer> ModuleServers { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 游戏地图集
|
||||
@ -37,11 +37,6 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
/// </summary>
|
||||
public Dictionary<string, ItemModule> Items { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 客户端模组与服务器模组的关联字典
|
||||
/// </summary>
|
||||
public Dictionary<GameModule, GameModuleServer?> AssociatedServers { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 已加载的模组DLL名称对应的路径
|
||||
/// </summary>
|
||||
@ -52,7 +47,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
/// <summary>
|
||||
/// 传入 <see cref="FunGameInfo.FunGame"/> 类型来创建指定端的模组读取器
|
||||
/// <para>runtime = <see cref="FunGameInfo.FunGame.FunGame_Desktop"/> 时,仅读取 <seealso cref="Modules"/></para>
|
||||
/// <para>runtime = <see cref="FunGameInfo.FunGame.FunGame_Server"/> 时,都会读取,并且生成关联字典 <see cref="AssociatedServers"/></para>
|
||||
/// <para>runtime = <see cref="FunGameInfo.FunGame.FunGame_Server"/> 时,仅读取 <seealso cref="ModuleServers"/></para>
|
||||
/// <seealso cref="Maps"/> 都会读取
|
||||
/// </summary>
|
||||
/// <param name="runtime">传入 <see cref="FunGameInfo.FunGame"/> 类型来创建指定端的模组读取器</param>
|
||||
@ -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
|
||||
/// <returns></returns>
|
||||
public GameModuleServer GetServerMode(string name)
|
||||
{
|
||||
return ServerModules[name];
|
||||
return ModuleServers[name];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -217,6 +217,15 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
/// <returns></returns>
|
||||
public static T? JsonDeserializeFromHashtable<T>(Hashtable hashtable, string key) => Service.JsonManager.GetObject<T>(hashtable, key);
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化Dictionary中的Json对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static T? JsonDeserializeFromDictionary<T>(Dictionary<string, object> dict, string key) => Service.JsonManager.GetObject<T>(dict, key);
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化IEnumerable中的Json对象
|
||||
/// </summary>
|
||||
|
@ -75,6 +75,15 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
||||
/// <returns></returns>
|
||||
public T? GetObject<T>(Hashtable table, string key) => JsonManager.GetObject<T>(table, key, options);
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化Dictionary中Key对应的Json对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public T? GetObject<T>(Dictionary<string, object> dict, string key) => JsonManager.GetObject<T>(dict, key, options);
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化IEnumerable中的Json对象 可指定反序列化选项
|
||||
/// </summary>
|
||||
@ -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() }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -1006,7 +1006,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色实例的名字、昵称
|
||||
/// </summary>
|
||||
@ -1122,7 +1122,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
builder.Append(skill.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (EquipSlot.Any())
|
||||
{
|
||||
builder.AppendLine("== 装备栏 ==");
|
||||
|
@ -20,7 +20,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// 物品的通用描述
|
||||
/// </summary>
|
||||
public virtual string GeneralDescription { get; set; } = "";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 物品的背景故事
|
||||
/// </summary>
|
||||
@ -45,7 +45,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// 装备槽位
|
||||
/// </summary>
|
||||
public virtual EquipSlotType EquipSlotType { get; set; } = EquipSlotType.None;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 武器类型(如果是武器)
|
||||
/// </summary>
|
||||
@ -65,7 +65,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// 是否可用(涉及冷却和禁用等)
|
||||
/// </summary>
|
||||
public bool Enable { get; set; } = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否是局内使用的物品(局内是指对角色生效的物品)
|
||||
/// </summary>
|
||||
@ -95,7 +95,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// 是否允许交易
|
||||
/// </summary>
|
||||
public bool IsTradable { get; set; } = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下次可交易的时间
|
||||
/// </summary>
|
||||
@ -160,7 +160,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
}
|
||||
if (Character != null) OnItemEquipped(Character, this, type);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当取消装备物品时
|
||||
/// </summary>
|
||||
@ -236,7 +236,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当物品被玩家使用时
|
||||
/// </summary>
|
||||
|
@ -19,7 +19,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// 技能描述
|
||||
/// </summary>
|
||||
public virtual string Description { get; set; } = "";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 技能的通用描述
|
||||
/// </summary>
|
||||
@ -145,7 +145,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// 游戏中的行动顺序表实例,在技能效果被触发时,此实例会获得赋值,使用时需要判断其是否存在
|
||||
/// </summary>
|
||||
public ActionQueue? ActionQueue { get; set; } = null;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 技能是否属于某个物品
|
||||
/// </summary>
|
||||
@ -302,7 +302,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
{
|
||||
return Id + "." + Name;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 判断两个技能是否相同 检查Id.Name
|
||||
/// </summary>
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
<NoWarn>1701;1702;CS1591;CS1587</NoWarn>
|
||||
<NoWarn>1701;1702;CS1591;CS1587;IDE0130</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
<NoWarn>1701;1702;CS1591;CS1587</NoWarn>
|
||||
<NoWarn>1701;1702;CS1591;CS1587;IDE0130</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<User> Users, IServerModel RoomMasterServerModel, Dictionary<string, IServerModel> ServerModels, params object[] args);
|
||||
|
||||
public Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data);
|
||||
public Dictionary<string, object> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
/// <summary>
|
||||
/// 客户端的套接字实例
|
||||
/// </summary>
|
||||
public abstract ClientSocket? Socket { get; }
|
||||
public abstract ISocketMessageProcessor? Socket { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户端的用户实例,在用户登录后有效
|
||||
@ -31,6 +32,11 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
||||
/// </summary>
|
||||
public bool IsDebugMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户端的游戏模组服务器
|
||||
/// </summary>
|
||||
public GameModuleServer? NowGamingServer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 向客户端发送消息
|
||||
/// </summary>
|
||||
@ -38,7 +44,7 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
||||
/// <param name="type"></param>
|
||||
/// <param name="objs"></param>
|
||||
/// <returns></returns>
|
||||
public bool Send(ClientSocket socket, SocketMessageType type, params object[] objs);
|
||||
public bool Send(ISocketMessageProcessor socket, SocketMessageType type, params object[] objs);
|
||||
|
||||
/// <summary>
|
||||
/// 向客户端发送系统消息
|
||||
@ -58,15 +64,15 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
||||
|
||||
/// <summary>
|
||||
/// 开始接收客户端消息
|
||||
/// <para>请勿在 <see cref="Library.Common.Addon.GameModuleServer"/> 中调用此方法</para>
|
||||
/// <para>请勿在 <see cref="GameModuleServer"/> 中调用此方法</para>
|
||||
/// </summary>
|
||||
/// <param name="socket"></param>
|
||||
/// <returns></returns>
|
||||
public bool Read(ClientSocket socket);
|
||||
public bool Read(ISocketMessageProcessor socket);
|
||||
|
||||
/// <summary>
|
||||
/// 启动对客户端的监听
|
||||
/// <para>请勿在 <see cref="Library.Common.Addon.GameModuleServer"/> 中调用此方法</para>
|
||||
/// <para>请勿在 <see cref="GameModuleServer"/> 中调用此方法</para>
|
||||
/// </summary>
|
||||
public void Start();
|
||||
}
|
||||
|
15
Interface/Base/ISocketMessageProcessor.cs
Normal file
15
Interface/Base/ISocketMessageProcessor.cs
Normal file
@ -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<SocketResult> SendAsync(SocketMessageType type, params object[] objs);
|
||||
public void Close();
|
||||
}
|
||||
}
|
10
Interface/Base/Sockets/IWebSocket.cs
Normal file
10
Interface/Base/Sockets/IWebSocket.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
/// </summary>
|
||||
public interface IGamingEventHandler
|
||||
{
|
||||
public delegate void GamingEventHandler(object sender, GamingEventArgs e, Hashtable data);
|
||||
public delegate void GamingEventHandler(object sender, GamingEventArgs e, Dictionary<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> 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<string, object> data);
|
||||
}
|
||||
}
|
||||
|
@ -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<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingDisconnectEvent
|
||||
{
|
||||
public void GamingDisconnectEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingDisconnectEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingReconnectEvent
|
||||
{
|
||||
public void GamingReconnectEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingReconnectEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingBanCharacterEvent
|
||||
{
|
||||
public void GamingBanCharacterEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingBanCharacterEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingPickCharacterEvent
|
||||
{
|
||||
public void GamingPickCharacterEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingPickCharacterEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingRandomEvent
|
||||
{
|
||||
public void GamingRandomEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingRandomEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingRoundEvent
|
||||
{
|
||||
public void GamingRoundEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingRoundEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingLevelUpEvent
|
||||
{
|
||||
public void GamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingLevelUpEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingMoveEvent
|
||||
{
|
||||
public void GamingMoveEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingMoveEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingAttackEvent
|
||||
{
|
||||
public void GamingAttackEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingAttackEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingSkillEvent
|
||||
{
|
||||
public void GamingSkillEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingSkillEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingItemEvent
|
||||
{
|
||||
public void GamingItemEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingItemEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingMagicEvent
|
||||
{
|
||||
public void GamingMagicEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingMagicEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingBuyEvent
|
||||
{
|
||||
public void GamingBuyEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingBuyEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingSuperSkillEvent
|
||||
{
|
||||
public void GamingSuperSkillEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingSuperSkillEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingPauseEvent
|
||||
{
|
||||
public void GamingPauseEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingPauseEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingUnpauseEvent
|
||||
{
|
||||
public void GamingUnpauseEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingUnpauseEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingSurrenderEvent
|
||||
{
|
||||
public void GamingSurrenderEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingSurrenderEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingUpdateInfoEvent
|
||||
{
|
||||
public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
|
||||
public interface IGamingPunishEvent
|
||||
{
|
||||
public void GamingPunishEvent(object sender, GamingEventArgs e, Hashtable data);
|
||||
public void GamingPunishEvent(object sender, GamingEventArgs e, Dictionary<string, object> data);
|
||||
}
|
||||
}
|
||||
|
@ -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<string, object> data)
|
||||
{
|
||||
// 在下方的Server示例中,服务器发来的data中,包含check字符串,因此客户端要主动发起确认连接的请求。
|
||||
if (data.ContainsKey("info_type"))
|
||||
{
|
||||
// 反序列化得到指定key的值
|
||||
string info_type = DataRequest.GetHashtableJsonObject<string>(data, "info_type") ?? "";
|
||||
string info_type = DataRequest.GetDictionaryJsonObject<string>(data, "info_type") ?? "";
|
||||
if (info_type == "check")
|
||||
{
|
||||
Guid token = DataRequest.GetHashtableJsonObject<Guid>(data, "connect_token");
|
||||
Guid token = DataRequest.GetDictionaryJsonObject<Guid>(data, "connect_token");
|
||||
// 发起连接确认请求
|
||||
DataRequest request = Controller.NewDataRequest(GamingType.Connect);
|
||||
// 传递参数
|
||||
@ -143,7 +144,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
|
||||
}
|
||||
|
||||
private readonly List<User> ConnectedUser = [];
|
||||
private readonly Dictionary<string, Hashtable> UserData = [];
|
||||
private readonly Dictionary<string, Dictionary<string, object>> UserData = [];
|
||||
|
||||
private async Task Test()
|
||||
{
|
||||
@ -154,7 +155,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
|
||||
// 在FunGame项目中,建议永远使用客户端主动发起请求,因为服务器主动发起的实现难度较高
|
||||
// 下面的演示基于综合的两种情况:服务器主动发送通知,客户端收到后,发起确认
|
||||
// UpdateInfo是一个灵活的类型。如果发送check字符串,意味着服务器要求客户端发送确认
|
||||
Hashtable data = [];
|
||||
Dictionary<string, object> 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<string, object>? 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<string, object> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data)
|
||||
{
|
||||
Hashtable result = [];
|
||||
Dictionary<string, object> result = [];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GamingType.Connect:
|
||||
// 编写处理“连接”命令的逻辑
|
||||
// 如果需要处理客户端传递的参数:获取与客户端约定好的参数key对应的值
|
||||
string un = NetworkUtility.JsonDeserializeFromHashtable<string>(data, "username") ?? "";
|
||||
Guid token = NetworkUtility.JsonDeserializeFromHashtable<Guid>(data, "connect_token");
|
||||
if (un == username && UserData.TryGetValue(username, out Hashtable? value) && value != null && (value["connect_token"]?.Equals(token) ?? false))
|
||||
string un = NetworkUtility.JsonDeserializeFromDictionary<string>(data, "username") ?? "";
|
||||
Guid token = NetworkUtility.JsonDeserializeFromDictionary<Guid>(data, "connect_token");
|
||||
if (un == username && UserData.TryGetValue(username, out Dictionary<string, object>? 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
public abstract RoomType RoomType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否隐藏主界面
|
||||
/// </summary>
|
||||
public abstract bool HideMain { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否连接其他的服务器模组
|
||||
/// </summary>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模组加载后需要做的事
|
||||
/// 模组完全加载后需要做的事
|
||||
/// </summary>
|
||||
protected virtual void AfterLoad()
|
||||
public virtual void AfterLoad(params object[] args)
|
||||
{
|
||||
// override
|
||||
}
|
||||
@ -142,7 +144,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
||||
/// 允许返回false来阻止加载此模组
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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<string, object> data)
|
||||
{
|
||||
GamingConnect?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingDisconnectEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingDisconnectEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingDisconnect?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingReconnectEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingReconnectEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingReconnect?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingBanCharacterEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingBanCharacterEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingBanCharacter?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingPickCharacterEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingPickCharacterEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingPickCharacter?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingRandomEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingRandomEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingRandom?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingRoundEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingRoundEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingRound?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingLevelUpEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingLevelUp?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingMoveEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingMoveEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingMove?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingAttackEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingAttackEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingAttack?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingSkillEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingSkillEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingSkill?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingItemEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingItemEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingItem?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingMagicEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingMagicEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingMagic?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingBuyEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingBuyEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingBuy?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingSuperSkillEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingSuperSkillEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingSuperSkill?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingPauseEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingPauseEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingPause?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingUnpauseEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingUnpauseEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingUnpause?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingSurrenderEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingSurrenderEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingSurrender?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingUpdateInfoEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingUpdateInfo?.Invoke(sender, e, data);
|
||||
}
|
||||
|
||||
public void OnGamingPunishEvent(object sender, GamingEventArgs e, Hashtable data)
|
||||
public void OnGamingPunishEvent(object sender, GamingEventArgs e, Dictionary<string, object> data)
|
||||
{
|
||||
GamingPunish?.Invoke(sender, e, data);
|
||||
}
|
||||
|
@ -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
|
||||
/// <param name="username">发送此消息的账号</param>
|
||||
/// <param name="type">消息类型</param>
|
||||
/// <param name="data">消息参数</param>
|
||||
/// <returns>底层会将哈希表中的数据发送给客户端</returns>
|
||||
public abstract Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data);
|
||||
/// <returns>底层会将字典中的数据发送给客户端</returns>
|
||||
public abstract Dictionary<string, object> GamingMessageHandler(string username, GamingType type, Dictionary<string, object> data);
|
||||
|
||||
/// <summary>
|
||||
/// 加载标记
|
||||
@ -94,16 +93,14 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
||||
{
|
||||
// 模组加载后,不允许再次加载此模组
|
||||
IsLoaded = true;
|
||||
// 如果加载后需要执行代码,请重写AfterLoad方法
|
||||
AfterLoad();
|
||||
}
|
||||
return IsLoaded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模组加载后需要做的事
|
||||
/// 模组完全加载后需要做的事
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给客户端发送局内消息
|
||||
/// </summary>
|
||||
/// <param name="clients"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param>
|
||||
protected virtual void SendGamingMessage(IEnumerable<IServerModel> clients, GamingType type, Dictionary<string, object> data)
|
||||
{
|
||||
// 发送局内消息
|
||||
foreach (IServerModel s in clients)
|
||||
{
|
||||
if (s != null && s.Socket != null)
|
||||
{
|
||||
s.Send(s.Socket, SocketMessageType.Gaming, type, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给客户端发送消息
|
||||
/// </summary>
|
||||
/// <param name="clients"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="args"></param>
|
||||
protected virtual void Send(IEnumerable<IServerModel> clients, SocketMessageType type, params object[] args)
|
||||
{
|
||||
// 发送消息
|
||||
foreach (IServerModel s in clients)
|
||||
{
|
||||
if (s != null && s.Socket != null)
|
||||
{
|
||||
s.Send(s.Socket, type, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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<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)
|
||||
|
43
Library/Common/Network/ClientWebSocket.cs
Normal file
43
Library/Common/Network/ClientWebSocket.cs
Normal file
@ -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<SocketResult> SendAsync(SocketMessageType type, params object[] objs)
|
||||
{
|
||||
return await HTTPManager.Send(Instance, new(type, token, objs));
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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<Guid, WebSocket> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<IServerModel> ClientList => OnlineClients.GetList();
|
||||
public List<IServerModel> UserList => OnlineUsers.GetList();
|
||||
@ -25,38 +21,38 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
||||
private readonly ModelManager<IServerModel> OnlineClients;
|
||||
private readonly ModelManager<IServerModel> 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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -44,7 +44,7 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
||||
/// 默认的时间格式 yyyy-MM-dd HH:mm:ss.fff
|
||||
/// </summary>
|
||||
public static string GeneralDateTimeFormat => "yyyy-MM-dd HH:mm:ss.fff";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// yyyy年MM月dd日 HH:mm:ss
|
||||
/// </summary>
|
||||
|
@ -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
|
||||
/// 无特殊效果
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 这是来自装备的特效
|
||||
/// </summary>
|
||||
@ -844,4 +845,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
|
||||
Plugin,
|
||||
GameModule
|
||||
}
|
||||
|
||||
public enum SQLMode
|
||||
{
|
||||
None,
|
||||
MySQL,
|
||||
SQLite
|
||||
}
|
||||
}
|
||||
|
@ -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)";
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
/// <param name="type">消息类型</param>
|
||||
/// <param name="data">接收到的数据</param>
|
||||
public void GamingHandler(GamingType type, Hashtable data)
|
||||
public void GamingHandler(GamingType type, Dictionary<string, object> data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -137,102 +133,102 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
}
|
||||
|
||||
private void Connect(Hashtable data)
|
||||
private void Connect(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingConnectEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Disconnect(Hashtable data)
|
||||
private void Disconnect(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingDisconnectEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Reconnect(Hashtable data)
|
||||
private void Reconnect(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingReconnectEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void BanCharacter(Hashtable data)
|
||||
private void BanCharacter(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingBanCharacterEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void PickCharacter(Hashtable data)
|
||||
private void PickCharacter(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingPickCharacterEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Random(Hashtable data)
|
||||
private void Random(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingRandomEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Round(Hashtable data)
|
||||
private void Round(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingRoundEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void LevelUp(Hashtable data)
|
||||
private void LevelUp(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingLevelUpEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Move(Hashtable data)
|
||||
private void Move(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingMoveEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Attack(Hashtable data)
|
||||
private void Attack(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingAttackEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Skill(Hashtable data)
|
||||
private void Skill(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingSkillEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Item(Hashtable data)
|
||||
private void Item(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingItemEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Magic(Hashtable data)
|
||||
private void Magic(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingMagicEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Buy(Hashtable data)
|
||||
private void Buy(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingBuyEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void SuperSkill(Hashtable data)
|
||||
private void SuperSkill(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingSuperSkillEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Pause(Hashtable data)
|
||||
private void Pause(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingPauseEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Unpause(Hashtable data)
|
||||
private void Unpause(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingUnpauseEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Surrender(Hashtable data)
|
||||
private void Surrender(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingSurrenderEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void UpdateInfo(Hashtable data)
|
||||
private void UpdateInfo(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingUpdateInfoEvent(this, EventArgs, data);
|
||||
}
|
||||
|
||||
private void Punish(Hashtable data)
|
||||
private void Punish(Dictionary<string, object> data)
|
||||
{
|
||||
GameModule.OnGamingPunishEvent(this, EventArgs, data);
|
||||
}
|
||||
|
@ -118,7 +118,6 @@ namespace Milimoe.FunGame.Core.Service
|
||||
/// <summary>
|
||||
/// 从modules目录加载所有适用于服务器的模组
|
||||
/// </summary>
|
||||
/// <param name="modules"></param>
|
||||
/// <param name="servers"></param>
|
||||
/// <param name="characters"></param>
|
||||
/// <param name="skills"></param>
|
||||
@ -126,7 +125,7 @@ namespace Milimoe.FunGame.Core.Service
|
||||
/// <param name="delegates"></param>
|
||||
/// <param name="otherobjs"></param>
|
||||
/// <returns></returns>
|
||||
internal static Dictionary<string, GameModuleServer> LoadGameModulesForServer(Dictionary<string, GameModule> modules, Dictionary<string, GameModuleServer> servers, Dictionary<string, CharacterModule> characters, Dictionary<string, SkillModule> skills, Dictionary<string, ItemModule> items, Hashtable delegates, params object[] otherobjs)
|
||||
internal static Dictionary<string, GameModuleServer> LoadGameModulesForServer(Dictionary<string, GameModuleServer> servers, Dictionary<string, CharacterModule> characters, Dictionary<string, SkillModule> skills, Dictionary<string, ItemModule> 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) =>
|
||||
{
|
||||
|
@ -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<ClientWebSocket?> Connect(Uri uri)
|
||||
internal static async Task<System.Net.WebSockets.ClientWebSocket?> 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<SocketResult> Send(ClientWebSocket socket, SocketObject obj)
|
||||
internal static async Task<SocketResult> 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<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)
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +138,27 @@ namespace Milimoe.FunGame.Core.Service
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化Dictionary中Key对应的Json对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
internal static T? GetObject<T>(Dictionary<string, object> dict, string key)
|
||||
{
|
||||
if (dict.TryGetValue(key, out object? value))
|
||||
{
|
||||
JsonElement? element = (JsonElement?)value;
|
||||
if (element != null)
|
||||
{
|
||||
T? result = ((JsonElement)element).Deserialize<T>(GeneralOptions);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化IEnumerable中的Json对象
|
||||
/// </summary>
|
||||
@ -205,6 +226,28 @@ namespace Milimoe.FunGame.Core.Service
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化Dictionary中Key对应的Json对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
internal static T? GetObject<T>(Dictionary<string, object> dict, string key, JsonSerializerOptions options)
|
||||
{
|
||||
if (dict.TryGetValue(key, out object? value))
|
||||
{
|
||||
JsonElement? element = (JsonElement?)value;
|
||||
if (element != null)
|
||||
{
|
||||
T? result = ((JsonElement)element).Deserialize<T>(options);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化多个Json对象
|
||||
/// 注意必须是相同的Json对象才可以使用此方法解析
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于服务器端向客户端Socket发送信息 [ 异步版 ]
|
||||
/// </summary>
|
||||
/// <param name="ClientSocket">客户端Socket</param>
|
||||
/// <param name="SocketObject">Socket信息容器</param>
|
||||
/// <returns>通信结果</returns>
|
||||
internal static async Task<SocketResult> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于客户端向服务器Socket发送信息
|
||||
/// </summary>
|
||||
@ -163,6 +184,24 @@ namespace Milimoe.FunGame.Core.Service
|
||||
return SocketResult.NotSent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于客户端向服务器Socket发送信息 [ 异步版 ]
|
||||
/// </summary>
|
||||
/// <param name="SocketObject">Socket信息容器</param>
|
||||
/// <returns>通信结果</returns>
|
||||
internal static async Task<SocketResult> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收数据流中的信息
|
||||
/// <para/>如果是服务器接收信息需要传入客户端Socket <paramref name="ClientSocket"/>
|
||||
@ -171,54 +210,62 @@ namespace Milimoe.FunGame.Core.Service
|
||||
/// <returns>SocketObjects</returns>
|
||||
internal static Library.Common.Network.SocketObject[] Receive(Socket? ClientSocket = null)
|
||||
{
|
||||
List<Library.Common.Network.SocketObject> 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<Library.Common.Network.SocketObject> result = [];
|
||||
Socket? tempSocket = ClientSocket is null ? Socket : ClientSocket;
|
||||
if (tempSocket != null)
|
||||
{
|
||||
msg = General.DefaultEncoding.GetString(buffer, 0, length);
|
||||
if (JsonManager.IsCompleteJson<Library.Common.Network.SocketObject>(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<Library.Common.Network.SocketObject>(msg))
|
||||
msg = General.DefaultEncoding.GetString(buffer, 0, length);
|
||||
if (JsonManager.IsCompleteJson<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)
|
||||
foreach (Library.Common.Network.SocketObject obj in JsonManager.GetObjects<Library.Common.Network.SocketObject>(msg))
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
||||
return [];
|
||||
}
|
||||
return [.. result];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
Loading…
x
Reference in New Issue
Block a user