From a963c878131eeec176d686389927b8bad92694db Mon Sep 17 00:00:00 2001 From: IRacle <79921583+IRacle1@users.noreply.github.com> Date: Thu, 26 Dec 2024 21:25:57 +0300 Subject: [PATCH] fix(feat theoretically): Many bugfixes (#338) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: item related stuff * ah * test * fix: roundend IsAllowed * Фикс DryFire ивента * revert * little fix --- EXILED/Exiled.API/Features/Items/Armor.cs | 6 +- .../Features/Items/ExplosiveGrenade.cs | 4 +- EXILED/Exiled.API/Features/Items/Firearm.cs | 4 +- .../Exiled.API/Features/Items/FlashGrenade.cs | 4 +- EXILED/Exiled.API/Features/Items/Item.cs | 20 ++++- EXILED/Exiled.API/Features/Items/Jailbird.cs | 4 +- EXILED/Exiled.API/Features/Items/Keycard.cs | 4 +- EXILED/Exiled.API/Features/Items/Scp244.cs | 4 +- EXILED/Exiled.API/Features/Items/Usable.cs | 4 +- .../Features/Pickups/BodyArmorPickup.cs | 3 +- .../Features/Pickups/FirearmPickup.cs | 9 +- EXILED/Exiled.Events/Handlers/Player.cs | 2 +- .../Events/Player/ChangingRoleAndSpawned.cs | 13 ++- .../Patches/Events/Player/DryFire.cs | 2 +- .../Patches/Events/Server/RoundEnd.cs | 4 +- .../FixOnAddedBeingCallAfterOnRemoved.cs | 82 +++++++++++++------ 16 files changed, 109 insertions(+), 60 deletions(-) diff --git a/EXILED/Exiled.API/Features/Items/Armor.cs b/EXILED/Exiled.API/Features/Items/Armor.cs index 6fe2bc097..238de555e 100644 --- a/EXILED/Exiled.API/Features/Items/Armor.cs +++ b/EXILED/Exiled.API/Features/Items/Armor.cs @@ -150,7 +150,6 @@ public IEnumerable CategoryLimits { Weight = Weight, StaminaUseMultiplier = StaminaUseMultiplier, - RemoveExcessOnDrop = RemoveExcessOnDrop, CategoryLimits = CategoryLimits, StaminaRegenMultiplier = StaminaRegenMultiplier, AmmoLimits = AmmoLimits, @@ -159,14 +158,13 @@ public IEnumerable CategoryLimits }; /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is Pickups.BodyArmorPickup armorPickup) { HelmetEfficacy = armorPickup.HelmetEfficacy; VestEfficacy = armorPickup.VestEfficacy; - RemoveExcessOnDrop = armorPickup.RemoveExcessOnDrop; StaminaUseMultiplier = armorPickup.StaminaUseMultiplier; StaminaRegenMultiplier = armorPickup.StaminaRegenMultiplier; AmmoLimits = armorPickup.AmmoLimits; diff --git a/EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs b/EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs index 1ee536c43..b550c1345 100644 --- a/EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs +++ b/EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs @@ -162,9 +162,9 @@ public ExplosionGrenadeProjectile SpawnActive(Vector3 position, Player owner = n }; /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is ExplosiveGrenadePickup explosiveGrenadePickup) { MaxRadius = explosiveGrenadePickup.MaxRadius; diff --git a/EXILED/Exiled.API/Features/Items/Firearm.cs b/EXILED/Exiled.API/Features/Items/Firearm.cs index 98cd780c2..e77622d67 100644 --- a/EXILED/Exiled.API/Features/Items/Firearm.cs +++ b/EXILED/Exiled.API/Features/Items/Firearm.cs @@ -699,9 +699,9 @@ internal override void ChangeOwner(Player oldOwner, Player newOwner) } /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is FirearmPickup firearmPickup) { diff --git a/EXILED/Exiled.API/Features/Items/FlashGrenade.cs b/EXILED/Exiled.API/Features/Items/FlashGrenade.cs index ccebfa394..867d11b3a 100644 --- a/EXILED/Exiled.API/Features/Items/FlashGrenade.cs +++ b/EXILED/Exiled.API/Features/Items/FlashGrenade.cs @@ -139,9 +139,9 @@ public FlashbangProjectile SpawnActive(Vector3 position, Player owner = null) public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{FuseTime}|"; /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is FlashGrenadePickup flashGrenadePickup) { MinimalDurationEffect = flashGrenadePickup.MinimalDurationEffect; diff --git a/EXILED/Exiled.API/Features/Items/Item.cs b/EXILED/Exiled.API/Features/Items/Item.cs index e5207c99f..c55a6e75b 100644 --- a/EXILED/Exiled.API/Features/Items/Item.cs +++ b/EXILED/Exiled.API/Features/Items/Item.cs @@ -429,12 +429,30 @@ internal virtual void ChangeOwner(Player oldOwner, Player newOwner) /// Helper method for saving data between items and pickups. /// /// -related data to give to the . - internal virtual void ReadPickupInfo(Pickup pickup) + /// + /// Analog to , but it is called before item initialization. + /// . + /// + /// + internal virtual void ReadPickupInfoBefore(Pickup pickup) { if (pickup is not null) { Scale = pickup.Scale; } } + + /// + /// Helper method for saving data between items and pickups. + /// + /// -related data to give to the . + /// + /// Analog to , but it is called after item initialization. + /// . + /// + /// + internal virtual void ReadPickupInfoAfter(Pickup pickup) + { + } } } diff --git a/EXILED/Exiled.API/Features/Items/Jailbird.cs b/EXILED/Exiled.API/Features/Items/Jailbird.cs index b7a48eae6..6d7ac7d32 100644 --- a/EXILED/Exiled.API/Features/Items/Jailbird.cs +++ b/EXILED/Exiled.API/Features/Items/Jailbird.cs @@ -185,9 +185,9 @@ public void Break() public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}*"; /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is JailbirdPickup jailbirdPickup) { MeleeDamage = jailbirdPickup.MeleeDamage; diff --git a/EXILED/Exiled.API/Features/Items/Keycard.cs b/EXILED/Exiled.API/Features/Items/Keycard.cs index 6bd7ca93a..0bd390018 100644 --- a/EXILED/Exiled.API/Features/Items/Keycard.cs +++ b/EXILED/Exiled.API/Features/Items/Keycard.cs @@ -69,9 +69,9 @@ public KeycardPermissions Permissions public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{Permissions}|"; /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is KeycardPickup keycardPickup) { Permissions = keycardPickup.Permissions; diff --git a/EXILED/Exiled.API/Features/Items/Scp244.cs b/EXILED/Exiled.API/Features/Items/Scp244.cs index 0cfea6c3a..9f9c73530 100644 --- a/EXILED/Exiled.API/Features/Items/Scp244.cs +++ b/EXILED/Exiled.API/Features/Items/Scp244.cs @@ -119,9 +119,9 @@ public override Pickup CreatePickup(Vector3 position, Quaternion? rotation = nul public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* -{Primed}-"; /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is Scp244Pickup scp244) { Health = scp244.Health; diff --git a/EXILED/Exiled.API/Features/Items/Usable.cs b/EXILED/Exiled.API/Features/Items/Usable.cs index 6ba68e2cb..65c858b74 100644 --- a/EXILED/Exiled.API/Features/Items/Usable.cs +++ b/EXILED/Exiled.API/Features/Items/Usable.cs @@ -136,9 +136,9 @@ public virtual void Use() } /// - internal override void ReadPickupInfo(Pickup pickup) + internal override void ReadPickupInfoBefore(Pickup pickup) { - base.ReadPickupInfo(pickup); + base.ReadPickupInfoBefore(pickup); if (pickup is UsablePickup usablePickup) { UseTime = usablePickup.UseTime; diff --git a/EXILED/Exiled.API/Features/Pickups/BodyArmorPickup.cs b/EXILED/Exiled.API/Features/Pickups/BodyArmorPickup.cs index 47cfb108c..1b6376353 100644 --- a/EXILED/Exiled.API/Features/Pickups/BodyArmorPickup.cs +++ b/EXILED/Exiled.API/Features/Pickups/BodyArmorPickup.cs @@ -73,6 +73,7 @@ internal BodyArmorPickup(ItemType type) /// /// Gets or sets a value indicating whether excess ammo should be removed when the armor is dropped. /// + [Obsolete("Propetry is internal, and controls armor remove logic for clearing inventory")] public bool RemoveExcessOnDrop { get; set; } /// @@ -132,7 +133,6 @@ internal override void ReadItemInfo(Item item) { helmetEfficacy = armoritem.HelmetEfficacy; vestEfficacy = armoritem.VestEfficacy; - RemoveExcessOnDrop = armoritem.RemoveExcessOnDrop; StaminaUseMultiplier = armoritem.StaminaUseMultiplier; StaminaRegenMultiplier = armoritem.StaminaRegenMultiplier; AmmoLimits = armoritem.AmmoLimits; @@ -148,7 +148,6 @@ protected override void InitializeProperties(ItemBase itemBase) { helmetEfficacy = armoritem.HelmetEfficacy; vestEfficacy = armoritem.VestEfficacy; - RemoveExcessOnDrop = !armoritem.DontRemoveExcessOnDrop; StaminaUseMultiplier = armoritem._staminaUseMultiplier; StaminaRegenMultiplier = armoritem.StaminaRegenMultiplier; AmmoLimits = armoritem.AmmoLimits.Select(limit => (ArmorAmmoLimit)limit); diff --git a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs index 3db97dac8..feb8d4c57 100644 --- a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs +++ b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs @@ -138,9 +138,12 @@ public override void Spawn() /// internal override void ReadItemInfo(Items.Item item) { - Items.Firearm firearm = (Items.Firearm)item; - MaxAmmo = firearm.PrimaryMagazine.ConstantMaxAmmo; - AmmoDrain = firearm.AmmoDrain; + if (item is Items.Firearm firearm) + { + MaxAmmo = firearm.PrimaryMagazine.ConstantMaxAmmo; + AmmoDrain = firearm.AmmoDrain; + } + base.ReadItemInfo(item); } diff --git a/EXILED/Exiled.Events/Handlers/Player.cs b/EXILED/Exiled.Events/Handlers/Player.cs index d87675450..59519b21e 100644 --- a/EXILED/Exiled.Events/Handlers/Player.cs +++ b/EXILED/Exiled.Events/Handlers/Player.cs @@ -1024,7 +1024,7 @@ public static void OnItemAdded(ReferenceHub referenceHub, InventorySystem.Items. { ItemAddedEventArgs ev = new(referenceHub, itemBase, pickupBase); - ev.Item.ReadPickupInfo(ev.Pickup); + ev.Item.ReadPickupInfoAfter(ev.Pickup); ev.Player.ItemsValue.Add(ev.Item); diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs index 47f1ede44..d31306a20 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs @@ -220,16 +220,13 @@ private static void ChangeInventory(ChangingRoleEventArgs ev) inventory.SendAmmoNextFrame = true; } - if (!StartingInventories.DefinedInventories.TryGetValue(ev.NewRole, out InventoryRoleInfo value)) - return; - - foreach (KeyValuePair item in value.Ammo) - inventory.ServerAddAmmo(item.Key, item.Value); + foreach (KeyValuePair ammo in ev.Ammo) + inventory.ServerAddAmmo(ammo.Key, ammo.Value); - for (int i = 0; i < value.Items.Length; i++) + foreach (ItemType item in ev.Items) { - ItemBase arg = inventory.ServerAddItem(value.Items[i], ItemAddReason.StartingItem, 0); - InventoryItemProvider.OnItemProvided?.Invoke(ev.Player.ReferenceHub, arg); + ItemBase itemBase = inventory.ServerAddItem(item, ItemAddReason.StartingItem); + InventoryItemProvider.OnItemProvided?.Invoke(ev.Player.ReferenceHub, itemBase); } InventoryItemProvider.InventoriesToReplenish.Enqueue(ev.Player.ReferenceHub); diff --git a/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs b/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs index 0c58fe435..59b209e10 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs @@ -67,7 +67,7 @@ private static IEnumerable Transpiler(IEnumerable x.Calls(PropertyGetter(typeof(AutomaticActionModule), nameof(AutomaticActionModule.Cocked)))) + offset; + int index = newInstructions.FindLastIndex(x => x.Calls(PropertyGetter(typeof(AutomaticActionModule), nameof(AutomaticActionModule.Cocked)))) + offset; newInstructions.InsertRange(index, GetInstructions(newInstructions[index], ret)); diff --git a/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs b/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs index 41f13b628..afe065a74 100644 --- a/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs @@ -112,7 +112,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable @@ -30,36 +36,64 @@ internal class FixOnAddedBeingCallAfterOnRemoved private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { List newInstructions = ListPool.Pool.Get(instructions); - /* - // Modify this - itemBase2.OnAdded(pickup); - Action onItemAdded = InventoryExtensions.OnItemAdded; - if (onItemAdded != null) - { - onItemAdded(inv._hub, itemBase2, pickup); - } - // To this - Action onItemAdded = InventoryExtensions.OnItemAdded; - if (onItemAdded != null) + + Label continueLabel = generator.DefineLabel(); + + int offset = -1; + int index = newInstructions.FindLastIndex(instruction => instruction.Calls(PropertyGetter(typeof(NetworkBehaviour), nameof(NetworkBehaviour.isLocalPlayer)))) + offset; + + // set label for code right after OnAdded/OnItemAdded, to skip that part for ammo + Label afterAmmoLabel = newInstructions[index].labels[0]; + + offset = -2; + index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(ItemBase), nameof(ItemBase.OnAdded)))) + offset; + + newInstructions.InsertRange( + index, + new[] { - onItemAdded(inv._hub, itemBase2, pickup); - } - itemBase2.OnAdded(pickup); - */ - int opCodesToMove = 3; - int offset = -2; - int indexOnAdded = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(ItemBase), nameof(ItemBase.OnAdded)))) + offset; + // CallBefore(itemBase, pickup) + new CodeInstruction(OpCodes.Ldloc_1), + new(OpCodes.Ldarg_S, 4), + new(OpCodes.Call, Method(typeof(FixOnAddedBeingCallAfterOnRemoved), nameof(FixOnAddedBeingCallAfterOnRemoved.CallBefore))), - offset = 1; - int indexInvoke = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(Action), nameof(Action.Invoke)))) + offset; + // if (itemBase is not AmmoItem) + // skip; + new CodeInstruction(OpCodes.Ldloc_1), + new(OpCodes.Isinst, typeof(AmmoItem)), + new(OpCodes.Brfalse_S, continueLabel), - newInstructions.InsertRange(indexInvoke, newInstructions.GetRange(indexOnAdded, opCodesToMove)); - newInstructions[indexInvoke].MoveLabelsFrom(newInstructions[indexInvoke + opCodesToMove]); - newInstructions.RemoveRange(indexOnAdded, opCodesToMove); + // call help method for inverse call + // InverseCall(itemBase, inv._hub, pickup) + new(OpCodes.Ldloc_1), + new(OpCodes.Ldarg_0), + new(OpCodes.Ldfld, Field(typeof(Inventory), nameof(Inventory._hub))), + new(OpCodes.Ldarg_S, 4), + new(OpCodes.Call, Method(typeof(FixOnAddedBeingCallAfterOnRemoved), nameof(FixOnAddedBeingCallAfterOnRemoved.InverseCall))), + + // move after basegame OnAdded/OnItemAdded + new(OpCodes.Br_S, afterAmmoLabel), + + new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel), + }); for (int z = 0; z < newInstructions.Count; z++) yield return newInstructions[z]; + ListPool.Pool.Return(newInstructions); } + + private static void InverseCall(ItemBase item, ReferenceHub referenceHub, ItemPickupBase pickup) + { + Exiled.API.Extensions.ReflectionExtensions.InvokeStaticEvent(typeof(InventoryExtensions), nameof(InventoryExtensions.OnItemAdded), new object[] { referenceHub, item, pickup }); + item.OnAdded(pickup); + } + + private static void CallBefore(ItemBase itemBase, ItemPickupBase pickupBase) + { + Item item = Item.Get(itemBase); + Pickup pickup = Pickup.Get(pickupBase); + item.ReadPickupInfoBefore(pickup); + } } }