diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs index 9b5b6240d..8cad547ff 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs @@ -82,7 +82,7 @@ public static void OnRestartingRound() /// public static void OnChangingRole(ChangingRoleEventArgs ev) { - if (!ev.Player.IsHost && ev.NewRole == RoleTypeId.Spectator && ev.Reason is not(SpawnReason.Destroyed or SpawnReason.Died) && Events.Instance.Config.ShouldDropInventory) + if (!ev.Player.IsHost && ev.NewRole == RoleTypeId.Spectator && ev.Reason is not SpawnReason.Destroyed && Events.Instance.Config.ShouldDropInventory) ev.Player.Inventory.ServerDropEverything(); } diff --git a/EXILED/Exiled.Events/Patches/Fixes/Fix1344Dupe.cs b/EXILED/Exiled.Events/Patches/Fixes/Fix1344Dupe.cs new file mode 100644 index 000000000..1bd3f62bf --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Fixes/Fix1344Dupe.cs @@ -0,0 +1,63 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Fixes +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Pools; + using HarmonyLib; + using InventorySystem; + using InventorySystem.Items; + using InventorySystem.Items.Usables.Scp1344; + + using static HarmonyLib.AccessTools; + + /// + /// Patches the method. + /// Fixes the dupe where 2 copies of SCP-1344 can be created when a player dies. + /// Bug not reported to NW yet (rare in vanilla servers). + /// + [HarmonyPatch(typeof(Scp1344Item), nameof(Scp1344Item.OnPlayerInventoryDropped))] + public class Fix1344Dupe + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + Label returnLabel = generator.DefineLabel(); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + int offset = 1; + int index = newInstructions.FindIndex(x => x.opcode == OpCodes.Ret) + offset; + + newInstructions.InsertRange(index, new[] + { + // this.OwnerInventory.UserInventory.Items + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(Scp1344Item), nameof(Scp1344Item.OwnerInventory))), + new(OpCodes.Ldfld, Field(typeof(Inventory), nameof(Inventory.UserInventory))), + new(OpCodes.Ldfld, Field(typeof(InventoryInfo), nameof(InventoryInfo.Items))), + + // this.ItemSerial + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(Scp1344Item), nameof(Scp1344Item.ItemSerial))), + + // if (!this.OwnerInventory.UserInventory.Items.ContainsKey(this.ItemSerial) return; + new(OpCodes.Callvirt, Method(typeof(Dictionary), nameof(Dictionary.ContainsKey))), + new(OpCodes.Brfalse_S, returnLabel), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file