Skip to content

Commit

Permalink
Fix TogglingWeaponFlashlight & AimingDownSight events
Browse files Browse the repository at this point in the history
  • Loading branch information
xNexusACS committed Dec 6, 2024
1 parent 00a919e commit 47fa0f0
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 13 deletions.
17 changes: 6 additions & 11 deletions Exiled.Events/EventArgs/Player/AimingDownSightEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,20 @@ public class AimingDownSightEventArgs : IPlayerEvent, IFirearmEvent
/// <param name="firearm">
/// <inheritdoc cref="Firearm" />
/// </param>
/// <param name="adsIn">
/// <inheritdoc cref="AdsIn" />
/// <param name="aiming">
/// <inheritdoc cref="Aiming" />
/// </param>
public AimingDownSightEventArgs(Player player, Firearm firearm, bool adsIn)
public AimingDownSightEventArgs(Player player, Firearm firearm, bool aiming)
{
Firearm = firearm;
Player = player;
AdsIn = adsIn;
Aiming = aiming;
}

/// <summary>
/// Gets a value indicating whether or not the player is aiming down sight in.
/// Gets a value indicating whether the player starts aiming or stops aiming.
/// </summary>
public bool AdsIn { get; }

/// <summary>
/// Gets a value indicating whether or not the player is aiming down sight out.
/// </summary>
public bool AdsOut => !AdsIn;
public bool Aiming { get; }

/// <summary>
/// Gets the <see cref="API.Features.Items.Firearm" /> used to trigger the aim action.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public TogglingWeaponFlashlightEventArgs(Player player, Firearm firearm, bool ne
}

/// <summary>
/// Gets a value indicating whether the new weapon's flashlight state will be enabled.
/// Gets or sets a value indicating whether the weapon's flashlight will turn on or off.
/// </summary>
public bool NewState { get; }
public bool NewState { get; set; }

/// <summary>
/// Gets or sets a value indicating whether or not the weapon's flashlight can be toggled.
Expand Down
71 changes: 71 additions & 0 deletions Exiled.Events/Patches/Events/Player/FirearmActionEvents/Aiming.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// -----------------------------------------------------------------------
// <copyright file="Aiming.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Patches.Events.Player.FirearmActionEvents
{
using System.Collections.Generic;
using System.Reflection.Emit;

using Exiled.API.Features.Core.Generic.Pools;
using Exiled.API.Features.Items;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;
using HarmonyLib;
using InventorySystem.Items.Firearms.Modules;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="LinearAdsModule.ServerProcessCmd" />.
/// Adds <see cref="Handlers.Player.AimingDownSight" /> event.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.AimingDownSight))]
[HarmonyPatch(typeof(LinearAdsModule), nameof(LinearAdsModule.ServerProcessCmd))]
internal static class Aiming
{
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> OnAimStatusChanged(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label returnLabel = generator.DefineLabel();

int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ret);

newInstructions.InsertRange(index, new[]
{
// Player.Get(this.Firearm.Owner)
new CodeInstruction(OpCodes.Ldarg_0),
new(OpCodes.Callvirt, PropertyGetter(typeof(LinearAdsModule), nameof(LinearAdsModule.Firearm))),
new(OpCodes.Callvirt, PropertyGetter(typeof(InventorySystem.Items.Firearms.Firearm), nameof(InventorySystem.Items.Firearms.Firearm.Owner))),
new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),

// (Firearm)Item.Get(this.Firearm)
new(OpCodes.Ldarg_0),
new(OpCodes.Callvirt, PropertyGetter(typeof(LinearAdsModule), nameof(LinearAdsModule.Firearm))),
new(OpCodes.Call, Method(typeof(Item), nameof(Item.Get), new[] { typeof(InventorySystem.Items.Firearms.Firearm) })),
new(OpCodes.Castclass, typeof(Firearm)),

// this._userInput
new(OpCodes.Ldfld, Field(typeof(LinearAdsModule), nameof(LinearAdsModule._userInput))),

// AimingDownSightEventArgs args = new(Player, Firearm, bool)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AimingDownSightEventArgs))[0]),

// Player.OnAimingDownSight(args)
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnAimingDownSight))),
});

newInstructions[newInstructions.Count - 1].labels.Add(returnLabel);

foreach (CodeInstruction instruction in newInstructions)
yield return instruction;

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// -----------------------------------------------------------------------
// <copyright file="ToggleWeaponFlashlight.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Patches.Events.Player.FirearmActionEvents
{
using System.Collections.Generic;
using System.Reflection.Emit;

using Exiled.API.Features.Core.Generic.Pools;
using Exiled.API.Features.Items;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;
using HarmonyLib;
using InventorySystem.Items.Firearms.Attachments;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="FlashlightAttachment.ServerSendStatus" />.
/// Adds <see cref="Handlers.Player.TogglingWeaponFlashlight" /> & <see cref="Handlers.Player.ToggledWeaponFlashlight" /> event.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.TogglingWeaponFlashlight))]
[HarmonyPatch(typeof(FlashlightAttachment), nameof(FlashlightAttachment.ServerSendStatus))]
internal static class ToggleWeaponFlashlight
{
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> OnToggleWeaponFlashlight(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label returnLabel = generator.DefineLabel();
LocalBuilder ev = generator.DeclareLocal(typeof(TogglingWeaponFlashlightEventArgs));
LocalBuilder firearm = generator.DeclareLocal(typeof(Firearm));
LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player));
LocalBuilder status = generator.DeclareLocal(typeof(bool));

newInstructions.InsertRange(0, new CodeInstruction[]
{
// Player.Get(this.Firearm.Owner)
new(OpCodes.Ldarg_0),
new(OpCodes.Callvirt, PropertyGetter(typeof(FlashlightAttachment), nameof(FlashlightAttachment.Firearm))),
new(OpCodes.Callvirt, PropertyGetter(typeof(InventorySystem.Items.Firearms.Firearm), nameof(InventorySystem.Items.Firearms.Firearm.Owner))),
new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),
new(OpCodes.Stloc_S, player.LocalIndex),

// (Firearm)Item.Get(this.Firearm)
new(OpCodes.Ldarg_0),
new(OpCodes.Callvirt, PropertyGetter(typeof(FlashlightAttachment), nameof(FlashlightAttachment.Firearm))),
new(OpCodes.Call, Method(typeof(Item), nameof(Item.Get), new[] { typeof(InventorySystem.Items.Firearms.Firearm) })),
new(OpCodes.Castclass, typeof(Firearm)),
new(OpCodes.Stloc_S, firearm.LocalIndex),

// status
new(OpCodes.Ldarg_1),

// true
new(OpCodes.Ldc_I4_1),

// TogglingWeaponFlashlightEventArgs args = new(Player, Firearm, bool, bool)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(TogglingWeaponFlashlightEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, ev.LocalIndex),

new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnTogglingWeaponFlashlight))),

// if (!args.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),

// status = NewState
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.NewState))),
new(OpCodes.Starg_S, 1),
new(OpCodes.Ldarg_1),
new(OpCodes.Stloc_S, status.LocalIndex),
});

newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[]
{
// Player
new(OpCodes.Ldloc_S, player.LocalIndex),

// Firearm
new(OpCodes.Ldloc_S, firearm.LocalIndex),

// status
new(OpCodes.Ldloc_S, status.LocalIndex),

new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ToggledWeaponFlashlightEventArgs))[0]),
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnToggledWeaponFlashlight))),
});

newInstructions[newInstructions.Count - 1].labels.Add(returnLabel);

foreach (CodeInstruction instruction in newInstructions)
yield return instruction;

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
2 changes: 2 additions & 0 deletions Exiled.Events/Patches/Events/Player/FirearmRequestReceived.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace Exiled.Events.Patches.Events.Player

using static HarmonyLib.AccessTools;

/*
/// <summary>
/// Patches <see cref="FirearmBasicMessagesHandler.ServerRequestReceived" />.
/// Adds <see cref="Player.ReloadingWeapon" />, <see cref="Player.ReloadedWeapon" />,
Expand Down Expand Up @@ -329,4 +330,5 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
*/
}

0 comments on commit 47fa0f0

Please sign in to comment.