using System.Collections.Concurrent;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Library.Common.Addon
{
public abstract class GameModuleServer : IGameModuleServer
{
///
/// 服务器模组的名称
/// 如果服务器模组配合一个相关联的模组使用,那么它们的 名称必须相同。
///
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 GameModuleDepend GameModuleDepend { get; }
///
/// 是否是匿名服务器
///
public virtual bool IsAnonymous { get; set; } = false;
///
/// 包含了一些常用方法的控制器
///
public ServerAddonController Controller
{
get => _Controller ?? throw new NotImplementedException();
internal set => _Controller = value;
}
///
/// base控制器
///
BaseAddonController IAddonController.Controller
{
get => Controller;
set => _Controller = (ServerAddonController?)value;
}
///
/// 控制器内部变量
///
private ServerAddonController? _Controller;
///
/// 此模组所有正在运行的游戏对象
///
public ConcurrentDictionary GamingObjects { get; } = [];
///
/// 启动服务器监听 请在此处实现服务器逻辑。注意,此方法必须立即返回
///
///
///
///
public abstract bool StartServer(GamingObject obj, params object[] args);
///
/// 接收并处理GamingMessage
///
/// 发送此消息的客户端
/// 消息类型
/// 消息参数
/// 底层会将字典中的数据发送给客户端
public abstract Task> GamingMessageHandler(IServerModel model, GamingType type, Dictionary data);
///
/// 启动匿名服务器监听
///
///
///
///
public virtual bool StartAnonymousServer(IServerModel model, Dictionary data)
{
return true;
}
///
/// 结束匿名服务器监听
///
///
///
public virtual void CloseAnonymousServer(IServerModel model)
{
}
///
/// 接收并处理匿名服务器监听消息
/// 此方法为可选实现,可以帮助 RESTful API 处理不需要验证的 WebSocket 请求
///
/// 发送此消息的客户端
/// 消息参数
/// 底层会将字典中的数据发送给客户端
public virtual async Task> AnonymousGameServerHandler(IServerModel model, Dictionary data)
{
await Task.Delay(1);
return [];
}
///
/// 加载标记
///
private bool IsLoaded = false;
///
/// 加载模组
///
public bool Load(params object[] objs)
{
if (IsLoaded)
{
return false;
}
// BeforeLoad可以阻止加载此模组
if (BeforeLoad())
{
// 模组加载后,不允许再次加载此模组
IsLoaded = true;
}
return IsLoaded;
}
///
/// 模组完全加载后需要做的事
///
public virtual void AfterLoad(params object[] args)
{
// override
}
///
/// 允许返回false来阻止加载此模组
///
///
protected virtual bool BeforeLoad()
{
return true;
}
///
/// 给所有客户端发送游戏结束通知
///
///
public virtual async void SendEndGame(GamingObject obj)
{
GamingObjects.TryRemove(obj.Room.Roomid, out _);
await Send(obj.All.Values, SocketMessageType.EndGame, obj.Room, obj.Users);
foreach (IServerModel model in obj.All.Values)
{
model.NowGamingServer = null;
}
}
///
/// 给客户端发送局内消息
///
///
///
///
/// 发送失败的客户端
protected virtual async Task> SendGamingMessage(IEnumerable clients, GamingType type, Dictionary data)
{
// 发送局内消息
List failedModels = [];
foreach (IServerModel s in clients)
{
try
{
await s.Send(SocketMessageType.Gaming, type, data);
}
catch (System.Exception e)
{
Controller.Error(e);
failedModels.Add(s);
}
}
return failedModels;
}
///
/// 给客户端发送消息
///
///
///
///
/// 发送失败的客户端
protected virtual async Task> Send(IEnumerable clients, SocketMessageType type, params object[] args)
{
// 发送消息
List failedModels = [];
foreach (IServerModel s in clients)
{
try
{
await s.Send(type, args);
}
catch (System.Exception e)
{
Controller.Error(e);
failedModels.Add(s);
}
}
return failedModels;
}
///
/// 给客户端发送匿名服务器消息
///
///
///
/// 发送失败的客户端
protected virtual async Task> SendAnonymousGameServerMessage(IEnumerable clients, Dictionary data)
{
List failedModels = [];
foreach (IServerModel s in clients)
{
try
{
await s.Send(SocketMessageType.AnonymousGameServer, data);
}
catch (System.Exception e)
{
Controller.Error(e);
failedModels.Add(s);
}
}
return failedModels;
}
}
}