加载器、服务器模组、地图优化 (#83)

* 修改 LoadGameModulesForServer

* 添加 AssociatedServers

* Update GameModuleServer.cs

* 添加 IsConnectToOtherServerModule 和 AssociatedServerModuleName

* Create Grid.cs

* 添加 Grids

* Update ExampleGameModule.cs

* 更新 example-plugin 的名称;修改 GameMap.this.get

---------

Co-authored-by: milimoe <mili@wrss.org>
This commit is contained in:
yeziuku 2024-08-06 01:07:09 +08:00 committed by GitHub
parent 8ba4ef263f
commit b53d95525a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 262 additions and 29 deletions

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Service;
@ -37,12 +37,17 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// </summary>
public Dictionary<string, ItemModule> Items { get; } = [];
/// <summary>
/// 客户端模组与服务器模组的关联字典
/// </summary>
public Dictionary<GameModule, GameModuleServer?> AssociatedServers { get; } = [];
private GameModuleLoader() { }
/// <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"/> 时,仅读取 <seealso cref="ServerModules"/></para>
/// <para>runtime = <see cref="FunGameInfo.FunGame.FunGame_Server"/> 时,都会读取,并且生成关联字典 <see cref="AssociatedServers"/></para>
/// <seealso cref="Maps"/> 都会读取
/// </summary>
/// <param name="runtime">传入 <see cref="FunGameInfo.FunGame"/> 类型来创建指定端的模组读取器</param>
@ -59,7 +64,16 @@ namespace Milimoe.FunGame.Core.Api.Utility
}
else if (runtime == FunGameInfo.FunGame.FunGame_Server)
{
AddonManager.LoadGameModulesForServer(loader.ServerModules, loader.Characters, loader.Skills, loader.Items, delegates, otherobjs);
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.LoadGameMaps(loader.Maps, otherobjs);
}
return loader;

View File

@ -386,11 +386,16 @@
物品表
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Api.Utility.GameModuleLoader.AssociatedServers">
<summary>
客户端模组与服务器模组的关联字典
</summary>
</member>
<member name="M:Milimoe.FunGame.Core.Api.Utility.GameModuleLoader.LoadGameModules(Milimoe.FunGame.Core.Library.Constant.FunGameInfo.FunGame,System.Collections.Hashtable,System.Object[])">
<summary>
传入 <see cref="T:Milimoe.FunGame.Core.Library.Constant.FunGameInfo.FunGame"/> 类型来创建指定端的模组读取器
<para>runtime = <see cref="F:Milimoe.FunGame.Core.Library.Constant.FunGameInfo.FunGame.FunGame_Desktop"/> 时,仅读取 <seealso cref="P:Milimoe.FunGame.Core.Api.Utility.GameModuleLoader.Modules"/></para>
<para>runtime = <see cref="F:Milimoe.FunGame.Core.Library.Constant.FunGameInfo.FunGame.FunGame_Server"/> 时,仅读取 <seealso cref="P:Milimoe.FunGame.Core.Api.Utility.GameModuleLoader.ServerModules"/></para>
<para>runtime = <see cref="F:Milimoe.FunGame.Core.Library.Constant.FunGameInfo.FunGame.FunGame_Server"/> 时,都会读取,并且生成关联字典 <see cref="P:Milimoe.FunGame.Core.Api.Utility.GameModuleLoader.AssociatedServers"/></para>
<seealso cref="P:Milimoe.FunGame.Core.Api.Utility.GameModuleLoader.Maps"/> 都会读取
</summary>
<param name="runtime">传入 <see cref="T:Milimoe.FunGame.Core.Library.Constant.FunGameInfo.FunGame"/> 类型来创建指定端的模组读取器</param>
@ -1940,6 +1945,11 @@
使用switch块分类处理 <see cref="T:Milimoe.FunGame.Core.Library.Constant.GamingType"/>
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Example.ExampleGameModuleServer.Name">
<summary>
注意:服务器模组的名称必须和模组名称相同。除非你指定了 <see cref="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.IsConnectToOtherServerModule"/><see cref="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.AssociatedServerModuleName"/>
</summary>
</member>
<member name="T:Milimoe.FunGame.Core.Library.Common.Addon.Example.ExampleGameMap">
<summary>
地图:必须继承基类:<see cref="T:Milimoe.FunGame.Core.Library.Common.Addon.GameMap"/><para/>
@ -1986,6 +1996,11 @@
地图作者
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameMap.Length">
<summary>
长度
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameMap.Width">
<summary>
宽度
@ -2001,6 +2016,27 @@
格子大小
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameMap.Grids">
<summary>
格子集
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameMap.Item(System.Single,System.Single,System.Single)">
<summary>
使用坐标获取格子0号格子的坐标是(0, 0),如果你还有高度的话,则是(0, 0, 0)
</summary>
<param name="x"></param>
<param name="y"></param>
<param name="z"></param>
<returns></returns>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameMap.Item(System.Int32)">
<summary>
使用坐标获取格子从0号开始
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="F:Milimoe.FunGame.Core.Library.Common.Addon.GameMap.IsLoaded">
<summary>
加载标记
@ -2059,6 +2095,16 @@
适用的房间模式
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.IsConnectToOtherServerModule">
<summary>
是否连接其他的服务器模组
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.AssociatedServerModuleName">
<summary>
如果将 <see cref="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.IsConnectToOtherServerModule"/> 设置为true那么此属性必须指定一个存在的服务器模组的 <see cref="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.Name"/> 名称。
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.Controller">
<summary>
包含了一些常用方法的控制器
@ -2126,6 +2172,11 @@
Config对象
</summary>
</member>
<member name="F:Milimoe.FunGame.Core.Library.Common.Addon.GameModule._AssociatedServerModuleName">
<summary>
关联的服务器模组名称
</summary>
</member>
<member name="M:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.BindEvent">
<summary>
绑定事件。在<see cref="M:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.BeforeLoad"/>后触发
@ -2201,7 +2252,8 @@
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModuleServer.Name">
<summary>
模组名称
服务器模组的名称<para/>
如果服务器模组配合一个相关联的模组使用,那么它们的 <see cref="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModule.Name"/> 名称必须相同。
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.GameModuleServer.Description">
@ -2281,6 +2333,41 @@
</summary>
<returns></returns>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.Id">
<summary>
格子编号
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.X">
<summary>
格子在地图中的x坐标
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.Y">
<summary>
格子在地图中的y坐标
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.Z">
<summary>
格子在地图中的z坐标
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.Characters">
<summary>
是谁站在这格子上?
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.Skills">
<summary>
此格子目前受到了什么影响?或者它有什么技能…
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.Grid.Color">
<summary>
此格子呈现的颜色(默认为 <see cref="P:System.Drawing.Color.Gray"/>
</summary>
</member>
<member name="P:Milimoe.FunGame.Core.Library.Common.Addon.ItemModule.Name">
<summary>
模组名称
@ -3011,11 +3098,12 @@
<param name="otherobjs"></param>
<returns></returns>
</member>
<member name="M:Milimoe.FunGame.Core.Service.AddonManager.LoadGameModulesForServer(System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.GameModuleServer},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.CharacterModule},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.SkillModule},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.ItemModule},System.Collections.Hashtable,System.Object[])">
<member name="M:Milimoe.FunGame.Core.Service.AddonManager.LoadGameModulesForServer(System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.GameModule},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.GameModuleServer},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.CharacterModule},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.SkillModule},System.Collections.Generic.Dictionary{System.String,Milimoe.FunGame.Core.Library.Common.Addon.ItemModule},System.Collections.Hashtable,System.Object[])">
<summary>
从modules目录加载所有适用于服务器的模组
</summary>
<param name="modules"></param>
<param name="servers"></param>
<param name="characters"></param>
<param name="skills"></param>
<param name="items"></param>

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
@ -16,11 +16,16 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public class ExampleGameModuleConstant
{
public static GameModuleDepend GameModuleDepend => _depends;
public const string ExampleGameModule = "fungame.example.gamemodule";
public const string ExampleMap = "fungame.example.gamemap";
public const string ExampleCharacter = "fungame.example.character";
public const string ExampleSkill = "fungame.example.skill";
public const string ExampleItem = "fungame.example.item";
private static readonly string[] Maps = ["Example GameMap"];
private static readonly string[] Characters = ["Example CharacterModule"];
private static readonly string[] Skills = ["Example SkillModule"];
private static readonly string[] Items = ["Example ItemModule"];
private static readonly string[] Maps = [ExampleMap];
private static readonly string[] Characters = [ExampleCharacter];
private static readonly string[] Skills = [ExampleSkill];
private static readonly string[] Items = [ExampleItem];
private static readonly GameModuleDepend _depends = new(Maps, Characters, Skills, Items);
}
@ -30,7 +35,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExampleGameModule : GameModule, IGamingUpdateInfoEvent
{
public override string Name => "FunGame Example GameModule";
public override string Name => ExampleGameModuleConstant.ExampleGameModule;
public override string Description => "My First GameModule";
@ -44,6 +49,14 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public override RoomType RoomType => RoomType.Mix;
public ExampleGameModule()
{
// 构造函数中可以指定模组连接到哪个模组服务器。
// 如果你使用自己的,保持默认即可:删除下面两行,并将模组服务器的名称设置为与此模组的名称相同
IsConnectToOtherServerModule = true;
AssociatedServerModuleName = ExampleGameModuleConstant.ExampleGameModule;
}
protected Gaming? Instance;
protected Room room = General.HallInstance;
protected List<User> users = [];
@ -97,7 +110,10 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExampleGameModuleServer : GameModuleServer
{
public override string Name => "FunGame Example GameModule";
/// <summary>
/// 注意:服务器模组的名称必须和模组名称相同。除非你指定了 <see cref="GameModule.IsConnectToOtherServerModule"/> 和 <see cref="GameModule.AssociatedServerModuleName"/>
/// </summary>
public override string Name => ExampleGameModuleConstant.ExampleGameModule;
public override string Description => "My First GameModule";
@ -245,7 +261,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExampleGameMap : GameMap
{
public override string Name => "Example GameMap";
public override string Name => ExampleGameModuleConstant.ExampleMap;
public override string Description => "My First GameMap";
@ -253,9 +269,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
public override string Author => "FunGamer";
public override float Length => 12.0f;
public override float Width => 12.0f;
public override float Height => 12.0f;
public override float Height => 6.0f;
public override float Size => 4.0f;
}
@ -265,7 +283,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExampleCharacterModule : CharacterModule
{
public override string Name => "Example CharacterModule";
public override string Name => ExampleGameModuleConstant.ExampleCharacter;
public override string Description => "My First CharacterModule";
@ -301,7 +319,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExampleSkillModule : SkillModule
{
public override string Name => "Example SkillModule";
public override string Name => ExampleGameModuleConstant.ExampleSkill;
public override string Description => "My First SkillModule";
@ -328,7 +346,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExampleItemModule : ItemModule
{
public override string Name => "Example ItemModule";
public override string Name => ExampleGameModuleConstant.ExampleItem;
public override string Description => "My First ItemModule";

View File

@ -9,7 +9,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example
/// </summary>
public class ExamplePlugin : Plugin, ILoginEvent
{
public override string Name => "FunGame Example Plugin";
public override string Name => "fungame.example.plugin";
public override string Description => "My First Plugin";

View File

@ -1,4 +1,4 @@
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Interface.Addons;
namespace Milimoe.FunGame.Core.Library.Common.Addon
{
@ -24,6 +24,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// </summary>
public abstract string Author { get; }
/// <summary>
/// 长度
/// </summary>
public abstract float Length { get; }
/// <summary>
/// 宽度
/// </summary>
@ -39,6 +44,27 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// </summary>
public abstract float Size { get; }
/// <summary>
/// 格子集
/// </summary>
public Dictionary<long, Grid> Grids { get; } = [];
/// <summary>
/// 使用坐标获取格子0号格子的坐标是(0, 0),如果你还有高度的话,则是(0, 0, 0)
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns></returns>
public Grid this[float x, float y, float z = 0] => Grids.Values.Where(g => g.X == x && g.Y == y && g.Z == z).FirstOrDefault();
/// <summary>
/// 使用坐标获取格子从0号开始
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Grid this[int id] => Grids[id];
/// <summary>
/// 加载标记
/// </summary>
@ -60,6 +86,17 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
{
// 地图加载后,不允许再次加载此地图
IsLoaded = true;
// 生成格子
for (float x = 0; x < Length; x++)
{
for (float y = 0; y< Width; y++)
{
for (float z = 0; z < Height; z++)
{
Grids.Add(Grids.Count, new(Grids.Count, x, y, z));
}
}
}
// 如果加载后需要执行代码请重写AfterLoad方法
AfterLoad();
}

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface;
using Milimoe.FunGame.Core.Interface.Addons;
@ -45,6 +45,20 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// </summary>
public abstract RoomType RoomType { get; }
/// <summary>
/// 是否连接其他的服务器模组
/// </summary>
public bool IsConnectToOtherServerModule { get; set; } = false;
/// <summary>
/// 如果将 <see cref="IsConnectToOtherServerModule"/> 设置为true那么此属性必须指定一个存在的服务器模组的 <see cref="Name"/> 名称。
/// </summary>
public string AssociatedServerModuleName
{
get => IsConnectToOtherServerModule ? _AssociatedServerModuleName : Name;
set => _AssociatedServerModuleName = value;
}
/// <summary>
/// 包含了一些常用方法的控制器
/// </summary>
@ -152,6 +166,11 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// </summary>
protected FunGameConfig Config = new();
/// <summary>
/// 关联的服务器模组名称
/// </summary>
private string _AssociatedServerModuleName = "";
/// <summary>
/// 绑定事件。在<see cref="BeforeLoad"/>后触发
/// </summary>

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Addons;
@ -10,7 +10,8 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
public abstract class GameModuleServer : IGameModuleServer
{
/// <summary>
/// 模组名称
/// 服务器模组的名称<para/>
/// 如果服务器模组配合一个相关联的模组使用,那么它们的 <see cref="GameModule.Name"/> 名称必须相同。
/// </summary>
public abstract string Name { get; }

View File

@ -0,0 +1,43 @@
using System.Drawing;
using Milimoe.FunGame.Core.Entity;
namespace Milimoe.FunGame.Core.Library.Common.Addon
{
public struct Grid(int id, float x, float y, float z)
{
/// <summary>
/// 格子编号
/// </summary>
public int Id { get; } = id;
/// <summary>
/// 格子在地图中的x坐标
/// </summary>
public float X { get; } = x;
/// <summary>
/// 格子在地图中的y坐标
/// </summary>
public float Y { get; } = y;
/// <summary>
/// 格子在地图中的z坐标
/// </summary>
public float Z { get; } = z;
/// <summary>
/// 是谁站在这格子上?
/// </summary>
public Dictionary<string, Character> Characters { get; set; } = [];
/// <summary>
/// 此格子目前受到了什么影响?或者它有什么技能…
/// </summary>
public Dictionary<string, Skill> Skills { get; set; } = [];
/// <summary>
/// 此格子呈现的颜色(默认为 <see cref="Color.Gray"/>
/// </summary>
public Color Color { get; set; } = Color.Gray;
}
}

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using System.Reflection;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.Common.Addon;
@ -99,15 +99,16 @@ namespace Milimoe.FunGame.Core.Service
/// 从modules目录加载所有适用于服务器的模组
/// </summary>
/// <param name="modules"></param>
/// <param name="servers"></param>
/// <param name="characters"></param>
/// <param name="skills"></param>
/// <param name="items"></param>
/// <param name="delegates"></param>
/// <param name="otherobjs"></param>
/// <returns></returns>
internal static Dictionary<string, GameModuleServer> LoadGameModulesForServer(Dictionary<string, GameModuleServer> modules, 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, GameModule> modules, 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 modules;
if (!Directory.Exists(ReflectionSet.GameModuleFolderPath)) return servers;
string[] dlls = Directory.GetFiles(ReflectionSet.GameModuleFolderPath, "*.dll");
@ -117,7 +118,7 @@ namespace Milimoe.FunGame.Core.Service
foreach (Type type in assembly.GetTypes().AsEnumerable().Where(type => typeof(IAddon).IsAssignableFrom(type)))
{
if (type.IsSubclassOf(typeof(GameModuleServer)))
if (type.IsSubclassOf(typeof(GameModule)))
{
AddAddonInstances(type, modules, (instance) =>
{
@ -129,6 +130,18 @@ namespace Milimoe.FunGame.Core.Service
return false;
});
}
else if (type.IsSubclassOf(typeof(GameModuleServer)))
{
AddAddonInstances(type, servers, (instance) =>
{
if (instance.Load(otherobjs))
{
instance.Controller = new(instance, delegates);
return true;
}
return false;
});
}
else if (type.IsSubclassOf(typeof(CharacterModule)))
{
AddAddonInstances(type, characters, (instance) => instance.Load(otherobjs));
@ -144,7 +157,7 @@ namespace Milimoe.FunGame.Core.Service
}
}
return modules;
return servers;
}
/// <summary>