using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using FishNet.Connection; using FishNet.Object; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("HowToFishPvp")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HowToFishPvp")] [assembly: AssemblyTitle("HowToFishPvp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 HowToFishPvp { [HarmonyPatch] internal static class DeathPatch { [HarmonyPatch(typeof(PlayerUI), "ToggleDeathUI")] [HarmonyPrefix] private static bool SkipDeathUi(bool to) { if (!PvpSession.Queued) { return true; } return !to; } [HarmonyPatch(typeof(PlayerDeathCam), "EnableDeathCam")] [HarmonyPrefix] private static bool SkipDeathCam() { if (!PvpSession.Queued) { return true; } if (PvpSession.Phase == PvpPhase.MatchOver || PvpSession.Phase == PvpPhase.Fighting) { return true; } return false; } [HarmonyPatch(typeof(PlayerDying), "DeathEffects")] [HarmonyPrefix] private static bool SkipHideBody() { if (!PvpSession.Queued) { return true; } if (PvpLobby.IsSkyLobby() || Time.time < PvpSession.ProtectUntil) { return false; } return true; } [HarmonyPatch(typeof(PlayerDying), "LocalRespawn")] [HarmonyPrefix] private static bool SkipGiveUpRespawn() { return !PvpSession.Queued; } [HarmonyPatch(typeof(DeadPlayer), "PrimaryInput")] [HarmonyPrefix] private static bool SkipSlapRevive() { return !PvpSession.Queued; } [HarmonyPatch(typeof(PlayerDying), "ResurrectEffect")] [HarmonyPostfix] private static void AfterResurrect(PlayerDying __instance) { if (PvpSession.Queued && !((Object)(object)__instance == (Object)null)) { Player val = null; try { object? value = AccessTools.Field(typeof(PlayerDying), "_player").GetValue(__instance); val = (Player)((value is Player) ? value : null); } catch { } if (!((Object)(object)val == (Object)null)) { PvpController.RestorePlayerView(val); } } } [HarmonyPatch(typeof(Player), "LocalTeleport")] [HarmonyPostfix] private static void AfterTeleport(Player __instance) { if (PvpSession.Queued && !((Object)(object)__instance == (Object)null) && !PvpController.QuietTeleport && (PvpSession.Phase != PvpPhase.Fighting || !((Object)(object)__instance.Dying != (Object)null) || !__instance.Dying.IsDead)) { PvpController.RestoreVisuals(__instance); } } [HarmonyPatch(typeof(Player), "get_BlockInputs")] [HarmonyPostfix] private static void FreezeDuringCountdown(ref bool __result) { if (PvpSession.Queued && PvpSession.Phase == PvpPhase.Countdown && PvpSession.CountdownDisplay >= 1 && !PvpLobby.IsSkyLobby()) { __result = true; } } } [HarmonyPatch(typeof(Server), "RpcLogic___HitPlayer___2449261505")] internal static class HitPatch { private static void Postfix(Player __0, Player __5) { if (PvpSession.MatchRunning && PvpSession.Phase == PvpPhase.Fighting && !((Object)(object)__0 == (Object)null) && !((Object)(object)__0.Vitals == (Object)null) && __0.Vitals.Health <= 0 && !((Object)(object)__5 == (Object)null) && !((Object)(object)__5 == (Object)(object)__0)) { PvpSession.EnsurePlayer(__5); } } } [HarmonyPatch(typeof(PlayerVitals))] internal static class HungerPatch { [HarmonyPrefix] [HarmonyPatch("LowerFullnessTick")] private static bool SkipHungerTick() { return !PvpSession.Queued; } [HarmonyPrefix] [HarmonyPatch("DamageFromFullness")] private static bool SkipHungerDamage() { return !PvpSession.Queued; } [HarmonyPrefix] [HarmonyPatch("LowerFullness")] private static bool SkipLoseFullness() { return !PvpSession.Queued; } } internal static class IslandPatch { private static float _nextClean; private static bool InPvp() { if (PvpSession.Queued || MenuPatch.PvpSelected) { return true; } try { if (PvpSync.LobbySaysPvp()) { return true; } } catch { } try { ServerSaveObject curServerSave = SaveManager.CurServerSave; if (curServerSave != null && !string.IsNullOrEmpty(curServerSave.Name) && curServerSave.Name.IndexOf("PVP", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } catch { } return false; } internal static void TickClean() { if (InPvp() && !(Time.unscaledTime < _nextClean)) { _nextClean = Time.unscaledTime + 0.35f; ClearBlack(); KillTips(); } } internal static void ClearBlack() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) try { CanvasManager.ToggleBlackscreen(false, true, 0f); } catch { } try { object? value = AccessTools.Field(typeof(CanvasManager), "_instance").GetValue(null); CanvasManager val = (CanvasManager)((value is CanvasManager) ? value : null); if (!((Object)(object)val == (Object)null)) { object? value2 = AccessTools.Field(typeof(CanvasManager), "_blackScreen").GetValue(val); Image val2 = (Image)((value2 is Image) ? value2 : null); if (!((Object)(object)val2 == (Object)null)) { ((Graphic)val2).color = new Color(0f, 0f, 0f, 0f); ((Component)val2).gameObject.SetActive(false); } } } catch { } } internal static void KillTips() { try { if ((Object)(object)PlayerTutorial.Instance != (Object)null) { PlayerTutorial.Instance.SkipTutorial(); } } catch { } try { PlayerTutorial instance = PlayerTutorial.Instance; if (!((Object)(object)instance == (Object)null)) { object? value = AccessTools.Field(typeof(PlayerTutorial), "_tutorialGroup").GetValue(instance); CanvasGroup val = (CanvasGroup)((value is CanvasGroup) ? value : null); if ((Object)(object)val != (Object)null) { val.alpha = 0f; ((Component)val).gameObject.SetActive(false); } object? value2 = AccessTools.Field(typeof(PlayerTutorial), "_tutorialHolder").GetValue(instance); RectTransform val2 = (RectTransform)((value2 is RectTransform) ? value2 : null); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } AccessTools.Field(typeof(PlayerTutorial), "_hide").SetValue(instance, true); } } catch { } } [HarmonyPatch(typeof(MainMenuManager), "CrashAnimation")] [HarmonyPrefix] private static bool SkipJoinCinematic() { if (!InPvp()) { return true; } try { AccessTools.Field(typeof(MainMenuManager), "_isShowingCutscene").SetValue(null, true); MainMenuManager.InstantCrash(); } catch { } try { Player.ToggleLocalPlayer(true); } catch { } PvpSession.EnsureQueued(); ClearBlack(); KillTips(); return false; } [HarmonyPatch(typeof(MainMenuManager), "HideBoat")] [HarmonyPrefix] private static bool SkipHideBoatFade() { if (!InPvp()) { return true; } try { AccessTools.Field(typeof(MainMenuManager), "_isShowingCutscene").SetValue(null, false); } catch { } ClearBlack(); return false; } [HarmonyPatch(typeof(CanvasManager), "ToggleBlackscreen")] [HarmonyPrefix] private static bool SkipPvpBlackFade(bool to, ref bool instant) { if (!InPvp()) { return true; } if (to) { return false; } instant = true; return true; } [HarmonyPatch(typeof(TutorialManager), "AddTutorial")] [HarmonyPrefix] private static bool SkipTutorial() { return !InPvp(); } [HarmonyPatch(typeof(TutorialManager), "Start")] [HarmonyPrefix] private static bool SkipTutorialStart() { return !InPvp(); } [HarmonyPatch(typeof(PlayerTutorial), "AddTutorial")] [HarmonyPrefix] private static bool SkipPlayerTutorial() { return !InPvp(); } [HarmonyPatch(typeof(PlayerTutorial), "InitializeLocal")] [HarmonyPostfix] private static void AfterTutorialInit() { if (InPvp()) { KillTips(); } } [HarmonyPatch(typeof(OnlineIslandManager), "OnStartServer")] [HarmonyPostfix] private static void OnStartServerPostfix(OnlineIslandManager __instance) { if (!PvpSession.Queued) { return; } try { MenuPatch.ApplyPvpSaveIslands(); PvpController.UnlockAllIslands(); if ((Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).IsServerInitialized) { __instance.SpawnIsland((byte)1); } } catch (Exception ex) { Debug.LogError((object)("[HowToFishPvp] OnStartServer island set failed: " + ex)); } ClearBlack(); KillTips(); } [HarmonyPatch(typeof(OnlineIslandManager), "OnStartClient")] [HarmonyPostfix] private static void OnStartClientPostfix() { if (!PvpSession.Queued || PvpSession.MatchRunning) { return; } KillTips(); ClearBlack(); try { OnlineIslandManager.ToggleTeleportPlayers(true); IslandManager.LoadIsland((byte)1); IslandManager.OnIslandChange((byte)1); } catch (Exception ex) { Debug.LogError((object)("[HowToFishPvp] OnStartClient island load failed: " + ex)); } } [HarmonyPatch(typeof(BoatManager), "TrySpawnBoat")] [HarmonyPrefix] private static bool SkipSpawnBoat() { return !InPvp(); } [HarmonyPatch(typeof(BoatManager), "TryMoveBoat")] [HarmonyPrefix] private static bool SkipMoveBoat() { return !InPvp(); } [HarmonyPatch(typeof(IslandManager), "OnIslandChange")] [HarmonyPostfix] private static void AfterIslandChange() { if (PvpSession.Queued) { PvpController.HideShops(); PvpController.RestoreAllViews(); ClearBlack(); KillTips(); } } } [HarmonyPatch] internal static class LobbyPatch { private static bool InSafePeriod() { if (PvpLobby.IsSkyLobby()) { return true; } if (!PvpSession.Queued) { return false; } if (Time.time < PvpSession.ProtectUntil) { return true; } return PvpSession.Phase == PvpPhase.Countdown; } private static Player PlayerOf(PlayerMovement move) { if ((Object)(object)move == (Object)null) { return null; } try { object? value = AccessTools.Field(typeof(PlayerMovement), "_player").GetValue(move); return (Player)((value is Player) ? value : null); } catch { return null; } } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerVitals), "TakeDamage")] private static bool SkipLobbyDamage() { return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerVitals), "LocalHit")] private static bool SkipLobbyLocalHit() { return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerVitals), "TickUpdate")] private static bool SkipLobbyTicks() { return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerVitals), "FireTick")] private static bool SkipLobbyFire() { return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerVitals), "PoisonTick")] private static bool SkipLobbyPoison() { return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerMovement), "UnderWaterCheck")] private static bool SkipLobbyDrown(PlayerMovement __instance) { if (PvpBoats.IsStandingOnBoat(PlayerOf(__instance))) { return false; } return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(Server), "HitPlayer")] private static bool SkipLobbyHit() { return !InSafePeriod(); } [HarmonyPrefix] [HarmonyPatch(typeof(Server), "RpcLogic___HitPlayer___2449261505")] private static bool SkipLobbyHitRpc() { return !InSafePeriod(); } } internal static class MenuPatch { [CompilerGenerated] private static class <>O { public static UnityAction <0>__StartPvpFromMenu; } private const string ButtonObjectName = "HowToFishPvpModeButton"; internal static bool PvpSelected; private static Button _pvpButton; internal static void TryAttachIfNeeded() { ButtonManager manager = GetManager(); if ((Object)(object)manager != (Object)null) { EnsurePvpButton(manager); } } [HarmonyPatch(typeof(ButtonManager), "Start")] [HarmonyPostfix] private static void StartPostfix(ButtonManager __instance) { try { EnsurePvpButton(__instance); } catch (Exception ex) { Debug.LogError((object)("[HowToFishPvp] Menu setup failed: " + ex)); } } [HarmonyPatch(typeof(ButtonManager), "ToggleCreateServerButton")] [HarmonyPostfix] private static void KeepPvpClickable() { if ((Object)(object)_pvpButton != (Object)null) { ((Selectable)_pvpButton).interactable = true; PaintEnabled(_pvpButton); } } [HarmonyPatch(typeof(ButtonManager), "CreateNewServer")] [HarmonyPrefix] private static void CreatePrefix(ButtonManager __instance) { if (PvpSelected) { QueuePvp(__instance); } } [HarmonyPatch(typeof(SaveManager), "CreateServer")] [HarmonyPostfix] private static void CreateServerPostfix() { if (PvpSession.Queued) { ApplyPvpSaveIslands(); } } internal static void QueuePvp(ButtonManager manager) { PvpSelected = true; PvpSession.Queued = true; PvpSession.ResetMatch(); PvpSession.Phase = PvpPhase.WaitingForPlayers; PvpSession.Banner = "PVP MODE"; PvpSession.SubBanner = "Invite friends, then wait in-world"; ApplyPvpSaveIslands(); object? value = AccessTools.Field(typeof(ButtonManager), "_serverNameInputField").GetValue(manager); TMP_InputField val = (TMP_InputField)((value is TMP_InputField) ? value : null); if ((Object)(object)val != (Object)null && string.IsNullOrEmpty(val.text)) { val.text = "PVP Arena"; } AccessTools.Field(typeof(ButtonManager), "_useSteam").SetValue(manager, true); AccessTools.Field(typeof(ButtonManager), "_isPublic").SetValue(manager, false); } internal static void ApplyPvpSaveIslands() { ServerSaveObject curServerSave = SaveManager.CurServerSave; if (curServerSave != null) { curServerSave.SpawnedIsland = 1; curServerSave.MaxIsland = byte.MaxValue; } } internal static void StartPvpFromMenu() { ButtonManager manager = GetManager(); if (!((Object)(object)manager == (Object)null)) { QueuePvp(manager); object? value = AccessTools.Field(typeof(ButtonManager), "_serverNameInputField").GetValue(manager); TMP_InputField val = (TMP_InputField)((value is TMP_InputField) ? value : null); if ((Object)(object)val != (Object)null) { val.text = "PVP Arena"; } AccessTools.Method(typeof(ButtonManager), "ToggleCreateServerButton", (Type[])null, (Type[])null).Invoke(manager, new object[1] { true }); manager.CreateNewServer(); } } private static ButtonManager GetManager() { object? value = AccessTools.Field(typeof(ButtonManager), "_instance").GetValue(null); ButtonManager val = (ButtonManager)((value is ButtonManager) ? value : null); if ((Object)(object)val == (Object)null) { val = Object.FindObjectOfType(); } return val; } private static void EnsurePvpButton(ButtonManager manager) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00cb: 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_00d6: Expected O, but got Unknown object? value = AccessTools.Field(typeof(ButtonManager), "_createServerButton").GetValue(manager); Button val = (Button)((value is Button) ? value : null); if ((Object)(object)val == (Object)null) { return; } Transform parent = ((Component)val).transform.parent; if ((Object)(object)parent == (Object)null) { return; } Transform val2 = parent.Find("HowToFishPvpModeButton"); if ((Object)(object)val2 != (Object)null) { _pvpButton = ((Component)val2).GetComponent