summaryrefslogtreecommitdiff
path: root/Impostor-dev/src/Impostor.Tools.Proxy
diff options
context:
space:
mode:
Diffstat (limited to 'Impostor-dev/src/Impostor.Tools.Proxy')
-rw-r--r--Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs70
-rw-r--r--Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj17
-rw-r--r--Impostor-dev/src/Impostor.Tools.Proxy/Program.cs198
3 files changed, 285 insertions, 0 deletions
diff --git a/Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs b/Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs
new file mode 100644
index 0000000..79517b4
--- /dev/null
+++ b/Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Text;
+
+namespace Impostor.Tools.Proxy
+{
+ public static class HexUtils
+ {
+ public static string HexDump(byte[] bytes, int bytesPerLine = 16)
+ {
+ if (bytes == null) return "<null>";
+ int bytesLength = bytes.Length;
+
+ char[] HexChars = "0123456789ABCDEF".ToCharArray();
+
+ int firstHexColumn =
+ 8 // 8 characters for the address
+ + 3; // 3 spaces
+
+ int firstCharColumn = firstHexColumn
+ + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space
+ + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th
+ + 2; // 2 spaces
+
+ int lineLength = firstCharColumn
+ + bytesPerLine // - characters to show the ascii value
+ + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2)
+
+ char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray();
+ int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine;
+ StringBuilder result = new StringBuilder(expectedLines * lineLength);
+
+ for (int i = 0; i < bytesLength; i += bytesPerLine)
+ {
+ line[0] = HexChars[(i >> 28) & 0xF];
+ line[1] = HexChars[(i >> 24) & 0xF];
+ line[2] = HexChars[(i >> 20) & 0xF];
+ line[3] = HexChars[(i >> 16) & 0xF];
+ line[4] = HexChars[(i >> 12) & 0xF];
+ line[5] = HexChars[(i >> 8) & 0xF];
+ line[6] = HexChars[(i >> 4) & 0xF];
+ line[7] = HexChars[(i >> 0) & 0xF];
+
+ int hexColumn = firstHexColumn;
+ int charColumn = firstCharColumn;
+
+ for (int j = 0; j < bytesPerLine; j++)
+ {
+ if (j > 0 && (j & 7) == 0) hexColumn++;
+ if (i + j >= bytesLength)
+ {
+ line[hexColumn] = ' ';
+ line[hexColumn + 1] = ' ';
+ line[charColumn] = ' ';
+ }
+ else
+ {
+ byte b = bytes[i + j];
+ line[hexColumn] = HexChars[(b >> 4) & 0xF];
+ line[hexColumn + 1] = HexChars[b & 0xF];
+ line[charColumn] = (b < 32 ? '·' : (char)b);
+ }
+ hexColumn += 3;
+ charColumn++;
+ }
+ result.Append(line);
+ }
+ return result.ToString();
+ }
+ }
+} \ No newline at end of file
diff --git a/Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj b/Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj
new file mode 100644
index 0000000..8f523dc
--- /dev/null
+++ b/Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0" />
+ <PackageReference Include="Pcap.Net.x64" Version="1.0.4.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Impostor.Hazel\Impostor.Hazel.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Impostor-dev/src/Impostor.Tools.Proxy/Program.cs b/Impostor-dev/src/Impostor.Tools.Proxy/Program.cs
new file mode 100644
index 0000000..9e765f0
--- /dev/null
+++ b/Impostor-dev/src/Impostor.Tools.Proxy/Program.cs
@@ -0,0 +1,198 @@
+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<byte, string> TagMap = new Dictionary<byte, string>
+ {
+ {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<MessageReader> _readerPool;
+
+ //c 服务器入口
+ private static void Main(string[] args)
+ {
+ var services = new ServiceCollection();
+ services.AddHazel();
+
+ _serviceProvider = services.BuildServiceProvider();
+ _readerPool = _serviceProvider.GetRequiredService<ObjectPool<MessageReader>>();
+
+ 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;
+ }
+ }
+ }
+}