Campofinale/Campofinale/NotifyManager.cs
2025-03-20 18:06:02 -07:00

69 lines
2.8 KiB
C#

namespace Campofinale
{
using Pastel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Collections.Immutable;
using System.Linq.Expressions;
using System.Reflection;
using Campofinale.Protocol;
using Campofinale.Network;
internal static class NotifyManager
{
private static List<Type> s_handlerTypes = new List<Type>();
private static ImmutableDictionary<CsMsgId, (Server.HandlerAttribute, Server.HandlerAttribute.HandlerDelegate)> s_notifyReqGroup;
public static void Init()
{
var handlers = ImmutableDictionary.CreateBuilder<CsMsgId, (Server.HandlerAttribute, Server.HandlerAttribute.HandlerDelegate)>();
foreach (var type in s_handlerTypes)
{
foreach (var method in type.GetMethods())
{
var attribute = method.GetCustomAttribute<Server.HandlerAttribute>();
if (attribute == null)
continue;
var parameterInfo = method.GetParameters();
var sessionParameter = Expression.Parameter(typeof(Player));
var cmdIdParameter = Expression.Parameter(typeof(int));
var packetParameter = Expression.Parameter(typeof(Packet));
var call = Expression.Call(method,
Expression.Convert(sessionParameter, parameterInfo[0].ParameterType),
Expression.Convert(cmdIdParameter, parameterInfo[1].ParameterType),
Expression.Convert(packetParameter, parameterInfo[2].ParameterType));
var lambda = Expression.Lambda<Server.HandlerAttribute.HandlerDelegate>(call, sessionParameter, cmdIdParameter, packetParameter);
if (!handlers.TryGetKey(attribute.CmdId, out _))
handlers.Add(attribute.CmdId, (attribute, lambda.Compile()));
}
}
s_notifyReqGroup = handlers.ToImmutable();
}
public static void Notify(Player session, CsMsgId cmdId, Network.Packet packet)
{
if (s_notifyReqGroup.TryGetValue(cmdId, out var handler))
{
handler.Item2.Invoke(session, ((int)cmdId), packet);
}
else
{
if (!Server.hideLog.Contains(cmdId) && Server.config.logOptions.packets)
Logger.PrintWarn($"Can't find handler for {(Enum.GetName(typeof(CsMsgId), cmdId)).ToString().Pastel(Color.FromArgb(165, 229, 250))} ({(cmdId).ToString().Pastel(Color.FromArgb(165, 229, 250))})");
}
}
public static void AddReqGroupHandler(Type type)
{
s_handlerTypes.Add(type);
}
}
}