]> git.deb.at Git - rhonda/impostor.git/commitdiff
Bugfix/fix outfit RPCs (#653)
authordanbudworthmead <danbudworthmead@gmail.com>
Sat, 5 Oct 2024 10:44:08 +0000 (11:44 +0100)
committerGitHub <noreply@github.com>
Sat, 5 Oct 2024 10:44:08 +0000 (12:44 +0200)
* implemented the sequence ID

* implemented the sequence ID for the player outfits

the sequence ID in the set call must be greater than that stored on the client otherwise the client disregards the set call.

* make sequence IDs internal

* added space after closing brace

* make the sequence ID addition +5

src/Impostor.Api/Innersloth/Customization/PlayerOutfit.cs
src/Impostor.Api/Net/Messages/Rpcs/Rpc39SetHatStr.cs
src/Impostor.Api/Net/Messages/Rpcs/Rpc40SetSkinStr.cs
src/Impostor.Api/Net/Messages/Rpcs/Rpc41SetPetStr.cs
src/Impostor.Api/Net/Messages/Rpcs/Rpc42SetVisorStr.cs
src/Impostor.Api/Net/Messages/Rpcs/Rpc43SetNamePlateStr.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.cs

index dbe698bbfc24da2c506b5581eab3c3c36cf32ba5..82f8cedc9f55ceaaec3ecd6881c554ab5cb3ff45 100644 (file)
@@ -59,15 +59,15 @@ namespace Impostor.Api.Innersloth.Customization
             internal set => SetField(ref _namePlateId, value);
         }
 
-        private byte HatSequenceId { get; set; } = 0;
+        internal byte HatSequenceId { get; set; } = 0;
 
-        private byte PetSequenceId { get; set; } = 0;
+        internal byte PetSequenceId { get; set; } = 0;
 
-        private byte SkinSequenceId { get; set; } = 0;
+        internal byte SkinSequenceId { get; set; } = 0;
 
-        private byte VisorSequenceId { get; set; } = 0;
+        internal byte VisorSequenceId { get; set; } = 0;
 
-        private byte NamePlateSequenceId { get; set; } = 0;
+        internal byte NamePlateSequenceId { get; set; } = 0;
 
         /// <summary>
         /// Gets a value indicating whether a player outfit is complete or whether it needs to receive additional cosmetics.
index 1b5300ab283eeab2d8f71f56c67d299c3cf6b72b..35f1ffd6c8fac9c1d3fe7ae2cd66bc87be8c9b63 100644 (file)
@@ -2,14 +2,16 @@ namespace Impostor.Api.Net.Messages.Rpcs
 {
     public static class Rpc39SetHatStr
     {
-        public static void Serialize(IMessageWriter writer, string hat)
+        public static void Serialize(IMessageWriter writer, string hat, byte nextRpcSequenceId)
         {
             writer.Write(hat);
+            writer.Write(nextRpcSequenceId);
         }
 
-        public static void Deserialize(IMessageReader reader, out string hat)
+        public static void Deserialize(IMessageReader reader, out string hat, out byte nextRpcSequenceId)
         {
             hat = reader.ReadString();
+            nextRpcSequenceId = reader.ReadByte();
         }
     }
 }
index 796be7a13543f938283fbffa00995edc392f2ff3..f09c580a4937691854197a309fe3935fbfc7ccb3 100644 (file)
@@ -2,14 +2,16 @@ namespace Impostor.Api.Net.Messages.Rpcs
 {
     public static class Rpc40SetSkinStr
     {
-        public static void Serialize(IMessageWriter writer, string skin)
+        public static void Serialize(IMessageWriter writer, string skin, byte nextRpcSequenceId)
         {
             writer.Write(skin);
+            writer.Write(nextRpcSequenceId);
         }
 
-        public static void Deserialize(IMessageReader reader, out string skin)
+        public static void Deserialize(IMessageReader reader, out string skin, out byte nextRpcSequenceId)
         {
             skin = reader.ReadString();
+            nextRpcSequenceId = reader.ReadByte();
         }
     }
 }
index 03dfd3e1a6b86f6feae32ce003e758e5a8675845..d511b8dac6ef67a213780f0352a1798bd3c82f33 100644 (file)
@@ -2,14 +2,16 @@ namespace Impostor.Api.Net.Messages.Rpcs
 {
     public static class Rpc41SetPetStr
     {
-        public static void Serialize(IMessageWriter writer, string pet)
+        public static void Serialize(IMessageWriter writer, string pet, byte nextRpcSequenceId)
         {
             writer.Write(pet);
+            writer.Write(nextRpcSequenceId);
         }
 
-        public static void Deserialize(IMessageReader reader, out string pet)
+        public static void Deserialize(IMessageReader reader, out string pet, out byte nextRpcSequenceId)
         {
             pet = reader.ReadString();
+            nextRpcSequenceId = reader.ReadByte();
         }
     }
 }
index bffcd33e23ff201ddfc3d893486ce017b3e57c47..cd74db0e435735ac47c0c4d666c0037d232221de 100644 (file)
@@ -2,14 +2,16 @@ namespace Impostor.Api.Net.Messages.Rpcs
 {
     public static class Rpc42SetVisorStr
     {
-        public static void Serialize(IMessageWriter writer, string visor)
+        public static void Serialize(IMessageWriter writer, string visor, byte nextRpcSequenceId)
         {
             writer.Write(visor);
+            writer.Write(nextRpcSequenceId);
         }
 
-        public static void Deserialize(IMessageReader reader, out string visor)
+        public static void Deserialize(IMessageReader reader, out string visor, out byte nextRpcSequenceId)
         {
             visor = reader.ReadString();
+            nextRpcSequenceId = reader.ReadByte();
         }
     }
 }
index e685c9e3f6159255882aeabdc03d8f450ab8ba98..eaf8092e3b04e4f30f06509d04fb192a1de137c2 100644 (file)
@@ -2,14 +2,16 @@ namespace Impostor.Api.Net.Messages.Rpcs
 {
     public static class Rpc43SetNamePlateStr
     {
-        public static void Serialize(IMessageWriter writer, string namePlate)
+        public static void Serialize(IMessageWriter writer, string namePlate, byte nextRpcSequenceId)
         {
             writer.Write(namePlate);
+            writer.Write(nextRpcSequenceId);
         }
 
-        public static void Deserialize(IMessageReader reader, out string namePlate)
+        public static void Deserialize(IMessageReader reader, out string namePlate, out byte nextRpcSequenceId)
         {
             namePlate = reader.ReadString();
+            nextRpcSequenceId = reader.ReadByte();
         }
     }
 }
index 2d8a8f153649703ed7ab7b1d81bac38cad0ffb5d..a4d280c6dfa3ce2038150b92b78977524f6dd23d 100644 (file)
@@ -40,8 +40,8 @@ namespace Impostor.Server.Net.Inner.Objects
         {
             PlayerInfo.CurrentOutfit.HatId = hatId;
 
-            using var writer = Game.StartRpc(NetId, RpcCalls.SetHat);
-            Rpc39SetHatStr.Serialize(writer, hatId);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetHatStr);
+            Rpc39SetHatStr.Serialize(writer, hatId, PlayerInfo.GetNextRpcSequenceId(RpcCalls.SetHatStr));
             await Game.FinishRpcAsync(writer);
         }
 
@@ -49,8 +49,8 @@ namespace Impostor.Server.Net.Inner.Objects
         {
             PlayerInfo.CurrentOutfit.PetId = petId;
 
-            using var writer = Game.StartRpc(NetId, RpcCalls.SetPet);
-            Rpc41SetPetStr.Serialize(writer, petId);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetPetStr);
+            Rpc41SetPetStr.Serialize(writer, petId, PlayerInfo.GetNextRpcSequenceId(RpcCalls.SetPetStr));
             await Game.FinishRpcAsync(writer);
         }
 
@@ -58,8 +58,26 @@ namespace Impostor.Server.Net.Inner.Objects
         {
             PlayerInfo.CurrentOutfit.SkinId = skinId;
 
-            using var writer = Game.StartRpc(NetId, RpcCalls.SetSkin);
-            Rpc40SetSkinStr.Serialize(writer, skinId);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetSkinStr);
+            Rpc40SetSkinStr.Serialize(writer, skinId, PlayerInfo.GetNextRpcSequenceId(RpcCalls.SetSkinStr));
+            await Game.FinishRpcAsync(writer);
+        }
+
+        public async ValueTask SetVisorAsync(string visorId)
+        {
+            PlayerInfo.CurrentOutfit.VisorId = visorId;
+
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetVisorStr);
+            Rpc42SetVisorStr.Serialize(writer, visorId, PlayerInfo.GetNextRpcSequenceId(RpcCalls.SetVisorStr));
+            await Game.FinishRpcAsync(writer);
+        }
+
+        public async ValueTask SetNamePlateAsync(string nameplateId)
+        {
+            PlayerInfo.CurrentOutfit.NamePlateId = nameplateId;
+
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetNamePlateStr);
+            Rpc43SetNamePlateStr.Serialize(writer, nameplateId, PlayerInfo.GetNextRpcSequenceId(RpcCalls.SetNamePlateStr));
             await Game.FinishRpcAsync(writer);
         }
 
index 9aaeef7e0c70a4f1e1054a3b0e46e928983a12a4..6503ed493c6a496fceea0512613ed992978d661b 100644 (file)
@@ -203,8 +203,8 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc39SetHatStr.Deserialize(reader, out var hat);
-                    return await HandleSetHat(sender, hat);
+                    Rpc39SetHatStr.Deserialize(reader, out var hat, out var nextRpcSequenceId);
+                    return await HandleSetHat(sender, hat, nextRpcSequenceId);
                 }
 
                 case RpcCalls.SetSkinStr:
@@ -215,8 +215,8 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc40SetSkinStr.Deserialize(reader, out var skin);
-                    return await HandleSetSkin(sender, skin);
+                    Rpc40SetSkinStr.Deserialize(reader, out var skin, out var nextRpcSequenceId);
+                    return await HandleSetSkin(sender, skin, nextRpcSequenceId);
                 }
 
                 case RpcCalls.SetVisorStr:
@@ -227,8 +227,8 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc42SetVisorStr.Deserialize(reader, out var visor);
-                    return await HandleSetVisor(sender, visor);
+                    Rpc42SetVisorStr.Deserialize(reader, out var visor, out var nextRpcSequenceId);
+                    return await HandleSetVisor(sender, visor, nextRpcSequenceId);
                 }
 
                 case RpcCalls.SetNamePlateStr:
@@ -238,8 +238,8 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc43SetNamePlateStr.Deserialize(reader, out var namePlate);
-                    return await HandleSetNamePlate(sender, namePlate);
+                    Rpc43SetNamePlateStr.Deserialize(reader, out var namePlate, out var nextRpcSequenceId);
+                    return await HandleSetNamePlate(sender, namePlate, nextRpcSequenceId);
                 }
 
                 case RpcCalls.SetLevel:
@@ -335,8 +335,8 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc41SetPetStr.Deserialize(reader, out var pet);
-                    return await HandleSetPet(sender, pet);
+                    Rpc41SetPetStr.Deserialize(reader, out var pet, out var nextRpcSequenceId);
+                    return await HandleSetPet(sender, pet, nextRpcSequenceId);
                 }
 
                 case RpcCalls.SetStartCounter:
@@ -848,54 +848,58 @@ namespace Impostor.Server.Net.Inner.Objects
             return true;
         }
 
-        private async ValueTask<bool> HandleSetHat(ClientPlayer sender, string hat)
+        private async ValueTask<bool> HandleSetHat(ClientPlayer sender, string hat, byte nextRpcSequenceId)
         {
             if (Game.GameState == GameStates.Started &&
-                await sender.Client.ReportCheatAsync(RpcCalls.SetHat, CheatCategory.GameFlow, "Client tried to change hat while not in lobby"))
+                await sender.Client.ReportCheatAsync(RpcCalls.SetHatStr, CheatCategory.GameFlow, "Client tried to change hat while not in lobby"))
             {
                 return false;
             }
 
             PlayerInfo.CurrentOutfit.HatId = hat;
+            PlayerInfo.CurrentOutfit.HatSequenceId = nextRpcSequenceId;
 
             return true;
         }
 
-        private async ValueTask<bool> HandleSetSkin(ClientPlayer sender, string skin)
+        private async ValueTask<bool> HandleSetSkin(ClientPlayer sender, string skin, byte nextRpcSequenceId)
         {
             if (Game.GameState == GameStates.Started &&
-                await sender.Client.ReportCheatAsync(RpcCalls.SetSkin, CheatCategory.GameFlow, "Client tried to change skin while not in lobby"))
+                await sender.Client.ReportCheatAsync(RpcCalls.SetSkinStr, CheatCategory.GameFlow, "Client tried to change skin while not in lobby"))
             {
                 return false;
             }
 
             PlayerInfo.CurrentOutfit.SkinId = skin;
+            PlayerInfo.CurrentOutfit.SkinSequenceId = nextRpcSequenceId;
 
             return true;
         }
 
-        private async ValueTask<bool> HandleSetVisor(ClientPlayer sender, string visor)
+        private async ValueTask<bool> HandleSetVisor(ClientPlayer sender, string visor, byte nextRpcSequenceId)
         {
             if (Game.GameState == GameStates.Started &&
-                await sender.Client.ReportCheatAsync(RpcCalls.SetVisor, CheatCategory.GameFlow, "Client tried to change visor while not in lobby"))
+                await sender.Client.ReportCheatAsync(RpcCalls.SetVisorStr, CheatCategory.GameFlow, "Client tried to change visor while not in lobby"))
             {
                 return false;
             }
 
             PlayerInfo.CurrentOutfit.VisorId = visor;
+            PlayerInfo.CurrentOutfit.VisorSequenceId = nextRpcSequenceId;
 
             return true;
         }
 
-        private async ValueTask<bool> HandleSetNamePlate(ClientPlayer sender, string skin)
+        private async ValueTask<bool> HandleSetNamePlate(ClientPlayer sender, string namePlate, byte nextRpcSequenceId)
         {
             if (Game.GameState == GameStates.Started &&
-                await sender.Client.ReportCheatAsync(RpcCalls.SetNamePlate, CheatCategory.GameFlow, "Client tried to change skin while not in lobby"))
+                await sender.Client.ReportCheatAsync(RpcCalls.SetNamePlateStr, CheatCategory.GameFlow, "Client tried to change skin while not in lobby"))
             {
                 return false;
             }
 
-            PlayerInfo.CurrentOutfit.NamePlateId = skin;
+            PlayerInfo.CurrentOutfit.NamePlateId = namePlate;
+            PlayerInfo.CurrentOutfit.NamePlateSequenceId = nextRpcSequenceId;
 
             return true;
         }
@@ -1057,15 +1061,16 @@ namespace Impostor.Server.Net.Inner.Objects
             await _eventManager.CallAsync(new PlayerStartMeetingEvent(Game, Game.GetClientPlayer(this.OwnerId)!, this, deadPlayer));
         }
 
-        private async ValueTask<bool> HandleSetPet(ClientPlayer sender, string pet)
+        private async ValueTask<bool> HandleSetPet(ClientPlayer sender, string pet, byte nextRpcSequenceId)
         {
             if (Game.GameState == GameStates.Started &&
-                await sender.Client.ReportCheatAsync(RpcCalls.SetPet, CheatCategory.GameFlow, "Client tried to change pet while not in lobby"))
+                await sender.Client.ReportCheatAsync(RpcCalls.SetPetStr, CheatCategory.GameFlow, "Client tried to change pet while not in lobby"))
             {
                 return false;
             }
 
             PlayerInfo.CurrentOutfit.PetId = pet;
+            PlayerInfo.CurrentOutfit.PetSequenceId = nextRpcSequenceId;
 
             return true;
         }
index e449aaef1d33f543a01a9f1280173f65d7ee8f11..8ce707162cd3999c20e1134bb47a23954850696e 100644 (file)
@@ -215,5 +215,46 @@ namespace Impostor.Server.Net.Inner.Objects
                 Tasks.Add(new TaskInfo(this, _eventManager, taskId++, taskType));
             }
         }
+
+        public byte GetNextRpcSequenceId(RpcCalls rpc)
+        {
+            var defaultOutfit = this.Outfits[PlayerOutfitType.Default];
+
+            byte nextRpcSequenceId = 0;
+            const byte SequenceIdAddition = 5;
+
+            // ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
+            switch (rpc)
+            {
+                case RpcCalls.SetHatStr:
+                    defaultOutfit.HatSequenceId += SequenceIdAddition;
+                    nextRpcSequenceId = defaultOutfit.HatSequenceId;
+                    break;
+                case RpcCalls.SetSkinStr:
+                    defaultOutfit.SkinSequenceId += SequenceIdAddition;
+                    nextRpcSequenceId = defaultOutfit.SkinSequenceId;
+                    break;
+                case RpcCalls.SetPetStr:
+                    defaultOutfit.PetSequenceId += SequenceIdAddition;
+                    nextRpcSequenceId = defaultOutfit.PetSequenceId;
+                    break;
+                case RpcCalls.SetVisorStr:
+                    defaultOutfit.VisorSequenceId += SequenceIdAddition;
+                    nextRpcSequenceId = defaultOutfit.VisorSequenceId;
+                    break;
+                case RpcCalls.SetNamePlateStr:
+                    defaultOutfit.NamePlateSequenceId += SequenceIdAddition;
+                    nextRpcSequenceId = defaultOutfit.NamePlateSequenceId;
+                    break;
+                default:
+                    _logger.LogError(
+                        "{NextRpcSequenceIdName} was called for an RPC it doesn\'t know how to handle: {Rpc}",
+                        nameof(GetNextRpcSequenceId),
+                        rpc);
+                    break;
+            }
+
+            return nextRpcSequenceId;
+        }
     }
 }