help
Root Question Message
public class anythinggoes
{
static Dictionary<_MAP_LOGIN_PROTOCOL, Delegate> loginPacketDef = new Dictionary<_MAP_LOGIN_PROTOCOL, Delegate>()
{
{LOGIN_PROTOCOL.LOGIN, new Action<_rcmRequestGateLogin>(PacketHandler.OnLoginPacket)},
};
}
public class PacketHandler//Packet handling
{
private SocketClient connection;
PacketHandler handler = null;
public PacketHandler(SocketClient connection)
{
//Code
}
public void SendPacket(byte[] data)
{
//Code
}
public void OnLoginPacket(_rcmRequestGateLogin request)
{
//Code
}
}
var handlers = BuildHandlers();
var packet = new PacketHandler(null);
handlers[Opcode._MAP_LOGIN_PROTOCOL].Invoke(packet, new _rcmRequestGateLogin());
handlers[Opcode._MAP_LOGOUT_PROTOCOL].Invoke(packet, null);
Dictionary<Opcode, Action<PacketHandler, object>> BuildHandlers()
{
var handlers = new Dictionary<Opcode, Action<PacketHandler, object>>();
foreach(var methodInfo in typeof(PacketHandler).GetMethods())
{
var handlerAttribute = methodInfo.GetCustomAttribute<HandlerAttribute>();
if (handlerAttribute == null)
continue;
var methodParamType = methodInfo.GetParameters()[0].ParameterType;
var thisParam = Expression.Parameter(typeof(PacketHandler));
var requestParam = Expression.Parameter(typeof(object));
var cast = Expression.Convert(requestParam, methodParamType);
var call = Expression.Call(thisParam, methodInfo, cast);
var lambda = Expression.Lambda<Action<PacketHandler, object>>(call, thisParam, requestParam);
var action = lambda.Compile();
handlers.Add(handlerAttribute.Opcode, action);
}
return handlers;
}
enum Opcode
{
_MAP_LOGIN_PROTOCOL,
_MAP_LOGOUT_PROTOCOL,
}
public class PacketHandler//Packet handling
{
private SocketClient connection;
PacketHandler handler = null;
public PacketHandler(SocketClient connection)
{
}
public void SendPacket(byte[] data)
{
//Code
}
[Handler(Opcode._MAP_LOGIN_PROTOCOL)]
public void OnLoginPacket(_rcmRequestGateLogin request)
{
Console.WriteLine("OnLoginPacket");
//Code
}
[Handler(Opcode._MAP_LOGOUT_PROTOCOL)]
public void OnLogoutPacket(object _)
{
Console.WriteLine("OnLogoutPacket");
}
}
class HandlerAttribute : Attribute
{
public Opcode Opcode { get; }
public HandlerAttribute(Opcode opcode)
{
Opcode = opcode;
}
}
Handler
attribute on your handler methodspublic static class HandlersManager
{
public static Dictionary<Opcode, Func<PacketHandler, object, object>> returnHandlers = new();
public static T? Invoke<T>(Opcode opcode, PacketHandler packetHandler, object args) where T : class
{
return Invoke(opcode, packetHandler, args) as T;
}
public static object? Invoke(Opcode opcode, PacketHandler packetHandler, object args)
{
return returnHandlers.TryGetValue(opcode, out var handler) ? handler(packetHandler, args) : null;
}
public static void BuildHandlers()
{
var handlers = new Dictionary<Opcode, Action<PacketHandler, object>>();
foreach (var methodInfo in typeof(PacketHandler).GetMethods())
{
var handlerAttribute = methodInfo.GetCustomAttribute<HandlerAttribute>();
if (handlerAttribute == null)
continue;
var methodParamType = methodInfo.GetParameters()[0].ParameterType;
var thisParam = Expression.Parameter(typeof(PacketHandler));
var requestParam = Expression.Parameter(typeof(object));
var cast = Expression.Convert(requestParam, methodParamType);
var call = Expression.Call(thisParam, methodInfo, cast);
Func<PacketHandler, object, object>? func;
if (methodInfo.ReturnType != typeof(void))
{
func = Expression.Lambda<Func<PacketHandler, object, object>>(call, thisParam, requestParam).Compile();
}
else
{
func = Expression.Lambda<Func<PacketHandler, object, object>>(Expression.Block(call, Expression.Constant(null)), thisParam, requestParam).Compile();
}
returnHandlers.Add(handlerAttribute.Opcode, func);
}
}
}