From 5db481e039f89e1d1c4b64642216a1b90be6a96d Mon Sep 17 00:00:00 2001 From: AeonLucid Date: Sun, 20 Sep 2020 20:24:13 +0200 Subject: [PATCH] Fix bug where other players weren't visible --- src/AmongUs.Server/Net/Game.cs | 2 +- .../AmongUs.Tools.Proxy.csproj | 16 ++ src/AmongUs.Tools.Proxy/HexUtils.cs | 70 +++++++ src/AmongUs.Tools.Proxy/Program.cs | 183 ++++++++++++++++++ src/AmongUsServer.sln | 13 ++ submodules/Hazel-Networking | 2 +- 6 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 src/AmongUs.Tools.Proxy/AmongUs.Tools.Proxy.csproj create mode 100644 src/AmongUs.Tools.Proxy/HexUtils.cs create mode 100644 src/AmongUs.Tools.Proxy/Program.cs diff --git a/src/AmongUs.Server/Net/Game.cs b/src/AmongUs.Server/Net/Game.cs index 6fb35ef..23318e7 100644 --- a/src/AmongUs.Server/Net/Game.cs +++ b/src/AmongUs.Server/Net/Game.cs @@ -108,7 +108,7 @@ namespace AmongUs.Server.Net message.Write(_hostId); message.WritePacked(_players.Count - 1); - foreach (var (_, p) in _players.Where(x => x.Value == player)) + foreach (var (_, p) in _players.Where(x => x.Value != player)) { message.WritePacked(p.Client.Id); } diff --git a/src/AmongUs.Tools.Proxy/AmongUs.Tools.Proxy.csproj b/src/AmongUs.Tools.Proxy/AmongUs.Tools.Proxy.csproj new file mode 100644 index 0000000..1a89dbd --- /dev/null +++ b/src/AmongUs.Tools.Proxy/AmongUs.Tools.Proxy.csproj @@ -0,0 +1,16 @@ + + + + Exe + net452 + + + + + + + + + + + diff --git a/src/AmongUs.Tools.Proxy/HexUtils.cs b/src/AmongUs.Tools.Proxy/HexUtils.cs new file mode 100644 index 0000000..c2a3398 --- /dev/null +++ b/src/AmongUs.Tools.Proxy/HexUtils.cs @@ -0,0 +1,70 @@ +using System; +using System.Text; + +namespace AmongUs.Tools.Proxy +{ + public static class HexUtils + { + public static string HexDump(byte[] bytes, int bytesPerLine = 16) + { + if (bytes == null) return ""; + 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/src/AmongUs.Tools.Proxy/Program.cs b/src/AmongUs.Tools.Proxy/Program.cs new file mode 100644 index 0000000..6136f50 --- /dev/null +++ b/src/AmongUs.Tools.Proxy/Program.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Hazel; +using Hazel.Udp; +using PcapDotNet.Core; +using PcapDotNet.Packets; + +namespace AmongUs.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 void Main(string[] args) + { + 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()) + { + var reader = MessageReader.Get(stream.ToArray()); + if (reader.Buffer[0] == (byte) SendOption.Reliable) + { + reader.Offset = 3; + reader.Length = udp.Payload.Length - 3; + reader.Position = 0; + } + else if (reader.Buffer[0] == (byte) UdpSendOption.Acknowledgement || + reader.Buffer[0] == (byte) UdpSendOption.Ping || + reader.Buffer[0] == (byte) UdpSendOption.Hello || + reader.Buffer[0] == (byte) UdpSendOption.Disconnect) + { + return; + } + else + { + reader.Offset = 1; + reader.Length = udp.Payload.Length - 1; + reader.Position = 0; + } + + var isSent = ipSrc.StartsWith("192."); + + while (true) + { + if (reader.Position >= reader.Length) + { + break; + } + + 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, MessageReader 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.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, MessageReader 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.Take(packet.Length).ToArray())); + packet.Position = packet.Length; + break; + } + } + } +} diff --git a/src/AmongUsServer.sln b/src/AmongUsServer.sln index 415e728..391da3d 100644 --- a/src/AmongUsServer.sln +++ b/src/AmongUsServer.sln @@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hazel", "..\submodules\Haze EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AmongUs.Tests", "AmongUs.Tests\AmongUs.Tests.csproj", "{C1385C67-A7DD-46D2-80F6-FA428B85FB22}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{56DD9707-D811-4056-9E2C-8A9CC2479B07}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AmongUs.Tools.Proxy", "AmongUs.Tools.Proxy\AmongUs.Tools.Proxy.csproj", "{D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,6 +75,14 @@ Global {C1385C67-A7DD-46D2-80F6-FA428B85FB22}.Release|Any CPU.Build.0 = Release|Any CPU {C1385C67-A7DD-46D2-80F6-FA428B85FB22}.Release|x86.ActiveCfg = Release|Any CPU {C1385C67-A7DD-46D2-80F6-FA428B85FB22}.Release|x86.Build.0 = Release|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Debug|x86.ActiveCfg = Debug|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Debug|x86.Build.0 = Debug|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Release|Any CPU.Build.0 = Release|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Release|x86.ActiveCfg = Release|Any CPU + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -80,5 +92,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {02CFBD30-D77D-400F-94B2-700F60EFDD7F} = {DFA3CC6A-A27C-4713-876D-A55912C78C45} + {D16B8DE9-8EE2-4F6A-9352-305D5AB0233D} = {56DD9707-D811-4056-9E2C-8A9CC2479B07} EndGlobalSection EndGlobal diff --git a/submodules/Hazel-Networking b/submodules/Hazel-Networking index a12a40e..314637e 160000 --- a/submodules/Hazel-Networking +++ b/submodules/Hazel-Networking @@ -1 +1 @@ -Subproject commit a12a40e915db2df2afeaf6e1ad6e94f8f2bbc832 +Subproject commit 314637e6aa07ea77c3668ac7334930dbc5716c29 -- 2.39.5