mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-02 12:16:03 +08:00
feat: cache the handlers that are loaded from reflection
This commit is contained in:
@@ -83,9 +83,9 @@ public class ServerOption
|
||||
public ServerAnnounce ServerAnnounce { get; set; } = new();
|
||||
public ServerProfile ServerProfile { get; set; } = new();
|
||||
public bool AutoCreateUser { get; set; } = true;
|
||||
public bool SavePersonalDebugFile { get; set; } = false;
|
||||
public LogOption LogOption { get; set; } = new();
|
||||
public int FarmingDropRate { get; set; } = 1;
|
||||
public bool UseCache { get; set; } = true;
|
||||
public bool UseCache { get; set; } = false; // didnt recommend
|
||||
|
||||
public int ValidFarmingDropRate()
|
||||
{
|
||||
@@ -93,6 +93,18 @@ public class ServerOption
|
||||
}
|
||||
}
|
||||
|
||||
public class LogOption
|
||||
{
|
||||
#if DEBUG
|
||||
public bool EnableGamePacketLog { get; set; } = true;
|
||||
#else
|
||||
public bool EnableGamePacketLog { get; set; } = false;
|
||||
#endif
|
||||
public bool LogPacketToConsole { get; set; } = true;
|
||||
public bool DisableLogDetailPacket { get; set; } = false;
|
||||
public bool SavePersonalDebugFile { get; set; } = false;
|
||||
}
|
||||
|
||||
public class ServerAnnounce
|
||||
{
|
||||
public bool EnableAnnounce { get; set; } = true;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using EggLink.DanhengServer.Kcp.KcpSharp;
|
||||
using EggLink.DanhengServer.Util;
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.Reflection;
|
||||
|
||||
namespace EggLink.DanhengServer.Kcp;
|
||||
|
||||
@@ -73,24 +70,21 @@ public class DanhengConnection
|
||||
|
||||
public void LogPacket(string sendOrRecv, ushort opcode, byte[] payload)
|
||||
{
|
||||
if (!ConfigManager.Config.ServerOption.LogOption.EnableGamePacketLog) return;
|
||||
|
||||
try
|
||||
{
|
||||
//Logger.DebugWriteLine($"{sendOrRecv}: {Enum.GetName(typeof(OpCode), opcode)}({opcode})\r\n{Convert.ToHexString(payload)}");
|
||||
if (IgnoreLog.Contains(opcode)) return;
|
||||
var typ = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SingleOrDefault(assembly => assembly.GetName().Name == "DanhengProto")!.GetTypes()
|
||||
.First(t => t.Name == $"{LogMap[opcode]}"); //get the type using the packet name
|
||||
var descriptor =
|
||||
typ.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static)?.GetValue(
|
||||
null, null) as MessageDescriptor; // get the static property Descriptor
|
||||
var packet = descriptor?.Parser.ParseFrom(payload);
|
||||
var formatter = JsonFormatter.Default;
|
||||
var asJson = formatter.Format(packet);
|
||||
|
||||
if (ConfigManager.Config.ServerOption.LogOption.DisableLogDetailPacket) throw new Exception();
|
||||
|
||||
var asJson = PacketLogHelper.ConvertPacketToJson(opcode, payload);
|
||||
var output = $"{sendOrRecv}: {LogMap[opcode]}({opcode})\r\n{asJson}";
|
||||
#if DEBUG
|
||||
Logger.Debug(output);
|
||||
#endif
|
||||
if (DebugFile == "" || !ConfigManager.Config.ServerOption.SavePersonalDebugFile) return;
|
||||
|
||||
if (ConfigManager.Config.ServerOption.LogOption.LogPacketToConsole)
|
||||
Logger.Debug(output);
|
||||
|
||||
if (DebugFile == "" || !ConfigManager.Config.ServerOption.LogOption.SavePersonalDebugFile) return;
|
||||
var sw = GetWriter();
|
||||
sw.WriteLine($"[{DateTime.Now:HH:mm:ss}] [GameServer] [DEBUG] " + output);
|
||||
sw.Flush();
|
||||
@@ -98,10 +92,11 @@ public class DanhengConnection
|
||||
catch
|
||||
{
|
||||
var output = $"{sendOrRecv}: {LogMap.GetValueOrDefault(opcode, "UnknownPacket")}({opcode})";
|
||||
#if DEBUG
|
||||
Logger.Debug(output);
|
||||
#endif
|
||||
if (DebugFile != "" && ConfigManager.Config.ServerOption.SavePersonalDebugFile)
|
||||
|
||||
if (ConfigManager.Config.ServerOption.LogOption.LogPacketToConsole)
|
||||
Logger.Debug(output);
|
||||
|
||||
if (DebugFile != "" && ConfigManager.Config.ServerOption.LogOption.SavePersonalDebugFile)
|
||||
{
|
||||
var sw = GetWriter();
|
||||
sw.WriteLine($"[{DateTime.Now:HH:mm:ss}] [GameServer] [DEBUG] " + output);
|
||||
|
||||
@@ -25,7 +25,8 @@ public class DanhengListener
|
||||
KeepAliveOptions = new KcpKeepAliveOptions(1000, 30000)
|
||||
};
|
||||
|
||||
public static Type BaseConnection { get; set; } = typeof(DanhengConnection);
|
||||
public delegate DanhengConnection ConnectionCreatedHandler(KcpConversation conversation, IPEndPoint remote);
|
||||
public static ConnectionCreatedHandler? CreateConnection { get; set; } = null;
|
||||
|
||||
private static Socket? UDPListener => UDPClient?.Client;
|
||||
private static IKcpMultiplexConnection? Multiplex => KCPTransport?.Connection;
|
||||
@@ -120,8 +121,8 @@ public class DanhengListener
|
||||
{
|
||||
var convId = Connections.GetNextAvailableIndex();
|
||||
var convo = Multiplex?.CreateConversation(convId, rcv.RemoteEndPoint, ConvOpt);
|
||||
if (convo == null) return;
|
||||
var con = (DanhengConnection)Activator.CreateInstance(BaseConnection, convo, rcv.RemoteEndPoint)!;
|
||||
if (convo == null || CreateConnection == null) return;
|
||||
var con = CreateConnection(convo, rcv.RemoteEndPoint);
|
||||
RegisterConnection(con);
|
||||
await SendHandshakeResponse(con, enet);
|
||||
}
|
||||
|
||||
63
DanhengKcpSharp/PacketLogHelper.cs
Normal file
63
DanhengKcpSharp/PacketLogHelper.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.Reflection;
|
||||
|
||||
namespace EggLink.DanhengServer.Kcp;
|
||||
|
||||
public static class PacketLogHelper
|
||||
{
|
||||
private delegate IMessage ParseIMessage(byte[] data);
|
||||
private static ConcurrentDictionary<ushort, ParseIMessage> CachedParsers { get; } = [];
|
||||
|
||||
public static string ConvertPacketToJson(ushort opcode, byte[] payload)
|
||||
{
|
||||
var descriptor = GetParser(opcode);
|
||||
if (descriptor == null)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
var message = descriptor(payload);
|
||||
var formatter = JsonFormatter.Default;
|
||||
var asJson = formatter.Format(message);
|
||||
return asJson ?? throw new Exception();
|
||||
}
|
||||
|
||||
private static ParseIMessage? GetParser(ushort opcode)
|
||||
{
|
||||
if (CachedParsers.TryGetValue(opcode, out var parser))
|
||||
{
|
||||
return parser;
|
||||
}
|
||||
|
||||
lock (CachedParsers)
|
||||
{
|
||||
// try to find the descriptor by opcode
|
||||
var asbly = Assembly.GetAssembly(typeof(PlayerGetTokenCsReq));
|
||||
if (asbly == null) return null;
|
||||
|
||||
var typ = asbly.GetType($"EggLink.DanhengServer.Proto.{DanhengConnection.LogMap[opcode]}");
|
||||
if (typ == null) return null;
|
||||
var desc = typ.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static);
|
||||
if (desc?.GetMethod == null) return null;
|
||||
|
||||
// get parser
|
||||
if (desc.GetValue(null) is not MessageDescriptor parserProperty) return null;
|
||||
|
||||
var parserMethod = parserProperty.Parser.GetType().GetMethod("ParseFrom", [typeof(byte[])]);
|
||||
if (parserMethod == null) return null;
|
||||
|
||||
parser = (ParseIMessage)Delegate.CreateDelegate(
|
||||
typeof(ParseIMessage),
|
||||
parserProperty.Parser,
|
||||
parserMethod
|
||||
);
|
||||
|
||||
CachedParsers[opcode] = parser;
|
||||
|
||||
return parser;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,17 +35,6 @@ public class ChessRogueInstance : BaseRogueInstance
|
||||
EventManager = new RogueEventManager(player, this);
|
||||
RogueType = rogueSubMode == RogueSubModeEnum.ChessRogueNous ? 160 : 130;
|
||||
|
||||
|
||||
var types = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attr = type.GetCustomAttribute<ModifierEffectAttribute>();
|
||||
if (attr == null) continue;
|
||||
|
||||
var handler = (ModifierEffectHandler)Activator.CreateInstance(type, null)!;
|
||||
ModifierEffectHandlers.Add(attr.EffectType, handler);
|
||||
}
|
||||
|
||||
foreach (var difficulty in areaExcel.DifficultyID)
|
||||
if (GameData.RogueDLCDifficultyData.TryGetValue(difficulty, out var diff))
|
||||
DifficultyExcel.Add(diff);
|
||||
@@ -69,7 +58,7 @@ public class ChessRogueInstance : BaseRogueInstance
|
||||
public int BossAeonId { get; set; }
|
||||
public List<RogueDLCDifficultyExcel> DifficultyExcel { get; set; } = [];
|
||||
public ChessRogueDiceInstance DiceInstance { get; set; }
|
||||
public Dictionary<ModifierEffectTypeEnum, ModifierEffectHandler> ModifierEffectHandlers { get; set; } = [];
|
||||
public static Dictionary<ModifierEffectTypeEnum, ModifierEffectHandler> ModifierEffectHandlers { get; set; } = [];
|
||||
|
||||
public Dictionary<int, ChessRogueCellInstance> RogueCells { get; set; } = [];
|
||||
public ChessRogueCellInstance? CurCell { get; set; }
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ChessRogueDiceModifierInstance(int modifierId, ChessRogueDiceSurfac
|
||||
{
|
||||
var effect = EffectConfig.EffectType;
|
||||
|
||||
instance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
ChessRogueInstance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
|
||||
if (handler != null)
|
||||
await handler.SelectCell(this, instance, selectCellId);
|
||||
@@ -51,7 +51,7 @@ public class ChessRogueDiceModifierInstance(int modifierId, ChessRogueDiceSurfac
|
||||
{
|
||||
var effect = EffectConfig.EffectType;
|
||||
|
||||
instance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
ChessRogueInstance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
|
||||
if (handler != null)
|
||||
await handler.SelectModifierCell(this, instance, selectCellId);
|
||||
@@ -63,7 +63,7 @@ public class ChessRogueDiceModifierInstance(int modifierId, ChessRogueDiceSurfac
|
||||
{
|
||||
var effect = EffectConfig.EffectType;
|
||||
|
||||
instance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
ChessRogueInstance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
|
||||
if (handler != null)
|
||||
await handler.OnConfirmed(this, instance);
|
||||
@@ -75,7 +75,7 @@ public class ChessRogueDiceModifierInstance(int modifierId, ChessRogueDiceSurfac
|
||||
{
|
||||
var effect = EffectConfig.EffectType;
|
||||
|
||||
instance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
ChessRogueInstance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
|
||||
if (handler != null)
|
||||
handler.BeforeBattle(this, battle, instance);
|
||||
@@ -87,7 +87,7 @@ public class ChessRogueDiceModifierInstance(int modifierId, ChessRogueDiceSurfac
|
||||
{
|
||||
var effect = EffectConfig.EffectType;
|
||||
|
||||
instance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
ChessRogueInstance.ModifierEffectHandlers.TryGetValue(effect, out var handler);
|
||||
|
||||
if (handler != null)
|
||||
await handler.AfterBattle(this, battle);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.Database;
|
||||
using EggLink.DanhengServer.Database.Inventory;
|
||||
@@ -19,39 +18,16 @@ using MissionData = EggLink.DanhengServer.Database.Quests.MissionData;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Mission;
|
||||
|
||||
public class MissionManager : BasePlayerManager
|
||||
public class MissionManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
{
|
||||
#region Initializer & Properties
|
||||
|
||||
public MissionData Data { get; set; }
|
||||
public Dictionary<FinishActionTypeEnum, MissionFinishActionHandler> ActionHandlers = [];
|
||||
public Dictionary<MissionFinishTypeEnum, MissionFinishTypeHandler> FinishTypeHandlers = [];
|
||||
public MissionData Data { get; set; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew<MissionData>(player.Uid);
|
||||
public static readonly Dictionary<FinishActionTypeEnum, MissionFinishActionHandler> ActionHandlers = [];
|
||||
public static readonly Dictionary<MissionFinishTypeEnum, MissionFinishTypeHandler> FinishTypeHandlers = [];
|
||||
|
||||
public readonly List<int> SkipSubMissionList = []; // bug
|
||||
|
||||
public MissionManager(PlayerInstance player) : base(player)
|
||||
{
|
||||
Data = DatabaseHelper.Instance!.GetInstanceOrCreateNew<MissionData>(player.Uid);
|
||||
|
||||
var types = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attr = type.GetCustomAttribute<MissionFinishActionAttribute>();
|
||||
if (attr != null)
|
||||
{
|
||||
var handler = (MissionFinishActionHandler)Activator.CreateInstance(type, null)!;
|
||||
ActionHandlers.Add(attr.FinishAction, handler);
|
||||
}
|
||||
|
||||
var attr2 = type.GetCustomAttribute<MissionFinishTypeAttribute>();
|
||||
if (attr2 != null)
|
||||
{
|
||||
var handler = (MissionFinishTypeHandler)Activator.CreateInstance(type, null)!;
|
||||
FinishTypeHandlers.Add(attr2.FinishType, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mission Actions
|
||||
|
||||
@@ -10,14 +10,9 @@ using EggLink.DanhengServer.Util;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Mission;
|
||||
|
||||
public class StoryLineManager : BasePlayerManager
|
||||
public class StoryLineManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
{
|
||||
public StoryLineManager(PlayerInstance player) : base(player)
|
||||
{
|
||||
StoryLineData = DatabaseHelper.Instance!.GetInstanceOrCreateNew<StoryLineData>(player.Uid);
|
||||
}
|
||||
|
||||
public StoryLineData StoryLineData { get; set; }
|
||||
public StoryLineData StoryLineData { get; set; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew<StoryLineData>(player.Uid);
|
||||
|
||||
public async ValueTask CheckIfEnterStoryLine()
|
||||
{
|
||||
|
||||
@@ -1,44 +1,18 @@
|
||||
using System.Reflection;
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Enums.Rogue;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueCommon;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Rogue.Event;
|
||||
|
||||
public class RogueEventManager
|
||||
public class RogueEventManager(PlayerInstance player, BaseRogueInstance rogueInstance)
|
||||
{
|
||||
public Dictionary<DialogueEventCostTypeEnum, RogueEventCostHandler> CostHandler = [];
|
||||
public Dictionary<DialogueEventTypeEnum, RogueEventEffectHandler> EffectHandler = [];
|
||||
public PlayerInstance Player;
|
||||
public BaseRogueInstance Rogue;
|
||||
public static Dictionary<DialogueEventCostTypeEnum, RogueEventCostHandler> CostHandler = [];
|
||||
public static Dictionary<DialogueEventTypeEnum, RogueEventEffectHandler> EffectHandler = [];
|
||||
public PlayerInstance Player = player;
|
||||
public BaseRogueInstance Rogue = rogueInstance;
|
||||
public List<RogueEventInstance> RunningEvent = [];
|
||||
|
||||
public RogueEventManager(PlayerInstance player, BaseRogueInstance rogueInstance)
|
||||
{
|
||||
Player = player;
|
||||
Rogue = rogueInstance;
|
||||
|
||||
var types = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attr = type.GetCustomAttribute<RogueEventAttribute>();
|
||||
if (attr == null) continue;
|
||||
if (attr.EffectType != DialogueEventTypeEnum.None)
|
||||
{
|
||||
// Effect
|
||||
var effect = (RogueEventEffectHandler)Activator.CreateInstance(type, null)!;
|
||||
EffectHandler.Add(attr.EffectType, effect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cost
|
||||
var cost = (RogueEventCostHandler)Activator.CreateInstance(type, null)!;
|
||||
CostHandler.Add(attr.CostType, cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnNextRoom()
|
||||
{
|
||||
RunningEvent.Clear(); // Clear all running events
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using System.Collections.Concurrent;
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.Data.Config.Task;
|
||||
using EggLink.DanhengServer.Enums.Avatar;
|
||||
@@ -22,9 +23,13 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
|
||||
#region Selector
|
||||
|
||||
public List<BaseGameEntity> TargetAlias(TargetEvaluator selector, BaseGameEntity casterEntity,
|
||||
List<BaseGameEntity> targetEntities)
|
||||
public async ValueTask<object> TargetAlias(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
var selector = param.TargetEvaluator!;
|
||||
var casterEntity = param.CasterEntity;
|
||||
var targetEntities = param.TargetEntities;
|
||||
|
||||
if (selector is TargetAlias target)
|
||||
return target.Alias switch
|
||||
{
|
||||
@@ -33,7 +38,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
_ => targetEntities
|
||||
};
|
||||
|
||||
return [];
|
||||
return new List<BaseGameEntity>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -69,14 +74,13 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
{
|
||||
var methodName = param.Act.Type.Replace("RPG.GameCore.", "");
|
||||
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var res = method.Invoke(this, [param]);
|
||||
if (res is AbilityLevelResult result) return result;
|
||||
// try to get from cache
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return new AbilityLevelResult();
|
||||
|
||||
if (res is ValueTask<AbilityLevelResult> valueTask) return await valueTask;
|
||||
}
|
||||
var res = method(param);
|
||||
var re = await res;
|
||||
if (re is AbilityLevelResult result) return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -86,11 +90,28 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
private ExecuteTask? GetOrCreateExecuteTask(string methodName)
|
||||
{
|
||||
// try to get from cache
|
||||
if (_cachedTasks.TryGetValue(methodName, out var method)) return method;
|
||||
var methodProp = GetType().GetMethod(methodName);
|
||||
if (methodProp == null) return null;
|
||||
|
||||
method = (ExecuteTask)Delegate.CreateDelegate(typeof(ExecuteTask), this, methodProp);
|
||||
_cachedTasks[methodName] = method; // cached
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private delegate ValueTask<object> ExecuteTask(AbilityLevelParam param);
|
||||
|
||||
private readonly ConcurrentDictionary<string, ExecuteTask> _cachedTasks = [];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task
|
||||
|
||||
public async ValueTask<AbilityLevelResult> PredicateTaskList(AbilityLevelParam param)
|
||||
public async ValueTask<object> PredicateTaskList(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
@@ -99,32 +120,23 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
{
|
||||
// handle predicateCondition
|
||||
var methodName = predicateTaskList.Predicate.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
var res = true;
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this, [param with { Act = predicateTaskList.Predicate }]);
|
||||
if (resp is not bool res) return new AbilityLevelResult(instance, battleInfos);
|
||||
|
||||
res = predicateTaskList.Predicate.Inverse ? !res : res;
|
||||
if (res)
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null) battleInfos.AddRange(result.BattleInfos);
|
||||
|
||||
if (result.Instance != null) instance = result.Instance;
|
||||
}
|
||||
var resp = await method(param with { Act = predicateTaskList.Predicate });
|
||||
if (resp is not bool r)
|
||||
{
|
||||
res = false;
|
||||
}
|
||||
else
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null) battleInfos.AddRange(result.BattleInfos);
|
||||
|
||||
if (result.Instance != null) instance = result.Instance;
|
||||
}
|
||||
{
|
||||
res = predicateTaskList.Predicate.Inverse ? !r : r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (res)
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
@@ -132,13 +144,20 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
|
||||
if (result.Instance != null) instance = result.Instance;
|
||||
}
|
||||
}
|
||||
else
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null) battleInfos.AddRange(result.BattleInfos);
|
||||
|
||||
if (result.Instance != null) instance = result.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AdventureTriggerAttack(AbilityLevelParam param)
|
||||
public async ValueTask<object> AdventureTriggerAttack(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
@@ -146,39 +165,37 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
if (param.Act is AdventureTriggerAttack adventureTriggerAttack)
|
||||
{
|
||||
var methodName = adventureTriggerAttack.AttackTargetType.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return new AbilityLevelResult();
|
||||
var resp = await method(param with { TargetEvaluator = adventureTriggerAttack.AttackTargetType });
|
||||
|
||||
if (resp is List<BaseGameEntity> target)
|
||||
{
|
||||
var resp = method.Invoke(this,
|
||||
[adventureTriggerAttack.AttackTargetType, param.CasterEntity, param.TargetEntities]);
|
||||
if (resp is List<BaseGameEntity> target)
|
||||
foreach (var task in adventureTriggerAttack.OnAttack)
|
||||
{
|
||||
foreach (var task in adventureTriggerAttack.OnAttack)
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null) battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (target.Count > 0 && adventureTriggerAttack.TriggerBattle)
|
||||
{
|
||||
foreach (var task in adventureTriggerAttack.OnBattle)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null) battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (target.Count > 0 && adventureTriggerAttack.TriggerBattle)
|
||||
foreach (var entity in param.TargetEntities)
|
||||
{
|
||||
foreach (var task in adventureTriggerAttack.OnBattle)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null) battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
var type = MonsterBattleType.TriggerBattle;
|
||||
if (entity is EntityMonster { IsAlive: false })
|
||||
type = MonsterBattleType.DirectDieSkipBattle;
|
||||
|
||||
foreach (var entity in param.TargetEntities)
|
||||
{
|
||||
var type = MonsterBattleType.TriggerBattle;
|
||||
if (entity is EntityMonster { IsAlive: false })
|
||||
type = MonsterBattleType.DirectDieSkipBattle;
|
||||
|
||||
battleInfos.Add(new HitMonsterInstance(entity.EntityId, type));
|
||||
}
|
||||
|
||||
instance = await Player.BattleManager!.StartBattle(param.CasterEntity, param.TargetEntities,
|
||||
param.Request.SkillIndex == 1);
|
||||
battleInfos.Add(new HitMonsterInstance(entity.EntityId, type));
|
||||
}
|
||||
|
||||
instance = await Player.BattleManager!.StartBattle(param.CasterEntity, param.TargetEntities,
|
||||
param.Request.SkillIndex == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,7 +203,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AddMazeBuff(AbilityLevelParam param)
|
||||
public async ValueTask<object> AddMazeBuff(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
@@ -194,32 +211,29 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
if (param.Act is AddMazeBuff addMazeBuff)
|
||||
{
|
||||
var methodName = addMazeBuff.TargetType.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this,
|
||||
[addMazeBuff.TargetType, param.CasterEntity, param.TargetEntities]);
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return new AbilityLevelResult();
|
||||
var resp = await method(param with { TargetEvaluator = addMazeBuff.TargetType });
|
||||
|
||||
Dictionary<string, float> dynamic = [];
|
||||
foreach (var dynamicValue in addMazeBuff.DynamicValues)
|
||||
dynamic.Add(dynamicValue.Key, dynamicValue.Value.GetValue());
|
||||
Dictionary<string, float> dynamic = [];
|
||||
foreach (var dynamicValue in addMazeBuff.DynamicValues)
|
||||
dynamic.Add(dynamicValue.Key, dynamicValue.Value.GetValue());
|
||||
|
||||
if (resp is not List<BaseGameEntity> target) return new AbilityLevelResult(instance, battleInfos);
|
||||
if (resp is not List<BaseGameEntity> target) return new AbilityLevelResult(instance, battleInfos);
|
||||
|
||||
foreach (var entity in target)
|
||||
await entity.AddBuff(new SceneBuff(addMazeBuff.ID, 1,
|
||||
(param.CasterEntity as AvatarSceneInfo)?.AvatarInfo.BaseAvatarId ?? 0,
|
||||
addMazeBuff.LifeTime.FixedValue.Value < -1 ? 20 : -1)
|
||||
{
|
||||
DynamicValues = dynamic
|
||||
});
|
||||
}
|
||||
foreach (var entity in target)
|
||||
await entity.AddBuff(new SceneBuff(addMazeBuff.ID, 1,
|
||||
(param.CasterEntity as AvatarSceneInfo)?.AvatarInfo.BaseAvatarId ?? 0,
|
||||
addMazeBuff.LifeTime.FixedValue.Value < -1 ? 20 : -1)
|
||||
{
|
||||
DynamicValues = dynamic
|
||||
});
|
||||
}
|
||||
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AdventureFireProjectile(AbilityLevelParam param)
|
||||
public async ValueTask<object> AdventureFireProjectile(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
@@ -248,7 +262,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> NewAdventureFireProjectile(AbilityLevelParam param)
|
||||
public async ValueTask<object> NewAdventureFireProjectile(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
@@ -277,7 +291,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> CreateSummonUnit(AbilityLevelParam param)
|
||||
public async ValueTask<object> CreateSummonUnit(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is CreateSummonUnit createSummonUnit)
|
||||
{
|
||||
@@ -304,7 +318,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> DestroySummonUnit(AbilityLevelParam param)
|
||||
public async ValueTask<object> DestroySummonUnit(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is DestroySummonUnit destroySummonUnit)
|
||||
await Player.SceneInstance!.RemoveSummonUnitById(destroySummonUnit.SummonUnit.SummonUnitID); // TODO
|
||||
@@ -312,7 +326,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AddAdventureModifier(AbilityLevelParam param)
|
||||
public async ValueTask<object> AddAdventureModifier(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is AddAdventureModifier addAdventureModifier)
|
||||
{
|
||||
@@ -325,7 +339,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> RemoveAdventureModifier(AbilityLevelParam param)
|
||||
public async ValueTask<object> RemoveAdventureModifier(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is RemoveAdventureModifier removeAdventureModifier)
|
||||
{
|
||||
@@ -338,7 +352,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> RemoveSelfModifier(AbilityLevelParam param)
|
||||
public async ValueTask<object> RemoveSelfModifier(AbilityLevelParam param)
|
||||
{
|
||||
if (param.ModifierName != null)
|
||||
if (param.CasterEntity is IGameModifier mod)
|
||||
@@ -347,7 +361,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> RefreshMazeBuffTime(AbilityLevelParam param)
|
||||
public async ValueTask<object> RefreshMazeBuffTime(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is RefreshMazeBuffTime refreshMazeBuffTime)
|
||||
{
|
||||
@@ -361,7 +375,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AdvModifyMaxMazeMP(AbilityLevelParam param)
|
||||
public async ValueTask<object> AdvModifyMaxMazeMP(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
@@ -379,7 +393,7 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask AdventureSetAttackTargetMonsterDie(AbilityLevelParam param)
|
||||
public async ValueTask<object> AdventureSetAttackTargetMonsterDie(AbilityLevelParam param)
|
||||
{
|
||||
var avatar = param.CasterEntity as AvatarSceneInfo;
|
||||
if (GameData.AvatarConfigData.TryGetValue(avatar?.AvatarInfo.AvatarId ?? 0, out var excel))
|
||||
@@ -418,14 +432,18 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
await instance.GainMoney(Random.Shared.Next(20, 60));
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Predicate
|
||||
|
||||
public bool ByAllowInstantKill(AbilityLevelParam param)
|
||||
public async ValueTask<object> ByAllowInstantKill(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
foreach (var targetEntity in param.TargetEntities)
|
||||
if (targetEntity is EntityMonster monster)
|
||||
if (monster.MonsterData.Rank < MonsterRankEnum.Elite)
|
||||
@@ -434,30 +452,31 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ByIsContainAdventureModifier(AbilityLevelParam param)
|
||||
public async ValueTask<object> ByIsContainAdventureModifier(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (param.Act is ByIsContainAdventureModifier byIsContain)
|
||||
{
|
||||
// get target
|
||||
var result = false;
|
||||
var methodName = byIsContain.TargetType.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this,
|
||||
[byIsContain.TargetType, param.CasterEntity, param.TargetEntities]);
|
||||
|
||||
if (resp is List<BaseGameEntity> target)
|
||||
foreach (var entity in target)
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return false;
|
||||
|
||||
var resp = await method(param with { TargetEvaluator = byIsContain.TargetType });
|
||||
|
||||
if (resp is List<BaseGameEntity> target)
|
||||
foreach (var entity in target)
|
||||
{
|
||||
if (entity is not IGameModifier modifier) continue;
|
||||
if (modifier.Modifiers.Contains(byIsContain.ModifierName))
|
||||
{
|
||||
if (entity is not IGameModifier modifier) continue;
|
||||
if (modifier.Modifiers.Contains(byIsContain.ModifierName))
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -465,42 +484,50 @@ public class AbilityLevelTask(PlayerInstance player)
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AdventureByInMotionState(AbilityLevelParam param)
|
||||
public async ValueTask<object> AdventureByInMotionState(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AdventureByPlayerCurrentSkillType(AbilityLevelParam param)
|
||||
public async ValueTask<object> AdventureByPlayerCurrentSkillType(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (param.Act is AdventureByPlayerCurrentSkillType byPlayerCurrentSkillType)
|
||||
return param.Request.SkillIndex == (uint)byPlayerCurrentSkillType.SkillType;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ByCompareCarryMazebuff(AbilityLevelParam param)
|
||||
public async ValueTask<object> ByCompareCarryMazebuff(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (param.Act is ByCompareCarryMazebuff byCompareCarryMazebuff)
|
||||
return param.CasterEntity.BuffList.Any(x => x.BuffId == byCompareCarryMazebuff.BuffID);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ByAnd(AbilityLevelParam param)
|
||||
public async ValueTask<object> ByAnd(AbilityLevelParam param)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (param.Act is ByAnd byAnd)
|
||||
{
|
||||
foreach (var task in byAnd.PredicateList)
|
||||
{
|
||||
var methodName = task.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this, [param with { Act = task }]);
|
||||
if (resp is not bool res) return false;
|
||||
res = task.Inverse ? !res : res;
|
||||
if (!res) return false;
|
||||
}
|
||||
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return false;
|
||||
|
||||
var resp = await method(param with { Act = task });
|
||||
if (resp is not bool res) return false;
|
||||
res = task.Inverse ? !res : res;
|
||||
if (!res) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -520,4 +547,5 @@ public record AbilityLevelParam(
|
||||
BaseGameEntity CasterEntity,
|
||||
List<BaseGameEntity> TargetEntities,
|
||||
SceneCastSkillCsReq Request,
|
||||
string? ModifierName);
|
||||
string? ModifierName,
|
||||
TargetEvaluator? TargetEvaluator = null);
|
||||
@@ -3,6 +3,8 @@ using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.Lineup;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
using System.Collections.Concurrent;
|
||||
using EggLink.DanhengServer.Util;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Task.AvatarTask;
|
||||
|
||||
@@ -10,9 +12,11 @@ public class SummonUnitLevelTask
|
||||
{
|
||||
#region Task Condition
|
||||
|
||||
public bool ByIsContainAdventureModifier(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
public async ValueTask<object?> ByIsContainAdventureModifier(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
EntitySummonUnit? summonUnit)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -31,19 +35,40 @@ public class SummonUnitLevelTask
|
||||
{
|
||||
var methodName = act.Type.Replace("RPG.GameCore.", "");
|
||||
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null) _ = method.Invoke(this, [act, targetEntities, summonUnit]);
|
||||
// try to get from cache
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return;
|
||||
|
||||
method(act, targetEntities, summonUnit);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.GetByClassName().Error("An error occured, ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ExecuteTask? GetOrCreateExecuteTask(string methodName)
|
||||
{
|
||||
// try to get from cache
|
||||
if (_cachedTasks.TryGetValue(methodName, out var method)) return method;
|
||||
var methodProp = GetType().GetMethod(methodName);
|
||||
if (methodProp == null) return null;
|
||||
|
||||
method = (ExecuteTask)Delegate.CreateDelegate(typeof(ExecuteTask), this, methodProp);
|
||||
_cachedTasks[methodName] = method; // cached
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private delegate ValueTask<object?> ExecuteTask(TaskConfigInfo act, List<BaseGameEntity> targetEntities, EntitySummonUnit? summonUnit);
|
||||
|
||||
private readonly ConcurrentDictionary<string, ExecuteTask> _cachedTasks = [];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task
|
||||
|
||||
public async ValueTask PredicateTaskList(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
public async ValueTask<object?> PredicateTaskList(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
EntitySummonUnit? summonUnit)
|
||||
{
|
||||
if (act is PredicateTaskList predicateTaskList)
|
||||
@@ -51,26 +76,25 @@ public class SummonUnitLevelTask
|
||||
// handle predicateCondition
|
||||
var methodName = predicateTaskList.Predicate.Type.Replace("RPG.GameCore.", "");
|
||||
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this, [predicateTaskList.Predicate, targetEntities, summonUnit]);
|
||||
if (resp is bool res && res)
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
TriggerTask(task, targetEntities, summonUnit);
|
||||
else
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
TriggerTask(task, targetEntities, summonUnit);
|
||||
}
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return null;
|
||||
|
||||
var resp = await method(predicateTaskList.Predicate, targetEntities, summonUnit);
|
||||
if (resp is true)
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
TriggerTask(task, targetEntities, summonUnit);
|
||||
else
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
TriggerTask(task, targetEntities, summonUnit);
|
||||
}
|
||||
|
||||
await ValueTask.CompletedTask;
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask AddMazeBuff(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
public async ValueTask<object?> AddMazeBuff(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
EntitySummonUnit? summonUnit)
|
||||
{
|
||||
if (act is not AddMazeBuff addMazeBuff) return;
|
||||
if (act is not AddMazeBuff addMazeBuff) return null;
|
||||
|
||||
var buff = new SceneBuff(addMazeBuff.ID, 1, summonUnit?.CreateAvatarId ?? 0)
|
||||
{
|
||||
@@ -86,12 +110,14 @@ public class SummonUnitLevelTask
|
||||
|
||||
await monster.AddBuff(buff);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask RemoveMazeBuff(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
public async ValueTask<object?> RemoveMazeBuff(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
EntitySummonUnit? summonUnit)
|
||||
{
|
||||
if (act is not RemoveMazeBuff removeMazeBuff) return;
|
||||
if (act is not RemoveMazeBuff removeMazeBuff) return null;
|
||||
|
||||
foreach (var targetEntity in targetEntities)
|
||||
{
|
||||
@@ -99,12 +125,14 @@ public class SummonUnitLevelTask
|
||||
|
||||
await monster.RemoveBuff(removeMazeBuff.ID);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask RefreshMazeBuffTime(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
public async ValueTask<object?> RefreshMazeBuffTime(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
EntitySummonUnit? summonUnit)
|
||||
{
|
||||
if (act is not RefreshMazeBuffTime refreshMazeBuffTime) return;
|
||||
if (act is not RefreshMazeBuffTime refreshMazeBuffTime) return null;
|
||||
|
||||
var buff = new SceneBuff(refreshMazeBuffTime.ID, 1, summonUnit?.CreateAvatarId ?? 0)
|
||||
{
|
||||
@@ -118,9 +146,11 @@ public class SummonUnitLevelTask
|
||||
|
||||
await monster.AddBuff(buff);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask TriggerHitProp(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
public async ValueTask<object?> TriggerHitProp(TaskConfigInfo act, List<BaseGameEntity> targetEntities,
|
||||
EntitySummonUnit? summonUnit)
|
||||
{
|
||||
foreach (var targetEntity in targetEntities)
|
||||
@@ -145,6 +175,8 @@ public class SummonUnitLevelTask
|
||||
|
||||
prop.Scene.Player.RogueManager!.GetRogueInstance()?.OnPropDestruct(prop);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -7,7 +7,9 @@ using EggLink.DanhengServer.Enums.Scene;
|
||||
using EggLink.DanhengServer.Enums.Task;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
using EggLink.DanhengServer.GameServer.Game.Task.AvatarTask;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Task;
|
||||
|
||||
@@ -17,8 +19,10 @@ public class LevelTask(PlayerInstance player)
|
||||
|
||||
#region Prop Target
|
||||
|
||||
public EntityProp? TargetFetchAdvPropEx(TargetEvaluator act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> TargetFetchAdvPropEx(TargetEvaluator act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (act is TargetFetchAdvPropEx fetch)
|
||||
{
|
||||
if (fetch.FetchType != TargetFetchAdvPropFetchTypeEnum.SinglePropByPropID) return null;
|
||||
@@ -51,33 +55,54 @@ public class LevelTask(PlayerInstance player)
|
||||
{
|
||||
var methodName = act.Type.Replace("RPG.GameCore.", "");
|
||||
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null) _ = method.Invoke(this, [act, subMission, group]);
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method != null) _ = method(act, subMission, group);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private ExecuteTask? GetOrCreateExecuteTask(string methodName)
|
||||
{
|
||||
// try to get from cache
|
||||
if (_cachedTasks.TryGetValue(methodName, out var method)) return method;
|
||||
var methodProp = GetType().GetMethod(methodName);
|
||||
if (methodProp == null) return null;
|
||||
|
||||
method = (ExecuteTask)Delegate.CreateDelegate(typeof(ExecuteTask), this, methodProp);
|
||||
_cachedTasks[methodName] = method; // cached
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private delegate ValueTask<object?> ExecuteTask(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null);
|
||||
|
||||
private readonly ConcurrentDictionary<string, ExecuteTask> _cachedTasks = [];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task
|
||||
|
||||
public async ValueTask PlayMessage(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> PlayMessage(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is PlayMessage message) await Player.MessageManager!.AddMessageSection(message.MessageSectionID);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask DestroyProp(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> DestroyProp(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is DestroyProp destroyProp)
|
||||
foreach (var entity in Player.SceneInstance!.Entities.Values)
|
||||
if (entity is EntityProp prop && prop.GroupId == destroyProp.GroupID.GetValue() &&
|
||||
prop.InstId == destroyProp.ID.GetValue())
|
||||
await Player.SceneInstance.RemoveEntity(entity);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask TriggerCustomString(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> TriggerCustomString(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is TriggerCustomString triggerCustomString)
|
||||
{
|
||||
@@ -91,21 +116,27 @@ public class LevelTask(PlayerInstance player)
|
||||
|
||||
await Player.MissionManager!.HandleFinishType(MissionFinishTypeEnum.PropState);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask EnterMap(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> EnterMap(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is EnterMap enterMap)
|
||||
await Player.EnterSceneByEntranceId(enterMap.EntranceID, enterMap.GroupID, enterMap.AnchorID, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask EnterMapByCondition(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> EnterMapByCondition(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is EnterMapByCondition enterMapByCondition)
|
||||
await Player.EnterSceneByEntranceId(enterMapByCondition.EntranceID.GetValue(), 0, 0, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask TriggerPerformance(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> TriggerPerformance(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is TriggerPerformance triggerPerformance)
|
||||
{
|
||||
@@ -117,63 +148,68 @@ public class LevelTask(PlayerInstance player)
|
||||
subMission);
|
||||
}
|
||||
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask PredicateTaskList(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> PredicateTaskList(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is PredicateTaskList predicateTaskList)
|
||||
{
|
||||
// handle predicateCondition
|
||||
var methodName = predicateTaskList.Predicate.Type.Replace("RPG.GameCore.", "");
|
||||
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this, [predicateTaskList.Predicate, subMission, group]);
|
||||
if (resp is bool res && res)
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
TriggerTask(task, subMission, group);
|
||||
else
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
TriggerTask(task, subMission, group);
|
||||
}
|
||||
var method = GetOrCreateExecuteTask(methodName);
|
||||
if (method == null) return null;
|
||||
|
||||
var resp = await method(predicateTaskList.Predicate, subMission, group);
|
||||
if (resp is true)
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
TriggerTask(task, subMission, group);
|
||||
else
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
TriggerTask(task, subMission, group);
|
||||
}
|
||||
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask ChangePropState(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> ChangePropState(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.PropState)
|
||||
foreach (var entity in Player.SceneInstance!.Entities.Values)
|
||||
if (entity is EntityProp prop && prop.GroupId == subMission.SubMissionInfo.ParamInt1 &&
|
||||
prop.InstId == subMission.SubMissionInfo.ParamInt2)
|
||||
try
|
||||
{
|
||||
if (prop.Excel.PropStateList.Contains(PropStateEnum.Closed))
|
||||
{
|
||||
await prop.SetState(PropStateEnum.Closed);
|
||||
}
|
||||
else
|
||||
{
|
||||
await prop.SetState(
|
||||
prop.Excel.PropStateList[prop.Excel.PropStateList.IndexOf(prop.State) + 1]);
|
||||
if (subMission.SubMissionInfo?.FinishType != MissionFinishTypeEnum.PropState) return null;
|
||||
|
||||
// Elevator
|
||||
foreach (var id in prop.PropInfo.UnlockControllerID)
|
||||
foreach (var entity2 in Player.SceneInstance!.Entities.Values)
|
||||
if (entity2 is EntityProp prop2 && prop2.GroupId == id.Key &&
|
||||
id.Value.Contains(prop2.InstId))
|
||||
await prop2.SetState(PropStateEnum.Closed);
|
||||
}
|
||||
}
|
||||
catch
|
||||
foreach (var entity in Player.SceneInstance!.Entities.Values)
|
||||
if (entity is EntityProp prop && prop.GroupId == subMission.SubMissionInfo.ParamInt1 &&
|
||||
prop.InstId == subMission.SubMissionInfo.ParamInt2)
|
||||
try
|
||||
{
|
||||
if (prop.Excel.PropStateList.Contains(PropStateEnum.Closed))
|
||||
{
|
||||
await prop.SetState(PropStateEnum.Closed);
|
||||
}
|
||||
else
|
||||
{
|
||||
await prop.SetState(
|
||||
prop.Excel.PropStateList[prop.Excel.PropStateList.IndexOf(prop.State) + 1]);
|
||||
|
||||
// Elevator
|
||||
foreach (var id in prop.PropInfo.UnlockControllerID)
|
||||
foreach (var entity2 in Player.SceneInstance!.Entities.Values)
|
||||
if (entity2 is EntityProp prop2 && prop2.GroupId == id.Key &&
|
||||
id.Value.Contains(prop2.InstId))
|
||||
await prop2.SetState(PropStateEnum.Closed);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask CreateTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> CreateTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.GetTrialAvatar)
|
||||
await Player.LineupManager!.AddAvatarToCurTeam(subMission.SubMissionInfo.ParamInt1);
|
||||
@@ -181,9 +217,11 @@ public class LevelTask(PlayerInstance player)
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.GetTrialAvatarList)
|
||||
subMission.SubMissionInfo.ParamIntList?.ForEach(
|
||||
async x => await Player.LineupManager!.AddAvatarToCurTeam(x));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask ReplaceTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> ReplaceTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.GetTrialAvatar)
|
||||
{
|
||||
@@ -199,9 +237,11 @@ public class LevelTask(PlayerInstance player)
|
||||
subMission.SubMissionInfo.ParamIntList?.ForEach(
|
||||
async x => await Player.LineupManager!.AddAvatarToCurTeam(x));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask StoryLineReplaceTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> StoryLineReplaceTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.StoryLineAddTrialAvatar)
|
||||
{
|
||||
@@ -209,11 +249,13 @@ public class LevelTask(PlayerInstance player)
|
||||
ids.ForEach(async void (x) => await Player.LineupManager!.RemoveAvatarFromCurTeam(x.BaseAvatarId, false));
|
||||
await Player.LineupManager!.AddAvatarToCurTeam(subMission.SubMissionInfo.ParamInt1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask ReplaceVirtualTeam(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> ReplaceVirtualTeam(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (Player.LineupManager!.GetCurLineup()?.IsExtraLineup() != true) return;
|
||||
if (Player.LineupManager!.GetCurLineup()?.IsExtraLineup() != true) return null;
|
||||
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.GetTrialAvatar)
|
||||
{
|
||||
@@ -230,9 +272,11 @@ public class LevelTask(PlayerInstance player)
|
||||
subMission.SubMissionInfo.ParamIntList?.ForEach(
|
||||
async x => await Player.LineupManager!.AddAvatarToCurTeam(x));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask CreateHeroTrialPlayer(TaskConfigInfo act, SubMissionData subMission,
|
||||
public async ValueTask<object?> CreateHeroTrialPlayer(TaskConfigInfo act, SubMissionData subMission,
|
||||
GroupInfo? group = null)
|
||||
{
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.GetTrialAvatar)
|
||||
@@ -266,24 +310,30 @@ public class LevelTask(PlayerInstance player)
|
||||
|
||||
list.ForEach(async x => await Player.LineupManager!.AddAvatarToCurTeam(x));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask DestroyTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> DestroyTrialPlayer(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (subMission.SubMissionInfo?.FinishType == MissionFinishTypeEnum.DelTrialAvatar)
|
||||
await Player.LineupManager!.RemoveAvatarFromCurTeam(subMission.SubMissionInfo.ParamInt1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask ChangeGroupState(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> ChangeGroupState(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (group != null)
|
||||
foreach (var entity in Player.SceneInstance?.Entities.Values.ToList() ?? [])
|
||||
if (entity is EntityProp prop && prop.GroupId == group.Id)
|
||||
if (prop.Excel.PropStateList.Contains(PropStateEnum.Open))
|
||||
await prop.SetState(PropStateEnum.Open);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask TriggerEntityServerEvent(TaskConfigInfo act, SubMissionData subMission,
|
||||
public async ValueTask<object?> TriggerEntityServerEvent(TaskConfigInfo act, SubMissionData subMission,
|
||||
GroupInfo? group = null)
|
||||
{
|
||||
if (group != null)
|
||||
@@ -292,9 +342,11 @@ public class LevelTask(PlayerInstance player)
|
||||
if (prop.Excel.PropStateList.Contains(PropStateEnum.Open) &&
|
||||
(prop.State == PropStateEnum.Closed || prop.State == PropStateEnum.Locked))
|
||||
await prop.SetState(PropStateEnum.Open);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask TriggerEntityEvent(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> TriggerEntityEvent(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is TriggerEntityEvent triggerEntityEvent)
|
||||
if (group != null)
|
||||
@@ -303,18 +355,22 @@ public class LevelTask(PlayerInstance player)
|
||||
prop.InstId == triggerEntityEvent.InstanceID.GetValue())
|
||||
if (prop.Excel.PropStateList.Contains(PropStateEnum.Closed))
|
||||
await prop.SetState(PropStateEnum.Closed);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask PropSetupUITrigger(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> PropSetupUITrigger(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is PropSetupUITrigger propSetupUiTrigger)
|
||||
foreach (var task in propSetupUiTrigger.ButtonCallback)
|
||||
TriggerTask(task, subMission, group);
|
||||
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask PropStateExecute(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> PropStateExecute(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
if (act is PropStateExecute propStateExecute)
|
||||
{
|
||||
@@ -328,14 +384,18 @@ public class LevelTask(PlayerInstance player)
|
||||
if (resp is EntityProp result) await result.SetState(propStateExecute.State);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task Condition
|
||||
|
||||
public bool ByCompareSubMissionState(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> ByCompareSubMissionState(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (act is ByCompareSubMissionState compare)
|
||||
{
|
||||
var mission = Player.MissionManager!.GetSubMissionStatus(compare.SubMissionID);
|
||||
@@ -345,8 +405,10 @@ public class LevelTask(PlayerInstance player)
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ByCompareFloorSavedValue(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
public async ValueTask<object?> ByCompareFloorSavedValue(TaskConfigInfo act, SubMissionData subMission, GroupInfo? group = null)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
|
||||
if (act is ByCompareFloorSavedValue compare)
|
||||
{
|
||||
var value = Player.SceneData!.FloorSavedData.GetValueOrDefault(Player.Data.FloorId, []);
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.Lobby;
|
||||
using EggLink.DanhengServer.Enums.Rogue;
|
||||
using EggLink.DanhengServer.GameServer.Game.ChessRogue.Modifier.ModifierEffect;
|
||||
using EggLink.DanhengServer.GameServer.Game.Lobby;
|
||||
using EggLink.DanhengServer.GameServer.Game.Mission;
|
||||
using EggLink.DanhengServer.GameServer.Game.Mission.FinishAction;
|
||||
using EggLink.DanhengServer.GameServer.Game.Mission.FinishType;
|
||||
using EggLink.DanhengServer.GameServer.Game.MultiPlayer;
|
||||
using EggLink.DanhengServer.GameServer.Game.Rogue.Event;
|
||||
using System.Reflection;
|
||||
using EggLink.DanhengServer.GameServer.Game.ChessRogue;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Server;
|
||||
|
||||
@@ -7,4 +15,63 @@ public static class ServerUtils
|
||||
{
|
||||
public static LobbyServerManager LobbyServerManager { get; set; } = new();
|
||||
public static MultiPlayerGameServerManager MultiPlayerGameServerManager { get; set; } = new();
|
||||
|
||||
public static void InitializeHandlers()
|
||||
{
|
||||
// mission handlers
|
||||
{
|
||||
var types = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attr = type.GetCustomAttribute<MissionFinishActionAttribute>();
|
||||
if (attr != null)
|
||||
{
|
||||
var handler = (MissionFinishActionHandler)Activator.CreateInstance(type, null)!;
|
||||
MissionManager.ActionHandlers.Add(attr.FinishAction, handler);
|
||||
}
|
||||
|
||||
var attr2 = type.GetCustomAttribute<MissionFinishTypeAttribute>();
|
||||
if (attr2 != null)
|
||||
{
|
||||
var handler = (MissionFinishTypeHandler)Activator.CreateInstance(type, null)!;
|
||||
MissionManager.FinishTypeHandlers.Add(attr2.FinishType, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rogue event handlers
|
||||
{
|
||||
var types = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attr = type.GetCustomAttribute<RogueEventAttribute>();
|
||||
if (attr == null) continue;
|
||||
if (attr.EffectType != DialogueEventTypeEnum.None)
|
||||
{
|
||||
// Effect
|
||||
var effect = (RogueEventEffectHandler)Activator.CreateInstance(type, null)!;
|
||||
RogueEventManager.EffectHandler.Add(attr.EffectType, effect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cost
|
||||
var cost = (RogueEventCostHandler)Activator.CreateInstance(type, null)!;
|
||||
RogueEventManager.CostHandler.Add(attr.CostType, cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// chess rogue modifier handlers
|
||||
{
|
||||
var types = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
var attr = type.GetCustomAttribute<ModifierEffectAttribute>();
|
||||
if (attr == null) continue;
|
||||
|
||||
var handler = (ModifierEffectHandler)Activator.CreateInstance(type, null)!;
|
||||
ChessRogueInstance.ModifierEffectHandlers.Add(attr.EffectType, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +166,8 @@ public class EntryPoint
|
||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.ServerRunning", I18NManager.Translate("Word.Dispatch"),
|
||||
GetConfig().HttpServer.GetDisplayAddress()));
|
||||
|
||||
DanhengListener.BaseConnection = typeof(Connection);
|
||||
var handler = new DanhengListener.ConnectionCreatedHandler((conversation, remote) => new Connection(conversation, remote));
|
||||
DanhengListener.CreateConnection = handler;
|
||||
DanhengListener.StartListener();
|
||||
|
||||
GenerateLogMap();
|
||||
@@ -326,6 +327,8 @@ public class EntryPoint
|
||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItem", I18NManager.Translate("Word.Database")));
|
||||
}
|
||||
|
||||
ServerUtils.InitializeHandlers();
|
||||
|
||||
// check if the database is up to date
|
||||
var updated = false;
|
||||
foreach (var avatarData in DatabaseHelper.GetAllInstanceFromMap<AvatarData>()!)
|
||||
|
||||
Reference in New Issue
Block a user