diff --git a/Main.cs b/Main.cs index 95664c25d..abbf4e48f 100644 --- a/Main.cs +++ b/Main.cs @@ -40,7 +40,7 @@ public class Main : BasePlugin { private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d"; private const string DebugKeySalt = "59687b"; - private const string PluginGuid = "com.gurge44.endlesshostroles"; + public const string PluginGuid = "com.gurge44.endlesshostroles"; public const string PluginVersion = "7.4.0"; public const string PluginDisplayVersion = "7.4.0"; public const bool TestBuild = false; diff --git a/Patches/HandshakePatch.cs b/Patches/HandshakePatch.cs new file mode 100644 index 000000000..4c43fdd69 --- /dev/null +++ b/Patches/HandshakePatch.cs @@ -0,0 +1,100 @@ +using System; +using HarmonyLib; +using Hazel; +using Il2CppInterop.Runtime.InteropTypes.Arrays; +using InnerNet; + +namespace EHR.Patches; + +// This is taken from Reactor modded handshake. +// We do not want to pull in Reactor as a dependency though. + +/// +/// Represents flags of the mod. +/// +[Flags] +public enum ModFlags : ushort +{ + /// + /// No flags. + /// + None = 0, + + /// + /// Requires all clients in a lobby to have the mod. + /// + RequireOnAllClients = 1 << 0, + + /// + /// Requires the server to have a plugin that handles the mod. + /// + RequireOnServer = 1 << 1, + + /// + /// Requires the host of the lobby to have the mod. + /// + RequireOnHost = 1 << 2, + + /// + /// Notifies the game server that the host has authority over game logic. + /// + DisableServerAuthority = 1 << 3, +} + + +/// +/// Version of the Reactor.Networking protocol format. +/// +public enum ReactorProtocolVersion : byte +{ + /// + /// First public Reactor Protocol version. + /// + V2 = 1, + + /// + /// Version introducing vanilla server support, syncer concept and registries. + /// + V3 = 2, + + /// + /// Latest version. + /// + Latest = V3, +} + +[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.GetConnectionData))] +public static class HandshakePatch +{ + private const ulong MAGIC = 0x72656163746f72; // "reactor" in ascii, 7 bytes + + public static void Prefix(ref bool useDtlsLayout) + { + // Due to reasons currently unknown, the useDtlsLayout parameter sometimes doesn't reflect whether DTLS + // is actually supposed to be enabled. This causes a bad handshake message and a quick disconnect. + // The field on AmongUsClient appears to be more reliable, so override this parameter with what it is supposed to be. + useDtlsLayout = AmongUsClient.Instance.useDtls; + } + + public static void Postfix(ref Il2CppStructArray __result) + { + var handshake = new MessageWriter(1000); + + // Original data + handshake.Write(__result); + + // Reactor Header + var version = (byte) ReactorProtocolVersion.Latest; + var value = (MAGIC << 8) | version; + handshake.Write(value); + + // ModdedHandshakeC2S + handshake.WritePacked(1); + handshake.Write(Main.PluginGuid); + handshake.Write(Main.PluginVersion); + handshake.Write((ushort) (ModFlags.RequireOnHost | ModFlags.RequireOnAllClients)); + + __result = handshake.ToByteArray(true); + handshake.Recycle(); + } +} \ No newline at end of file