Skip to content
Closed
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
454871a
interacting door
Misaka-ZeroTwo May 12, 2023
aeef386
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo May 12, 2023
eb85bdc
Update InteractingDoorEventArgs.cs
Misaka-ZeroTwo May 13, 2023
2495896
line
Misaka-ZeroTwo May 13, 2023
b6d3694
base game logic
Misaka-ZeroTwo May 13, 2023
b1c97a3
rename
Misaka-ZeroTwo May 13, 2023
c5b714f
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo May 13, 2023
3b91bc9
Merge branch 'dev' into interacting-door
louis1706 May 14, 2023
054f5dc
Merge branch 'dev' into interacting-door
louis1706 May 22, 2023
11e7290
transpiler
Misaka-ZeroTwo May 22, 2023
1b618d2
better
Misaka-ZeroTwo May 22, 2023
a8e0b25
oopsie
Misaka-ZeroTwo May 22, 2023
33e64e5
fix docs
Misaka-ZeroTwo May 22, 2023
22c4e62
more comments
Misaka-ZeroTwo May 23, 2023
70955b1
Merge branch 'interacting-door' of https://github.com/Misaka-ZeroTwo/…
Misaka-ZeroTwo May 23, 2023
235d45e
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo May 24, 2023
9c57637
Merge branch 'dev' into interacting-door
NaoUnderscore May 25, 2023
cb00541
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo May 26, 2023
f6dfda0
Merge branch 'dev' into interacting-door
louis1706 May 26, 2023
b5cb0bb
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo May 30, 2023
cca1686
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo Sep 1, 2023
e530aaa
Merge branch 'dev' into interacting-door
louis1706 Sep 1, 2023
c64d82a
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo Sep 1, 2023
84d1b65
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo Sep 1, 2023
a0cbe1d
Merge branch 'dev' into interacting-door
Misaka-ZeroTwo Sep 1, 2023
eea1b74
Merge branch 'dev' into interacting-door
louis1706 Sep 5, 2023
29db0c0
Merge branch 'dev' into interacting-door
Thundermaker300 Sep 14, 2023
a03f0ee
Merge branch 'dev' into interacting-door
louis1706 Sep 14, 2023
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
12 changes: 11 additions & 1 deletion Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Exiled.Events.EventArgs.Player
{
using API.Enums;
using API.Features;
using Exiled.API.Features.Doors;
using Interactables.Interobjects.DoorUtils;
Expand All @@ -29,11 +30,15 @@ public class InteractingDoorEventArgs : IPlayerEvent, IDoorEvent, IDeniableEvent
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public InteractingDoorEventArgs(Player player, DoorVariant door, bool isAllowed = true)
/// <param name="interactionResult">
/// <inheritdoc cref="InteractionResult" />
/// </param>
public InteractingDoorEventArgs(Player player, DoorVariant door, bool isAllowed = true, DoorBeepType interactionResult = DoorBeepType.InteractionAllowed)
{
Player = player;
Door = Door.Get(door);
IsAllowed = isAllowed;
InteractionResult = interactionResult;
}

/// <summary>
Expand All @@ -50,5 +55,10 @@ public InteractingDoorEventArgs(Player player, DoorVariant door, bool isAllowed
/// Gets the player who's interacting with the door.
/// </summary>
public Player Player { get; }

/// <summary>
/// Gets or sets a value indicating the result of the interaction.
/// </summary>
public DoorBeepType InteractionResult { get; set; }
}
}
145 changes: 96 additions & 49 deletions Exiled.Events/Patches/Events/Player/InteractingDoor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@

namespace Exiled.Events.Patches.Events.Player
{
#pragma warning disable SA1313
#pragma warning disable SA1005
#pragma warning disable SA1515
#pragma warning disable SA1513
#pragma warning disable SA1512
using System;
using System.Collections.Generic;
using System.Reflection.Emit;

using API.Features;
using Exiled.API.Enums;
using Exiled.API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;
Expand All @@ -19,6 +26,10 @@ namespace Exiled.Events.Patches.Events.Player

using Interactables.Interobjects.DoorUtils;

using PlayerRoles;

using PluginAPI.Events;

using static HarmonyLib.AccessTools;

/// <summary>
Expand All @@ -34,91 +45,127 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

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

List<Label> jmp = null;
Label interactionAllowed = generator.DefineLabel();
Label permissionDenied = generator.DefineLabel();
Label retLabel = generator.DefineLabel();
Label jmp = generator.DefineLabel();
Label skip = generator.DefineLabel();

newInstructions.InsertRange(
0,
new CodeInstruction[]
{
new(OpCodes.Ldarg_0),
new(OpCodes.Call, Method(typeof(InteractingDoor), nameof(InteractingDoor.CanStateChange))),
new(OpCodes.Brfalse_S, retLabel),

// InteractingDoorEventArgs ev = new(Player.Get(ply), __instance, false);
// InteractingDoorEventArgs ev = new(Player.Get(ply), __instance, true, DoorBeepType.InteractionAllowed);
new(OpCodes.Ldarg_1),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
new(OpCodes.Ldarg_0),
new(OpCodes.Ldc_I4_0),
new(OpCodes.Ldc_I4_1),
new(OpCodes.Ldc_I4_3),
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InteractingDoorEventArgs))[0]),
new(OpCodes.Stloc_S, ev.LocalIndex),
});

int offset = -3;
int offset = -5;
int index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(DoorVariant), nameof(DoorVariant.LockBypassDenied)))) + offset;
newInstructions[index] = new CodeInstruction(OpCodes.Brtrue_S, jmp);

offset = 2;
index += offset;

newInstructions.RemoveRange(index, 4);

newInstructions.InsertRange(
index,
new CodeInstruction[]
{
// Handlers.Player.OnInteractingDoor(ev);
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Dup),
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingDoor))),

// if (ev.IsAllowed)
// go to interactionAllowed;
new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))),
new(OpCodes.Brtrue_S, interactionAllowed),
});
// jmp
// ev.InteractionResult = DoorBeepType.LockBypassDenied;
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).WithLabels(jmp),
new(OpCodes.Ldc_I4_1),
new(OpCodes.Callvirt, PropertySetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.InteractionResult))),

// attaching permission denied label
offset = -3;
index = newInstructions.FindIndex(i => i.Calls(Method(typeof(DoorVariant), nameof(DoorVariant.PermissionsDenied)))) + offset;
newInstructions[index].WithLabels(permissionDenied);
// InteractingDoor.Process(__instance, ply, colliderId, ev);
new(OpCodes.Ldarg_0),
new(OpCodes.Ldarg_1),
new(OpCodes.Ldarg_2),
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Call, Method(typeof(InteractingDoor), nameof(InteractingDoor.Process))),
});

// replace the condition check
offset = -7;
index = newInstructions.FindIndex(instruction => instruction.Calls(PropertySetter(typeof(DoorVariant), nameof(DoorVariant.NetworkTargetState)))) + offset;
jmp = newInstructions[index].ExtractLabels();
newInstructions.RemoveRange(index, 2);
offset = 2;
index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(DoorVariant), nameof(DoorVariant.AllowInteracting)))) + offset;

// insert interaction Allowed label
newInstructions[index].WithLabels(interactionAllowed);
newInstructions.InsertRange(
index,
new CodeInstruction[]
{
// ev.IsAllowed = flag;
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).WithLabels(jmp),
new(OpCodes.Ldloc_0),
new(OpCodes.Callvirt, PropertySetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))),
// ev.IsAllowed = false;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Ldc_I4_0),
new(OpCodes.Callvirt, PropertySetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))),

// ev.InteractionResult = DoorBeepType.InteractionDenied;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Ldc_I4_2),
new(OpCodes.Callvirt, PropertySetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.InteractionResult))),

// InteractingDoor.Process(__instance, ply, colliderId, ev);
new(OpCodes.Ldarg_0),
new(OpCodes.Ldarg_1),
new(OpCodes.Ldarg_2),
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Call, Method(typeof(InteractingDoor), nameof(InteractingDoor.Process))),
});

// Handlers.Player.OnInteractingDoor(ev);
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Dup),
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingDoor))),
offset = -6;
index = newInstructions.FindIndex(instruction => instruction.Calls(PropertySetter(typeof(DoorVariant), nameof(DoorVariant.NetworkTargetState)))) + offset;

// if (!ev.IsAllowed)
// go to permission denied;
new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, permissionDenied),
newInstructions.RemoveRange(index, 19);
newInstructions.InsertRange(
index,
new CodeInstruction[]
{
// if (flag)
// goto skip
new(OpCodes.Brtrue_S, skip),

// ev.InteractionResult = DoorBeepType.PermissionDenied;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Ldc_I4_0),
new(OpCodes.Callvirt, PropertySetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.InteractionResult))),

// skip
// InteractingDoor.Process(__instance, ply, colliderId, ev);
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(skip),
new(OpCodes.Ldarg_1),
new(OpCodes.Ldarg_2),
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Call, Method(typeof(InteractingDoor), nameof(InteractingDoor.Process))),
});

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

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

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

private static bool CanStateChange(DoorVariant variant)
private static void Process(DoorVariant __instance, ReferenceHub ply, byte colliderId, InteractingDoorEventArgs ev)
{
return !(variant.GetExactState() > 0f && variant.GetExactState() < 1f);
Handlers.Player.OnInteractingDoor(ev);
if (ev.IsAllowed)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am really not sure about this because mostly every plugin use this to just DeniedPermission

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and even in a breaking change update it's will be confusing for people

{
switch (ev.InteractionResult)
{
case DoorBeepType.PermissionDenied:
__instance.PermissionsDenied(ply, colliderId);
DoorEvents.TriggerAction(__instance, DoorAction.AccessDenied, ply);
break;
case DoorBeepType.LockBypassDenied:
__instance.LockBypassDenied(ply, colliderId);
break;
default:
__instance.NetworkTargetState = !__instance.TargetState;
__instance._triggerPlayer = ply;
break;
}
}
}
}
}