forked from Raphael/SCHALE.GameServer
141 lines
5.1 KiB
C#
141 lines
5.1 KiB
C#
using Google.FlatBuffers;
|
|
using SCHALE.Common.NetworkProtocol;
|
|
using System.Text.Json.Nodes;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Newtonsoft.Json;
|
|
using Serilog;
|
|
using System.Reflection;
|
|
|
|
namespace SCHALE.GameServer.Utils
|
|
{
|
|
public static class PcapUtils
|
|
{
|
|
private static readonly string DefaultPcapFileName = "packets.json";
|
|
//private static readonly string CurrentPcapFileName = "";
|
|
|
|
private static List<RequestPacket> RequestPackets { get; } = null;
|
|
private static List<ResponsePacket> ResponsePackets { get; } = null;
|
|
|
|
static PcapUtils()
|
|
{
|
|
RequestPackets = new List<RequestPacket>();
|
|
ResponsePackets = new List<ResponsePacket>();
|
|
|
|
PcapUtils.Load(DefaultPcapFileName);
|
|
}
|
|
|
|
// gets all packets of that type
|
|
public static T[] GetPacketsFromPcap<T>(Protocol protocol, PacketType packetType) where T : BasePacket
|
|
{
|
|
if (packetType == PacketType.Request)
|
|
{
|
|
return RequestPackets.Where(x => x.Protocol == protocol).Select(x => x as T).ToArray();
|
|
}
|
|
else
|
|
{
|
|
return ResponsePackets.Where(x => x.Protocol == protocol).Select(x => x as T).ToArray();
|
|
}
|
|
}
|
|
|
|
// get a single packet, remember to change the sessionkey, accountId, etc..
|
|
public static T GetPacketFromPcap<T>(Protocol protocol, PacketType packetType) where T : BasePacket
|
|
{
|
|
return GetPacketsFromPcap<T>((Protocol)protocol, packetType).FirstOrDefault();
|
|
}
|
|
|
|
public static bool Load(string pcapFileName)
|
|
{
|
|
// clear first? not clearing can cause conflicts
|
|
RequestPackets.Clear();
|
|
ResponsePackets.Clear();
|
|
|
|
string PcapFilePath = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), pcapFileName);
|
|
|
|
if (!Path.Exists(PcapFilePath))
|
|
{
|
|
Log.Error($"Pcap json file was not found at path {PcapFilePath}.");
|
|
return false;
|
|
}
|
|
|
|
var json = File.ReadAllText(PcapFilePath);
|
|
var jsonPackets = System.Text.Json.JsonSerializer.Deserialize<JsonArray>(json);
|
|
|
|
foreach (JsonNode packetNode in jsonPackets)
|
|
{
|
|
PacketType packetType = packetNode["type"].ToString() == "REQUEST" ? PacketType.Request : PacketType.Response;
|
|
JsonNode packetPayload = packetNode["payload"];
|
|
|
|
Protocol protocol = (Protocol?)packetPayload?["Protocol"]?.GetValue<int?>() ?? Protocol.None;
|
|
|
|
if (protocol == Protocol.None)
|
|
{
|
|
Log.Warning("Failed to read protocol from JsonNode, {Payload:j}", packetNode.ToString());
|
|
continue;
|
|
}
|
|
|
|
Type packetClassType;
|
|
object packet;
|
|
|
|
try
|
|
{
|
|
packetClassType = GetPacketTypeByProtocol(protocol, packetType);
|
|
|
|
packet = packetPayload.Deserialize(packetClassType);
|
|
} catch (Exception ex)
|
|
{
|
|
Log.Warning($"Failed to deserialize {packetNode["type"]} protocol {protocol} from JsonNode, payload: {packetPayload.ToString()}");
|
|
continue;
|
|
}
|
|
|
|
if (packetType == PacketType.Request)
|
|
{
|
|
RequestPackets.Add((RequestPacket)packet);
|
|
}
|
|
else
|
|
{
|
|
ResponsePackets.Add((ResponsePacket)packet);
|
|
}
|
|
|
|
Log.Information($"Loaded Pcap Type: {packetNode["type"]}, Protocol: {protocol}");
|
|
}
|
|
|
|
Log.Information($"Successfully Loaded Packets from: {PcapFilePath}!");
|
|
return true;
|
|
}
|
|
|
|
public static Type? GetPacketTypeByProtocol(Protocol protocol, PacketType packetType)
|
|
{
|
|
var assembly = Assembly.GetAssembly(typeof(BasePacket));
|
|
Type baseType = packetType == PacketType.Request ? typeof(RequestPacket) : typeof(ResponsePacket);
|
|
var packetTypeCandidates = assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t) && !t.IsAbstract);
|
|
|
|
foreach (var candidate in packetTypeCandidates)
|
|
{
|
|
var protocolProperty = candidate.GetProperty("Protocol", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
|
|
|
if (protocolProperty != null && protocolProperty.PropertyType == typeof(Protocol))
|
|
{
|
|
var instance = Activator.CreateInstance(candidate);
|
|
if (instance != null)
|
|
{
|
|
var protocolValue = protocolProperty.GetValue(instance);
|
|
if (protocolValue != null && protocolValue.Equals(protocol))
|
|
{
|
|
return candidate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public enum PacketType
|
|
{
|
|
Request,
|
|
Response,
|
|
}
|
|
}
|