Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 0 additions & 1 deletion Reactor/GlobalUsings.cs

This file was deleted.

58 changes: 42 additions & 16 deletions Reactor/Networking/Patches/ClientPatches.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System;
using System.Linq;
using System.Reflection;
using AmongUs.Data;
using AmongUs.InnerNet.GameDataMessages;
using BepInEx.Unity.IL2CPP.Utils;
using HarmonyLib;
using Hazel;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using InnerNet;
using Reactor.Networking.Extensions;
using Reactor.Networking.Messages;
using Reactor.Utilities;
using UnityEngine;
using IEnumerator = System.Collections.IEnumerator;

Expand All @@ -30,15 +33,22 @@ public static void Prefix(InnerNetClient __instance, ref DisconnectReasons reaso
}
}

[HarmonyPatch(typeof(InnerNetClient._HandleGameDataInner_d__165), nameof(InnerNetClient._HandleGameDataInner_d__165.MoveNext))]
[HarmonyPatch]
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;
var reader = __instance.reader;
return StateMachineWrapper<InnerNetClient>.GetStateMachineMoveNext(nameof(InnerNetClient.HandleGameDataInner))!;
}

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 (__instance.__1__state != 0) return true;
if (wrapper.State != 0) return true;

if (reader.Tag == byte.MaxValue)
{
Expand Down Expand Up @@ -162,14 +172,22 @@ IEnumerator CoKick()
}
}

[HarmonyPatch(typeof(InnerNetClient._CoSendSceneChange_d__156), nameof(InnerNetClient._CoSendSceneChange_d__156.MoveNext))]
[HarmonyPatch]
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;

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
if (!innerNetClient.AmHost &&
Expand All @@ -184,7 +202,7 @@ public static bool Prefix(InnerNetClient._CoSendSceneChange_d__156 __instance, r
writer.Write(innerNetClient.GameId);
writer.StartMessage((byte) GameDataTypes.SceneChangeFlag);
writer.WritePacked(innerNetClient.ClientId);
writer.Write(__instance.sceneName);
writer.Write(sceneName);

// PATCH - Inject ReactorHandshakeC2S
Debug("Injecting ReactorHandshakeC2S to CoSendSceneChange");
Expand All @@ -197,10 +215,10 @@ public static bool Prefix(InnerNetClient._CoSendSceneChange_d__156 __instance, r
writer.Recycle();

// 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
__instance.__1__state = -1;
wrapper.State = -1;
__result = false;
return false;
}
Expand All @@ -210,16 +228,24 @@ public static bool Prefix(InnerNetClient._CoSendSceneChange_d__156 __instance, r
}
}

[HarmonyPatch(typeof(InnerNetClient._CoHandleSpawn_d__166), nameof(InnerNetClient._CoHandleSpawn_d__166.MoveNext))]
[HarmonyPatch]
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 (!__result && !AmongUsClient.Instance.AmHost && __instance._ownerId_5__2 == AmongUsClient.Instance.ClientId)
var wrapper = new StateMachineWrapper<InnerNetClient>(__instance);
var ownerId = wrapper.GetParameter<int>("_ownerId_5__2");

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))
{
ModdedHandshakeS2C.Deserialize(reader, out var serverName, out var serverVersion, out _);
Expand All @@ -228,7 +254,7 @@ public static void Postfix(InnerNetClient._CoHandleSpawn_d__166 __instance, bool
else
{
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);
}
Expand Down
23 changes: 15 additions & 8 deletions Reactor/Networking/Patches/ReactorConnection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Reflection;
using HarmonyLib;
using InnerNet;
using Reactor.Utilities;

namespace Reactor.Networking.Patches;

Expand All @@ -20,24 +22,29 @@ public class ReactorConnection
/// </summary>
public static ReactorConnection? Instance { get; private set; }

// CoConnect(string) was inlined, so we patch the MoveNext method instead.
[HarmonyPatch]
private static class Patches
internal static class CoConnectPatch
{
// CoConnect(string) was inlined, so we patch the MoveNext method instead.
[HarmonyPatch(typeof(InnerNetClient._CoConnect_d__65), nameof(InnerNetClient._CoConnect_d__65.MoveNext))]
[HarmonyPrefix]
public static void CoConnect()
public static MethodBase TargetMethod()
{
return StateMachineWrapper<InnerNetClient>.GetStateMachineMoveNext(nameof(InnerNetClient.CoConnect))!;
}

public static void Prefix()
{
if (Instance == null)
{
Debug("New ReactorConnection created");
Instance = new ReactorConnection();
}
}
}

[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.DisconnectInternal))]
[HarmonyPostfix]
public static void DisconnectInternalPostfix()
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.DisconnectInternal))]
internal static class InnerNetClientDisconnectPatch
{
public static void Postfix()
{
Debug("ReactorConnection disconnected");
Instance = null;
Expand Down
9 changes: 8 additions & 1 deletion Reactor/Patches/Fixes/CoFindGamePatch.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
using System.Reflection;
using HarmonyLib;
using Reactor.Utilities;

namespace Reactor.Patches.Fixes;

/// <summary>
/// Fixes Game Lists not working on servers using legacy matchmaking.
/// </summary>
[HarmonyPatch(typeof(AmongUsClient_CoFindGame), nameof(AmongUsClient_CoFindGame.MoveNext))]
[HarmonyPatch]
internal static class CoFindGamePatch
{
public static MethodBase TargetMethod()
{
return StateMachineWrapper<AmongUsClient>.GetStateMachineMoveNext(nameof(AmongUsClient.CoFindGame))!;
}

public static void Prefix()
{
if (AmongUsClient.Instance.LastDisconnectReason == DisconnectReasons.Unknown)
Expand Down
64 changes: 45 additions & 19 deletions Reactor/Patches/Miscellaneous/CustomServersPatch.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Reactor.Utilities;

namespace Reactor.Patches.Miscellaneous;

[HarmonyPatch]
internal static class CustomServersPatch
{
private static bool IsCurrentServerOfficial()
Expand All @@ -16,32 +19,55 @@ private static bool IsCurrentServerOfficial()
regionInfo.Servers.All(serverInfo => serverInfo.Ip.EndsWith(Domain, StringComparison.Ordinal));
}

[HarmonyPatch(typeof(AuthManager._CoConnect_d__4), nameof(AuthManager._CoConnect_d__4.MoveNext))]
[HarmonyPatch(typeof(AuthManager._CoWaitForNonce_d__6), nameof(AuthManager._CoWaitForNonce_d__6.MoveNext))]
[HarmonyPrefix]
public static bool DisableAuthServer(ref bool __result)
[HarmonyPatch]
public static class DisableAuthServerPatch
{
if (IsCurrentServerOfficial())
public static IEnumerable<MethodBase> TargetMethods() =>
[
StateMachineWrapper<AuthManager>.GetStateMachineMoveNext(nameof(AuthManager.CoConnect))!,
StateMachineWrapper<AuthManager>.GetStateMachineMoveNext(nameof(AuthManager.CoWaitForNonce))!
];

public static bool Prefix(ref bool __result)
{
return true;
}
if (IsCurrentServerOfficial())
{
return true;
}

__result = false;
return false;
__result = false;
return false;
}
}

[HarmonyPatch(typeof(AmongUsClient._CoJoinOnlinePublicGame_d__49), nameof(AmongUsClient._CoJoinOnlinePublicGame_d__49.MoveNext))]
[HarmonyPrefix]
public static void EnableUdpMatchmaking(AmongUsClient._CoJoinOnlinePublicGame_d__49 __instance)
[HarmonyPatch]
public static class EnableUdpPatch
{
// Skip to state 1 which just calls CoJoinOnlineGameDirect
if (__instance.__1__state == 0 && !ServerManager.Instance.IsHttp)
public static MethodBase TargetMethod()
{
return StateMachineWrapper<AmongUsClient>.GetStateMachineMoveNext(nameof(AmongUsClient.CoJoinOnlinePublicGame))!;
}

public static void Prefix(Il2CppObjectBase __instance)
{
__instance.__1__state = 1;
__instance.__8__1 = new AmongUsClient.__c__DisplayClass49_0
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);
}
}
}
}
Loading