From 1c0f8f93d92614c461eceb202bb5d85b6e6de4d7 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Tue, 21 Oct 2025 09:35:29 +0200 Subject: [PATCH] improved improved android support (but actually keeping all features instead of deleting them from pc also) --- EHR.csproj | 2 +- Main.cs | 2 + Modules/AutoHaunt.cs | 2 +- Modules/ChatBubbleShower.cs | 2 +- Modules/Debugger.cs | 9 ++++- Modules/EAC.cs | 13 +++++- Modules/ErrorText.cs | 7 ++++ Modules/ExtendedPlayerControl.cs | 3 +- Modules/Extensions/ObjectHelper.cs | 8 ++++ Modules/FixedUpdateCaller.cs | 19 +++++---- Modules/GuessManager.cs | 1 + Modules/LateTask.cs | 64 +++++++----------------------- Modules/Prompt.cs | 1 + Modules/RPC.cs | 4 +- Modules/Utils.cs | 25 ++++++------ Modules/Zoom.cs | 4 +- Patches/AnnouncementPatch.cs | 4 +- Patches/ChatCommandPatch.cs | 7 ++-- Patches/ChatControlPatch.cs | 4 +- Patches/ControlPatch.cs | 13 ++++-- Patches/CredentialsPatch.cs | 9 ++--- Patches/GameOptionsMenuPatch.cs | 18 ++++----- Patches/GameStartManagerPatch.cs | 30 +++++++------- Patches/IntroPatch.cs | 18 +++++---- Patches/MainMenuManagerPatch.cs | 5 ++- Patches/OnGameStartedPatch.cs | 6 +-- Patches/PhantomRolePatch.cs | 4 +- Patches/PlayerControlPatch.cs | 2 +- Patches/PlayerJoinAndLeftPatch.cs | 2 +- Patches/SabotageButtonPatch.cs | 2 +- Patches/TextBoxPatch.cs | 4 +- 31 files changed, 157 insertions(+), 137 deletions(-) diff --git a/EHR.csproj b/EHR.csproj index 61682c366..080add53a 100644 --- a/EHR.csproj +++ b/EHR.csproj @@ -51,7 +51,7 @@ - + diff --git a/Main.cs b/Main.cs index 9ac799e3f..0147aad2f 100644 --- a/Main.cs +++ b/Main.cs @@ -861,7 +861,9 @@ public class Main : BasePlugin { CustomLogger.ClearLog(); +#if !ANDROID StartCoroutine(ModNewsFetcher.FetchNews()); +#endif try { DevManager.StartFetchingTags(); } catch (Exception e) { Utils.ThrowException(e); } diff --git a/Modules/AutoHaunt.cs b/Modules/AutoHaunt.cs index 2f8db131f..14256791a 100644 --- a/Modules/AutoHaunt.cs +++ b/Modules/AutoHaunt.cs @@ -39,7 +39,7 @@ public static class AutoHaunt { while (Main.AutoHaunt.Value) { - if (GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks && !PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Data.RoleType is RoleTypes.CrewmateGhost or RoleTypes.ImpostorGhost && !ExtendedPlayerControl.TempExiled.Contains(PlayerControl.LocalPlayer.PlayerId)) + if (HudManager.InstanceExists && GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks && !PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Data.RoleType is RoleTypes.CrewmateGhost or RoleTypes.ImpostorGhost && !ExtendedPlayerControl.TempExiled.Contains(PlayerControl.LocalPlayer.PlayerId)) { if (HauntMenuMinigameStartPatch.Instance != null) { diff --git a/Modules/ChatBubbleShower.cs b/Modules/ChatBubbleShower.cs index 34960a044..815d576db 100644 --- a/Modules/ChatBubbleShower.cs +++ b/Modules/ChatBubbleShower.cs @@ -17,7 +17,7 @@ public static class ChatBubbleShower { try { - if (Queue.Count == 0 || ExileController.Instance) return; + if (Queue.Count == 0 || ExileController.Instance || !HudManager.InstanceExists) return; long now = Utils.TimeStamp; int wait = GameStates.IsInTask ? 8 : 4; diff --git a/Modules/Debugger.cs b/Modules/Debugger.cs index 76c43da2a..c99a68f5f 100644 --- a/Modules/Debugger.cs +++ b/Modules/Debugger.cs @@ -147,7 +147,11 @@ internal static class Logger public class CustomLogger { - private static readonly string LOGFilePath = $"{Main.DataPath}/BepInEx/log.html"; +#if ANDROID + public static readonly string LOGFilePath = $"{Main.DataPath}/EHR/log.html"; +#else + public static readonly string LOGFilePath = $"{Main.DataPath}/BepInEx/log.html"; +#endif private const string HtmlHeader = """ @@ -188,6 +192,9 @@ public class CustomLogger private CustomLogger() { +#if ANDROID + Directory.CreateDirectory(Path.GetDirectoryName(LOGFilePath) ?? throw new InvalidOperationException()); +#endif if (!File.Exists(LOGFilePath)) File.WriteAllText(LOGFilePath, HtmlHeader); else if (Options.IsLoaded && new FileInfo(LOGFilePath).Length > 4 * 1024 * 1024) // 4 MB { diff --git a/Modules/EAC.cs b/Modules/EAC.cs index b762c23af..6e90cb7f9 100644 --- a/Modules/EAC.cs +++ b/Modules/EAC.cs @@ -1,8 +1,10 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using AmongUs.GameOptions; using AmongUs.QuickChat; +using BepInEx.Unity.IL2CPP.Utils.Collections; using HarmonyLib; using Hazel; using InnerNet; @@ -1222,11 +1224,19 @@ internal enum GameDataTag : byte XboxDeclareXuid = 207 } +#if !ANDROID [HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.HandleGameDataInner))] internal class GameDataHandlerPatch { - public static bool Prefix(InnerNetClient __instance, MessageReader reader, int msgNum) + private static IEnumerator EmptyCoroutine() { + yield break; + } + + public static bool Prefix(InnerNetClient __instance, MessageReader reader, int msgNum, ref Il2CppSystem.Collections.IEnumerator __result) + { + __result = EmptyCoroutine().WrapToIl2Cpp(); // fix errors if we return false + var tag = (GameDataTag)reader.Tag; switch (tag) @@ -1365,6 +1375,7 @@ internal static class StartGameHostPatchEAC if (ShipStatus.Instance != null) IsStartingAsHost = false; } } +#endif //[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.FixedUpdate))] internal static class CheckInvalidMovementPatch diff --git a/Modules/ErrorText.cs b/Modules/ErrorText.cs index c394880f2..032948785 100644 --- a/Modules/ErrorText.cs +++ b/Modules/ErrorText.cs @@ -172,6 +172,13 @@ public class ErrorText : MonoBehaviour try { + if (!HudManager.InstanceExists) + { + _camera = Camera.main; + Logger.Error("Hudmanager instance not found", "ErrorText"); + return; + } + _camera1 = HudManager.Instance.PlayerCam.GetComponent(); _camera = Camera.main; } diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index ad6587def..a2bb652c9 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -2034,6 +2034,7 @@ internal static class ExtendedPlayerControl public static void NoCheckStartMeeting(this PlayerControl reporter, NetworkedPlayerInfo target, bool force = false) { + if (!HudManager.InstanceExists) return; if (Options.DisableMeeting.GetBool() && !force) return; ReportDeadBodyPatch.AfterReportTasks(reporter, target); @@ -2281,7 +2282,7 @@ internal static class ExtendedPlayerControl if (Main.UserData.TryGetValue(pc.FriendCode, out Options.UserData userData) && !string.IsNullOrWhiteSpace(userData.Tag) && userData.Tag.Length > 0) return true; ClientData client = pc.GetClient(); - return client != null && FastDestroyableSingleton.Instance.IsPlayerFriend(client.ProductUserId); + return client != null && FriendsListManager.InstanceExists && FastDestroyableSingleton.Instance.IsPlayerFriend(client.ProductUserId); } public static bool IsBeginner(this PlayerControl pc) diff --git a/Modules/Extensions/ObjectHelper.cs b/Modules/Extensions/ObjectHelper.cs index 6116a0128..f24c7249d 100644 --- a/Modules/Extensions/ObjectHelper.cs +++ b/Modules/Extensions/ObjectHelper.cs @@ -66,9 +66,13 @@ public static unsafe class FastDestroyableSingleton where T : MonoBehaviour { get { +#if ANDROID + return DestroyableSingleton.Instance; +#else IntPtr objectPointer; IL2CPP.il2cpp_field_static_get_value(FieldPtr, &objectPointer); return objectPointer == IntPtr.Zero ? DestroyableSingleton.Instance : CreateObject(objectPointer); +#endif } } } @@ -79,7 +83,11 @@ public static class Il2CppCastHelper public static T CastFast(this Il2CppObjectBase obj) where T : Il2CppObjectBase { if (obj is T casted) return casted; +#if ANDROID + return obj.Cast(); +#else return obj.Pointer.CastFast(); +#endif } private static T CastFast(this IntPtr ptr) where T : Il2CppObjectBase diff --git a/Modules/FixedUpdateCaller.cs b/Modules/FixedUpdateCaller.cs index da99bc6a2..3d19e726d 100644 --- a/Modules/FixedUpdateCaller.cs +++ b/Modules/FixedUpdateCaller.cs @@ -61,13 +61,16 @@ public static class FixedUpdateCaller GameStartManagerPatch.GameStartManagerUpdatePatch.Postfix_ManualCall(gameStartManager); #endif - HudManager hudManager = FastDestroyableSingleton.Instance; - - if (hudManager) + if (HudManager.InstanceExists) { - HudManagerPatch.Postfix(hudManager); - Zoom.Postfix(); - HudSpritePatch.Postfix(hudManager); + HudManager hudManager = FastDestroyableSingleton.Instance; + + if (hudManager) + { + HudManagerPatch.Postfix(hudManager); + Zoom.Postfix(); + HudSpritePatch.Postfix(hudManager); + } } try @@ -84,7 +87,7 @@ public static class FixedUpdateCaller try { - if (GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks && PlayerControl.LocalPlayer.CanUseKillButton()) + if (HudManager.InstanceExists && GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks && PlayerControl.LocalPlayer.CanUseKillButton()) { Predicate predicate = AmongUsClient.Instance.AmHost ? Options.CurrentGameMode switch @@ -99,7 +102,7 @@ public static class FixedUpdateCaller List players = PlayerControl.LocalPlayer.GetPlayersInAbilityRangeSorted(predicate); PlayerControl closest = players.Count == 0 ? null : players[0]; - KillButton killButton = hudManager.KillButton; + KillButton killButton = FastDestroyableSingleton.Instance.KillButton; if (killButton.currentTarget && killButton.currentTarget != closest) killButton.currentTarget.ToggleHighlight(false, RoleTeamTypes.Impostor); diff --git a/Modules/GuessManager.cs b/Modules/GuessManager.cs index 34d1adb12..93f621c46 100644 --- a/Modules/GuessManager.cs +++ b/Modules/GuessManager.cs @@ -611,6 +611,7 @@ public static class GuessManager private static void ProcessGuess(PlayerControl pc, MeetingHud meetingHud) { + if (!HudManager.InstanceExists) return; HudManager hudManager = FastDestroyableSingleton.Instance; SoundManager.Instance.PlaySound(pc.KillSfx, false, 0.8f); if (!Options.DisableKillAnimationOnGuess.GetBool()) hudManager.KillOverlay.ShowKillAnimation(pc.Data, pc.Data); diff --git a/Modules/LateTask.cs b/Modules/LateTask.cs index 86d2677f9..774c5558b 100644 --- a/Modules/LateTask.cs +++ b/Modules/LateTask.cs @@ -1,42 +1,12 @@ using System; -using System.Collections.Generic; +using System.Collections; using System.Runtime.CompilerServices; +using UnityEngine; namespace EHR; -internal class LateTask +internal static class LateTask { - private static readonly List Tasks = []; - private readonly Action Action; - private readonly string CallerData; - private readonly bool LOG; - private readonly string Name; - private float Timer; - - private LateTask(Action action, float time, string name, bool log, string callerData) - { - Action = action; - Timer = time; - Name = name; - LOG = log; - CallerData = callerData; - Tasks.Add(this); - if (log && name is not "" and not "No Name Task") Logger.Info($"\"{name}\" is created (completes in {time:N2})", "LateTask"); - } - - private bool Run(float deltaTime) - { - Timer -= deltaTime; - - if (Timer <= 0) - { - Action(); - return true; - } - - return false; - } - /// /// Creates a task that will be automatically completed after the specified amount of time /// @@ -46,28 +16,22 @@ internal class LateTask /// Whether to send log of the creation and completion of the Late Task public static void New(Action action, float time, string name = "No Name Task", bool log = true, [CallerFilePath] string path = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0) { - _ = new LateTask(action, time, name, log, $"created at {path.Split('\\')[^1]}, by member {member}, at line {line}"); - } + if (log && name is not "" and not "No Name Task") Logger.Info($"\"{name}\" is created (completes in {time:N2})", "LateTask"); + Main.Instance.StartCoroutine(CoLateTask()); + return; - public static void Update(float deltaTime) - { - foreach (LateTask task in Tasks.ToArray()) + IEnumerator CoLateTask() { + yield return new WaitForSeconds(time); + try { - if (task.Run(deltaTime)) - { - if (task.Name is not "" and not "No Name Task" && task.LOG) - Logger.Info($"\"{task.Name}\" is finished", "LateTask"); - - Tasks.Remove(task); - } - } - catch (Exception ex) - { - Logger.Error($"{ex.GetType()}: {ex.Message} in \"{task.Name}\" ({task.CallerData})\n\n{ex.StackTrace}", "LateTask.Error", false, multiLine: true); - Tasks.Remove(task); + action(); + + if (name is not "" and not "No Name Task" && log) + Logger.Info($"\"{name}\" is finished", "LateTask"); } + catch (Exception ex) { Logger.Error($"{ex.GetType()}: {ex.Message}\n in \"{name}\"\n (created at {path.Split('\\')[^1]}, by member {member}, at line {line})\n {ex.StackTrace}".Replace("\r\n", "\n"), "LateTask.Error", false, multiLine: true); } } } } \ No newline at end of file diff --git a/Modules/Prompt.cs b/Modules/Prompt.cs index 891eff080..cc401b5b5 100644 --- a/Modules/Prompt.cs +++ b/Modules/Prompt.cs @@ -17,6 +17,7 @@ public static class Prompt { try { + if (!HudManager.InstanceExists) return; HudManager hud = FastDestroyableSingleton.Instance; if (CurrentQuestion != string.Empty || !hud) diff --git a/Modules/RPC.cs b/Modules/RPC.cs index 622510160..e7f04d9e4 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -1520,10 +1520,10 @@ internal static class RPC case Sounds.KillSound: SoundManager.Instance.PlaySound(PlayerControl.LocalPlayer.KillSfx, false); break; - case Sounds.TaskComplete: + case Sounds.TaskComplete when HudManager.InstanceExists: SoundManager.Instance.PlaySound(FastDestroyableSingleton.Instance.TaskCompleteSound, false); break; - case Sounds.TaskUpdateSound: + case Sounds.TaskUpdateSound when HudManager.InstanceExists: SoundManager.Instance.PlaySound(FastDestroyableSingleton.Instance.TaskUpdateSound, false); break; case Sounds.ImpTransform: diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 708ddf7d7..ac5f8d000 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -12,6 +12,7 @@ using System.Text.RegularExpressions; using AmongUs.Data; using AmongUs.GameOptions; using AmongUs.InnerNet.GameDataMessages; +using BepInEx; using EHR.AddOns.Common; using EHR.AddOns.Crewmate; using EHR.AddOns.GhostRoles; @@ -1853,10 +1854,13 @@ public static class Utils if (sendTo != byte.MaxValue && receiver.IsLocalPlayer()) { - string name = sender.Data.PlayerName; - sender.SetName(title); - FastDestroyableSingleton.Instance.Chat.AddChat(sender, text); - sender.SetName(name); + if (HudManager.InstanceExists) + { + string name = sender.Data.PlayerName; + sender.SetName(title); + FastDestroyableSingleton.Instance.Chat.AddChat(sender, text); + sender.SetName(name); + } try { @@ -2060,7 +2064,7 @@ public static class Utils .Write(text) .EndRpc(); - if (sendTo == byte.MaxValue) + if (sendTo == byte.MaxValue && HudManager.InstanceExists) { string name = sender.Data.PlayerName; sender.SetName(title); @@ -3754,17 +3758,13 @@ public static class Utils if (!Directory.Exists(f)) Directory.CreateDirectory(f); var filename = $"{f}/EHR-v{Main.PluginVersion}-LOG"; -#if ANDROID - var directory = Main.DataPath; -#else - string directory = Environment.CurrentDirectory; -#endif - FileInfo[] files = [new($"{directory}/BepInEx/LogOutput.log"), new($"{directory}/BepInEx/log.html")]; + + FileInfo[] files = [new(Path.Combine(Paths.BepInExRootPath, "LogOutput.log")), new(CustomLogger.LOGFilePath)]; files.Do(x => x.CopyTo($"{filename}{x.Extension}")); if (!open) return; - if (PlayerControl.LocalPlayer != null) + if (PlayerControl.LocalPlayer != null && HudManager.InstanceExists) FastDestroyableSingleton.Instance?.Chat?.AddChat(PlayerControl.LocalPlayer, string.Format(GetString("Message.DumpfileSaved"), "EHR" + filename.Split("EHR")[1])); #if !ANDROID @@ -4006,6 +4006,7 @@ public static class Utils public static void FlashColor(Color color, float duration = 1f) { + if (!HudManager.InstanceExists) return; HudManager hud = FastDestroyableSingleton.Instance; if (hud.FullScreen == null) return; diff --git a/Modules/Zoom.cs b/Modules/Zoom.cs index 4b64873ff..29db6b89a 100644 --- a/Modules/Zoom.cs +++ b/Modules/Zoom.cs @@ -52,7 +52,7 @@ public static class Zoom public static void SetZoomSize(bool times = false, bool reset = false) { - if (Camera.main == null) return; + if (Camera.main == null || !HudManager.InstanceExists) return; var size = 1.5f; if (!times) size = 1 / size; @@ -81,7 +81,7 @@ public static class Zoom public static void OnFixedUpdate() { - if (Camera.main == null) return; + if (Camera.main == null || !HudManager.InstanceExists) return; FastDestroyableSingleton.Instance?.ShadowQuad?.gameObject.SetActive(Mathf.Approximately(Camera.main.orthographicSize, 3.0f) && PlayerControl.LocalPlayer.IsAlive()); } diff --git a/Patches/AnnouncementPatch.cs b/Patches/AnnouncementPatch.cs index 3900ef56c..f1971e79a 100644 --- a/Patches/AnnouncementPatch.cs +++ b/Patches/AnnouncementPatch.cs @@ -12,6 +12,7 @@ using UnityEngine.Networking; namespace EHR; +#if !ANDROID // ReSharper disable once ClassNeverInstantiated.Global public class ModNews { @@ -99,4 +100,5 @@ public static class ModNewsHistory for (var i = 0; i < finalAllNews.Count; i++) aRange[i] = finalAllNews[i]; } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index 1f2f2e85b..71d70969a 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -2833,6 +2833,7 @@ internal static class ChatCommands break; default: + if (!HudManager.InstanceExists) break; FastDestroyableSingleton.Instance.Chat.AddChat(player, "crew | imp"); break; } @@ -3358,7 +3359,7 @@ internal static class ChatCommands private static void VersionCommand(PlayerControl player, string text, string[] args) { string versionText = Main.PlayerVersion.OrderBy(pair => pair.Key).Aggregate(string.Empty, (current, kvp) => current + $"{kvp.Key}: ({Main.AllPlayerNames[kvp.Key]}) {kvp.Value.forkId}/{kvp.Value.version}({kvp.Value.tag})\n"); - if (versionText != string.Empty) FastDestroyableSingleton.Instance.Chat.AddChat(player, (player.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + versionText); + if (versionText != string.Empty && HudManager.InstanceExists) FastDestroyableSingleton.Instance.Chat.AddChat(player, (player.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + versionText); } private static void LTCommand(PlayerControl player, string text, string[] args) @@ -3681,7 +3682,7 @@ internal static class ChatUpdatePatch string name = player.Data.PlayerName; - if (clientId == -1) + if (clientId == -1 && HudManager.InstanceExists) { player.SetName(title); FastDestroyableSingleton.Instance.Chat.AddChat(player, msg); @@ -3753,7 +3754,7 @@ internal static class RpcSendChatPatch int return_count = PlayerControl.LocalPlayer.name.Count(x => x == '\n'); chatText = new StringBuilder(chatText).Insert(0, "\n", return_count).ToString(); - if (AmongUsClient.Instance.AmClient && FastDestroyableSingleton.Instance) FastDestroyableSingleton.Instance.Chat.AddChat(__instance, chatText); + if (AmongUsClient.Instance.AmClient && HudManager.InstanceExists) FastDestroyableSingleton.Instance.Chat.AddChat(__instance, chatText); if (chatText.Contains("who", StringComparison.OrdinalIgnoreCase)) FastDestroyableSingleton.Instance.SendWho(); diff --git a/Patches/ChatControlPatch.cs b/Patches/ChatControlPatch.cs index 3493e59f8..26c6f2b75 100644 --- a/Patches/ChatControlPatch.cs +++ b/Patches/ChatControlPatch.cs @@ -219,7 +219,7 @@ public static class ChatManager public static void SendPreviousMessagesToAll() { - if (!AmongUsClient.Instance.AmHost) return; + if (!AmongUsClient.Instance.AmHost || !HudManager.InstanceExists) return; Logger.Info(" Sending Previous Messages To Everyone", "ChatManager"); @@ -284,7 +284,7 @@ public static class ChatManager { bool toEveryone = receiver == null; bool toLocalPlayer = !toEveryone && receiver.IsLocalPlayer(); - if (toLocalPlayer || toEveryone) FastDestroyableSingleton.Instance.Chat.AddChat(player, "."); + if (HudManager.InstanceExists && (toLocalPlayer || toEveryone)) FastDestroyableSingleton.Instance.Chat.AddChat(player, "."); if (toLocalPlayer) return; MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)RpcCalls.SendChat, SendOption.Reliable, toEveryone ? -1 : receiver.OwnerId); writer.Write("."); diff --git a/Patches/ControlPatch.cs b/Patches/ControlPatch.cs index 4b2a57783..0f9cf19f2 100644 --- a/Patches/ControlPatch.cs +++ b/Patches/ControlPatch.cs @@ -10,6 +10,7 @@ using static EHR.Translator; namespace EHR; +#if !ANDROID [HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))] internal static class ControllerManagerUpdatePatch { @@ -133,7 +134,7 @@ internal static class ControllerManagerUpdatePatch Utils.ShowActiveSettings(); } - if (GameStates.IsLobby && KeysDown(KeyCode.Delete, KeyCode.LeftControl, KeyCode.LeftShift) && !IsResetting) + if (GameStates.IsLobby && HudManager.InstanceExists && KeysDown(KeyCode.Delete, KeyCode.LeftControl, KeyCode.LeftShift) && !IsResetting) { Prompt.Show(GetString("Promt.ResetAllOptions"), ResetAllOptions, () => { }); @@ -193,6 +194,7 @@ internal static class ControllerManagerUpdatePatch if (!Options.NoGameEnd.GetBool()) return; +#endif #if DEBUG if (KeysDown(KeyCode.Return, KeyCode.F, KeyCode.LeftShift)) { @@ -200,7 +202,7 @@ internal static class ControllerManagerUpdatePatch if (Constants.ShouldPlaySfx()) RPC.PlaySound(PlayerControl.LocalPlayer.PlayerId, Sounds.KillSound); } - if (KeysDown(KeyCode.Return, KeyCode.G, KeyCode.LeftShift) && GameStates.IsInGame) + if (KeysDown(KeyCode.Return, KeyCode.G, KeyCode.LeftShift) && GameStates.IsInGame && HudManager.InstanceExists) { HudManager.Instance.StartCoroutine(HudManager.Instance.CoFadeFullScreen(Color.clear, Color.black)); HudManager.Instance.StartCoroutine(FastDestroyableSingleton.Instance.CoShowIntro()); @@ -233,7 +235,7 @@ internal static class ControllerManagerUpdatePatch Logger.SendInGame(GetString("SyncCustomSettingsRPC")); } - if (Input.GetKeyDown(KeyCode.Equals) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) + if (Input.GetKeyDown(KeyCode.Equals) && !GameStates.IsMeeting && HudManager.InstanceExists && !HudManager.Instance.Chat.IsOpenOrOpening) { Main.VisibleTasksCount = !Main.VisibleTasksCount; FastDestroyableSingleton.Instance.Notifier.AddDisconnectMessage($"VisibleTaskCount changed to {Main.VisibleTasksCount}."); @@ -277,6 +279,7 @@ internal static class ControllerManagerUpdatePatch VentilationSystem.Update(VentilationSystem.Operation.StartCleaning, 0); #endif +#if !ANDROID } catch { } } @@ -321,11 +324,13 @@ internal static class HandleHUDPatch public static void Postfix(Player player) { if (player.GetButtonDown(8) && // 8: Kill button actionId + HudManager.InstanceExists && PlayerControl.LocalPlayer.Data?.Role?.IsImpostor == false && PlayerControl.LocalPlayer.CanUseKillButton()) FastDestroyableSingleton.Instance.KillButton.DoClick(); if (player.GetButtonDown(50) && // 50: Impostor vent button actionId + HudManager.InstanceExists && PlayerControl.LocalPlayer.Data?.Role?.IsImpostor == false && PlayerControl.LocalPlayer.CanUseImpostorVentButton()) FastDestroyableSingleton.Instance.ImpostorVentButton.DoClick(); @@ -448,5 +453,5 @@ public static class InGameRoleInfoMenu Menu?.SetActive(false); } } - } +#endif \ No newline at end of file diff --git a/Patches/CredentialsPatch.cs b/Patches/CredentialsPatch.cs index 2f4473f72..9bc7c2710 100644 --- a/Patches/CredentialsPatch.cs +++ b/Patches/CredentialsPatch.cs @@ -199,7 +199,7 @@ internal static class FriendsListUIOpenPatch __instance.currentSceneName = activeScene.name; __instance.UpdateFriendCodeUI(); - if ((DestroyableSingleton.InstanceExists && FastDestroyableSingleton.Instance != null && FastDestroyableSingleton.Instance.Chat != null && FastDestroyableSingleton.Instance.Chat.IsOpenOrOpening) || ShipStatus.Instance != null) + if ((HudManager.InstanceExists && FastDestroyableSingleton.Instance != null && FastDestroyableSingleton.Instance.Chat != null && FastDestroyableSingleton.Instance.Chat.IsOpenOrOpening) || ShipStatus.Instance != null) return false; __instance.friendBars = new(); @@ -406,7 +406,6 @@ internal static class ModManagerLateUpdatePatch { __instance.ShowModStamp(); - LateTask.Update(Time.deltaTime); ChatBubbleShower.Update(); if (LobbySharingAPI.LastRoomCode != string.Empty && Utils.TimeStamp - LobbySharingAPI.LastRequestTimeStamp > 60) @@ -417,7 +416,7 @@ internal static class ModManagerLateUpdatePatch public static void Postfix(ModManager __instance) { - __instance.localCamera = !DestroyableSingleton.InstanceExists + __instance.localCamera = !HudManager.InstanceExists ? Camera.main : FastDestroyableSingleton.Instance.GetComponentInChildren(); @@ -439,7 +438,7 @@ internal static class OptionsMenuBehaviourOpenPatch { try { - if (DestroyableSingleton.InstanceExists && !FastDestroyableSingleton.Instance.SettingsButton.activeSelf) return false; + if (HudManager.InstanceExists && !FastDestroyableSingleton.Instance.SettingsButton.activeSelf) return false; } catch { } @@ -459,7 +458,7 @@ internal static class OptionsMenuBehaviourOpenPatch __instance.UpdateButtons(); __instance.gameObject.SetActive(true); __instance.MenuButton?.SelectButton(true); - if (DestroyableSingleton.InstanceExists) ConsoleJoystick.SetMode_MenuAdditive(); + if (HudManager.InstanceExists) ConsoleJoystick.SetMode_MenuAdditive(); if (!__instance.grabbedControllerButtons) { diff --git a/Patches/GameOptionsMenuPatch.cs b/Patches/GameOptionsMenuPatch.cs index 3b651e825..71071a483 100644 --- a/Patches/GameOptionsMenuPatch.cs +++ b/Patches/GameOptionsMenuPatch.cs @@ -1,12 +1,12 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Linq; using BepInEx.Unity.IL2CPP.Utils.Collections; using EHR.AddOns.GhostRoles; using EHR.Modules; using EHR.Patches; using HarmonyLib; -using Il2CppSystem.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.Events; @@ -937,7 +937,7 @@ public static class StringOptionPatch [HarmonyPatch(typeof(GameSettingMenu))] public static class GameSettingMenuPatch { - public static System.Collections.Generic.List GMButtons = []; + public static List GMButtons = []; private static readonly Vector3 ButtonPositionLeft = new(-3.9f, -0.55f, 0f); private static readonly Vector3 ButtonPositionRight = new(-2.4f, -0.55f, 0f); @@ -948,15 +948,15 @@ public static class GameSettingMenuPatch private static GameOptionsMenu TemplateGameOptionsMenu; private static PassiveButton TemplateGameSettingsButton; - private static System.Collections.Generic.Dictionary ModSettingsButtons = []; - private static System.Collections.Generic.Dictionary ModSettingsTabs = []; + private static Dictionary ModSettingsButtons = []; + private static Dictionary ModSettingsTabs = []; public static NumberOption PresetBehaviour; public static long LastPresetChange; public static FreeChatInputField InputField; - private static System.Collections.Generic.List HiddenBySearch = []; + private static List HiddenBySearch = []; public static Action SearchForOptionsAction; private static int NumImpsOnOpen = 1; @@ -1196,7 +1196,7 @@ public static class GameSettingMenuPatch } - FreeChatInputField freeChatField = DestroyableSingleton.Instance.freeChatField; // FastDestroyableSingleton DOES NOT WORK HERE!!!! IF YOU USE THAT, IT BREAKS THE ENTIRE SETTINGS MENU + FreeChatInputField freeChatField = FastDestroyableSingleton.Instance.Chat.freeChatField; // FastDestroyableSingleton DOES NOT WORK HERE!!!! IF YOU USE THAT, IT BREAKS THE ENTIRE SETTINGS MENU FreeChatInputField field = Object.Instantiate(freeChatField, parentLeftPanel.parent); field.transform.localScale = new(0.3f, 0.59f, 1); field.transform.localPosition = new(-0.7f, -2.5f, -5f); @@ -1253,9 +1253,9 @@ public static class GameSettingMenuPatch string text = textField.textArea.text.Trim().ToLower(); var modTab = (TabGroup)(ModGameOptionsMenu.TabIndex - 3); OptionItem[] optionItems = Options.GroupedOptions[modTab]; - System.Collections.Generic.List result = optionItems.Where(x => x.Parent == null && !x.IsCurrentlyHidden() && !Translator.GetString($"{x.Name}").Contains(text, StringComparison.OrdinalIgnoreCase)).ToList(); + List result = optionItems.Where(x => x.Parent == null && !x.IsCurrentlyHidden() && !Translator.GetString($"{x.Name}").Contains(text, StringComparison.OrdinalIgnoreCase)).ToList(); HiddenBySearch = result; - System.Collections.Generic.List searchWinners = optionItems.Where(x => x.Parent == null && !x.IsCurrentlyHidden() && !result.Contains(x)).ToList(); + List searchWinners = optionItems.Where(x => x.Parent == null && !x.IsCurrentlyHidden() && !result.Contains(x)).ToList(); if (searchWinners.Count == 0 || !ModSettingsTabs.TryGetValue(modTab, out GameOptionsMenu gameSettings) || gameSettings == null) { @@ -1394,7 +1394,7 @@ public static class GameSettingMenuPatch ModGameOptionsMenu.CategoryHeaderList = new(); ControllerManager.Instance.OpenOverlayMenu(__instance.name, __instance.BackButton, __instance.DefaultButtonSelected, __instance.ControllerSelectable); - FastDestroyableSingleton.Instance.menuNavigationPrompts.SetActive(false); + if (HudManager.InstanceExists) FastDestroyableSingleton.Instance.menuNavigationPrompts.SetActive(false); if (Controller.currentTouchType != Controller.TouchType.Joystick) __instance.ChangeTab(1, false); __instance.StartCoroutine(__instance.CoSelectDefault()); diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs index 689a96d98..b8b63d960 100644 --- a/Patches/GameStartManagerPatch.cs +++ b/Patches/GameStartManagerPatch.cs @@ -51,7 +51,7 @@ public static class GameStartManagerPatch GameCountdown = Object.Instantiate(__instance.PlayerCounter, __instance.HostInfoPanel.transform); GameCountdown.text = string.Empty; - if (GameData.Instance && AmongUsClient.Instance.NetworkMode != NetworkModes.LocalGame && GameStates.CurrentServerType == GameStates.ServerType.Vanilla) + if (GameData.Instance && HudManager.InstanceExists && AmongUsClient.Instance.NetworkMode != NetworkModes.LocalGame && GameStates.CurrentServerType == GameStates.ServerType.Vanilla) { HudManager hudManager = FastDestroyableSingleton.Instance; hudManager.ShowLobbyTimer(597); @@ -323,8 +323,11 @@ public static class GameStartManagerPatch instance.GameStartText.text = string.Empty; } } + + if (!HudManager.InstanceExists) return; - if (instance.LobbyInfoPane.gameObject.activeSelf && FastDestroyableSingleton.Instance.Chat.IsOpenOrOpening) instance.LobbyInfoPane.DeactivatePane(); + if (instance.LobbyInfoPane.gameObject.activeSelf && FastDestroyableSingleton.Instance.Chat.IsOpenOrOpening) + instance.LobbyInfoPane.DeactivatePane(); instance.LobbyInfoPane.gameObject.SetActive(!FastDestroyableSingleton.Instance.Chat.IsOpenOrOpening); } @@ -454,7 +457,7 @@ public static class GameStartManagerPatch tmp.gameObject.SetActive(true); // Lobby timer - if (GameData.Instance && AmongUsClient.Instance.NetworkMode != NetworkModes.LocalGame && GameStates.CurrentServerType == GameStates.ServerType.Vanilla) + if (GameData.Instance && HudManager.InstanceExists && AmongUsClient.Instance.NetworkMode != NetworkModes.LocalGame && GameStates.CurrentServerType == GameStates.ServerType.Vanilla) { float timer = Timer; @@ -462,7 +465,7 @@ public static class GameStartManagerPatch LobbyTimerBg.sprite = Utils.LoadSprite("EHR.Resources.Images.LobbyTimerBG.png", 100f); LobbyTimerBg.color = GetTimerColor(timer); - if (timer <= 60 && !Warned) + if (timer <= 60 && !Warned && AmongUsClient.Instance.AmHost) { Warned = true; LobbyTimerExtensionUI lobbyTimerExtensionUI = FastDestroyableSingleton.Instance.LobbyTimerExtensionUI; @@ -538,6 +541,14 @@ public static class GameStartRandomMap Utils.SendMessage(msg, sendOption: SendOption.None); return false; } + + if (Options.RandomMapsMode.GetBool()) + { + Main.NormalOptions.MapId = SelectRandomMap(); + CreateOptionsPickerPatch.SetDleks = Main.CurrentMap == MapNames.Dleks; + } + else if (CreateOptionsPickerPatch.SetDleks) Main.NormalOptions.MapId = 3; + else if (CreateOptionsPickerPatch.SetSubmerged) Main.NormalOptions.MapId = 6; if (__instance.startState == GameStartManager.StartingStates.Countdown) Main.NormalOptions.KillCooldown = Main.LastKillCooldown.Value; @@ -566,17 +577,6 @@ public static class GameStartRandomMap return false; } - public static void Prefix( /*GameStartRandomMap __instance*/) - { - if (Options.RandomMapsMode.GetBool()) - { - Main.NormalOptions.MapId = SelectRandomMap(); - CreateOptionsPickerPatch.SetDleks = Main.CurrentMap == MapNames.Dleks; - } - else if (CreateOptionsPickerPatch.SetDleks) Main.NormalOptions.MapId = 3; - else if (CreateOptionsPickerPatch.SetSubmerged) Main.NormalOptions.MapId = 6; - } - public static byte SelectRandomMap() { System.Collections.Generic.Dictionary chance = Enumerable.Range(0, 6).ToDictionary(x => (byte)x, x => x switch diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index b23df709a..06804effa 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -2,6 +2,8 @@ using System; using System.Collections; using System.Linq; using AmongUs.GameOptions; +using BepInEx.Unity.IL2CPP.Utils.Collections; +using EHR.AddOns.Common; using EHR.Modules; using EHR.Neutral; using HarmonyLib; @@ -43,7 +45,7 @@ static class ShowRoleMoveNextPatch [HarmonyPatch(typeof(HudManager), nameof(HudManager.CoShowIntro))] static class CoShowIntroPatch { - public static bool Prefix(HudManager __instance) + public static bool Prefix(HudManager __instance, ref Il2CppSystem.Collections.IEnumerator __result) { if (!AmongUsClient.Instance.AmHost || !GameStates.IsModHost) return true; @@ -67,12 +69,12 @@ static class CoShowIntroPatch catch { Logger.Warn($"Game ended? {AmongUsClient.Instance.IsGameOver || GameStates.IsLobby || GameEndChecker.Ended}", "ShipStatus.Begin"); } }, 4f, "Assign Tasks"); - Main.Instance.StartCoroutine(CoShowIntro()); + __result = CoShowIntro().WrapToIl2Cpp(); return false; IEnumerator CoShowIntro() { - while (!ShipStatus.Instance) yield return null; + while (!ShipStatus.Instance || !HudManager.InstanceExists) yield return null; RPC.RpcVersionCheck(); GameStates.InGame = true; @@ -80,11 +82,9 @@ static class CoShowIntroPatch __instance.IsIntroDisplayed = true; __instance.LobbyTimerExtensionUI.HideAll(); __instance.SetMapButtonEnabled(false); + __instance.FullScreen.transform.localPosition = new Vector3(0.0f, 0.0f, -250f); - HudManager hudManager = FastDestroyableSingleton.Instance; - hudManager.FullScreen.transform.localPosition = new Vector3(0.0f, 0.0f, -250f); - - yield return hudManager.ShowEmblem(true); + yield return __instance.ShowEmblem(true); yield return CoBegin(Object.Instantiate(__instance.IntroPrefab, __instance.transform)); PlayerControl.LocalPlayer.SetKillTimer(10f); @@ -1326,6 +1326,8 @@ internal static class IntroCutsceneDestroyPatch pc.TP(new Vector2(3.32f, -26.57f)); } } + + if (!HudManager.InstanceExists) return; HudManager hud = FastDestroyableSingleton.Instance; @@ -1344,7 +1346,7 @@ internal static class IntroCutsceneDestroyPatch if (Options.CurrentGameMode == CustomGameMode.Standard && !Utils.HasTasks(PlayerControl.LocalPlayer.Data, forRecompute: false)) hud.TaskPanel.open = false; - if (!AmongUsClient.Instance.AmHost) return; + if (!AmongUsClient.Instance.AmHost || !Lovers.PrivateChat.GetBool()) return; Main.LoversPlayers.ForEach(x => x.SetChatVisible(true)); }, 1f, log: false); diff --git a/Patches/MainMenuManagerPatch.cs b/Patches/MainMenuManagerPatch.cs index 0c7a01ac0..bc364a2c9 100644 --- a/Patches/MainMenuManagerPatch.cs +++ b/Patches/MainMenuManagerPatch.cs @@ -173,7 +173,10 @@ public static class MainMenuManagerPatch foreach (string buttonName in new[] { "SettingsButton", "Inventory Button", "CreditsButton", "ExitGameButton" }) { - var buttonText = GameObject.Find(buttonName).transform.Find("FontPlacer/Text_TMP").GetComponent(); + var go = GameObject.Find(buttonName); + if (!go) continue; + var buttonText = go.GetComponentInChildren(); + if (!buttonText) continue; buttonText.DestroyTranslator(); buttonText.text = Translator.GetString($"MainMenu.{buttonName.Replace(" ", "")}"); } diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index d96cfe25e..aeecfe688 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -32,11 +32,11 @@ internal static class ChangeRoleSettings { public static bool BlockPopulateSkins; - public static bool Prefix(AmongUsClient __instance) + public static bool Prefix(AmongUsClient __instance, ref Il2CppSystem.Collections.IEnumerator __result) { - if (!GameStates.IsLocalGame) return true; + if (!GameStates.IsLocalGame || !HudManager.InstanceExists) return true; - __instance.StartCoroutine(CoStartGame().WrapToIl2Cpp()); + __result = CoStartGame().WrapToIl2Cpp(); return false; IEnumerator CoStartGame() diff --git a/Patches/PhantomRolePatch.cs b/Patches/PhantomRolePatch.cs index b80623583..cf8641a76 100644 --- a/Patches/PhantomRolePatch.cs +++ b/Patches/PhantomRolePatch.cs @@ -152,6 +152,8 @@ public static class PhantomRolePatch public static bool CheckTrigger(PlayerControl phantom) { + if (!HudManager.InstanceExists) return true; + RoleBase roleBase = Main.PlayerStates[phantom.PlayerId].Role; if ((phantom.Is(CustomRoles.Trainee) && MeetingStates.FirstMeeting) || !Rhapsode.CheckAbilityUse(phantom) || Stasis.IsTimeFrozen || TimeMaster.Rewinding || !roleBase.OnVanish(phantom)) @@ -337,7 +339,7 @@ public static class PhantomRoleUseAbilityPatch { public static bool Prefix(PhantomRole __instance) { - if (!AmongUsClient.Instance.AmHost) return true; + if (!AmongUsClient.Instance.AmHost || !HudManager.InstanceExists) return true; if (__instance.Player.AmOwner && !__instance.Player.Data.IsDead && __instance.Player.moveable && !Minigame.Instance && !__instance.IsCoolingDown && !__instance.fading) { diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index ae0562f6b..7ece64fa6 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -1189,7 +1189,7 @@ internal static class ReportDeadBodyPatch CustomNetObject.OnMeeting(); - FastDestroyableSingleton.Instance.SetRolePanelOpen(false); + if (HudManager.InstanceExists) FastDestroyableSingleton.Instance.SetRolePanelOpen(false); Asthmatic.RunChecks = false; diff --git a/Patches/PlayerJoinAndLeftPatch.cs b/Patches/PlayerJoinAndLeftPatch.cs index e3eabdcd6..f0a24bec2 100644 --- a/Patches/PlayerJoinAndLeftPatch.cs +++ b/Patches/PlayerJoinAndLeftPatch.cs @@ -472,7 +472,7 @@ internal static class OnPlayerJoinedPatch Logger.Info(msg, "Android Kick"); } - if (FastDestroyableSingleton.Instance.IsPlayerBlockedUsername(client.FriendCode) && AmongUsClient.Instance.AmHost && GameStates.CurrentServerType is not GameStates.ServerType.Modded and not GameStates.ServerType.Niko and not GameStates.ServerType.Local) + if (FriendsListManager.InstanceExists && FastDestroyableSingleton.Instance.IsPlayerBlockedUsername(client.FriendCode) && AmongUsClient.Instance.AmHost && GameStates.CurrentServerType is not GameStates.ServerType.Modded and not GameStates.ServerType.Niko and not GameStates.ServerType.Local) { AmongUsClient.Instance.KickPlayer(client.Id, true); Logger.Info($"Blocked Player {client.PlayerName}({client.FriendCode}) has been banned.", "BAN"); diff --git a/Patches/SabotageButtonPatch.cs b/Patches/SabotageButtonPatch.cs index a9966cfbf..d0cd5d51e 100644 --- a/Patches/SabotageButtonPatch.cs +++ b/Patches/SabotageButtonPatch.cs @@ -8,7 +8,7 @@ public static class SabotageButtonDoClickPatch { public static bool Prefix() { - if (!PlayerControl.LocalPlayer.inVent && GameManager.Instance.SabotagesEnabled()) + if (!PlayerControl.LocalPlayer.inVent && GameManager.Instance.SabotagesEnabled() && HudManager.InstanceExists) { FastDestroyableSingleton.Instance.ToggleMapVisible(new() { diff --git a/Patches/TextBoxPatch.cs b/Patches/TextBoxPatch.cs index a62b9a49b..a0d25e85d 100644 --- a/Patches/TextBoxPatch.cs +++ b/Patches/TextBoxPatch.cs @@ -109,7 +109,7 @@ public static class TextBoxPatch { try { - if (!__instance.gameObject.HasParentInHierarchy("ChatScreenRoot/ChatScreenContainer")) return; + if (!HudManager.InstanceExists || !__instance.gameObject.HasParentInHierarchy("ChatScreenRoot/ChatScreenContainer")) return; if (!Main.EnableCommandHelper.Value) { @@ -363,7 +363,7 @@ public static class TextBoxPatch { try { - bool open = FastDestroyableSingleton.Instance?.Chat?.IsOpenOrOpening ?? false; + bool open = HudManager.InstanceExists && (FastDestroyableSingleton.Instance?.Chat?.IsOpenOrOpening ?? false); PlaceHolderText?.gameObject.SetActive(open); CommandInfoText?.gameObject.SetActive(open); AdditionalInfoText?.gameObject.SetActive(open);