Skip to content
Open
Show file tree
Hide file tree
Changes from all 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