Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Shooting patch #249

Merged
merged 9 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 19 additions & 66 deletions EXILED/Exiled.Events/EventArgs/Player/ShootingEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,9 @@
namespace Exiled.Events.EventArgs.Player
{
using API.Features;

using Exiled.API.Features.Items;

using Interfaces;

using InventorySystem.Items.Firearms.BasicMessages;

using RelativePositioning;

using UnityEngine;
using InventorySystem.Items.Firearms.Modules.Misc;

using BaseFirearm = InventorySystem.Items.Firearms.Firearm;

Expand All @@ -29,85 +22,45 @@ public class ShootingEventArgs : IPlayerEvent, IDeniableEvent, IFirearmEvent
/// <summary>
/// Initializes a new instance of the <see cref="ShootingEventArgs" /> class.
/// </summary>
/// <param name="shooter">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="firearm">
/// <inheritdoc cref="Firearm" />
/// The <see cref="BaseFirearm"/> that is being fired.
/// </param>
public ShootingEventArgs(Player shooter, BaseFirearm firearm)
/// <param name="shotBacktrackData">
/// <see cref="ShotBacktrackData"/> sent by the client.
/// </param>
public ShootingEventArgs(BaseFirearm firearm, ShotBacktrackData shotBacktrackData)
{
Player = shooter;
Firearm = Item.Get(firearm).As<Firearm>();

// ShotMessage = msg;
Firearm = (Firearm)Item.Get(firearm);
Player = Firearm.Owner;
ShotBacktrackData = shotBacktrackData;
}

/// <summary>
/// Gets the player who's shooting.
/// Gets the player who is shooting.
/// </summary>
public Player Player { get; }

/// <summary>
/// Gets the target <see cref="API.Features.Items.Firearm" />.
/// Gets the target that client claims it hit. This value is controlled by the client and should not be trusted. Can be null.
/// </summary>
public Firearm Firearm { get; }
public Player ClaimedTarget => ShotBacktrackData.HasPrimaryTarget ? Player.Get(ShotBacktrackData.PrimaryTargetHub) : null;

/// <inheritdoc/>
public Item Item => Firearm;

/*
/// <summary>
/// Gets or sets the <see cref="ShotMessage" /> for the event.
/// Gets the <see cref="ShotBacktrackData" />. This object contains the data sent by the client to the server. Values should not be trusted.
/// </summary>
public ShotMessage ShotMessage { get; set; }
public ShotBacktrackData ShotBacktrackData { get; }

/// <summary>
/// Gets or sets the position of the shot.
/// Gets the target <see cref="API.Features.Items.Firearm" />.
/// </summary>
public Vector3 ShotPosition
{
get => ShotMessage.TargetPosition.Position;
set
{
ShotMessage msg = ShotMessage;
ShotMessage = new ShotMessage
{
ShooterPosition = msg.ShooterPosition,
ShooterCameraRotation = msg.ShooterCameraRotation,
ShooterWeaponSerial = msg.ShooterWeaponSerial,
TargetPosition = new RelativePosition(value),
TargetRotation = msg.TargetRotation,
TargetNetId = msg.TargetNetId,
};
}
}
public Firearm Firearm { get; }

/// <summary>
/// Gets or sets the netId of the target of the shot.
/// </summary>
public uint TargetNetId
{
get => ShotMessage.TargetNetId;
set
{
ShotMessage msg = ShotMessage;
ShotMessage = new ShotMessage
{
ShooterPosition = msg.ShooterPosition,
ShooterCameraRotation = msg.ShooterCameraRotation,
ShooterWeaponSerial = msg.ShooterWeaponSerial,
TargetPosition = msg.TargetPosition,
TargetRotation = msg.TargetRotation,
TargetNetId = value,
};
}
}
*/
/// <inheritdoc />
public Item Item => Firearm;

/// <summary>
/// Gets or sets a value indicating whether the shot can be fired.
/// </summary>
public bool IsAllowed { get; set; } = true;
}
}
}
88 changes: 44 additions & 44 deletions EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ namespace Exiled.Events.Patches.Events.Player

using HarmonyLib;

using InventorySystem.Items.Firearms.BasicMessages;
using InventorySystem.Items.Firearms.Modules;
using InventorySystem.Items.Firearms.Modules.Misc;

using static HarmonyLib.AccessTools;

Expand All @@ -29,64 +28,65 @@ namespace Exiled.Events.Patches.Events.Player
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Shooting))]

// [HarmonyPatch(typeof(FirearmBasicMessagesHandler), nameof(FirearmBasicMessagesHandler.ServerShotReceived))]
[HarmonyPatch(typeof(ShotBacktrackData), nameof(ShotBacktrackData.ProcessShot))]
internal static class Shooting
{
/*
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label isAllowedLabel = generator.DefineLabel();
Label returnLabel = generator.DefineLabel();

LocalBuilder ev = generator.DeclareLocal(typeof(ShootingEventArgs));

int offset = -2;
int index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(IActionModule), nameof(IActionModule.ServerAuthorizeShot)))) + offset;
/*
[] <= Here
IL_0078: ldarg.2 // processingMethod (FindIndex here)
IL_0079: ldarg.0 // this
IL_007a: ldfld class ReferenceHub InventorySystem.Items.Firearms.Modules.Misc.ShotBacktrackData::PrimaryTargetHub
IL_007f: callvirt instance void class [mscorlib]System.Action`1<class ReferenceHub>::Invoke(!0/*class ReferenceHub* /)
*/
int hasTargetIndex = newInstructions.FindIndex(instruction => instruction.IsLdarg(2)) - 1;
List<Label> hasTargetLabels = newInstructions[hasTargetIndex].ExtractLabels();
Banalny-Banan marked this conversation as resolved.
Show resolved Hide resolved

/*
[] <= Here
IL_0092: ldarg.2 // processingMethod (FindIndex here)
IL_0093: ldnull
IL_0094: callvirt instance void class [mscorlib]System.Action`1<class ReferenceHub>::Invoke(!0/*class ReferenceHub* /)
*/
int noTargetIndex = newInstructions.FindIndex(hasTargetIndex, instruction => instruction.IsLdarg(2)) - 1;
List<Label> noTargetLabels = newInstructions[noTargetIndex].ExtractLabels();

CodeInstruction[] patchInstructions =
{
// ShootingEventArgs ev = new(firearm, this)
new(OpCodes.Ldarg_0),
new(OpCodes.Ldarg_1),
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ShootingEventArgs))[0]),

// Handlers.Player.OnShooting(ev)
new(OpCodes.Dup), // Dup to keep ev on the stack
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnShooting))),

// if (!ev.IsAllowed) return
new(OpCodes.Callvirt, PropertyGetter(typeof(ShootingEventArgs), nameof(ShootingEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),
};

newInstructions.InsertRange( // noTargetIndex goes first because it's higher then hasTargetIndex so it won't mess it up
noTargetIndex,
patchInstructions);
newInstructions[noTargetIndex].WithLabels(noTargetLabels);

newInstructions.InsertRange(
index,
new[]
{
// Player.Get(referenceHub)
new CodeInstruction(OpCodes.Ldloc_0).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),

// firearm
new(OpCodes.Ldloc_1),

// msg
new(OpCodes.Ldarg_1),

// ShootingEventArgs ev = new(Player, firearm, ShotMessage)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ShootingEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc, ev.LocalIndex),

// Handlers.Player.OnShooting(ev)
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnShooting))),

// if (ev.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(ShootingEventArgs), nameof(ShootingEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),

// isAllowedLabel:
// msg = ev.ShotMessage
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).WithLabels(isAllowedLabel),
new(OpCodes.Callvirt, PropertyGetter(typeof(ShootingEventArgs), nameof(ShootingEventArgs.ShotMessage))),
new(OpCodes.Starg_S, 1),
});

hasTargetIndex,
patchInstructions);
newInstructions[hasTargetIndex].WithLabels(hasTargetLabels);
newInstructions[newInstructions.Count - 1].WithLabels(returnLabel);

for (int z = 0; z < newInstructions.Count; z++)
yield return newInstructions[z];

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
*/
}
}