From: miniduikboot Date: Fri, 14 Aug 2026 17:47:39 +0000 (+0200) Subject: Deserialize gamecode as packed in PackedGameDataTo (#738) X-Git-Tag: v1.10.7 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=202b955db16b30042b9faaf1e475721f46333120;p=rhonda%2Fimpostor.git Deserialize gamecode as packed in PackedGameDataTo (#738) * Deserialize gamecode as packed in PackedGameDataTo Most packets use a normal 32 bit int but not PackedGameDataTo. Instead, Innersloth decided to waste a byte by using WritePacked. As v2 game codes are always negative, this is less efficient, but alas. It was documented in the pseudocode and I didn't spot the difference when reviewing the implementation, so I made this mistake when deduplicating this code. Test plan: - Start EHR on at least 2 clients - Use the game mode "Natural Disasters" - Observe that pixelated blobs are visible for all players, not just the host * uopt: stop parsing code to string * Address review comments --- diff --git a/src/Impostor.Server/Net/Client.cs b/src/Impostor.Server/Net/Client.cs index 65d8e49..97bb7c2 100644 --- a/src/Impostor.Server/Net/Client.cs +++ b/src/Impostor.Server/Net/Client.cs @@ -268,10 +268,30 @@ namespace Impostor.Server.Net case MessageFlags.PackedGameDataTo: { + if (Player == null) + { + return; + } + + var game = Player.Game; + + // Innersloth Special: this message uses PackedInt32 instead of a normal int32 + var code = reader.ReadPackedInt32(); + + if (code != game.Code.Value) + { + _logger.LogWarning("gcm2 {0} {1}", code, game.Code.Value); + return; + } + // We're limiting this to hosts right now. If you have a use case for this for // players to use this feature, we're open to changing this. - if (!IsPacketAllowed(reader, true, flag)) + if (game.HostId != Id) { + await ReportCheatAsync( + new CheatContext(MessageFlags.FlagToString(flag)), + CheatCategory.MustBeHost, + "Client sent a PackedGameDataTo message"); return; } @@ -293,7 +313,7 @@ namespace Impostor.Server.Net return; } - if (packed.ReadInt32() != Player!.Game.Code) + if (packed.ReadInt32() != game.Code.Value) { _logger.LogWarning("PackedGameDataTo contained GameDataTo for the wrong game."); return; @@ -446,7 +466,8 @@ namespace Impostor.Server.Net var game = Player.Game; // GameCode must match code of the current game assigned to the player. - if (message.ReadInt32() != game.Code) + var code = message.ReadInt32(); + if (code != game.Code.Value) { return false; }