From c7dbdd444113072284efa83331b0bdf43cc3db7b Mon Sep 17 00:00:00 2001 From: VALERA771 Date: Mon, 7 Apr 2025 19:18:57 +0300 Subject: [PATCH 1/7] feat: a bunch of new evs --- .../Item/InspectedWeaponEventArgs.cs | 40 ++++++++++ .../Item/InspectingWeaponEventArgs.cs | 40 ++++++++++ .../Scp939/PlacingMimicPointEventArgs.cs | 48 ++++++++++++ EXILED/Exiled.Events/Events.cs | 4 + EXILED/Exiled.Events/Handlers/Item.cs | 22 ++++++ EXILED/Exiled.Events/Handlers/Scp939.cs | 11 +++ .../Patches/Events/Item/InspectedWeapon.cs | 61 +++++++++++++++ .../Patches/Events/Item/InspectingWeapon.cs | 55 ++++++++++++++ .../Events/Scp939/PlacingMimicPoint.cs | 76 +++++++++++++++++++ 9 files changed, 357 insertions(+) create mode 100644 EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs create mode 100644 EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs create mode 100644 EXILED/Exiled.Events/EventArgs/Scp939/PlacingMimicPointEventArgs.cs create mode 100644 EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs create mode 100644 EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs create mode 100644 EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs diff --git a/EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs new file mode 100644 index 0000000000..938a4126d4 --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs @@ -0,0 +1,40 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Item +{ + using Exiled.API.Features; + using Exiled.API.Features.Items; + using Exiled.Events.EventArgs.Interfaces; + using InventorySystem.Items; + + /// + /// Contains all information before weapon is inspected. + /// + public class InspectedWeaponEventArgs : IItemEvent + { + /// + /// Initializes a new instance of the class. + /// + /// + public InspectedWeaponEventArgs(ItemBase item) + { + Firearm = Item.Get(item); + } + + /// + public Player Player => Firearm.Owner; + + /// + public Item Item => Firearm; + + /// + /// Gets the firearm that is being inspected. + /// + public Firearm Firearm { get; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs new file mode 100644 index 0000000000..748097ddff --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs @@ -0,0 +1,40 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Item +{ + using Exiled.API.Features; + using Exiled.API.Features.Items; + using Exiled.Events.EventArgs.Interfaces; + using InventorySystem.Items; + + /// + /// Contains all information before weapon is inspected. + /// + public class InspectingWeaponEventArgs : IItemEvent + { + /// + /// Initializes a new instance of the class. + /// + /// + public InspectingWeaponEventArgs(ItemBase item) + { + Firearm = Item.Get(item); + } + + /// + public Player Player => Firearm.Owner; + + /// + public Item Item => Firearm; + + /// + /// Gets the firearm that is being inspected. + /// + public Firearm Firearm { get; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/EventArgs/Scp939/PlacingMimicPointEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp939/PlacingMimicPointEventArgs.cs new file mode 100644 index 0000000000..a761942caf --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Scp939/PlacingMimicPointEventArgs.cs @@ -0,0 +1,48 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Scp939 +{ + using Exiled.API.Features; + using Exiled.API.Features.Roles; + using Exiled.Events.EventArgs.Interfaces; + using RelativePositioning; + + /// + /// Contains all information before mimicry point is placed. + /// + public class PlacingMimicPointEventArgs : IScp939Event, IDeniableEvent + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + public PlacingMimicPointEventArgs(Player player, RelativePosition position, bool isAllowed = true) + { + Player = player; + Scp939 = player.Role.As(); + Position = position; + IsAllowed = isAllowed; + } + + /// + public Player Player { get; } + + /// + public Scp939Role Scp939 { get; } + + /// + public bool IsAllowed { get; set; } + + /// + /// Gets or sets a position of mimicry point. + /// + public RelativePosition Position { get; set; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs index ac37f5528a..eb96e0e711 100644 --- a/EXILED/Exiled.Events/Events.cs +++ b/EXILED/Exiled.Events/Events.cs @@ -5,6 +5,8 @@ // // ----------------------------------------------------------------------- +using UnityEngine; + namespace Exiled.Events { using System; @@ -86,6 +88,8 @@ public override void OnEnabled() ServerSpecificSettingsSync.ServerOnSettingValueReceived += SettingBase.OnSettingUpdated; EventManager.RegisterEvents(this); + + Handlers.Scp939.PlacingMimicPoint += ev => ev.Position = new(ev.Player.Position + Vector3.forward); } /// diff --git a/EXILED/Exiled.Events/Handlers/Item.cs b/EXILED/Exiled.Events/Handlers/Item.cs index 1c3f8b15e0..5de2c20bf7 100644 --- a/EXILED/Exiled.Events/Handlers/Item.cs +++ b/EXILED/Exiled.Events/Handlers/Item.cs @@ -58,6 +58,16 @@ public static class Item /// public static Event ChangingMicroHIDPickupState { get; set; } = new(); + /// + /// Invoked before weapon is inspected. + /// + public static Event InspectingWeapon { get; set; } = new(); + + /// + /// Invoked after weapon is inspected. + /// + public static Event InspectedWeapon { get; set; } = new(); + /// /// Called before the ammo of an firearm is changed. /// @@ -105,5 +115,17 @@ public static class Item /// /// The instance. public static void OnChangingMicroHIDPickupState(ChangingMicroHIDPickupStateEventArgs ev) => ChangingMicroHIDPickupState.InvokeSafely(ev); + + /// + /// Called before weapon is inspected. + /// + /// The instance. + public static void OnInspectingWeapon(InspectingWeaponEventArgs ev) => InspectingWeapon.InvokeSafely(ev); + + /// + /// Called after weapon is inspected. + /// + /// The instance. + public static void OnInspectedWeapon(InspectedWeaponEventArgs ev) => InspectedWeapon.InvokeSafely(ev); } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Handlers/Scp939.cs b/EXILED/Exiled.Events/Handlers/Scp939.cs index d2ca5e4533..d5d5da378e 100644 --- a/EXILED/Exiled.Events/Handlers/Scp939.cs +++ b/EXILED/Exiled.Events/Handlers/Scp939.cs @@ -74,6 +74,11 @@ public static class Scp939 /// public static Event ValidatingVisibility { get; set; } = new(); + /// + /// Invoked before mimicry point is placed. + /// + public static Event PlacingMimicPoint { get; set; } = new(); + /// /// Called before SCP-939 changes its target focus. /// @@ -139,5 +144,11 @@ public static class Scp939 /// /// The instance. public static void OnValidatingVisibility(ValidatingVisibilityEventArgs ev) => ValidatingVisibility.InvokeSafely(ev); + + /// + /// Called before mimicry point is placed. + /// + /// The instance. + public static void OnPlacingMimicPoint(PlacingMimicPointEventArgs ev) => PlacingMimicPoint.InvokeSafely(ev); } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs b/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs new file mode 100644 index 0000000000..823ac4505e --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs @@ -0,0 +1,61 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Item +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Item; + using HarmonyLib; + using InventorySystem.Items.Firearms.Modules; + + using static HarmonyLib.AccessTools; + + /// + /// Patches + /// to add event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedWeapon))] + [HarmonyPatch(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.SetInspecting))] + internal class InspectedWeapon + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_0); + + Label returnLabel = generator.DefineLabel(); + Label skipLabel = generator.DefineLabel(); + + newInstructions.InsertRange(index, new[] + { + new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Brtrue_S, skipLabel), + + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.Firearm))), + + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectedWeaponEventArgs))[0]), + + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectedWeapon))), + + new CodeInstruction(OpCodes.Nop).WithLabels(skipLabel), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs b/EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs new file mode 100644 index 0000000000..96ef956923 --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs @@ -0,0 +1,55 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Item +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Item; + using HarmonyLib; + using InventorySystem.Items.Firearms.Modules; + + using static HarmonyLib.AccessTools; + + /// + /// Patches + /// to add event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingWeapon))] + [HarmonyPatch(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.ServerProcessCmd))] + internal class InspectingWeapon + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_0); + + Label returnLabel = generator.DefineLabel(); + + newInstructions.InsertRange(index, new[] + { + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.Firearm))), + + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingWeaponEventArgs))[0]), + + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingWeapon))), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs b/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs new file mode 100644 index 0000000000..597d2b215b --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs @@ -0,0 +1,76 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Scp939 +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features; + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Scp939; + using HarmonyLib; + using PlayerRoles.PlayableScps.Scp939.Mimicry; + + using static HarmonyLib.AccessTools; + + /// + /// Patches + /// to add event. + /// + [EventPatch(typeof(Handlers.Scp939), nameof(Handlers.Scp939.PlacingMimicPoint))] + [HarmonyPatch(typeof(MimicPointController), nameof(MimicPointController.ServerProcessCmd))] + internal class PlacingMimicPoint + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = 1; + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Stfld) + offset; + + Label returnLabel = generator.DefineLabel(); + + LocalBuilder ev = generator.DeclareLocal(typeof(PlacingMimicPointEventArgs)); + + newInstructions.InsertRange(index, new CodeInstruction[] + { + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(MimicPointController), nameof(MimicPointController.Owner))), + new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), + + new(OpCodes.Ldarg_0), + new(OpCodes.Ldfld, Field(typeof(MimicPointController), nameof(MimicPointController._syncPos))), + + new(OpCodes.Ldc_I4_1), + + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(PlacingMimicPointEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, ev.LocalIndex), + + new(OpCodes.Call, Method(typeof(Handlers.Scp939), nameof(Handlers.Scp939.OnPlacingMimicPoint))), + + new(OpCodes.Callvirt, PropertyGetter(typeof(PlacingMimicPointEventArgs), nameof(PlacingMimicPointEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, returnLabel), + + new(OpCodes.Ldarg_0), + new(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(PlacingMimicPointEventArgs), nameof(PlacingMimicPointEventArgs.Position))), + new(OpCodes.Stfld, Field(typeof(MimicPointController), nameof(MimicPointController._syncPos))), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file From 0cf6a0599c16ac65a2876b77a9eaab2595e5211b Mon Sep 17 00:00:00 2001 From: VALERA771 Date: Mon, 7 Apr 2025 19:19:45 +0300 Subject: [PATCH 2/7] revert Events.cs changes --- EXILED/Exiled.Events/Events.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs index eb96e0e711..ac37f5528a 100644 --- a/EXILED/Exiled.Events/Events.cs +++ b/EXILED/Exiled.Events/Events.cs @@ -5,8 +5,6 @@ // // ----------------------------------------------------------------------- -using UnityEngine; - namespace Exiled.Events { using System; @@ -88,8 +86,6 @@ public override void OnEnabled() ServerSpecificSettingsSync.ServerOnSettingValueReceived += SettingBase.OnSettingUpdated; EventManager.RegisterEvents(this); - - Handlers.Scp939.PlacingMimicPoint += ev => ev.Position = new(ev.Player.Position + Vector3.forward); } /// From 1948a42a1120b2cf393ab9c138df0beefd992d07 Mon Sep 17 00:00:00 2001 From: VALERA771 Date: Wed, 9 Apr 2025 19:31:15 +0300 Subject: [PATCH 3/7] docs: comments for transpilers --- EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs | 6 ++++++ .../Exiled.Events/Patches/Events/Item/InspectingWeapon.cs | 3 +++ 2 files changed, 9 insertions(+) diff --git a/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs b/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs index 823ac4505e..5bbd654c96 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs @@ -37,16 +37,22 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Date: Mon, 28 Apr 2025 22:57:48 +0300 Subject: [PATCH 4/7] feat: support for all items --- ...EventArgs.cs => InspectedItemEventArgs.cs} | 8 +- ...ventArgs.cs => InspectingItemEventArgs.cs} | 23 +- EXILED/Exiled.Events/Events.cs | 5 + EXILED/Exiled.Events/Handlers/Item.cs | 21 +- .../Patches/Events/Item/Inspect.cs | 256 ++++++++++++++++++ .../Patches/Events/Item/InspectedWeapon.cs | 67 ----- .../Patches/Events/Item/InspectingWeapon.cs | 58 ---- 7 files changed, 288 insertions(+), 150 deletions(-) rename EXILED/Exiled.Events/EventArgs/Item/{InspectedWeaponEventArgs.cs => InspectedItemEventArgs.cs} (83%) rename EXILED/Exiled.Events/EventArgs/Item/{InspectingWeaponEventArgs.cs => InspectingItemEventArgs.cs} (54%) create mode 100644 EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs delete mode 100644 EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs delete mode 100644 EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs diff --git a/EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs similarity index 83% rename from EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs rename to EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs index 938a4126d4..b4a5683b39 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/InspectedWeaponEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------- -// +// // Copyright (c) ExMod Team. All rights reserved. // Licensed under the CC BY-SA 3.0 license. // @@ -15,13 +15,13 @@ namespace Exiled.Events.EventArgs.Item /// /// Contains all information before weapon is inspected. /// - public class InspectedWeaponEventArgs : IItemEvent + public class InspectedItemEventArgs : IItemEvent { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// - public InspectedWeaponEventArgs(ItemBase item) + public InspectedItemEventArgs(ItemBase item) { Firearm = Item.Get(item); } diff --git a/EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/InspectingItemEventArgs.cs similarity index 54% rename from EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs rename to EXILED/Exiled.Events/EventArgs/Item/InspectingItemEventArgs.cs index 748097ddff..5bb7cb4077 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/InspectingWeaponEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/InspectingItemEventArgs.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------- -// +// // Copyright (c) ExMod Team. All rights reserved. // Licensed under the CC BY-SA 3.0 license. // @@ -15,26 +15,27 @@ namespace Exiled.Events.EventArgs.Item /// /// Contains all information before weapon is inspected. /// - public class InspectingWeaponEventArgs : IItemEvent + public class InspectingItemEventArgs : IItemEvent, IDeniableEvent { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// - public InspectingWeaponEventArgs(ItemBase item) + /// + public InspectingItemEventArgs(ItemBase item, bool isAllowed = true) { - Firearm = Item.Get(item); + Item = Item.Get(item); + IsAllowed = isAllowed; } /// - public Player Player => Firearm.Owner; + public Player Player => Item.Owner; /// - public Item Item => Firearm; + public Item Item { get; } - /// - /// Gets the firearm that is being inspected. - /// - public Firearm Firearm { get; } + /// + /// Setter will not work if inspected is a or a . + public bool IsAllowed { get; set; } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs index 103ba58829..a239c7383c 100644 --- a/EXILED/Exiled.Events/Events.cs +++ b/EXILED/Exiled.Events/Events.cs @@ -88,6 +88,11 @@ public override void OnEnabled() ServerSpecificSettingsSync.ServerOnSettingValueReceived += SettingBase.OnSettingUpdated; ServerConsole.ReloadServerName(); + + Handlers.Item.InspectingItem += ev => + { + ev.IsAllowed = false; + }; } /// diff --git a/EXILED/Exiled.Events/Handlers/Item.cs b/EXILED/Exiled.Events/Handlers/Item.cs index 7e15ac60dc..4cca796fef 100644 --- a/EXILED/Exiled.Events/Handlers/Item.cs +++ b/EXILED/Exiled.Events/Handlers/Item.cs @@ -59,15 +59,16 @@ public static class Item public static Event ChangingMicroHIDPickupState { get; set; } = new(); /// - /// Invoked before weapon is inspected. + /// Invoked before item inspection is started. /// - public static Event InspectingWeapon { get; set; } = new(); + public static Event InspectingItem { get; set; } = new(); /// - /// Invoked after weapon is inspected. + /// Invoked after item inspection is started. /// - public static Event InspectedWeapon { get; set; } = new(); + public static Event InspectedItem { get; set; } = new(); + /// /// Invoked before a firing while on the ground. /// The client will still see all effects, like sounds and shoot. /// @@ -129,15 +130,15 @@ public static class Item public static void OnChangingMicroHIDPickupState(ChangingMicroHIDPickupStateEventArgs ev) => ChangingMicroHIDPickupState.InvokeSafely(ev); /// - /// Called before weapon is inspected. + /// Called before item inspection is started. /// - /// The instance. - public static void OnInspectingWeapon(InspectingWeaponEventArgs ev) => InspectingWeapon.InvokeSafely(ev); + /// The instance. + public static void OnInspectingItem(InspectingItemEventArgs ev) => InspectingItem.InvokeSafely(ev); /// - /// Called after weapon is inspected. + /// Called before item inspection is started. /// - /// The instance. - public static void OnInspectedWeapon(InspectedWeaponEventArgs ev) => InspectedWeapon.InvokeSafely(ev); + /// The instance. + public static void OnInspectedItem(InspectedItemEventArgs ev) => InspectedItem.InvokeSafely(ev); } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs new file mode 100644 index 0000000000..23cc10ed3b --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs @@ -0,0 +1,256 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Item +{ +#pragma warning disable SA1402 +#pragma warning disable SA1649 + + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Item; + using HarmonyLib; + using InventorySystem.Items.Firearms.Modules; + using InventorySystem.Items.Jailbird; + using InventorySystem.Items.Keycards; + using InventorySystem.Items.Usables.Scp1344; + + using static HarmonyLib.AccessTools; + + /// + /// Patches + /// to add and event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingItem))] + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedItem))] + [HarmonyPatch(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.ServerProcessCmd))] + internal class InspectWeapon + { + private static IEnumerable Transpiler(IEnumerable instructions) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_0); + + newInstructions.InsertRange(index, new[] + { + // this.Firearm + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.Firearm))), + + // true + new(OpCodes.Ldc_I4_1), + + // InspectingItemEventArgs ev = new(this.Firearm) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingItemEventArgs))[0]), + + // Handlers.Item.OnInspectingItem(ev) + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingItem))), + }); + + newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[] + { + // this.Firearm + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.Firearm))), + + // InspectedItemEventArgs ev = new(this.Firearm) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectedItemEventArgs))[0]), + + // Handlers.Item.OnInspectedItem(ev) + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectedItem))), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } + + /// + /// Patches + /// to add and event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingItem))] + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedItem))] + [HarmonyPatch(typeof(Scp1344NetworkHandler), nameof(Scp1344NetworkHandler.TryInspect))] + internal class InspectScp1344 + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = 1; + int index = newInstructions.FindIndex(x => x.Is(OpCodes.Callvirt, PropertyGetter(typeof(Scp1344Item), nameof(Scp1344Item.AllowInspect)))) + offset; + + LocalBuilder allowed = generator.DeclareLocal(typeof(bool)); + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // store isAllowed + new(OpCodes.Stloc_S, allowed.LocalIndex), + + // curInstance + new(OpCodes.Ldloc_0), + + // load isAllowed + new(OpCodes.Ldloc_S, allowed.LocalIndex), + + // InspectingItemEventArgs ev = new(curInstance, isAllowed); + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingItemEventArgs))[0]), + new(OpCodes.Dup), + + // Handlers.Item.OnInspectingItem(ev); + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingItem))), + + // load isAllowed + new(OpCodes.Callvirt, PropertyGetter(typeof(InspectingItemEventArgs), nameof(InspectingItemEventArgs.IsAllowed))), + }); + + newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[] + { + // curInstance + new(OpCodes.Ldloc_0), + + // InspectedItemEventArgs = new(curInstance); + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectedItemEventArgs))[0]), + + // Handlers.Item.OnInspectedItem(ev); + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectedItem))), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } + + /// + /// Patches + /// to add and event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingItem))] + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedItem))] + [HarmonyPatch(typeof(KeycardItem), nameof(KeycardItem.ServerProcessCmd))] + internal class InspectKeycard + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = 1; + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldloc_1) + offset; + + LocalBuilder allowed = generator.DeclareLocal(typeof(bool)); + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // save flag value as isAllowed + new(OpCodes.Stloc_S, allowed.LocalIndex), + + // this + new(OpCodes.Ldarg_0), + + // load isAllowed + new(OpCodes.Ldloc_S, allowed.LocalIndex), + + // InspectingItemEventArgs ev = new(this, isAllowed) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingItemEventArgs))[0]), + new(OpCodes.Dup), + + // Handlers.Item.OnInspectingItem(ev) + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingItem))), + + // load isAllowed + new(OpCodes.Callvirt, PropertyGetter(typeof(InspectingItemEventArgs), nameof(InspectingItemEventArgs.IsAllowed))), + }); + + newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[] + { + // this + new(OpCodes.Ldarg_0), + + // InspectedItemEventArgs ev = new(this) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectedItemEventArgs))[0]), + + // Handlers.Item.OnInspectedItem(ev) + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectedItem))), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } + + /// + /// Patches + /// to add and event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingItem))] + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedItem))] + [HarmonyPatch(typeof(JailbirdItem), nameof(JailbirdItem.ServerProcessCmd))] + internal class InspectJailbird + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = 1; + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldloc_2) + offset; + + LocalBuilder allowed = generator.DeclareLocal(typeof(bool)); + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // save flag value as isAllowed + new(OpCodes.Stloc_S, allowed.LocalIndex), + + // this + new(OpCodes.Ldarg_0), + + // load isAllowed + new(OpCodes.Ldloc_S, allowed.LocalIndex), + + // InspectingItemEventArgs ev = new(this, isAllowed) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingItemEventArgs))[0]), + new(OpCodes.Dup), + + // Handlers.Item.OnInspectingItem(ev) + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingItem))), + + // load isAllowed + new(OpCodes.Callvirt, PropertyGetter(typeof(InspectingItemEventArgs), nameof(InspectingItemEventArgs.IsAllowed))), + }); + + index = newInstructions.FindLastIndex(x => x.Calls(Method(typeof(JailbirdItem), nameof(JailbirdItem.SendRpc)))) + offset; + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // this + new(OpCodes.Ldarg_0), + + // InspectedItemEventArgs ev = new(this) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectedItemEventArgs))[0]), + + // Handlers.Item.OnInspectedItem(ev) + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectedItem))), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs b/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs deleted file mode 100644 index 5bbd654c96..0000000000 --- a/EXILED/Exiled.Events/Patches/Events/Item/InspectedWeapon.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) ExMod Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Events.Item -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using Exiled.API.Features.Pools; - using Exiled.Events.Attributes; - using Exiled.Events.EventArgs.Item; - using HarmonyLib; - using InventorySystem.Items.Firearms.Modules; - - using static HarmonyLib.AccessTools; - - /// - /// Patches - /// to add event. - /// - [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedWeapon))] - [HarmonyPatch(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.SetInspecting))] - internal class InspectedWeapon - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_0); - - Label returnLabel = generator.DefineLabel(); - Label skipLabel = generator.DefineLabel(); - - newInstructions.InsertRange(index, new[] - { - // if (val) - // skip event - new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Brtrue_S, skipLabel), - - // this.Firearm - new(OpCodes.Ldarg_0), - new(OpCodes.Callvirt, PropertyGetter(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.Firearm))), - - // InspectedWeaponEventArgs ev = new(this.Firearm) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectedWeaponEventArgs))[0]), - - // Handlers.Item.OnInspectedWeapon(ev) - new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectedWeapon))), - - // skip: - new CodeInstruction(OpCodes.Nop).WithLabels(skipLabel), - }); - - newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs b/EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs deleted file mode 100644 index 554acec9e1..0000000000 --- a/EXILED/Exiled.Events/Patches/Events/Item/InspectingWeapon.cs +++ /dev/null @@ -1,58 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) ExMod Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Events.Item -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using Exiled.API.Features.Pools; - using Exiled.Events.Attributes; - using Exiled.Events.EventArgs.Item; - using HarmonyLib; - using InventorySystem.Items.Firearms.Modules; - - using static HarmonyLib.AccessTools; - - /// - /// Patches - /// to add event. - /// - [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingWeapon))] - [HarmonyPatch(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.ServerProcessCmd))] - internal class InspectingWeapon - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_0); - - Label returnLabel = generator.DefineLabel(); - - newInstructions.InsertRange(index, new[] - { - // this.Firearm - new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Callvirt, PropertyGetter(typeof(SimpleInspectorModule), nameof(SimpleInspectorModule.Firearm))), - - // InspectingWeaponEventArgs ev = new(this.Firearm) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingWeaponEventArgs))[0]), - - // Handlers.Item.OnInspectingWeapon(ev) - new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingWeapon))), - }); - - newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file From b2fc8f90eb6303f23189eb42209bbee07c8e94c6 Mon Sep 17 00:00:00 2001 From: VALERA771 Date: Tue, 29 Apr 2025 17:52:13 +0300 Subject: [PATCH 5/7] feat: mhid support --- EXILED/Exiled.Events/Events.cs | 5 -- .../Patches/Events/Item/Inspect.cs | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs index a239c7383c..103ba58829 100644 --- a/EXILED/Exiled.Events/Events.cs +++ b/EXILED/Exiled.Events/Events.cs @@ -88,11 +88,6 @@ public override void OnEnabled() ServerSpecificSettingsSync.ServerOnSettingValueReceived += SettingBase.OnSettingUpdated; ServerConsole.ReloadServerName(); - - Handlers.Item.InspectingItem += ev => - { - ev.IsAllowed = false; - }; } /// diff --git a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs index 23cc10ed3b..0dde7fc4bf 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs @@ -9,7 +9,6 @@ namespace Exiled.Events.Patches.Events.Item { #pragma warning disable SA1402 #pragma warning disable SA1649 - using System.Collections.Generic; using System.Reflection.Emit; @@ -20,6 +19,7 @@ namespace Exiled.Events.Patches.Events.Item using InventorySystem.Items.Firearms.Modules; using InventorySystem.Items.Jailbird; using InventorySystem.Items.Keycards; + using InventorySystem.Items.MicroHID.Modules; using InventorySystem.Items.Usables.Scp1344; using static HarmonyLib.AccessTools; @@ -191,6 +191,8 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } + + private static void Return(KeycardItem item) => item.ServerSendPrivateRpc(x => KeycardItem.WriteInspect(x, false)); } /// @@ -253,4 +255,46 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } + + /// + /// Patches + /// to add and event. + /// + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingItem))] + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectedItem))] + [HarmonyPatch(typeof(DrawAndInspectorModule), nameof(DrawAndInspectorModule.ServerProcessCmd))] + internal class InspectMicroHid + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_0); + + Label returnLabel = generator.DefineLabel(); + + newInstructions.InsertRange(index, new[] + { + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(DrawAndInspectorModule), nameof(DrawAndInspectorModule.MicroHid))), + + new(OpCodes.Ldc_I4_1), + + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InspectingItemEventArgs))[0]), + new(OpCodes.Dup), + + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnInspectingItem))), + + new(OpCodes.Callvirt, PropertyGetter(typeof(InspectingItemEventArgs), nameof(InspectingItemEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, returnLabel), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } } \ No newline at end of file From 79f1ec630984582dc04ae2e7519d7595fac132df Mon Sep 17 00:00:00 2001 From: VALERA771 Date: Tue, 29 Apr 2025 17:54:06 +0300 Subject: [PATCH 6/7] docs: fetch documentation --- EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs | 2 +- .../Patches/Events/Scp939/PlacingMimicPoint.cs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs index 0dde7fc4bf..5317f72188 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs @@ -257,7 +257,7 @@ private static IEnumerable Transpiler(IEnumerable - /// Patches + /// Patches /// to add and event. /// [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.InspectingItem))] diff --git a/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs b/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs index 597d2b215b..753291df01 100644 --- a/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs +++ b/EXILED/Exiled.Events/Patches/Events/Scp939/PlacingMimicPoint.cs @@ -40,25 +40,33 @@ private static IEnumerable Transpiler(IEnumerable Date: Tue, 29 Apr 2025 17:58:21 +0300 Subject: [PATCH 7/7] fix: fix InspectedItemEventArgs.cs and docs update --- .../EventArgs/Item/InspectedItemEventArgs.cs | 11 +++-------- .../Patches/Events/Item/Inspect.cs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs index b4a5683b39..283fd4910f 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/InspectedItemEventArgs.cs @@ -23,18 +23,13 @@ public class InspectedItemEventArgs : IItemEvent /// public InspectedItemEventArgs(ItemBase item) { - Firearm = Item.Get(item); + Item = Item.Get(item); } /// - public Player Player => Firearm.Owner; + public Player Player => Item.Owner; /// - public Item Item => Firearm; - - /// - /// Gets the firearm that is being inspected. - /// - public Firearm Firearm { get; } + public Item Item { get; } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs index 5317f72188..860d064ea1 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/Inspect.cs @@ -275,20 +275,39 @@ private static IEnumerable Transpiler(IEnumerable