Skip to content

Commit 3eb2717

Browse files
fix: ReceivingPreference, AnnouncingScpTermination, ChangedRoom, and Jumping transpilers and patches (#603)
* Fix transpilers * doc * alter jumping and fix ChangingRadioPreset --------- Co-authored-by: Yamato <louismonneyron5@yahoo.com>
1 parent 7a205db commit 3eb2717

6 files changed

Lines changed: 55 additions & 33 deletions

File tree

EXILED/Exiled.Events/EventArgs/Player/JumpingEventArgs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public float Speed
5757
}
5858

5959
/// <summary>
60-
/// Gets or sets a value indicating whether the client data can be synchronized with the server.
60+
/// Gets or sets a value indicating whether or not the player can jump.
6161
/// </summary>
6262
public bool IsAllowed { get; set; }
6363
}

EXILED/Exiled.Events/Patches/Events/Item/ReceivingPreference.cs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
4040
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);
4141

4242
int offset = 1;
43-
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ret) + offset;
43+
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Stloc_2) + offset;
4444

4545
LocalBuilder ev = generator.DeclareLocal(typeof(ReceivingPreferenceEventArgs));
46-
LocalBuilder curCode = generator.DeclareLocal(typeof(uint));
4746

4847
Label cdc = generator.DefineLabel();
4948
Label ret = generator.DefineLabel();
@@ -54,14 +53,6 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
5453
index,
5554
new CodeInstruction[]
5655
{
57-
// dictionary::TryGetValue(AttachmentsSetupPreference::Weapon, *mem_0x02)
58-
new(OpCodes.Ldloc_1),
59-
new(OpCodes.Ldarg_1),
60-
new(OpCodes.Ldfld, Field(typeof(AttachmentsSetupPreference), nameof(AttachmentsSetupPreference.Weapon))),
61-
new(OpCodes.Ldloca_S, curCode.LocalIndex),
62-
new(OpCodes.Callvirt, Method(typeof(Dictionary<ItemType, uint>), nameof(Dictionary<ItemType, uint>.TryGetValue))),
63-
new(OpCodes.Brfalse_S, cdc),
64-
6556
// API::Features::Player::Get(referenceHub)
6657
new(OpCodes.Ldloc_0),
6758
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
@@ -70,12 +61,11 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
7061
new(OpCodes.Ldarg_1),
7162
new(OpCodes.Ldfld, Field(typeof(AttachmentsSetupPreference), nameof(AttachmentsSetupPreference.Weapon))),
7263

73-
// currentCode
74-
new(OpCodes.Ldloc_S, curCode.LocalIndex),
64+
// playerPreference (old attachments)
65+
new(OpCodes.Ldloc_1),
7566

76-
// AttachmentsSetupPreference::AttachmentsCode
77-
new(OpCodes.Ldarg_1),
78-
new(OpCodes.Ldfld, Field(typeof(AttachmentsSetupPreference), nameof(AttachmentsSetupPreference.AttachmentsCode))),
67+
// attachmentsCode (new attachments)
68+
new(OpCodes.Ldloc_2),
7969

8070
// true
8171
new(OpCodes.Ldc_I4_1),
@@ -84,18 +74,18 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
8474
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ReceivingPreferenceEventArgs))[0]),
8575
new(OpCodes.Dup),
8676
new(OpCodes.Dup),
87-
new(OpCodes.Stloc_S, ev.LocalIndex),
77+
new(OpCodes.Stloc, ev),
8878

8979
// Handlers::Item::OnReceivingPreference(ev)
9080
new(OpCodes.Call, Method(typeof(Item), nameof(Item.OnReceivingPreference))),
9181

9282
// ev.IsAllowed
9383
new(OpCodes.Callvirt, PropertyGetter(typeof(ReceivingPreferenceEventArgs), nameof(ReceivingPreferenceEventArgs.IsAllowed))),
94-
new(OpCodes.Brfalse_S, ret),
84+
new(OpCodes.Brfalse, ret),
9585

9686
// **AttachmentSetupPreference::AttachmentsCode = ev::NewCode
97-
new(OpCodes.Ldarga_S, 1),
98-
new(OpCodes.Ldloc_S, ev.LocalIndex),
87+
new(OpCodes.Ldarga, 1),
88+
new(OpCodes.Ldloc, ev),
9989
new(OpCodes.Callvirt, PropertyGetter(typeof(ReceivingPreferenceEventArgs), nameof(ReceivingPreferenceEventArgs.NewCode))),
10090
new(OpCodes.Stfld, Field(typeof(AttachmentsSetupPreference), nameof(AttachmentsSetupPreference.AttachmentsCode))),
10191
});

EXILED/Exiled.Events/Patches/Events/Map/AnnouncingScpTermination.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
4040

4141
Label ret = generator.DefineLabel();
4242

43-
int offset = -3;
43+
int offset = -4;
4444
int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.ServerEvents.CassieQueuingScpTerminationEventArgs))[0]) + offset;
4545

4646
newInstructions.InsertRange(

EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ namespace Exiled.Events.Patches.Events.Player
1515
using Exiled.Events.EventArgs.Player;
1616
using Exiled.Events.Handlers;
1717
using HarmonyLib;
18-
using LabApi.Events.Handlers;
1918
using MapGeneration;
19+
using PlayerRoles;
2020
using UnityEngine;
2121

2222
using static HarmonyLib.AccessTools;
@@ -34,12 +34,17 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
3434

3535
Label jump = generator.DefineLabel();
3636
int offset = 2;
37-
int index = newInstructions.FindIndex(x => x == (object)Method(typeof(Object), "op_Inequality", new[] { typeof(Object), typeof(Object) })) + offset;
37+
int index = newInstructions.FindIndex(x => x.Calls(Method(typeof(Object), "op_Inequality", new[] { typeof(Object), typeof(Object) }))) + offset;
3838

3939
newInstructions[index].labels.Add(jump);
4040

4141
newInstructions.InsertRange(index, new CodeInstruction[]
4242
{
43+
// referenceHub
44+
new(OpCodes.Ldarg_0),
45+
new(OpCodes.Ldfld, Field(typeof(CurrentRoomPlayerCache), nameof(CurrentRoomPlayerCache._roleManager))),
46+
new(OpCodes.Callvirt, PropertyGetter(typeof(PlayerRoleManager), nameof(PlayerRoleManager.Hub))),
47+
4348
// oldRoom
4449
new(OpCodes.Ldloc_2),
4550

EXILED/Exiled.Events/Patches/Events/Player/ChangingRadioPreset.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ namespace Exiled.Events.Patches.Events.Player
2121
using InventorySystem.Items;
2222
using InventorySystem.Items.Radio;
2323

24+
using LabApi.Events.Arguments.PlayerEvents;
25+
2426
using static HarmonyLib.AccessTools;
2527

2628
/// <summary>
@@ -40,7 +42,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
4042
LocalBuilder ev = generator.DeclareLocal(typeof(ChangingRadioPresetEventArgs));
4143

4244
const int offset = -5;
43-
int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Newobj) + offset;
45+
int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Constructor(typeof(PlayerChangingRadioRangeEventArgs), new[] { typeof(ReferenceHub), typeof(RadioItem), typeof(RadioMessages.RadioRangeLevel) })) + offset;
4446

4547
newInstructions.InsertRange(
4648
index,

EXILED/Exiled.Events/Patches/Events/Player/Jumping.cs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,41 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
3434
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);
3535

3636
LocalBuilder ev = generator.DeclareLocal(typeof(JumpingEventArgs));
37+
LocalBuilder jumping = generator.DeclareLocal(typeof(bool));
3738

38-
Label ret = generator.DefineLabel();
39+
Label cont = generator.DefineLabel();
40+
Label cancel = generator.DefineLabel();
3941

40-
const int offset = 1;
41-
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Stfld) + offset;
42+
// fun fact, the "int num = ProcessJump() ? 1 : 0;" in target method doesn't actually store anything, the bool result from ProcessJump is simply kept on stack.
43+
// our patch needs to know when player is jumping so we modify method to store that.
44+
int offset = 1;
45+
int index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(FpcJumpController), nameof(FpcJumpController.ProcessJump)))) + offset;
46+
47+
// after ProcessJump, store its result
48+
newInstructions.Insert(index, new CodeInstruction(OpCodes.Stloc, jumping));
49+
50+
// offset here is 0
51+
index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Brfalse_S);
52+
53+
// make br_false use stored value
54+
newInstructions.Insert(index, new CodeInstruction(OpCodes.Ldloc, jumping));
55+
56+
// The FindIndex finds when storing the field inside the moveDirection vector, so our patch occurs right before "this.MoveDirection = moveDirection;"
57+
offset = 1;
58+
index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Stfld) + offset;
59+
60+
newInstructions[index].WithLabels(cont);
4261

4362
newInstructions.InsertRange(
4463
index,
4564
new[]
4665
{
66+
// if not jumping, skip Jumping event
67+
new(OpCodes.Ldloc, jumping),
68+
new(OpCodes.Brfalse, cont),
69+
4770
// Player.Get(this.Hub)
48-
new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
71+
new(OpCodes.Ldarg_0),
4972
new(OpCodes.Ldfld, Field(typeof(FpcMotor), nameof(FpcMotor.Hub))),
5073
new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),
5174

@@ -59,23 +82,25 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
5982
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(JumpingEventArgs))[0]),
6083
new(OpCodes.Dup),
6184
new(OpCodes.Dup),
62-
new(OpCodes.Stloc_S, ev.LocalIndex),
85+
new(OpCodes.Stloc, ev),
6386

6487
// Player.OnJumping(ev)
6588
new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnJumping))),
6689

6790
// if (!ev.IsAllowed)
6891
// return;
6992
new(OpCodes.Callvirt, PropertyGetter(typeof(JumpingEventArgs), nameof(JumpingEventArgs.IsAllowed))),
70-
new(OpCodes.Brfalse_S, ret),
93+
new(OpCodes.Brfalse, cancel),
7194

7295
// moveDir = ev.Direction
73-
new(OpCodes.Ldloc_S, ev.LocalIndex),
96+
new(OpCodes.Ldloc, ev),
7497
new(OpCodes.Callvirt, PropertyGetter(typeof(JumpingEventArgs), nameof(JumpingEventArgs.Direction))),
7598
new(OpCodes.Stloc_0),
76-
});
99+
new(OpCodes.Br, cont),
77100

78-
newInstructions[newInstructions.Count - 1].WithLabels(ret);
101+
new CodeInstruction(OpCodes.Ldc_I4_0).WithLabels(cancel),
102+
new(OpCodes.Stloc, jumping),
103+
});
79104

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

0 commit comments

Comments
 (0)