using System; using System.Collections.Generic; using System.Linq; using Impostor.Api.Net.Messages; using Impostor.Hazel; using Impostor.Hazel.Extensions; using Impostor.Hazel.Udp; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.ObjectPool; using PcapDotNet.Core; using PcapDotNet.Packets; namespace Impostor.Tools.Proxy { internal static class Program { private const string DeviceName = "Intel(R) I211 Gigabit Network Connection"; private static readonly Dictionary TagMap = new Dictionary { {0, "HostGame"}, {1, "JoinGame"}, {2, "StartGame"}, {3, "RemoveGame"}, {4, "RemovePlayer"}, {5, "GameData"}, {6, "GameDataTo"}, {7, "JoinedGame"}, {8, "EndGame"}, {9, "GetGameList"}, {10, "AlterGame"}, {11, "KickPlayer"}, {12, "WaitForHost"}, {13, "Redirect"}, {14, "ReselectServer"}, {16, "GetGameListV2"} }; private static IServiceProvider _serviceProvider; private static ObjectPool _readerPool; //c 服务器入口 private static void Main(string[] args) { var services = new ServiceCollection(); services.AddHazel(); _serviceProvider = services.BuildServiceProvider(); _readerPool = _serviceProvider.GetRequiredService>(); var devices = LivePacketDevice.AllLocalMachine; if (devices.Count == 0) { Console.WriteLine("No interfaces found! Make sure WinPcap is installed."); return; } var device = devices.FirstOrDefault(x => x.Description.Contains(DeviceName)); if (device == null) { Console.WriteLine("Unable to find configured device."); return; } using (var communicator = device.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000)) { using (var filter = communicator.CreateFilter("udp and port 22023")) { communicator.SetFilter(filter); } communicator.ReceivePackets(0, PacketHandler); } } private static void PacketHandler(Packet packet) { var ip = packet.Ethernet.IpV4; var ipSrc = ip.Source.ToString(); var udp = ip.Udp; // True if this is our own packet. using (var stream = udp.Payload.ToMemoryStream()) { using var reader = _readerPool.Get(); reader.Update(stream.ToArray()); var option = reader.Buffer[0]; if (option == (byte) MessageType.Reliable) { reader.Seek(reader.Position + 3); } else if (option == (byte) UdpSendOption.Acknowledgement || option == (byte) UdpSendOption.Ping || option == (byte) UdpSendOption.Hello || option == (byte) UdpSendOption.Disconnect) { return; } else { reader.Seek(reader.Position + 1); } var isSent = ipSrc.StartsWith("192."); while (true) { if (reader.Position >= reader.Length) { break; } //c 消息 using var message = reader.ReadMessage(); if (isSent) { HandleToServer(ipSrc, message); } else { HandleToClient(ipSrc, message); } if (message.Position < message.Length) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("- Did not consume all bytes."); } } } } private static void HandleToClient(string source, IMessageReader packet) { var tagName = TagMap.ContainsKey(packet.Tag) ? TagMap[packet.Tag] : "Unknown"; Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine($"{source,-15} Client received: {packet.Tag,-2} {tagName}"); switch (packet.Tag) { case 14: case 13: // packet.Position = packet.Length; break; case 0: Console.WriteLine("- GameCode " + packet.ReadInt32()); break; case 5: case 6: Console.WriteLine(HexUtils.HexDump(packet.Buffer.ToArray().Take(packet.Length).ToArray())); // packet.Position = packet.Length; break; case 7: Console.WriteLine("- GameCode " + packet.ReadInt32()); Console.WriteLine("- PlayerId " + packet.ReadInt32()); Console.WriteLine("- Host " + packet.ReadInt32()); var playerCount = packet.ReadPackedInt32(); Console.WriteLine("- PlayerCount " + playerCount); for (var i = 0; i < playerCount; i++) { Console.WriteLine("- PlayerId " + packet.ReadPackedInt32()); } break; case 10: Console.WriteLine("- GameCode " + packet.ReadInt32()); Console.WriteLine("- Flag " + packet.ReadSByte()); Console.WriteLine("- Value " + packet.ReadBoolean()); break; } } private static void HandleToServer(string source, IMessageReader packet) { var tagName = TagMap.ContainsKey(packet.Tag) ? TagMap[packet.Tag] : "Unknown"; Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($"{source,-15} Server received: {packet.Tag,-2} {tagName}"); switch (packet.Tag) { case 0: Console.WriteLine("- GameInfo length " + packet.ReadBytesAndSize().Length); break; case 1: Console.WriteLine("- GameCode " + packet.ReadInt32()); Console.WriteLine("- Unknown " + packet.ReadByte()); break; case 5: case 6: Console.WriteLine("- GameCode " + packet.ReadInt32()); Console.WriteLine(HexUtils.HexDump(packet.Buffer.ToArray().Take(packet.Length).ToArray())); // packet.Position = packet.Length; break; } } } }