]> git.deb.at Git - rhonda/impostor.git/commitdiff
Fix MurderPlayer for vanilla clients
authorminiduikboot <mini@duikbo.at>
Thu, 26 Oct 2023 21:14:09 +0000 (23:14 +0200)
committerminiduikboot <mini@duikbo.at>
Thu, 26 Oct 2023 21:14:09 +0000 (23:14 +0200)
In 2023.10.24, vanilla started expecting that CheckMurder is handled on
the server. That is, unless the host is modded, then CheckMurder calls
are handled by the host as before

src/Impostor.Api/Innersloth/MurderResultFlags.cs [new file with mode: 0644]
src/Impostor.Api/Net/Messages/Rpcs/Rpc12MurderPlayer.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs
src/Impostor.Server/Net/State/Game.cs

diff --git a/src/Impostor.Api/Innersloth/MurderResultFlags.cs b/src/Impostor.Api/Innersloth/MurderResultFlags.cs
new file mode 100644 (file)
index 0000000..1618275
--- /dev/null
@@ -0,0 +1,13 @@
+using System;
+
+namespace Impostor.Api.Innersloth
+{
+    [Flags]
+    public enum MurderResultFlags
+    {
+        Succeeded = 1,
+        FailedError = 2,
+        FailedProtected = 4,
+        DecisionByHost = 8,
+    }
+}
index 82f55f6c76015e83cd7552012ef32b09470fcfd9..65d671cadf98442ef5a803d626bf86875442adbd 100644 (file)
@@ -1,18 +1,21 @@
 using Impostor.Api.Games;
 using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api.Net.Messages.Rpcs
 {
     public static class Rpc12MurderPlayer
     {
-        public static void Serialize(IMessageWriter writer, IInnerPlayerControl target)
+        public static void Serialize(IMessageWriter writer, IInnerPlayerControl target, MurderResultFlags result)
         {
             writer.Write(target);
+            writer.Write((int)result);
         }
 
-        public static void Deserialize(IMessageReader reader, IGame game, out IInnerPlayerControl? target)
+        public static void Deserialize(IMessageReader reader, IGame game, out IInnerPlayerControl? target, out MurderResultFlags result)
         {
             target = reader.ReadNetObject<IInnerPlayerControl>(game);
+            result = (MurderResultFlags)reader.ReadInt32();
         }
     }
 }
index cb073ff2cd6f2e234a88264608d88b297ffc5d43..58a5435798fec788603cce1f2e337a3c851e4338 100644 (file)
@@ -102,7 +102,7 @@ namespace Impostor.Server.Net.Inner.Objects
             ((InnerPlayerControl)target).Die(DeathReason.Kill);
 
             using var writer = Game.StartRpc(NetId, RpcCalls.MurderPlayer);
-            Rpc12MurderPlayer.Serialize(writer, target);
+            Rpc12MurderPlayer.Serialize(writer, target, MurderResultFlags.Succeeded);
             await Game.FinishRpcAsync(writer);
 
             await _eventManager.CallAsync(new PlayerMurderEvent(Game, Game.GetClientPlayer(OwnerId)!, this, target));
index ed05367ab430dfe7846489a24ad666f288aa4392..2eb8b0d92f1d1dfe490778e032d6934ff1dfdde1 100644 (file)
@@ -25,12 +25,14 @@ namespace Impostor.Server.Net.Inner.Objects
     {
         private static readonly byte ColorsCount = (byte)Enum.GetValues<ColorType>().Length;
 
+        private readonly Game _game;
         private readonly ILogger<InnerPlayerControl> _logger;
         private readonly IEventManager _eventManager;
         private readonly IDateTimeProvider _dateTimeProvider;
 
         public InnerPlayerControl(ICustomMessageManager<ICustomRpc> customMessageManager, Game game, ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, IDateTimeProvider dateTimeProvider) : base(customMessageManager, game)
         {
+            _game = game;
             _logger = logger;
             _eventManager = eventManager;
             _dateTimeProvider = dateTimeProvider;
@@ -250,8 +252,8 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc12MurderPlayer.Deserialize(reader, Game, out var murdered);
-                    return await HandleMurderPlayer(sender, murdered);
+                    Rpc12MurderPlayer.Deserialize(reader, Game, out var murdered, out var result);
+                    return await HandleMurderPlayer(sender, murdered, result);
                 }
 
                 case RpcCalls.SendChat:
@@ -652,8 +654,6 @@ namespace Impostor.Server.Net.Inner.Objects
                 }
             }
 
-            PlayerInfo.LastMurder = _dateTimeProvider.UtcNow - TimeSpan.FromMilliseconds(sender.Client.Connection.AveragePing);
-
             if (target == null || target.PlayerInfo.IsImpostor)
             {
                 if (await sender.Client.ReportCheatAsync(RpcCalls.CheckMurder, "Client tried to murder invalid target"))
@@ -662,12 +662,26 @@ namespace Impostor.Server.Net.Inner.Objects
                 }
             }
 
+            PlayerInfo.LastMurder = _dateTimeProvider.UtcNow - TimeSpan.FromMilliseconds(sender.Client.Connection.AveragePing);
             IsMurdering = target;
 
-            return true;
+            // Check if host authority mode is on
+            if (_game.IsHostModded()) {
+                // Pass the RPC on unharmed, the client will handle it
+                return true;
+            }
+
+            // TODO check if protected by GA
+
+            if (target != null)
+            {
+                MurderPlayerAsync(target);
+            }
+
+            return false;
         }
 
-        private async ValueTask<bool> HandleMurderPlayer(ClientPlayer sender, IInnerPlayerControl? target)
+        private async ValueTask<bool> HandleMurderPlayer(ClientPlayer sender, IInnerPlayerControl? target, MurderResultFlags result)
         {
             if (target == null || target.PlayerInfo.IsImpostor)
             {
index a0cf261ef525b5dea716d46e9dc570ef02a45b5e..46ad67cf7131cbb36f368e17db1f089d0bbb6bac 100644 (file)
@@ -145,5 +145,14 @@ namespace Impostor.Server.Net.State
                 .Select(p => p.Client.Connection)
                 .Where(c => c != null && c.IsConnected)!;
         }
+
+        internal bool IsHostModded()
+        {
+            if (Host == null) {
+                return false;
+            } else {
+                return Host.Client.GameVersion.Revision >= 25;
+            }
+        }
     }
 }