Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LateRepo v1.6.4
plugins/LateRepo.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using LateRepo.Patches; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LateRepo")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.6.3.0")] [assembly: AssemblyInformationalVersion("1.6.3+9d7dcafb5936c5801908597da461971340dc9791")] [assembly: AssemblyProduct("LateRepo")] [assembly: AssemblyTitle("LateRepo")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LateRepo { [BepInPlugin("chaos.holz.laterepo", "LateRepo", "1.6.4")] public class Plugin : BaseUnityPlugin { private const string modGUID = "chaos.holz.laterepo"; private const string modName = "LateRepo"; private const string modVersion = "1.6.4"; private static readonly Harmony _harmony = new Harmony("LateRepo"); internal static readonly ManualLogSource logger = Logger.CreateLogSource("LateRepo"); internal static ConfigEntry<bool> JoinButton; internal static ConfigEntry<bool> JoinShop; internal static ConfigEntry<bool> splashScreen; internal static ConfigEntry<bool> moonPhase; internal static ConfigEntry<bool> PlayGamePopup; internal static ConfigEntry<bool> StartGamePopup; internal static ConfigEntry<bool> LoadSavePopup; internal static ConfigEntry<bool> PickRegion; internal static ConfigEntry<bool> PasswordSkip; internal static ConfigEntry<string> PasswordSet; private void Awake() { Configs(); LateJoinPatch.InitializeHooks(); PatchAllStuff(); logger.LogInfo((object)"[LateRepo] erfolgreich geladen!"); } private void Configs() { JoinButton = ((BaseUnityPlugin)this).Config.Bind<bool>("Late Join", "Invite Button", true, "If true, a button appears in the Escape menu that opens the Steam overlay for inviting players."); JoinShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Late Join", "Late Join Shop", false, "If it’s true, players can late join in the shop."); PickRegion = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby Settings", "Auto Region", true, "If true, it automatically picks the best region, so it doesn’t ask you to choose a region anymore."); PasswordSkip = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby Settings", "Passwort Skip", false, "If true, it automatically bypasses the password input screen."); PasswordSet = ((BaseUnityPlugin)this).Config.Bind<string>("Lobby Settings", "SetPasswort", "", "Enter the password you want for your private lobby. If it’s empty, no password will be set. This only works if Password Skip is true."); splashScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("Popup", "Splash Screen", true, "If true, the splash screen at the beginning is skipped."); moonPhase = ((BaseUnityPlugin)this).Config.Bind<bool>("Popup", "Moon Phase Change", true, "If true,"); PlayGamePopup = ((BaseUnityPlugin)this).Config.Bind<bool>("Popup", "Play Game Popup", true, "If true, the pop-ups for “Host a Game?” and “Warning: Playing with random players” are automatically accepted when you click PUBLIC or PRIVATE GAME, so they don’t appear anymore."); LoadSavePopup = ((BaseUnityPlugin)this).Config.Bind<bool>("Popup", "Load Save Popup", false, "If true, the pop-up for “Load Save?” is automatically accepted when you click LOAD SAVE, so it doesn’t appear anymore."); StartGamePopup = ((BaseUnityPlugin)this).Config.Bind<bool>("Popup", "Start Game Popup", true, "If true, the pop-up for “Start Game” is automatically accepted when you click START GAME, so it doesn’t appear anymore."); } private void PatchAllStuff() { if (splashScreen.Value) { _harmony.PatchAll(typeof(LevelGeneratorPatch)); } if (PickRegion.Value) { _harmony.PatchAll(typeof(MenuPageRegionPatch)); } if (StartGamePopup.Value || PlayGamePopup.Value || LoadSavePopup.Value) { _harmony.PatchAll(typeof(PopUpPatch)); } if (PasswordSkip.Value || !string.IsNullOrEmpty(PasswordSet.Value)) { _harmony.PatchAll(typeof(MenuPagePasswordPatch)); } _harmony.PatchAll(typeof(PlayerNameCheckerUpdatePatch)); _harmony.PatchAll(typeof(MenuPageEscPatch)); if (moonPhase.Value) { _harmony.PatchAll(typeof(MoonUIPatch)); } } } } namespace LateRepo.Patches { [HarmonyPatch(typeof(MenuPageRegions))] internal static class MenuPageRegionPatch { [HarmonyPatch(typeof(MenuPageRegions), "Start")] [HarmonyPrefix] private static void MenuPageRegionStartPatch(MenuPageRegions __instance) { __instance.PickRegion(""); } [HarmonyPatch(typeof(MenuPagePublicGameChoice), "ExitPage")] [HarmonyPrefix] private static bool PublicExitPagePatch() { MenuManager.instance.PageCloseAll(); MenuManager.instance.PageOpen((MenuPageIndex)0, false); return false; } } [HarmonyPatch(typeof(MenuManager))] internal static class PopUpPatch { public static bool isPublicGame; [HarmonyPatch(typeof(MenuManager), "PagePopUpTwoOptions")] [HarmonyPrefix] private static bool PagePopUpTwoOptionsPatch(MenuButtonPopUp menuButtonPopUp, string popUpHeader, Color popUpHeaderColor, string popUpText, string option1Text, string option2Text, bool richText) { if (IsPrivateGamePopup(popUpHeader, popUpText)) { isPublicGame = false; } else if (IsPublicGamePopup(popUpHeader, popUpText)) { isPublicGame = true; } if (Plugin.PlayGamePopup.Value) { if (IsPrivateGamePopup(popUpHeader, popUpText)) { UnityEvent option1Event = menuButtonPopUp.option1Event; if (option1Event != null) { option1Event.Invoke(); } return false; } if (IsPublicGamePopup(popUpHeader, popUpText)) { UnityEvent option1Event2 = menuButtonPopUp.option1Event; if (option1Event2 != null) { option1Event2.Invoke(); } return false; } } if (Plugin.StartGamePopup.Value && IsStartGamePopup(popUpHeader, popUpText)) { UnityEvent option1Event3 = menuButtonPopUp.option1Event; if (option1Event3 != null) { option1Event3.Invoke(); } return false; } if (Plugin.LoadSavePopup.Value && IsLoadSavePopup(popUpHeader, popUpText)) { UnityEvent option1Event4 = menuButtonPopUp.option1Event; if (option1Event4 != null) { option1Event4.Invoke(); } return false; } return true; } private static bool IsPrivateGamePopup(string header, string body) { header = header.ToLower(); body = body.ToLower(); if (!header.Contains("host") && !body.Contains("best computer")) { return body.Contains("are you this friend"); } return true; } private static bool IsPublicGamePopup(string header, string body) { header = header.ToLower(); body = body.ToLower(); if (!header.Contains("warning") && !body.Contains("random players")) { return body.Contains("mean people"); } return true; } private static bool IsStartGamePopup(string header, string body) { header = header.ToLower(); body = body.ToLower(); if (!header.Contains("start") && !body.Contains("everyone ready")) { return body.Contains("once the game"); } return true; } private static bool IsLoadSavePopup(string header, string body) { header = header.ToLower(); body = body.ToLower(); if (!header.Contains("load")) { return body.Contains("load this save"); } return true; } } [HarmonyPatch(typeof(MenuPagePassword))] internal static class MenuPagePasswordPatch { private static bool passwordAlreadySet; [HarmonyPatch(typeof(MenuPagePassword), "Update")] [HarmonyPrefix] private static void PasswordSkipPatch(MenuPagePassword __instance) { if (!Plugin.PasswordSkip.Value) { return; } if (!string.IsNullOrEmpty(Plugin.PasswordSet.Value)) { if (string.IsNullOrEmpty(Plugin.PasswordSet.Value) || passwordAlreadySet) { return; } string text = Plugin.PasswordSet.Value.ToUpper().Replace("\n", "").Replace("\r", "") .Replace(" ", ""); AccessTools.Field(typeof(MenuPagePassword), "password").SetValue(__instance, text); passwordAlreadySet = true; Plugin.logger.LogInfo((object)("[LateRepo] Automatisches Passwort gesetzt: " + text)); } __instance.ConfirmButton(); } [HarmonyPatch(typeof(MenuPagePassword), "Start")] [HarmonyPrefix] private static void PasswortStartPatch() { passwordAlreadySet = false; } } [HarmonyPatch(typeof(MoonUI))] internal static class MoonUIPatch { [HarmonyPatch(typeof(MoonUI), "Check")] [HarmonyPostfix] private static void MoonUICheckPatch(MoonUI __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 if ((int)(State)AccessTools.Field(typeof(MoonUI), "state").GetValue(__instance) > 0) { AccessTools.Field(typeof(MoonUI), "skip").SetValue(__instance, true); __instance.SetState((State)0); } } } [HarmonyPatch(typeof(LevelGenerator))] internal static class LevelGeneratorPatch { [HarmonyPatch(typeof(LevelGenerator), "Start")] [HarmonyPrefix] private static void LevelGeneratorStartPatch() { if (SemiFunc.IsSplashScreen() && Object.op_Implicit((Object)(object)RunManager.instance) && Object.op_Implicit((Object)(object)DataDirector.instance) && DataDirector.instance.SettingValueFetch((Setting)58) == 1) { RunManager.instance.levelCurrent = RunManager.instance.levelMainMenu; } } } internal static class LateJoinPatch { private static readonly FieldInfo removeFilterFieldInfo = AccessTools.Field(typeof(PhotonNetwork), "removeFilter"); private static readonly FieldInfo keyByteSevenFieldInfo = AccessTools.Field(typeof(PhotonNetwork), "keyByteSeven"); private static readonly FieldInfo serverCleanOptionsFieldInfo = AccessTools.Field(typeof(PhotonNetwork), "ServerCleanOptions"); private static readonly MethodInfo raiseEventInternalMethodInfo = AccessTools.Method(typeof(PhotonNetwork), "RaiseEventInternal", (Type[])null, (Type[])null); private static Hook changeLevelHook; private static Hook spawnHook; private static Hook levelGenHook; private static Hook startHook; public static bool canJoin; public static void InitializeHooks() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown changeLevelHook = new Hook((MethodBase)AccessTools.Method(typeof(RunManager), "ChangeLevel", (Type[])null, (Type[])null), typeof(LateJoinPatch).GetMethod("ChangeLevelHook")); spawnHook = new Hook((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Spawn", (Type[])null, (Type[])null), typeof(LateJoinPatch).GetMethod("SpawnHook")); levelGenHook = new Hook((MethodBase)AccessTools.Method(typeof(LevelGenerator), "Start", (Type[])null, (Type[])null), typeof(LateJoinPatch).GetMethod("LevelGeneratorHook")); startHook = new Hook((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Start", (Type[])null, (Type[])null), typeof(LateJoinPatch).GetMethod("PlayerAvatarStartHook")); } public static void ChangeLevelHook(Action<RunManager, bool, bool, ChangeLevelType> orig, RunManager self, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (_levelFailed || !PhotonNetwork.IsMasterClient) { orig(self, _completedLevel, _levelFailed, _changeLevelType); return; } object value = AccessTools.Field(typeof(RunManager), "runManagerPUN").GetValue(self); object? value2 = AccessTools.Field(typeof(RunManagerPUN), "photonView").GetValue(value); PhotonNetwork.RemoveBufferedRPCs(((PhotonView)((value2 is PhotonView) ? value2 : null)).ViewID, (string)null, (int[])null); PhotonView[] array = Object.FindObjectsOfType<PhotonView>(); foreach (PhotonView val in array) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).buildIndex != -1) { ClearPhotonCache(val); } } orig(self, _completedLevel, arg3: false, _changeLevelType); canJoin = SemiFunc.RunIsLobbyMenu() || SemiFunc.RunIsLobby() || (SemiFunc.RunIsShop() && Plugin.JoinShop.Value); if (canJoin) { SteamManager.instance.UnlockLobby(true); PhotonNetwork.CurrentRoom.IsOpen = true; Plugin.logger.LogInfo((object)"[LateRepo] Lobbystatus geändert: offen"); if (PopUpPatch.isPublicGame) { Plugin.logger.LogInfo((object)"Public"); PhotonNetwork.CurrentRoom.IsVisible = true; GameManager.instance.SetConnectRandom(true); } } else { SteamManager.instance.LockLobby(); PhotonNetwork.CurrentRoom.IsOpen = false; if (PopUpPatch.isPublicGame) { PhotonNetwork.CurrentRoom.IsVisible = false; GameManager.instance.SetConnectRandom(false); Plugin.logger.LogInfo((object)"nicht Public"); } } } public static void SpawnHook(Action<PlayerAvatar, Vector3, Quaternion> orig, PlayerAvatar self, Vector3 position, Quaternion rotation) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!(bool)AccessTools.Field(typeof(PlayerAvatar), "spawned").GetValue(self)) { orig(self, position, rotation); } } public static void LevelGeneratorHook(Action<LevelGenerator> orig, LevelGenerator self) { if (PhotonNetwork.IsMasterClient && SemiFunc.RunIsLobby()) { PhotonNetwork.RemoveBufferedRPCs(self.PhotonView.ViewID, (string)null, (int[])null); } orig(self); } public static void PlayerAvatarStartHook(Action<PlayerAvatar> orig, PlayerAvatar self) { orig(self); if (PhotonNetwork.IsMasterClient && !SemiFunc.RunIsLobby()) { self.photonView.RPC("LoadingLevelAnimationCompletedRPC", (RpcTarget)3, Array.Empty<object>()); } } private static void ClearPhotonCache(PhotonView photonView) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { object? value = removeFilterFieldInfo.GetValue(null); Hashtable val = (Hashtable)((value is Hashtable) ? value : null); object value2 = keyByteSevenFieldInfo.GetValue(null); object? value3 = serverCleanOptionsFieldInfo.GetValue(null); RaiseEventOptions val2 = (RaiseEventOptions)((value3 is RaiseEventOptions) ? value3 : null); val[value2] = photonView.InstantiationId; val2.CachingOption = (EventCaching)6; raiseEventInternalMethodInfo.Invoke(null, new object[4] { (byte)202, val, val2, SendOptions.SendReliable }); } catch (Exception ex) { Plugin.logger.LogError((object)("[LateRepo] ClearPhotonCache Fehler: " + ex.Message)); } } } [HarmonyPatch(typeof(MenuPageEsc))] internal static class MenuPageEscPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__0_0; internal void <MenuPageStartPatch>b__0_0() { SteamManager instance = SteamManager.instance; if (instance != null) { instance.OpenSteamOverlayToInvite(); } } } [CompilerGenerated] private sealed class <FixInviteNextFrame>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject inviteGO; public GameObject quitGameGO; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FixInviteNextFrame>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; if ((Object)(object)inviteGO == (Object)null || (Object)(object)quitGameGO == (Object)null) { return false; } SetInviteText(inviteGO); RectTransform component = inviteGO.GetComponent<RectTransform>(); RectTransform component2 = quitGameGO.GetComponent<RectTransform>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return false; } component.anchorMin = component2.anchorMin; component.anchorMax = component2.anchorMax; component.pivot = component2.pivot; component.sizeDelta = component2.sizeDelta; ((Transform)component).localScale = ((Transform)component2).localScale; component.anchoredPosition = component2.anchoredPosition + new Vector2(0f, 30f); ResizeButtonToText(inviteGO); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch("Start")] [HarmonyPostfix] private static void MenuPageStartPatch(MenuPageEsc __instance) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown if (!Plugin.JoinButton.Value || !LateJoinPatch.canJoin || (Object)(object)__instance == (Object)null) { return; } MenuButton val = FindButtonByLabel(((Component)__instance).transform, "QUIT GAME"); if ((Object)(object)val == (Object)null) { return; } Transform parent = ((Component)val).transform.parent; if ((Object)(object)parent == (Object)null || (Object)(object)parent.Find("InviteButton") != (Object)null) { return; } GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent); MenuButtonPopUp component = val2.GetComponent<MenuButtonPopUp>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } SetInviteText(val2); Button component2 = val2.GetComponent<Button>(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = true; ((Selectable)component2).interactable = true; ((UnityEventBase)component2.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = component2.onClick; object obj = <>c.<>9__0_0; if (obj == null) { UnityAction val3 = delegate { SteamManager instance = SteamManager.instance; if (instance != null) { instance.OpenSteamOverlayToInvite(); } }; <>c.<>9__0_0 = val3; obj = (object)val3; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } val2.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex()); ((MonoBehaviour)__instance).StartCoroutine(FixInviteNextFrame(val2, ((Component)val).gameObject)); } [IteratorStateMachine(typeof(<FixInviteNextFrame>d__1))] private static IEnumerator FixInviteNextFrame(GameObject inviteGO, GameObject quitGameGO) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FixInviteNextFrame>d__1(0) { inviteGO = inviteGO, quitGameGO = quitGameGO }; } private static void SetInviteText(GameObject inviteGO) { if (!((Object)(object)inviteGO == (Object)null)) { MenuButton component = inviteGO.GetComponent<MenuButton>(); if (component != null) { component.buttonTextString = "INVITE"; } TextMeshProUGUI[] componentsInChildren = inviteGO.GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI obj in componentsInChildren) { ((TMP_Text)obj).SetText("INVITE", true); ((TMP_Text)obj).ForceMeshUpdate(false, false); } } } private static void ResizeButtonToText(GameObject buttonGO) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)buttonGO == (Object)null)) { TextMeshProUGUI componentInChildren = buttonGO.GetComponentInChildren<TextMeshProUGUI>(true); RectTransform component = buttonGO.GetComponent<RectTransform>(); if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)component == (Object)null)) { ((TMP_Text)componentInChildren).ForceMeshUpdate(false, false); Vector2 preferredValues = ((TMP_Text)componentInChildren).GetPreferredValues(((TMP_Text)componentInChildren).text); component.SetSizeWithCurrentAnchors((Axis)0, preferredValues.x); } } } private static MenuButton FindButtonByLabel(Transform root, string label) { if ((Object)(object)root == (Object)null) { return null; } MenuButton[] componentsInChildren = ((Component)root).GetComponentsInChildren<MenuButton>(true); foreach (MenuButton val in componentsInChildren) { TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren != (Object)null && string.Equals(((TMP_Text)componentInChildren).text?.Trim(), label, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } } [HarmonyPatch(typeof(PlayerNameChecker))] internal class PlayerNameCheckerUpdatePatch { public static class PlayerNamePatch { [HarmonyPatch(typeof(PlayerNameChecker), "Update")] [HarmonyPrefix] private static bool SafeUpdate(PlayerNameChecker __instance) { if ((Object)(object)__instance == (Object)null) { return false; } Type type = ((object)__instance).GetType(); FieldInfo field = type.GetField("target", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("label", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); object? obj = field?.GetValue(__instance); object obj2 = field2?.GetValue(__instance); if (obj == null || obj2 == null) { return false; } return true; } } } }