Use compiler generated wrappers for patching

This commit is contained in:
XtraCube authored and miniduikboot committed 2026-06-10 00:24:01 +02:00
1 parent a1f6164ca0
commit 5818041b27
5 files changed
+111 -46

No files matched your search

-1
View File
@@ -1 +0,0 @@
global using AmongUsClient_CoFindGame = AmongUsClient._CoFindGame_d__54;
+42 -16
View File
@@ -1,15 +1,18 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection;
using AmongUs.Data; using AmongUs.Data;
using AmongUs.InnerNet.GameDataMessages; using AmongUs.InnerNet.GameDataMessages;
using BepInEx.Unity.IL2CPP.Utils; using BepInEx.Unity.IL2CPP.Utils;
using HarmonyLib; using HarmonyLib;
using Hazel; using Hazel;
using Il2CppInterop.Runtime; using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.InteropTypes.Arrays;
using InnerNet; using InnerNet;
using Reactor.Networking.Extensions; using Reactor.Networking.Extensions;
using Reactor.Networking.Messages; using Reactor.Networking.Messages;
using Reactor.Utilities;
using UnityEngine; using UnityEngine;
using IEnumerator = System.Collections.IEnumerator; using IEnumerator = System.Collections.IEnumerator;
@@ -30,15 +33,22 @@ internal static class ClientPatches
} }
} }
[HarmonyPatch(typeof(InnerNetClient._HandleGameDataInner_d__165), nameof(InnerNetClient._HandleGameDataInner_d__165.MoveNext))] [HarmonyPatch]
public static class HandleGameDataInnerPatch public static class HandleGameDataInnerPatch
{ {
public static bool Prefix(InnerNetClient._HandleGameDataInner_d__165 __instance, ref bool __result) public static MethodBase TargetMethod()
{ {
var innerNetClient = __instance.__4__this; return StateMachineWrapper<InnerNetClient>.GetStateMachineMoveNext(nameof(InnerNetClient.HandleGameDataInner))!;
var reader = __instance.reader; }
if (__instance.__1__state != 0) return true; public static bool Prefix(Il2CppObjectBase __instance, ref bool __result)
{
var wrapper = new StateMachineWrapper<InnerNetClient>(__instance);
var innerNetClient = wrapper.Instance;
var reader = wrapper.GetParameter<MessageReader>("reader");
if (wrapper.State != 0) return true;
if (reader.Tag == byte.MaxValue) if (reader.Tag == byte.MaxValue)
{ {
@@ -162,14 +172,22 @@ internal static class ClientPatches
} }
} }
[HarmonyPatch(typeof(InnerNetClient._CoSendSceneChange_d__156), nameof(InnerNetClient._CoSendSceneChange_d__156.MoveNext))] [HarmonyPatch]
public static class CoSendSceneChangePatch public static class CoSendSceneChangePatch
{ {
public static bool Prefix(InnerNetClient._CoSendSceneChange_d__156 __instance, ref bool __result) public static MethodBase TargetMethod()
{ {
return StateMachineWrapper<InnerNetClient>.GetStateMachineMoveNext(nameof(InnerNetClient.CoSendSceneChange))!;
}
public static bool Prefix(Il2CppObjectBase __instance, ref bool __result)
{
var wrapper = new StateMachineWrapper<InnerNetClient>(__instance);
if (ReactorConnection.Instance!.Syncer != Syncer.Host) return true; if (ReactorConnection.Instance!.Syncer != Syncer.Host) return true;
var innerNetClient = __instance.__4__this; var innerNetClient = wrapper.Instance;
var sceneName = wrapper.GetParameter<string>("sceneName");
// Check for the conditions when the scene change message should be sent // Check for the conditions when the scene change message should be sent
if (!innerNetClient.AmHost && if (!innerNetClient.AmHost &&
@@ -184,7 +202,7 @@ internal static class ClientPatches
writer.Write(innerNetClient.GameId); writer.Write(innerNetClient.GameId);
writer.StartMessage((byte) GameDataTypes.SceneChangeFlag); writer.StartMessage((byte) GameDataTypes.SceneChangeFlag);
writer.WritePacked(innerNetClient.ClientId); writer.WritePacked(innerNetClient.ClientId);
writer.Write(__instance.sceneName); writer.Write(sceneName);
// PATCH - Inject ReactorHandshakeC2S // PATCH - Inject ReactorHandshakeC2S
Debug("Injecting ReactorHandshakeC2S to CoSendSceneChange"); Debug("Injecting ReactorHandshakeC2S to CoSendSceneChange");
@@ -197,10 +215,10 @@ internal static class ClientPatches
writer.Recycle(); writer.Recycle();
// Create a new coroutine to let AmongUsClient handle scene changes too // Create a new coroutine to let AmongUsClient handle scene changes too
innerNetClient.StartCoroutine(innerNetClient.CoOnPlayerChangedScene(clientData, __instance.sceneName)); innerNetClient.StartCoroutine(innerNetClient.CoOnPlayerChangedScene(clientData, sceneName));
// Cancel this coroutine // Cancel this coroutine
__instance.__1__state = -1; wrapper.State = -1;
__result = false; __result = false;
return false; return false;
} }
@@ -210,16 +228,24 @@ internal static class ClientPatches
} }
} }
[HarmonyPatch(typeof(InnerNetClient._CoHandleSpawn_d__166), nameof(InnerNetClient._CoHandleSpawn_d__166.MoveNext))] [HarmonyPatch]
public static class CoHandleSpawnPatch public static class CoHandleSpawnPatch
{ {
public static void Postfix(InnerNetClient._CoHandleSpawn_d__166 __instance, bool __result) public static MethodBase TargetMethod()
{
return StateMachineWrapper<InnerNetClient>.GetStateMachineMoveNext(nameof(InnerNetClient.CoHandleSpawn))!;
}
public static void Postfix(Il2CppObjectBase __instance, bool __result)
{ {
if (ReactorConnection.Instance!.Syncer != Syncer.Host) return; if (ReactorConnection.Instance!.Syncer != Syncer.Host) return;
if (!__result && !AmongUsClient.Instance.AmHost && __instance._ownerId_5__2 == AmongUsClient.Instance.ClientId) var wrapper = new StateMachineWrapper<InnerNetClient>(__instance);
var ownerId = wrapper.GetParameter<int>("ownerId");
if (!__result && !AmongUsClient.Instance.AmHost && ownerId == AmongUsClient.Instance.ClientId)
{ {
var reader = __instance.reader; var reader = wrapper.GetParameter<MessageReader>("reader");
if (reader.BytesRemaining >= ReactorHeader.Size && ReactorHeader.Read(reader)) if (reader.BytesRemaining >= ReactorHeader.Size && ReactorHeader.Read(reader))
{ {
ModdedHandshakeS2C.Deserialize(reader, out var serverName, out var serverVersion, out _); ModdedHandshakeS2C.Deserialize(reader, out var serverName, out var serverVersion, out _);
@@ -228,7 +254,7 @@ internal static class ClientPatches
else else
{ {
Debug("Host is not modded"); Debug("Host is not modded");
if (!Mod.Validate(ModList.Current, Array.Empty<Mod>(), out var reason)) if (!Mod.Validate(ModList.Current, [], out var reason))
{ {
AmongUsClient.Instance.DisconnectWithReason(reason); AmongUsClient.Instance.DisconnectWithReason(reason);
} }
@@ -1,5 +1,7 @@
using System.Reflection;
using HarmonyLib; using HarmonyLib;
using InnerNet; using InnerNet;
using Reactor.Utilities;
namespace Reactor.Networking.Patches; namespace Reactor.Networking.Patches;
@@ -20,13 +22,16 @@ public class ReactorConnection
/// </summary> /// </summary>
public static ReactorConnection? Instance { get; private set; } public static ReactorConnection? Instance { get; private set; }
// CoConnect(string) was inlined, so we patch the MoveNext method instead.
[HarmonyPatch] [HarmonyPatch]
private static class Patches internal static class CoConnectPatch
{ {
// CoConnect(string) was inlined, so we patch the MoveNext method instead. public static MethodBase TargetMethod()
[HarmonyPatch(typeof(InnerNetClient._CoConnect_d__65), nameof(InnerNetClient._CoConnect_d__65.MoveNext))] {
[HarmonyPrefix] return StateMachineWrapper<InnerNetClient>.GetStateMachineMoveNext(nameof(InnerNetClient.CoConnect))!;
public static void CoConnect() }
public static void Prefix()
{ {
if (Instance == null) if (Instance == null)
{ {
@@ -34,10 +39,12 @@ public class ReactorConnection
Instance = new ReactorConnection(); Instance = new ReactorConnection();
} }
} }
}
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.DisconnectInternal))] [HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.DisconnectInternal))]
[HarmonyPostfix] internal static class InnerNetClientDisconnectPatch
public static void DisconnectInternalPostfix() {
public static void Postfix()
{ {
Debug("ReactorConnection disconnected"); Debug("ReactorConnection disconnected");
Instance = null; Instance = null;
+8 -1
View File
@@ -1,13 +1,20 @@
using System.Reflection;
using HarmonyLib; using HarmonyLib;
using Reactor.Utilities;
namespace Reactor.Patches.Fixes; namespace Reactor.Patches.Fixes;
/// <summary> /// <summary>
/// Fixes Game Lists not working on servers using legacy matchmaking. /// Fixes Game Lists not working on servers using legacy matchmaking.
/// </summary> /// </summary>
[HarmonyPatch(typeof(AmongUsClient_CoFindGame), nameof(AmongUsClient_CoFindGame.MoveNext))] [HarmonyPatch]
internal static class CoFindGamePatch internal static class CoFindGamePatch
{ {
public static MethodBase TargetMethod()
{
return StateMachineWrapper<AmongUsClient>.GetStateMachineMoveNext(nameof(AmongUsClient.CoFindGame))!;
}
public static void Prefix() public static void Prefix()
{ {
if (AmongUsClient.Instance.LastDisconnectReason == DisconnectReasons.Unknown) if (AmongUsClient.Instance.LastDisconnectReason == DisconnectReasons.Unknown)
@@ -1,10 +1,13 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using HarmonyLib; using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Reactor.Utilities;
namespace Reactor.Patches.Miscellaneous; namespace Reactor.Patches.Miscellaneous;
[HarmonyPatch]
internal static class CustomServersPatch internal static class CustomServersPatch
{ {
private static bool IsCurrentServerOfficial() private static bool IsCurrentServerOfficial()
@@ -16,32 +19,55 @@ internal static class CustomServersPatch
regionInfo.Servers.All(serverInfo => serverInfo.Ip.EndsWith(Domain, StringComparison.Ordinal)); regionInfo.Servers.All(serverInfo => serverInfo.Ip.EndsWith(Domain, StringComparison.Ordinal));
} }
[HarmonyPatch(typeof(AuthManager._CoConnect_d__4), nameof(AuthManager._CoConnect_d__4.MoveNext))] [HarmonyPatch]
[HarmonyPatch(typeof(AuthManager._CoWaitForNonce_d__6), nameof(AuthManager._CoWaitForNonce_d__6.MoveNext))] public static class DisableAuthServerPatch
[HarmonyPrefix]
public static bool DisableAuthServer(ref bool __result)
{ {
if (IsCurrentServerOfficial()) public static IEnumerable<MethodBase> TargetMethods() =>
{ [
return true; StateMachineWrapper<AuthManager>.GetStateMachineMoveNext(nameof(AuthManager.CoConnect))!,
} StateMachineWrapper<AuthManager>.GetStateMachineMoveNext(nameof(AuthManager.CoWaitForNonce))!
];
__result = false; public static bool Prefix(ref bool __result)
return false; {
if (IsCurrentServerOfficial())
{
return true;
}
__result = false;
return false;
}
} }
[HarmonyPatch(typeof(AmongUsClient._CoJoinOnlinePublicGame_d__49), nameof(AmongUsClient._CoJoinOnlinePublicGame_d__49.MoveNext))] [HarmonyPatch]
[HarmonyPrefix] public static class EnableUdpPatch
public static void EnableUdpMatchmaking(AmongUsClient._CoJoinOnlinePublicGame_d__49 __instance)
{ {
// Skip to state 1 which just calls CoJoinOnlineGameDirect public static MethodBase TargetMethod()
if (__instance.__1__state == 0 && !ServerManager.Instance.IsHttp)
{ {
__instance.__1__state = 1; return StateMachineWrapper<AmongUsClient>.GetStateMachineMoveNext(nameof(AmongUsClient.CoJoinOnlinePublicGame))!;
__instance.__8__1 = new AmongUsClient.__c__DisplayClass49_0 }
public static void Prefix(Il2CppObjectBase __instance)
{
var stateMachine = new StateMachineWrapper<AmongUsClient>(__instance);
// Skip to state 1 which just calls CoJoinOnlineGameDirect
if (stateMachine.State == 0 && !ServerManager.Instance.IsHttp)
{ {
matchmakerToken = string.Empty, stateMachine.State = 1;
}; var lambdaType = stateMachine.GetParameter<Il2CppObjectBase>("__8__1").GetType();
var newDisplayClass = Activator.CreateInstance(lambdaType);
if (newDisplayClass == null)
{
throw new InvalidOperationException($"Could not create display class of type '{lambdaType}'.");
}
var displayClass = new CompilerGeneratedObjectWrapper(newDisplayClass);
displayClass.SetField("matchmakerToken", string.Empty);
stateMachine.SetParameter("__8__1", newDisplayClass);
}
} }
} }
} }