diff --git a/Api/Utility/GameModeLoader.cs b/Api/Utility/GameModeLoader.cs
index aec5b31..3ccd0b1 100644
--- a/Api/Utility/GameModeLoader.cs
+++ b/Api/Utility/GameModeLoader.cs
@@ -1,15 +1,40 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
+using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Service;
namespace Milimoe.FunGame.Core.Api.Utility
{
public class GameModeLoader
{
+ ///
+ /// 适用于客户端的模组集
+ ///
public Dictionary Modes { get; } = [];
+
+ ///
+ /// 适用于服务器的模组集
+ ///
+ public Dictionary ServerModes { get; } = [];
+
+ ///
+ /// 游戏地图集
+ ///
public Dictionary Maps { get; } = [];
+
+ ///
+ /// 角色表
+ ///
public List Characters { get; } = [];
+
+ ///
+ /// 技能表
+ ///
public List Skills { get; } = [];
+
+ ///
+ /// 物品表
+ ///
public List- Items { get; } = [];
private GameModeLoader()
@@ -17,14 +42,38 @@ namespace Milimoe.FunGame.Core.Api.Utility
}
- public static GameModeLoader LoadGameModes(params object[] objs)
+ ///
+ /// 传入 类型来创建指定端的模组读取器
+ /// runtime = 时,仅读取
+ /// runtime = 时,仅读取
+ /// 都会读取
+ ///
+ /// 传入 类型来创建指定端的模组读取器
+ /// 用于构建
+ /// 其他需要传入给插件初始化的对象
+ ///
+ public static GameModeLoader LoadGameModes(FunGameInfo.FunGame runtime, Delegate[] delegates, params object[] otherobjs)
{
GameModeLoader loader = new();
- AddonManager.LoadGameModes(loader.Modes, loader.Characters, loader.Skills, loader.Items, objs);
- AddonManager.LoadGameMaps(loader.Maps, objs);
+ if (runtime == FunGameInfo.FunGame.FunGame_Desktop)
+ {
+ AddonManager.LoadGameModes(loader.Modes, loader.Characters, loader.Skills, loader.Items, delegates, otherobjs);
+ AddonManager.LoadGameMaps(loader.Maps, otherobjs);
+ }
+ else if (runtime == FunGameInfo.FunGame.FunGame_Server)
+ {
+ AddonManager.LoadGameModesForServer(loader.ServerModes, loader.Characters, loader.Skills, loader.Items, delegates, otherobjs);
+ AddonManager.LoadGameMaps(loader.Maps, otherobjs);
+ }
return loader;
}
+ ///
+ /// 获取对应名称的模组实例
+ /// 如果需要取得服务器模组的实例,请调用
+ ///
+ ///
+ ///
public GameMode this[string name]
{
get
@@ -37,6 +86,21 @@ namespace Milimoe.FunGame.Core.Api.Utility
}
}
+ ///
+ /// 获取对应名称的服务器模组实例
+ ///
+ ///
+ ///
+ public GameModeServer GetServerMode(string name)
+ {
+ return ServerModes[name];
+ }
+
+ ///
+ /// 获取对应名称的游戏地图
+ ///
+ ///
+ ///
public GameMap GetGameMap(string name)
{
return Maps[name];
diff --git a/Api/Utility/PluginLoader.cs b/Api/Utility/PluginLoader.cs
index a211bcd..b13738e 100644
--- a/Api/Utility/PluginLoader.cs
+++ b/Api/Utility/PluginLoader.cs
@@ -6,6 +6,10 @@ namespace Milimoe.FunGame.Core.Api.Utility
{
public class PluginLoader
{
+ ///
+ /// 已读取的插件列表
+ /// key 是
+ ///
public Dictionary Plugins { get; } = [];
private PluginLoader()
@@ -13,10 +17,16 @@ namespace Milimoe.FunGame.Core.Api.Utility
}
- public static PluginLoader LoadPlugins(params object[] objs)
+ ///
+ /// 构建一个插件读取器并读取插件
+ ///
+ /// 用于构建
+ /// 其他需要传入给插件初始化的对象
+ ///
+ public static PluginLoader LoadPlugins(Delegate[] delegates, params object[] otherobjs)
{
PluginLoader loader = new();
- AddonManager.LoadPlugins(loader.Plugins, objs);
+ AddonManager.LoadPlugins(loader.Plugins, delegates, otherobjs);
return loader;
}
diff --git a/Controller/AddonController.cs b/Controller/AddonController.cs
new file mode 100644
index 0000000..5021e50
--- /dev/null
+++ b/Controller/AddonController.cs
@@ -0,0 +1,70 @@
+using Milimoe.FunGame.Core.Api.Transmittal;
+using Milimoe.FunGame.Core.Interface;
+using Milimoe.FunGame.Core.Library.Constant;
+
+namespace Milimoe.FunGame.Core.Controller
+{
+ public class AddonController
+ {
+ private IAddon Addon { get; }
+
+ ///
+ /// 输出系统消息
+ ///
+ private Action MaskMethod_WriteLine { get; set; } = new(msg => Console.Write("\r" + msg + "\n\r> "));
+
+ ///
+ /// 基于本地已连接的Socket创建新的数据请求
+ ///
+ private Func MaskMethod_NewDataRequest { get; set; }
+
+ ///
+ /// 基于本地已连接的Socket创建长时间运行的数据请求
+ ///
+ private Func MaskMethod_NewLongRunningDataRequest { get; set; }
+
+ ///
+ /// 输出系统消息
+ ///
+ ///
+ ///
+ public void WriteLine(string msg) => MaskMethod_WriteLine(msg);
+
+ ///
+ /// 基于本地已连接的Socket创建新的数据请求
+ /// 请勿在 中调用此方法
+ ///
+ ///
+ ///
+ public DataRequest NewDataRequest(DataRequestType type) => MaskMethod_NewDataRequest(type);
+
+ ///
+ /// 基于本地已连接的Socket创建长时间运行的数据请求
+ /// 请勿在 中调用此方法
+ ///
+ ///
+ ///
+ public DataRequest NewLongRunningDataRequest(DataRequestType type) => MaskMethod_NewLongRunningDataRequest(type);
+
+ ///
+ /// 新建一个AddonController
+ ///
+ ///
+ ///
+ public AddonController(IAddon Addon, Delegate[] delegates)
+ {
+ this.Addon = Addon;
+ if (delegates.Length > 0) MaskMethod_WriteLine = (Action)delegates[0];
+ if (delegates.Length > 1) MaskMethod_NewDataRequest = (Func)delegates[1];
+ if (delegates.Length > 2) MaskMethod_NewLongRunningDataRequest = (Func)delegates[2];
+ MaskMethod_NewDataRequest ??= new(DefaultNewDataRequest);
+ MaskMethod_NewLongRunningDataRequest ??= new(DefaultNewDataRequest);
+ }
+
+ private DataRequest DefaultNewDataRequest(DataRequestType type)
+ {
+ if (Addon is IGameModeServer) throw new NotSupportedException("请勿在GameModeServer类中调用此方法");
+ else throw new ConnectFailedException();
+ }
+ }
+}
diff --git a/Controller/RunTimeController.cs b/Controller/RunTimeController.cs
index 1357a52..baf9449 100644
--- a/Controller/RunTimeController.cs
+++ b/Controller/RunTimeController.cs
@@ -57,6 +57,26 @@ namespace Milimoe.FunGame.Core.Controller
return result;
}
+
+ ///
+ /// 发送结束游戏反馈
+ ///
+ ///
+ public bool EndGame()
+ {
+ bool result = false;
+
+ try
+ {
+ result = _Socket?.Send(SocketMessageType.EndGame, "") == SocketResult.Success;
+ }
+ catch (Exception e)
+ {
+ WritelnSystemInfo(e.GetErrorInfo());
+ }
+
+ return result;
+ }
///
/// 连接服务器
diff --git a/Docs/FunGame.Core.xml b/Docs/FunGame.Core.xml
index 16a4b25..8cb4136 100644
--- a/Docs/FunGame.Core.xml
+++ b/Docs/FunGame.Core.xml
@@ -331,6 +331,70 @@
+
+
+ 适用于客户端的模组集
+
+
+
+
+ 适用于服务器的模组集
+
+
+
+
+ 游戏地图集
+
+
+
+
+ 角色表
+
+
+
+
+ 技能表
+
+
+
+
+ 物品表
+
+
+
+
+ 传入 类型来创建指定端的模组读取器
+ runtime = 时,仅读取
+ runtime = 时,仅读取
+ 都会读取
+
+ 传入 类型来创建指定端的模组读取器
+ 用于构建
+ 其他需要传入给插件初始化的对象
+
+
+
+
+ 获取对应名称的模组实例
+ 如果需要取得服务器模组的实例,请调用
+
+
+
+
+
+
+ 获取对应名称的服务器模组实例
+
+
+
+
+
+
+ 获取对应名称的游戏地图
+
+
+
+
网络服务工具箱
@@ -698,6 +762,20 @@
Private JsonSerializerOptions
+
+
+ 已读取的插件列表
+ key 是
+
+
+
+
+ 构建一个插件读取器并读取插件
+
+ 用于构建
+ 其他需要传入给插件初始化的对象
+
+
单例表:表中的对象以类名作为Key保存,并以Key获取该对象,Key具有唯一约束
@@ -882,6 +960,51 @@
+
+
+ 输出系统消息
+
+
+
+
+ 基于本地已连接的Socket创建新的数据请求
+
+
+
+
+ 基于本地已连接的Socket创建长时间运行的数据请求
+
+
+
+
+ 输出系统消息
+
+
+
+
+
+
+ 基于本地已连接的Socket创建新的数据请求
+ 请勿在 中调用此方法
+
+
+
+
+
+
+ 基于本地已连接的Socket创建长时间运行的数据请求
+ 请勿在 中调用此方法
+
+
+
+
+
+
+ 新建一个AddonController
+
+
+
+
此类实现服务器连接、断开连接、心跳检测、创建数据请求等功能
@@ -919,6 +1042,12 @@
+
+
+ 发送结束游戏反馈
+
+
+
连接服务器
@@ -1138,6 +1267,70 @@
Key为赛季(long),每个key代表第key赛季,key = 0时为生涯数据。
+
+
+ 服务器实例是否在运行
+
+
+
+
+ 客户端的套接字实例
+
+
+
+
+ 客户端的用户实例,在用户登录后有效
+
+
+
+
+ 客户端的名称,默认是客户端的IP地址
+
+
+
+
+ 客户端是否启动了开发者模式
+
+
+
+
+ 向客户端发送消息
+
+
+
+
+
+
+
+
+ 向客户端发送系统消息
+
+
+
+
+
+
+
+
+
+ 获取客户端的名称,通常未登录时显示为客户端的IP地址,登录后显示为账号名
+
+
+
+
+
+ 开始接收客户端消息
+ 请勿在 中调用此方法
+
+
+
+
+
+
+ 启动对客户端的监听
+ 请勿在 中调用此方法
+
+
窗体继承这些接口便能实现事件,或为插件预留。
@@ -1298,6 +1491,16 @@
模组所使用的地图
+
+
+ 包含了一些常用方法的控制器
+
+
+
+
+ 控制器内部变量
+
+
如模组有界面,请重写此方法
@@ -1332,21 +1535,6 @@
传递委托以便让模组调用
-
-
- 输出系统消息
-
-
-
-
- 基于本地已连接的Socket创建新的数据请求
-
-
-
-
- 基于本地已连接的Socket创建长时间运行的数据请求
-
-
Session对象
@@ -1362,6 +1550,88 @@
绑定事件。在后触发
+
+
+ 模组名称
+
+
+
+
+ 模组描述
+
+
+
+
+ 模组版本
+
+
+
+
+ 模组作者
+
+
+
+
+ 默认地图
+
+
+
+
+ 模组所使用的地图
+
+
+
+
+ 包含了一些常用方法的控制器
+
+
+
+
+ 控制器内部变量
+
+
+
+
+ 启动服务器监听 请在此处实现服务器逻辑
+
+
+
+
+
+
+
+
+
+
+
+ 接收并处理GamingMessage
+
+ 发送此消息的账号
+ 消息类型
+ 消息参数
+ 底层会将哈希表中的数据发送给客户端
+
+
+
+ 加载标记
+
+
+
+
+ 加载模组
+
+
+
+
+ 模组加载后需要做的事
+
+
+
+
+ 允许返回false来阻止加载此模组
+
+
+
模组名称
@@ -1428,6 +1698,16 @@
插件作者
+
+
+ 包含了一些常用方法的控制器
+
+
+
+
+ 控制器内部变量
+
+
加载标记
@@ -1454,21 +1734,6 @@
传递委托以便让插件调用
-
-
- 输出系统消息
-
-
-
-
- 基于本地已连接的Socket创建新的数据请求
-
-
-
-
- 基于本地已连接的Socket创建长时间运行的数据请求
-
-
Session对象
@@ -2043,23 +2308,37 @@
所处的房间
-
+
从plugins目录加载所有插件
-
+
+
-
+
从gamemodes目录加载所有模组
-
-
-
-
+
+
+
+
+
+
+
+
+
+ 从gamemodes目录加载所有适用于服务器的模组
+
+
+
+
+
+
+
diff --git a/Interface/Base/IAddon.cs b/Interface/Base/IAddon.cs
index d27ab52..c612d24 100644
--- a/Interface/Base/IAddon.cs
+++ b/Interface/Base/IAddon.cs
@@ -1,4 +1,6 @@
-namespace Milimoe.FunGame.Core.Interface
+using Milimoe.FunGame.Core.Controller;
+
+namespace Milimoe.FunGame.Core.Interface
{
public interface IAddon
{
diff --git a/Interface/Base/IAddonController.cs b/Interface/Base/IAddonController.cs
new file mode 100644
index 0000000..1ac82bb
--- /dev/null
+++ b/Interface/Base/IAddonController.cs
@@ -0,0 +1,9 @@
+using Milimoe.FunGame.Core.Controller;
+
+namespace Milimoe.FunGame.Core.Interface.Base
+{
+ public interface IAddonController
+ {
+ public AddonController Controller { get; set; }
+ }
+}
diff --git a/Interface/Base/IGameMode.cs b/Interface/Base/IGameMode.cs
index 3d84e97..a6d0830 100644
--- a/Interface/Base/IGameMode.cs
+++ b/Interface/Base/IGameMode.cs
@@ -1,6 +1,8 @@
-namespace Milimoe.FunGame.Core.Interface
+using Milimoe.FunGame.Core.Interface.Base;
+
+namespace Milimoe.FunGame.Core.Interface
{
- public interface IGameMode : IAddon, IGamingConnectEventHandler, IGamingDisconnectEventHandler, IGamingReconnectEventHandler, IGamingBanCharacterEventHandler, IGamingPickCharacterEventHandler,
+ public interface IGameMode : IAddon, IAddonController, IGamingConnectEventHandler, IGamingDisconnectEventHandler, IGamingReconnectEventHandler, IGamingBanCharacterEventHandler, IGamingPickCharacterEventHandler,
IGamingRandomEventHandler, IGamingRoundEventHandler, IGamingLevelUpEventHandler, IGamingMoveEventHandler, IGamingAttackEventHandler, IGamingSkillEventHandler, IGamingItemEventHandler, IGamingMagicEventHandler,
IGamingBuyEventHandler, IGamingSuperSkillEventHandler, IGamingPauseEventHandler, IGamingUnpauseEventHandler, IGamingSurrenderEventHandler, IGamingUpdateInfoEventHandler, IGamingPunishEventHandler
{
diff --git a/Interface/Base/IGameModeServer.cs b/Interface/Base/IGameModeServer.cs
new file mode 100644
index 0000000..a2b6ca7
--- /dev/null
+++ b/Interface/Base/IGameModeServer.cs
@@ -0,0 +1,14 @@
+using System.Collections;
+using Milimoe.FunGame.Core.Entity;
+using Milimoe.FunGame.Core.Interface.Base;
+using Milimoe.FunGame.Core.Library.Constant;
+
+namespace Milimoe.FunGame.Core.Interface
+{
+ public interface IGameModeServer : IAddon, IAddonController
+ {
+ public bool StartServer(string GameMode, Room Room, List Users, IServerModel RoomMasterServerModel, Dictionary OthersServerModel, params object[] args);
+
+ public Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data);
+ }
+}
diff --git a/Interface/Base/IPlugin.cs b/Interface/Base/IPlugin.cs
index 415a436..658b657 100644
--- a/Interface/Base/IPlugin.cs
+++ b/Interface/Base/IPlugin.cs
@@ -1,6 +1,8 @@
-namespace Milimoe.FunGame.Core.Interface
+using Milimoe.FunGame.Core.Interface.Base;
+
+namespace Milimoe.FunGame.Core.Interface
{
- public interface IPlugin : IAddon, IConnectEventHandler, IDisconnectEventHandler, ILoginEventHandler, ILogoutEventHandler, IRegEventHandler, IIntoRoomEventHandler, ISendTalkEventHandler,
+ public interface IPlugin : IAddon, IAddonController, IConnectEventHandler, IDisconnectEventHandler, ILoginEventHandler, ILogoutEventHandler, IRegEventHandler, IIntoRoomEventHandler, ISendTalkEventHandler,
ICreateRoomEventHandler, IQuitRoomEventHandler, IChangeRoomSettingEventHandler, IStartMatchEventHandler, IStartGameEventHandler, IChangeProfileEventHandler, IChangeAccountSettingEventHandler,
IOpenInventoryEventHandler, ISignInEventHandler, IOpenStoreEventHandler, IBuyItemEventHandler, IShowRankingEventHandler, IUseItemEventHandler, IEndGameEventHandler
{
diff --git a/Interface/Base/IServerModel.cs b/Interface/Base/IServerModel.cs
index 6b59bb8..849cfdb 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;
@@ -6,14 +7,68 @@ namespace Milimoe.FunGame.Core.Interface.Base
{
public interface IServerModel
{
+ ///
+ /// 服务器实例是否在运行
+ ///
public abstract bool Running { get; }
+
+ ///
+ /// 客户端的套接字实例
+ ///
public abstract ClientSocket? Socket { get; }
- public abstract Task? Task { get; }
+
+ ///
+ /// 客户端的用户实例,在用户登录后有效
+ ///
public abstract User User { get; }
+
+ ///
+ /// 客户端的名称,默认是客户端的IP地址
+ ///
public abstract string ClientName { get; }
- public abstract bool Read(ClientSocket socket);
- public abstract bool Send(ClientSocket socket, SocketMessageType type, params object[] objs);
- public abstract void Start();
+ ///
+ /// 客户端是否启动了开发者模式
+ ///
+ public bool IsDebugMode { get; }
+
+ ///
+ /// 向客户端发送消息
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool Send(ClientSocket socket, SocketMessageType type, params object[] objs);
+
+ ///
+ /// 向客户端发送系统消息
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendSystemMessage(ShowMessageType showtype, string msg, string title, int autoclose, params string[] usernames);
+
+ ///
+ /// 获取客户端的名称,通常未登录时显示为客户端的IP地址,登录后显示为账号名
+ ///
+ ///
+ public string GetClientName();
+
+ ///
+ /// 开始接收客户端消息
+ /// 请勿在 中调用此方法
+ ///
+ ///
+ ///
+ public bool Read(ClientSocket socket);
+
+ ///
+ /// 启动对客户端的监听
+ /// 请勿在 中调用此方法
+ ///
+ public void Start();
}
}
diff --git a/Interface/Event/GamingEvents.cs b/Interface/Event/GamingEvents.cs
index 871ae84..8e4c074 100644
--- a/Interface/Event/GamingEvents.cs
+++ b/Interface/Event/GamingEvents.cs
@@ -52,14 +52,6 @@ namespace Milimoe.FunGame.Core.Interface
public void FailedGamingRandomEvent(object sender, GamingEventArgs e, Hashtable data);
}
- public interface IGamingLevelUpEvent
- {
- public void BeforeGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
- public void AfterGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
- public void SucceedGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
- public void FailedGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
- }
-
public interface IGamingRoundEvent
{
public void BeforeGamingRoundEvent(object sender, GamingEventArgs e, Hashtable data);
@@ -68,6 +60,14 @@ namespace Milimoe.FunGame.Core.Interface
public void FailedGamingRoundEvent(object sender, GamingEventArgs e, Hashtable data);
}
+ public interface IGamingLevelUpEvent
+ {
+ public void BeforeGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void AfterGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void SucceedGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
+ public void FailedGamingLevelUpEvent(object sender, GamingEventArgs e, Hashtable data);
+ }
+
public interface IGamingMoveEvent
{
public void BeforeGamingMoveEvent(object sender, GamingEventArgs e, Hashtable data);
diff --git a/Library/Common/Addon/GameMode.cs b/Library/Common/Addon/GameMode.cs
index 7e1c199..73140d1 100644
--- a/Library/Common/Addon/GameMode.cs
+++ b/Library/Common/Addon/GameMode.cs
@@ -1,8 +1,7 @@
using System.Collections;
-using Milimoe.FunGame.Core.Api.Transmittal;
+using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface;
using Milimoe.FunGame.Core.Library.Common.Event;
-using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Library.Common.Addon
@@ -39,6 +38,20 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
///
public abstract string[] Maps { get; }
+ ///
+ /// 包含了一些常用方法的控制器
+ ///
+ public AddonController Controller
+ {
+ get => _Controller ?? throw new NotImplementedException();
+ set => _Controller = value;
+ }
+
+ ///
+ /// 控制器内部变量
+ ///
+ protected AddonController? _Controller;
+
///
/// 如模组有界面,请重写此方法
/// 此方法会在StartGame时调用
@@ -101,28 +114,10 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
///
private void Init(params object[] objs)
{
- if (objs.Length > 0) WritelnSystemInfo = (Action)objs[0];
- if (objs.Length > 1) NewDataRequest = (Func)objs[1];
- if (objs.Length > 2) NewLongRunningDataRequest = (Func)objs[2];
- if (objs.Length > 3) Session = (Session)objs[3];
- if (objs.Length > 4) Config = (FunGameConfig)objs[4];
+ if (objs.Length > 0) Session = (Session)objs[0];
+ if (objs.Length > 1) Config = (FunGameConfig)objs[1];
}
- ///
- /// 输出系统消息
- ///
- protected Action WritelnSystemInfo = new(msg => Console.Write("\r" + msg + "\n\r> "));
-
- ///
- /// 基于本地已连接的Socket创建新的数据请求
- ///
- protected Func NewDataRequest = new(type => throw new ConnectFailedException());
-
- ///
- /// 基于本地已连接的Socket创建长时间运行的数据请求
- ///
- protected Func NewLongRunningDataRequest = new(type => throw new ConnectFailedException());
-
///
/// Session对象
///
diff --git a/Library/Common/Addon/GameModeServer.cs b/Library/Common/Addon/GameModeServer.cs
new file mode 100644
index 0000000..f7b57e1
--- /dev/null
+++ b/Library/Common/Addon/GameModeServer.cs
@@ -0,0 +1,119 @@
+using System.Collections;
+using Milimoe.FunGame.Core.Controller;
+using Milimoe.FunGame.Core.Entity;
+using Milimoe.FunGame.Core.Interface;
+using Milimoe.FunGame.Core.Interface.Base;
+using Milimoe.FunGame.Core.Library.Constant;
+
+namespace Milimoe.FunGame.Core.Library.Common.Addon
+{
+ public abstract class GameModeServer : IGameModeServer
+ {
+ ///
+ /// 模组名称
+ ///
+ public abstract string Name { get; }
+
+ ///
+ /// 模组描述
+ ///
+ public abstract string Description { get; }
+
+ ///
+ /// 模组版本
+ ///
+ public abstract string Version { get; }
+
+ ///
+ /// 模组作者
+ ///
+ public abstract string Author { get; }
+
+ ///
+ /// 默认地图
+ ///
+ public abstract string DefaultMap { get; }
+
+ ///
+ /// 模组所使用的地图
+ ///
+ public abstract string[] Maps { get; }
+
+ ///
+ /// 包含了一些常用方法的控制器
+ ///
+ public AddonController Controller
+ {
+ get => _Controller ?? throw new NotImplementedException();
+ set => _Controller = value;
+ }
+
+ ///
+ /// 控制器内部变量
+ ///
+ protected AddonController? _Controller;
+
+ ///
+ /// 启动服务器监听 请在此处实现服务器逻辑
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public abstract bool StartServer(string GameMode, Room Room, List Users, IServerModel RoomMasterServerModel, Dictionary OthersServerModel, params object[] Args);
+
+ ///
+ /// 接收并处理GamingMessage
+ ///
+ /// 发送此消息的账号
+ /// 消息类型
+ /// 消息参数
+ /// 底层会将哈希表中的数据发送给客户端
+ public abstract Hashtable GamingMessageHandler(string username, GamingType type, Hashtable data);
+
+ ///
+ /// 加载标记
+ ///
+ private bool IsLoaded = false;
+
+ ///
+ /// 加载模组
+ ///
+ public bool Load(params object[] objs)
+ {
+ if (IsLoaded)
+ {
+ return false;
+ }
+ // BeforeLoad可以阻止加载此模组
+ if (BeforeLoad())
+ {
+ // 模组加载后,不允许再次加载此模组
+ IsLoaded = true;
+ // 如果加载后需要执行代码,请重写AfterLoad方法
+ AfterLoad();
+ }
+ return IsLoaded;
+ }
+
+ ///
+ /// 模组加载后需要做的事
+ ///
+ protected virtual void AfterLoad()
+ {
+ // override
+ }
+
+ ///
+ /// 允许返回false来阻止加载此模组
+ ///
+ ///
+ protected virtual bool BeforeLoad()
+ {
+ return true;
+ }
+ }
+}
diff --git a/Library/Common/Addon/Plugin.cs b/Library/Common/Addon/Plugin.cs
index ae189c1..1829e87 100644
--- a/Library/Common/Addon/Plugin.cs
+++ b/Library/Common/Addon/Plugin.cs
@@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Api.Transmittal;
+using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface;
using Milimoe.FunGame.Core.Library.Common.Event;
using Milimoe.FunGame.Core.Library.Constant;
@@ -28,6 +29,20 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
///
public abstract string Author { get; }
+ ///
+ /// 包含了一些常用方法的控制器
+ ///
+ public AddonController Controller
+ {
+ get => _Controller ?? throw new NotImplementedException();
+ set => _Controller = value;
+ }
+
+ ///
+ /// 控制器内部变量
+ ///
+ protected AddonController? _Controller;
+
///
/// 加载标记
///
@@ -79,28 +94,10 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
///
private void Init(params object[] objs)
{
- if (objs.Length > 0) WritelnSystemInfo = (Action)objs[0];
- if (objs.Length > 1) NewDataRequest = (Func)objs[1];
- if (objs.Length > 2) NewLongRunningDataRequest = (Func)objs[2];
- if (objs.Length > 3) Session = (Session)objs[3];
- if (objs.Length > 4) Config = (FunGameConfig)objs[4];
+ if (objs.Length > 0) Session = (Session)objs[0];
+ if (objs.Length > 1) Config = (FunGameConfig)objs[1];
}
- ///
- /// 输出系统消息
- ///
- protected Action WritelnSystemInfo = new(msg => Console.Write("\r" + msg + "\n\r> "));
-
- ///
- /// 基于本地已连接的Socket创建新的数据请求
- ///
- protected Func NewDataRequest = new(type => throw new ConnectFailedException());
-
- ///
- /// 基于本地已连接的Socket创建长时间运行的数据请求
- ///
- protected Func NewLongRunningDataRequest = new(type => throw new ConnectFailedException());
-
///
/// Session对象
///
diff --git a/Library/Constant/TypeEnum.cs b/Library/Constant/TypeEnum.cs
index f74a027..2066da2 100644
--- a/Library/Constant/TypeEnum.cs
+++ b/Library/Constant/TypeEnum.cs
@@ -380,4 +380,17 @@ namespace Milimoe.FunGame.Core.Library.Constant
Column,
Username
}
+
+ public enum InvokeMessageType
+ {
+ None,
+ Core,
+ Error,
+ System,
+ Api,
+ Interface,
+ DataRequest,
+ Plugin,
+ GameMode
+ }
}
diff --git a/Service/AddonManager.cs b/Service/AddonManager.cs
index 13fe8e8..75abb9b 100644
--- a/Service/AddonManager.cs
+++ b/Service/AddonManager.cs
@@ -11,9 +11,10 @@ namespace Milimoe.FunGame.Core.Service
/// 从plugins目录加载所有插件
///
///
- ///
+ ///
+ ///
///
- internal static Dictionary LoadPlugins(Dictionary plugins, params object[] objs)
+ internal static Dictionary LoadPlugins(Dictionary plugins, Delegate[] delegates, params object[] otherobjs)
{
if (!Directory.Exists(ReflectionSet.PluginFolderPath)) return plugins;
@@ -28,8 +29,9 @@ namespace Milimoe.FunGame.Core.Service
foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Plugin))))
{
Plugin? instance = (Plugin?)Activator.CreateInstance(type);
- if (instance != null && instance.Load(objs) && instance.Name.Trim() != "")
+ if (instance != null && instance.Load(otherobjs) && instance.Name.Trim() != "")
{
+ instance.Controller = new(instance, delegates);
plugins.TryAdd(instance.Name, instance);
}
}
@@ -42,12 +44,13 @@ namespace Milimoe.FunGame.Core.Service
/// 从gamemodes目录加载所有模组
///
///
- ///
- ///
- ///
- ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- internal static Dictionary LoadGameModes(Dictionary gamemodes, List Characters, List Skills, List
- Items, params object[] objs)
+ internal static Dictionary LoadGameModes(Dictionary gamemodes, List characters, List skills, List
- items, Delegate[] delegates, params object[] otherobjs)
{
if (!Directory.Exists(ReflectionSet.GameModeFolderPath)) return gamemodes;
@@ -60,8 +63,9 @@ namespace Milimoe.FunGame.Core.Service
foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(GameMode))))
{
GameMode? instance = (GameMode?)Activator.CreateInstance(type);
- if (instance != null && instance.Load(objs) && instance.Name.Trim() != "")
+ if (instance != null && instance.Load(otherobjs) && instance.Name.Trim() != "")
{
+ instance.Controller = new(instance, delegates);
gamemodes.TryAdd(instance.Name, instance);
}
}
@@ -69,27 +73,88 @@ namespace Milimoe.FunGame.Core.Service
foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Character))))
{
Character? instance = (Character?)Activator.CreateInstance(type);
- if (instance != null && instance.Name.Trim() != "" && !Characters.Contains(instance))
+ if (instance != null && instance.Name.Trim() != "" && !characters.Contains(instance))
{
- Characters.Add(instance);
+ characters.Add(instance);
}
}
foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Skill))))
{
Skill? instance = (Skill?)Activator.CreateInstance(type);
- if (instance != null && instance.Name.Trim() != "" && !Skills.Contains(instance))
+ if (instance != null && instance.Name.Trim() != "" && !skills.Contains(instance))
{
- Skills.Add(instance);
+ skills.Add(instance);
}
}
foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Item))))
{
Item? instance = (Item?)Activator.CreateInstance(type);
- if (instance != null && instance.Name.Trim() != "" && !Items.Contains(instance))
+ if (instance != null && instance.Name.Trim() != "" && !items.Contains(instance))
{
- Items.Add(instance);
+ items.Add(instance);
+ }
+ }
+ }
+
+ return gamemodes;
+ }
+
+ ///
+ /// 从gamemodes目录加载所有适用于服务器的模组
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static Dictionary LoadGameModesForServer(Dictionary gamemodes, List characters, List skills, List
- items, Delegate[] delegates, params object[] otherobjs)
+ {
+ if (!Directory.Exists(ReflectionSet.GameModeFolderPath)) return gamemodes;
+
+ string[] dlls = Directory.GetFiles(ReflectionSet.GameModeFolderPath, "*.dll");
+
+ foreach (string dll in dlls)
+ {
+ Assembly assembly = Assembly.LoadFrom(dll);
+
+ foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(GameModeServer))))
+ {
+ GameModeServer? instance = (GameModeServer?)Activator.CreateInstance(type);
+ if (instance != null && instance.Load(otherobjs) && instance.Name.Trim() != "")
+ {
+ instance.Controller = new(instance, delegates);
+ gamemodes.TryAdd(instance.Name, instance);
+ }
+ }
+
+ foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Character))))
+ {
+ Character? instance = (Character?)Activator.CreateInstance(type);
+ if (instance != null && instance.Name.Trim() != "" && !characters.Contains(instance))
+ {
+ characters.Add(instance);
+ }
+ }
+
+ foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Skill))))
+ {
+ Skill? instance = (Skill?)Activator.CreateInstance(type);
+ if (instance != null && instance.Name.Trim() != "" && !skills.Contains(instance))
+ {
+ skills.Add(instance);
+ }
+ }
+
+ foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => type.IsSubclassOf(typeof(Item))))
+ {
+ Item? instance = (Item?)Activator.CreateInstance(type);
+ if (instance != null && instance.Name.Trim() != "" && !items.Contains(instance))
+ {
+ items.Add(instance);
}
}
}