Skip to content

Commit

Permalink
fix(feat theoretically): Many bugfixes (#338)
Browse files Browse the repository at this point in the history
* fix: item related stuff

* ah

* test

* fix: roundend IsAllowed

* Фикс DryFire ивента

* revert

* little fix
  • Loading branch information
IRacle1 authored Dec 26, 2024
1 parent b1920da commit a963c87
Show file tree
Hide file tree
Showing 16 changed files with 109 additions and 60 deletions.
6 changes: 2 additions & 4 deletions EXILED/Exiled.API/Features/Items/Armor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ public IEnumerable<BodyArmor.ArmorCategoryLimitModifier> CategoryLimits
{
Weight = Weight,
StaminaUseMultiplier = StaminaUseMultiplier,
RemoveExcessOnDrop = RemoveExcessOnDrop,
CategoryLimits = CategoryLimits,
StaminaRegenMultiplier = StaminaRegenMultiplier,
AmmoLimits = AmmoLimits,
Expand All @@ -159,14 +158,13 @@ public IEnumerable<BodyArmor.ArmorCategoryLimitModifier> CategoryLimits
};

/// <inheritdoc/>
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;
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ public ExplosionGrenadeProjectile SpawnActive(Vector3 position, Player owner = n
};

/// <inheritdoc/>
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;
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/Firearm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -699,9 +699,9 @@ internal override void ChangeOwner(Player oldOwner, Player newOwner)
}

/// <inheritdoc/>
internal override void ReadPickupInfo(Pickup pickup)
internal override void ReadPickupInfoBefore(Pickup pickup)
{
base.ReadPickupInfo(pickup);
base.ReadPickupInfoBefore(pickup);

if (pickup is FirearmPickup firearmPickup)
{
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/FlashGrenade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ public FlashbangProjectile SpawnActive(Vector3 position, Player owner = null)
public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{FuseTime}|";

/// <inheritdoc/>
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;
Expand Down
20 changes: 19 additions & 1 deletion EXILED/Exiled.API/Features/Items/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,30 @@ internal virtual void ChangeOwner(Player oldOwner, Player newOwner)
/// Helper method for saving data between items and pickups.
/// </summary>
/// <param name="pickup"><see cref="Pickup"/>-related data to give to the <see cref="Item"/>.</param>
internal virtual void ReadPickupInfo(Pickup pickup)
/// <remarks>
/// Analog to <see cref="ReadPickupInfoAfter(Pickup)"/>, but it is called before item initialization.
/// <see cref="ItemBase.OnAdded(ItemPickupBase)"/>.
/// </remarks>
/// <see cref="ReadPickupInfoAfter"/>
internal virtual void ReadPickupInfoBefore(Pickup pickup)
{
if (pickup is not null)
{
Scale = pickup.Scale;
}
}

/// <summary>
/// Helper method for saving data between items and pickups.
/// </summary>
/// <param name="pickup"><see cref="Pickup"/>-related data to give to the <see cref="Item"/>.</param>
/// <remarks>
/// Analog to <see cref="ReadPickupInfoAfter(Pickup)"/>, but it is called after item initialization.
/// <see cref="ItemBase.OnAdded(ItemPickupBase)"/>.
/// </remarks>
/// <see cref="ReadPickupInfoBefore"/>
internal virtual void ReadPickupInfoAfter(Pickup pickup)
{
}
}
}
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/Jailbird.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ public void Break()
public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}*";

/// <inheritdoc/>
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;
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/Keycard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public KeycardPermissions Permissions
public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{Permissions}|";

/// <inheritdoc/>
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;
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/Scp244.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ public override Pickup CreatePickup(Vector3 position, Quaternion? rotation = nul
public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* -{Primed}-";

/// <inheritdoc/>
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;
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/Usable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ public virtual void Use()
}

/// <inheritdoc/>
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;
Expand Down
3 changes: 1 addition & 2 deletions EXILED/Exiled.API/Features/Pickups/BodyArmorPickup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ internal BodyArmorPickup(ItemType type)
/// <summary>
/// Gets or sets a value indicating whether excess ammo should be removed when the armor is dropped.
/// </summary>
[Obsolete("Propetry is internal, and controls armor remove logic for clearing inventory")]
public bool RemoveExcessOnDrop { get; set; }

/// <summary>
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,12 @@ public override void Spawn()
/// <inheritdoc/>
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);
}

Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.Events/Handlers/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ItemType, ushort> item in value.Ammo)
inventory.ServerAddAmmo(item.Key, item.Value);
foreach (KeyValuePair<ItemType, ushort> 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);
Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
Label ret = newInstructions[newInstructions.Count - 1 + offset].labels[0];

offset = -2;
int index = newInstructions.FindIndex(x => 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));

Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Ldfld, Field(typeof(RoundSummary), nameof(RoundSummary._roundEnded))),

// baseGameConditionsSatisfied
new(OpCodes.Ldloc_S, 5),
new(OpCodes.Ldloc_S, 6),

// EndingRoundEventArgs evEndingRound = new(RoundSummary.SumInfo_ClassList, bool, bool);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(EndingRoundEventArgs))[0]),
Expand All @@ -131,7 +131,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
// flag = ev.IsAllowed
new(OpCodes.Ldloc_S, evEndingRound.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(EndingRoundEventArgs), nameof(EndingRoundEventArgs.IsAllowed))),
new(OpCodes.Stloc_S, 5),
new(OpCodes.Stloc_S, 6),

// this.LeadingTeam = ev.LeadingTeam
new(OpCodes.Ldarg_0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ namespace Exiled.Events.Patches.Fixes
using System.Reflection.Emit;

using API.Features.Pools;
using Exiled.API.Features;

using Exiled.API.Features.Items;
using Exiled.API.Features.Pickups;

using HarmonyLib;
using InventorySystem;
using InventorySystem.Items;
using InventorySystem.Items.Firearms.Ammo;
using InventorySystem.Items.Pickups;

using Mirror;

using static HarmonyLib.AccessTools;

/// <summary>
Expand All @@ -30,36 +36,64 @@ internal class FixOnAddedBeingCallAfterOnRemoved
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);
/*
// Modify this
itemBase2.OnAdded(pickup);
Action<ReferenceHub, ItemBase, ItemPickupBase> onItemAdded = InventoryExtensions.OnItemAdded;
if (onItemAdded != null)
{
onItemAdded(inv._hub, itemBase2, pickup);
}
// To this
Action<ReferenceHub, ItemBase, ItemPickupBase> 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<ReferenceHub, ItemBase, ItemPickupBase>), nameof(Action<ReferenceHub, ItemBase, ItemPickupBase>.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<CodeInstruction>.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);
}
}
}

0 comments on commit a963c87

Please sign in to comment.