diff --git a/Reactor.Networking.Shared/ModFlags.cs b/Reactor.Networking.Shared/ModFlags.cs index b11c868..3fa3f7c 100644 --- a/Reactor.Networking.Shared/ModFlags.cs +++ b/Reactor.Networking.Shared/ModFlags.cs @@ -27,4 +27,9 @@ public enum ModFlags : ushort /// 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, } diff --git a/Reactor/Networking/ModList.cs b/Reactor/Networking/ModList.cs index 3db6e36..73d5932 100644 --- a/Reactor/Networking/ModList.cs +++ b/Reactor/Networking/ModList.cs @@ -39,7 +39,8 @@ internal static Mod GetByPluginType(Type pluginType) return _modByPluginType[pluginType]; } - internal static bool IsAnyModIsRequiredOnAllClients { get; private set; } + internal static bool IsAnyModRequiredOnAllClients { get; private set; } + internal static bool IsAnyModDisableServerAuthority { get; private set; } private static readonly Dictionary _modByNetId = new(); private static readonly Dictionary _netIdByMod = new(); @@ -115,7 +116,8 @@ private static void Refresh() netId++; } - IsAnyModIsRequiredOnAllClients = Current.Any(m => m.IsRequiredOnAllClients); + IsAnyModRequiredOnAllClients = Current.Any(m => m.IsRequiredOnAllClients); + IsAnyModDisableServerAuthority = Current.Any(m => (m.Flags & ModFlags.DisableServerAuthority) != 0); var debug = new StringBuilder("Mod list:"); foreach (var mod in Current) diff --git a/Reactor/Networking/Patches/ClientPatches.cs b/Reactor/Networking/Patches/ClientPatches.cs index d145a1d..8197333 100644 --- a/Reactor/Networking/Patches/ClientPatches.cs +++ b/Reactor/Networking/Patches/ClientPatches.cs @@ -84,7 +84,7 @@ public static bool Prefix(InnerNetClient._HandleGameDataInner_d__39 __instance, if (innerNetClient.AmHost) { - if (reactorClientData == null && ModList.IsAnyModIsRequiredOnAllClients) + if (reactorClientData == null && ModList.IsAnyModRequiredOnAllClients) { Warning("Kicking " + clientData.PlayerName + " for not having Reactor installed"); diff --git a/Reactor/Networking/Patches/HttpPatches.cs b/Reactor/Networking/Patches/HttpPatches.cs index 519962f..700a077 100644 --- a/Reactor/Networking/Patches/HttpPatches.cs +++ b/Reactor/Networking/Patches/HttpPatches.cs @@ -103,7 +103,7 @@ private static class GameStartManagerPatch public static void Postfix(GameStartManager __instance) { if (AmongUsClient.Instance.NetworkMode != NetworkModes.OnlineGame) return; - if (ModList.IsAnyModIsRequiredOnAllClients && !IsCurrentRegionModded()) + if (ModList.IsAnyModRequiredOnAllClients && !IsCurrentRegionModded()) { Warning("Vanilla region, locking public toggle"); diff --git a/Reactor/Patches/Miscellaneous/DisableServerAuthorityPatch.cs b/Reactor/Patches/Miscellaneous/DisableServerAuthorityPatch.cs new file mode 100644 index 0000000..7d7b9d4 --- /dev/null +++ b/Reactor/Patches/Miscellaneous/DisableServerAuthorityPatch.cs @@ -0,0 +1,41 @@ +using HarmonyLib; +using Reactor.Networking; + +namespace Reactor.Patches.Miscellaneous; + +[HarmonyPatch] +internal static class DisableServerAuthorityPatch +{ + private const int DisableServerAuthorityFlag = 25; + + public static bool Enabled => ModList.IsAnyModDisableServerAuthority || ReactorConfig.ForceDisableServerAuthority.Value; + + [HarmonyPatch(typeof(Constants), nameof(Constants.GetBroadcastVersion))] + [HarmonyPostfix] + public static void GetBroadcastVersionPatch(ref int __result) + { + if (!Enabled) return; + if (AmongUsClient.Instance.NetworkMode != NetworkModes.OnlineGame) return; + + Debug("Sending the DisableServerAuthority flag"); + + var revision = __result % 50; + if (revision < DisableServerAuthorityFlag) + { + __result += DisableServerAuthorityFlag; + } + } + + [HarmonyPatch(typeof(Constants), nameof(Constants.IsVersionModded))] + [HarmonyPrefix] + public static bool IsVersionModdedPatch(ref bool __result) + { + if (Enabled) + { + __result = true; + return false; + } + + return true; + } +} diff --git a/Reactor/ReactorConfig.cs b/Reactor/ReactorConfig.cs index 04e1036..922535b 100644 --- a/Reactor/ReactorConfig.cs +++ b/Reactor/ReactorConfig.cs @@ -6,7 +6,10 @@ internal static class ReactorConfig { public const string FeaturesSection = "Features"; + public static ConfigEntry ForceDisableServerAuthority { get; private set; } = null!; + public static void Bind(ConfigFile config) { + ForceDisableServerAuthority = config.Bind(FeaturesSection, nameof(ForceDisableServerAuthority), false, "Enables the DisableServerAuthority flag even when no mods declare it"); } }