mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-02 20:26:03 +08:00
58 lines
1.9 KiB
C#
58 lines
1.9 KiB
C#
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 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;
|
|
}
|
|
}
|
|
|
|
private delegate IMessage ParseIMessage(byte[] data);
|
|
} |