Decompiled source of Pro Golf Plus v0.1.43

BepInEx\plugins\ProGolfMod.dll

Decompiled a month ago
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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
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("ProGolfMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ProGolfMod")]
[assembly: AssemblyTitle("ProGolfMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 ProGolfMod
{
	[BepInPlugin("codex.superbattlegolf.progolfplus", "Pro Golf Plus", "0.1.43")]
	public sealed class ProGolfPlugin : BaseUnityPlugin
	{
		private sealed class DriveCandidate
		{
			public PlayerInfo Player;

			public ulong PlayerGuid;

			public Vector3 StartPosition;
		}

		private sealed class FirstDriveResult
		{
			public string PlayerName;

			public float Distance;

			public bool IsValid;
		}

		private sealed class ClosestToPinResult
		{
			public string PlayerName;

			public float Distance;

			public bool IsValid;
		}

		private sealed class CartFlipState
		{
			public WheelCollider[] Wheels = Array.Empty<WheelCollider>();

			public bool WasUprightOnWheels;

			public bool FlipInProgress;

			public int CurrentFlipStreak;

			public float AccumulatedFlipRadians;

			public float LastFlipPollTime = -1f;

			public float SettledSince = -1f;

			public ulong ResponsiblePlayerGuid;

			public string ResponsiblePlayerName;
		}

		[HarmonyPatch(typeof(CourseManager), "BeginCountdownToMatchEnd")]
		private static class SkipFirstFinishCountdownPatch
		{
			private static bool Prefix(CourseManager __instance)
			{
				if (!IsProGolfScoringActive() || (Object)(object)__instance == (Object)null)
				{
					return true;
				}
				if (ShouldBlockNativeEndCountdown(__instance))
				{
					return false;
				}
				if (AllActivePlayersResolved(__instance))
				{
					TryAnnounceClosestToPinIfReady();
					TryAnnounceHoleStatsIfReady();
					return true;
				}
				ProGolfPlugin instance = ProGolfPlugin.instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)"Skipped Pro Golf end-of-hole countdown because active players are still playing.");
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(CourseManager), "CountDownToMatchEndRoutine")]
		private static class SkipMatchEndCountdownRoutinePatch
		{
			private static bool Prefix(CourseManager __instance, ref IEnumerator __result)
			{
				if (ShouldBlockNativeEndCountdown(__instance))
				{
					__result = EmptyReadyUpHoldRoutine();
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(CourseManager), "OnMatchStateChanged")]
		private static class HoldReadyUpMatchStatePatch
		{
			private static bool Prefix(CourseManager __instance, MatchState previousState, MatchState currentState)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Invalid comparison between Unknown and I4
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if (suppressReadyMatchStateRollback || (int)currentState != 4 || !ShouldBlockNativeEndCountdown(__instance))
				{
					return true;
				}
				RollBackReadyUpMatchState(__instance, (MatchState)(((int)previousState == 4) ? 3 : ((int)previousState)));
				return false;
			}
		}

		[HarmonyPatch(typeof(CourseManager), "set_NetworkmatchState")]
		private static class BlockReadyUpMatchStateSetterPatch
		{
			private static bool Prefix(CourseManager __instance, ref MatchState value)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Expected I4, but got Unknown
				MatchState replacementState = value;
				if (!TryBlockReadyUpMatchStateChange(__instance, value, ref replacementState))
				{
					return true;
				}
				value = (MatchState)(int)replacementState;
				return true;
			}
		}

		[HarmonyPatch(typeof(CourseManager), "ServerStartNextMatch")]
		private static class BlockReadyUpNextMatchPatch
		{
			private static bool Prefix(CourseManager __instance)
			{
				if (!ShouldBlockNextMatchForReadyUp(__instance))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(MatchEndCountdown), "Show")]
		private static class SuppressReadyCountdownShowPatch
		{
			private static bool Prefix()
			{
				return !ShouldSuppressReadyCountdownUi();
			}
		}

		[HarmonyPatch(typeof(MatchEndCountdown), "SetTime")]
		private static class SuppressReadyCountdownSetTimePatch
		{
			private static bool Prefix()
			{
				if (!ShouldSuppressReadyCountdownUi())
				{
					return true;
				}
				MatchEndCountdown.Hide();
				return false;
			}
		}

		[HarmonyPatch(typeof(MatchEndCountdown), "EnterOvertime")]
		private static class SuppressReadyCountdownOvertimePatch
		{
			private static bool Prefix()
			{
				if (!ShouldSuppressReadyCountdownUi())
				{
					return true;
				}
				MatchEndCountdown.Hide();
				return false;
			}
		}

		[HarmonyPatch(typeof(CourseManager), "OnPlayerStatesChanged")]
		private static class AnnounceHoleStatsOnPlayerStateChangedPatch
		{
			private static void Postfix(CourseManager __instance)
			{
				if (!((Object)(object)__instance == (Object)null) && NetworkServer.active && IsProGolfScoringActive() && AllActivePlayersResolved(__instance))
				{
					TryAnnounceClosestToPinIfReady();
					TryAnnounceHoleStatsIfReady();
					OpenReadyGateForCurrentHole();
				}
			}
		}

		[HarmonyPatch(typeof(PlayerState), "CompareTo")]
		private static class ProGolfStrokeFirstPlayerStateSortPatch
		{
			private static bool Prefix(PlayerState __instance, PlayerState other, ref int __result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return !TryCompareProGolfPlayerStates(__instance, other, ref __result);
			}
		}

		[HarmonyPatch(typeof(ScoreboardEntry), "PopulateWith")]
		private static class ProGolfScoreboardEntryStatsPatch
		{
			private static void Postfix(ScoreboardEntry __instance, PlayerState playerState)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				UpdateScoreboardEntryProGolfStats(__instance, playerState);
			}
		}

		[HarmonyPatch(typeof(Scoreboard), "Show")]
		private static class OpenReadyGateOnScoreboardShowPatch
		{
			private static void Postfix()
			{
				if (NetworkServer.active && IsReadyScoreboardWindowActive())
				{
					OpenReadyGateForCurrentHole();
				}
			}
		}

		[HarmonyPatch(typeof(Scoreboard), "Refresh")]
		private static class ProGolfScoreboardStatCardPatch
		{
			private static void Postfix(Scoreboard __instance)
			{
				UpdateScoreboardProGolfStatCard(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerGolfer), "InformScored")]
		private static class CaptureClosestToPinOnScorePatch
		{
			private static void Prefix(PlayerGolfer __instance)
			{
				CaptureClosestToPinOnScore(__instance);
			}
		}

		[HarmonyPatch(typeof(CourseManager), "TryPlayHoleMusic")]
		private static class ForceNormalHoleMusicPatch
		{
			private static void Prefix(ref bool hurryUpInstantly)
			{
				if (IsActiveProGolf())
				{
					hurryUpInstantly = false;
				}
			}
		}

		[HarmonyPatch(typeof(CourseManager), "HurryUpHoleMusic")]
		private static class PreventHurryUpMusicPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(GolfBall), "OnWillApplyGolfSwingHitPhysics")]
		private static class BeginLongestDriveTrackingPatch
		{
			private static void Prefix(GolfBall __instance)
			{
				BeginDriveTracking(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerGolfer), "OnPlayerHitOwnBall")]
		private static class TrackPerfectShotPatch
		{
			private static void Postfix(PlayerGolfer __instance)
			{
				TrackPerfectShot(__instance);
			}
		}

		[HarmonyPatch(typeof(GolfBall), "set_IsStationary")]
		private static class CompleteLongestDriveTrackingPatch
		{
			private static void Postfix(GolfBall __instance, bool value)
			{
				if (value)
				{
					TryCompleteDriveTracking(__instance);
					TryCaptureClosestToPinFromStationaryBall(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(CourseManager), "AddPenaltyStroke")]
		private static class InvalidatePenaltyDrivePatch
		{
			private static void Prefix(PlayerGolfer penalizedPlayer)
			{
				InvalidateFirstDrive((penalizedPlayer != null) ? penalizedPlayer.PlayerInfo : null);
			}
		}

		[HarmonyPatch(typeof(PlayerGolfer), "ServerEliminate")]
		private static class HazardEliminationRespawnPatch
		{
			private static bool Prefix(PlayerGolfer __instance, EliminationReason immediateEliminationReason)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if (TryRespawnHazardEliminationAtBall(__instance, immediateEliminationReason))
				{
					return false;
				}
				MarkBallRespawnForHazardElimination(__instance, immediateEliminationReason);
				return true;
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "TryBeginRespawn")]
		private static class BeginRespawnAtBallPatch
		{
			private static void Prefix(PlayerMovement __instance, ref RespawnTarget respawnTarget)
			{
				RedirectHazardRespawnToBall(__instance, ref respawnTarget);
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "CmdPlayOutOfBoundsEliminationExplosionForAllClients")]
		private static class SuppressPlayerOutOfBoundsExplosionCommandPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "RpcPlayOutOfBoundsEliminationExplosion")]
		private static class SuppressPlayerOutOfBoundsExplosionRpcPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "PlayOutOfBoundsEliminationExplosionInternal")]
		private static class SuppressPlayerOutOfBoundsExplosionPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(GolfCartInfo), "ServerPlayOutOfBoundsEliminationExplosionForAllClients")]
		private static class SuppressCartOutOfBoundsExplosionServerPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(GolfCartInfo), "RpcPlayOutOfBoundsEliminationExplosion")]
		private static class SuppressCartOutOfBoundsExplosionRpcPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(GolfCartInfo), "PlayOutOfBoundsEliminationExplosionInternal")]
		private static class SuppressCartOutOfBoundsExplosionPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(PlayerGolfer), "CanMove")]
		private static class AllowMovementAfterHoleOutPatch
		{
			private static void Postfix(PlayerGolfer __instance, ref bool __result)
			{
				if (IsActiveProGolf() && HasPlayerScoredThisHole(__instance))
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(GolfHole), "ServerOnBallScored")]
		private static class SuppressHoleOutScoreBlastPatch
		{
			private static bool Prefix()
			{
				return !IsActiveProGolf();
			}
		}

		[HarmonyPatch(typeof(PlayerInfo), "RpcPopUpPlacementScore")]
		private static class SuppressPlacementScorePopupPatch
		{
			private static bool Prefix(PlayerInfo __instance)
			{
				if (!IsActiveProGolf())
				{
					return true;
				}
				ShowProGolfHoleOutPopup(__instance);
				return false;
			}
		}

		[HarmonyPatch]
		private static class SuppressPlacementScorePopupUserCodePatch
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(typeof(PlayerInfo), "UserCode_RpcPopUpPlacementScore__Int32__Int32", (Type[])null, (Type[])null);
			}

			private static bool Prefix(PlayerInfo __instance)
			{
				if (!IsActiveProGolf())
				{
					return true;
				}
				ShowProGolfHoleOutPopup(__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerInfo), "RpcPopUp")]
		private static class SuppressScorePopupPatch
		{
			private static bool Prefix(PlayerTextPopupType popupType)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				if (IsActiveProGolf())
				{
					return !IsProGolfScorePopupType(popupType);
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class SuppressScorePopupUserCodePatch
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(typeof(PlayerInfo), "UserCode_RpcPopUp__PlayerTextPopupType__Int32", (Type[])null, (Type[])null);
			}

			private static bool Prefix(PlayerInfo __instance, PlayerTextPopupType popupType)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				if (!IsActiveProGolf() || !IsProGolfScorePopupType(popupType))
				{
					return true;
				}
				if (HasPlayerScoredThisHole((__instance != null) ? __instance.AsGolfer : null))
				{
					ShowProGolfHoleOutPopup(__instance);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerInfo), "PopUpInternal")]
		private static class SuppressNativePlayerPopupInternalPatch
		{
			private static bool Prefix(PlayerInfo __instance)
			{
				if (!IsActiveProGolf() || isShowingProGolfHoleOutPopup)
				{
					return true;
				}
				if (HasPlayerScoredThisHole((__instance != null) ? __instance.AsGolfer : null))
				{
					ShowProGolfHoleOutPopup(__instance);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Checkpoint), "Awake")]
		private static class HideCheckpointOnAwakePatch
		{
			private static void Postfix(Checkpoint __instance)
			{
				if (IsActiveProGolf())
				{
					SuppressCheckpointVisuals(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerInventorySettings), "get_MaxItems")]
		private static class MinimumProGolfInventoryPatch
		{
			private static void Postfix(ref int __result)
			{
				if (IsActiveProGolf())
				{
					__result = 3;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "OnStartServer")]
		private static class ServerStartLoadoutPatch
		{
			private static void Postfix(PlayerInventory __instance)
			{
				EnsureProGolfLoadout(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "OnStartLocalPlayer")]
		private static class LocalStartLoadoutPatch
		{
			private static void Postfix(PlayerInventory __instance)
			{
				EnsureProGolfLoadout(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "ServerTryAddItem")]
		private static class ProGolfItemGrantPatch
		{
			private static bool Prefix(PlayerInventory __instance, ItemType itemToAdd, ref bool __result)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Invalid comparison between Unknown and I4
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				if (!IsActiveProGolf() || !NetworkServer.active)
				{
					return true;
				}
				EnsureProGolfLoadout(__instance);
				if ((int)itemToAdd == 6 || (int)itemToAdd == 1 || (int)itemToAdd == 5)
				{
					__result = true;
					return false;
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(ItemPool), "GetWeightedRandomItem")]
		private static class RemovePermanentItemsFromItemPoolsPatch
		{
			private static bool Prefix(ItemPool __instance, ref ItemType __result)
			{
				if (!IsActiveProGolf())
				{
					return true;
				}
				return !TryGetWeightedRandomAllowedPickupItem(__instance, out __result);
			}
		}

		[HarmonyPatch(typeof(ItemSpawner), "OnStartServer")]
		private static class HideInitialItemSpawnersPatch
		{
			private static void Postfix(ItemSpawner __instance)
			{
				if (IsActiveProGolf() && (Object)(object)__instance != (Object)null)
				{
					SuppressItemSpawner(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(ItemSpawner), "ServerSpawnItemBox")]
		private static class PreventItemSpawnerRespawnsPatch
		{
			private static bool Prefix(ItemSpawner __instance)
			{
				if (!IsActiveProGolf())
				{
					return true;
				}
				if ((Object)(object)__instance != (Object)null)
				{
					SuppressItemSpawner(__instance);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "DecrementUseFromSlotAt")]
		private static class KeepPermanentItemsLoadedPatch
		{
			private static bool Prefix(PlayerInventory __instance, int index)
			{
				return !IsReservedPermanentSlot(__instance, index);
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "RemoveIfOutOfUses")]
		private static class PreventPermanentItemsRemovalPatch
		{
			private static bool Prefix(PlayerInventory __instance, int index)
			{
				return !IsReservedPermanentSlot(__instance, index);
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "DropItem")]
		private static class PreventDroppingPermanentItemsPatch
		{
			private static bool Prefix(PlayerInventory __instance)
			{
				return !IsReservedPermanentSlot(__instance, __instance.EquippedItemIndex);
			}
		}

		private const string PluginGuid = "codex.superbattlegolf.progolfplus";

		private const string PluginName = "Pro Golf Plus";

		private const string PluginVersion = "0.1.43";

		private const string LobbyMemberVersionKey = "codex_progolfplus_member_version";

		private const string LobbyRequiredVersionKey = "codex_progolfplus_required_version";

		private const string LobbyActiveStateKey = "codex_progolfplus_active";

		private const string LobbyActiveVersionKey = "codex_progolfplus_active_version";

		private const string LobbyAnnouncementTextKey = "codex_progolfplus_announcement_text";

		private const string LobbyAnnouncementVersionKey = "codex_progolfplus_announcement_version";

		private const string LobbyHoleStatsPayloadKey = "codex_progolfplus_hole_stats_payload";

		private const string LobbyHoleStatsVersionKey = "codex_progolfplus_hole_stats_version";

		private const string LobbyReadyHoleKey = "codex_progolfplus_ready_hole";

		private const string LobbyReadyGateHoleKey = "codex_progolfplus_ready_gate_hole";

		private const string LobbyReadyGateVersionKey = "codex_progolfplus_ready_gate_version";

		private const float LobbyPollInterval = 1f;

		private const float LocalMemberVersionPublishInterval = 2f;

		private const int ReservedCartSlotIndex = 0;

		private const int ReservedCoffeeSlotIndex = 1;

		private const int ReservedSpringBootsSlotIndex = 2;

		private const int TotalInventorySlots = 3;

		private const float CartFlipPollInterval = 0.25f;

		private const float CartDiscoveryPollInterval = 1f;

		private const float CartUprightDotThreshold = 0.65f;

		private const float CartMovingSpeedThreshold = 0.35f;

		private const float CartMovingAngularThreshold = 0.35f;

		private const float CartFlipStartAngularThreshold = 1f;

		private const float CartFlipFullRotationRadians = (float)Math.PI * 2f;

		private const float CartSettledSeconds = 0.5f;

		private const float ClosestToPinRadiusMeters = 9.144f;

		private static ProGolfPlugin instance;

		private static FieldInfo inventorySlotsField;

		private static FieldInfo itemPoolSpawnChancesField;

		private static FieldInfo itemSpawnerVisualsField;

		private static FieldInfo itemSpawnerPickupColliderField;

		private static FieldInfo itemSpawnerVisualsFillingObjectField;

		private static FieldInfo itemSpawnerVisualsIdleObjectField;

		private static FieldInfo itemSpawnerVisualsFillRendererField;

		private static FieldInfo itemSpawnerVisualsAnimatorField;

		private static FieldInfo checkpointVisualCenterField;

		private static FieldInfo checkpointBaseMeshField;

		private static FieldInfo checkpointScreenMeshField;

		private static FieldInfo checkpointAnimatorField;

		private static FieldInfo scoreboardEntryStatsBackgroundField;

		private static FieldInfo scoreboardEntryNameField;

		private static FieldInfo scoreboardEntryParentField;

		private static FieldInfo scoreboardBestHoleScoreStatField;

		private static FieldInfo scoreboardLongestChipInStatField;

		private static FieldInfo scoreboardItemPickupsStatField;

		private static FieldInfo scoreboardKnockoutRatioStatField;

		private static FieldInfo scoreboardStatLabelField;

		private static FieldInfo golfBallIsInHoleField;

		private static MethodInfo scoreboardMarkDirtyMethod;

		private static MethodInfo playerPopUpTextMethod;

		private static bool isShowingProGolfHoleOutPopup;

		private static bool allLobbyMembersCompatible = true;

		private static string incompatibleLobbyMembers = string.Empty;

		private static float nextLobbyPollTime;

		private static float nextLocalMemberVersionPublishTime;

		private static float nextCompatibilityWarningTime;

		private static bool lastPublishedActiveState;

		private static string lastObservedActiveVersion = string.Empty;

		private static bool hasObservedActiveState;

		private static bool lastObservedActiveState;

		private static string lastObservedHoleStatsVersion = string.Empty;

		private static string lastObservedReadyGateVersion = string.Empty;

		private static int observedReadyGateHoleIndex = int.MinValue;

		private static readonly Dictionary<GolfBall, DriveCandidate> activeDrives = new Dictionary<GolfBall, DriveCandidate>();

		private static readonly Dictionary<ulong, FirstDriveResult> firstDriveResults = new Dictionary<ulong, FirstDriveResult>();

		private static readonly Dictionary<ulong, ClosestToPinResult> closestToPinResults = new Dictionary<ulong, ClosestToPinResult>();

		private static readonly Dictionary<ulong, int> perfectShotCounts = new Dictionary<ulong, int>();

		private static readonly Dictionary<ulong, int> cartBestFlipStreaks = new Dictionary<ulong, int>();

		private static readonly Dictionary<ulong, string> scoreboardRowRelativeScoreTexts = new Dictionary<ulong, string>();

		private static readonly Dictionary<int, int> parByHoleIndex = new Dictionary<int, int>();

		private static readonly Dictionary<ulong, float> holeStatsLongestDriveDistances = new Dictionary<ulong, float>();

		private static readonly Dictionary<ulong, float> holeStatsClosestToPinDistances = new Dictionary<ulong, float>();

		private static readonly Dictionary<ulong, float> holeStatsChipInDistances = new Dictionary<ulong, float>();

		private static readonly HashSet<ulong> holeOutPopupsShown = new HashSet<ulong>();

		private static readonly Dictionary<GolfCartMovement, CartFlipState> cartFlipStates = new Dictionary<GolfCartMovement, CartFlipState>();

		private static readonly HashSet<PlayerMovement> forceNextRespawnAtBall = new HashSet<PlayerMovement>();

		private static readonly HashSet<ItemSpawner> suppressedItemSpawners = new HashSet<ItemSpawner>();

		private static readonly HashSet<Checkpoint> suppressedCheckpoints = new HashSet<Checkpoint>();

		private static readonly List<GolfCartMovement> cachedCarts = new List<GolfCartMovement>();

		private static readonly List<GolfCartMovement> staleCarts = new List<GolfCartMovement>();

		private static int longestDriveHoleIndex = int.MinValue;

		private static bool longestDriveAnnounced;

		private static bool closestToPinAnnounced;

		private static bool holeStatsAnnounced;

		private static string lastObservedAnnouncementVersion = string.Empty;

		private static string topAnnouncementText = string.Empty;

		private static string topAnnouncementDetailText = string.Empty;

		private static float topAnnouncementVisibleUntil;

		private static float nextCartFlipPollTime;

		private static float nextCartDiscoveryPollTime;

		private static GUIStyle topAnnouncementBoxStyle;

		private static GUIStyle topAnnouncementTextStyle;

		private static GUIStyle topAnnouncementDetailStyle;

		private static GUIStyle readyUpBoxStyle;

		private static GUIStyle readyUpHeaderStyle;

		private static GUIStyle readyUpRowStyle;

		private static GUIStyle readyUpPromptStyle;

		private static Texture2D topAnnouncementBoxTexture;

		private static Texture2D readyUpBoxTexture;

		private static Texture2D proGolfCardHeaderTexture;

		private static Texture2D proGolfCardBandTexture;

		private static Texture2D proGolfReadyFlagTexture;

		private static Sprite proGolfCardHeaderSprite;

		private static Sprite proGolfCardBandSprite;

		private static Sprite proGolfReadyFlagSprite;

		private static readonly Dictionary<ScoreboardEntry, TextMeshProUGUI> scoreboardEntryStatLabels = new Dictionary<ScoreboardEntry, TextMeshProUGUI>();

		private static readonly Dictionary<ScoreboardEntry, GameObject> scoreboardEntryReadyIndicators = new Dictionary<ScoreboardEntry, GameObject>();

		private static readonly Dictionary<Scoreboard, GameObject> scoreboardAllPlayerStatsPanels = new Dictionary<Scoreboard, GameObject>();

		private static readonly Dictionary<Scoreboard, GameObject> scoreboardReadyUpPanels = new Dictionary<Scoreboard, GameObject>();

		private static int readyGateHoleIndex = int.MinValue;

		private static int readyGateCountdownTriggeredHoleIndex = int.MinValue;

		private static int localReadyHoleIndex = int.MinValue;

		private static int lastParTrackedHoleIndex = int.MinValue;

		private static float nextReadyGateLogTime;

		private static float nextReadyScoreboardRefreshTime;

		private static float nextReadyStateBlockLogTime;

		private static bool suppressReadyMatchStateRollback;

		private Harmony harmony;

		private ConfigEntry<bool> enabledConfig;

		private ConfigEntry<bool> readyUpBetweenHolesConfig;

		private ConfigEntry<float> grantCheckIntervalConfig;

		private ConfigEntry<float> longestDriveMinimumMetersConfig;

		private float nextGrantCheckTime;

		private void Awake()
		{
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Expected O, but got Unknown
			instance = this;
			enabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable Pro Golf Plus.");
			readyUpBetweenHolesConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Ready Up", "Enabled", true, "Require every active Pro Golf player to press A before the host advances from the end-of-hole scoreboard.");
			grantCheckIntervalConfig = ((BaseUnityPlugin)this).Config.Bind<float>("General", "GrantCheckIntervalSeconds", 0.5f, "How often the host checks whether every Pro Golf player needs a cart.");
			longestDriveMinimumMetersConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Longest Drive", "MinimumDistanceMeters", 15f, "Minimum drive distance required before a Longest Drive popup can appear.");
			inventorySlotsField = AccessTools.Field(typeof(PlayerInventory), "slots");
			itemPoolSpawnChancesField = AccessTools.Field(typeof(ItemPool), "spawnChances");
			itemSpawnerVisualsField = AccessTools.Field(typeof(ItemSpawner), "visuals");
			itemSpawnerPickupColliderField = AccessTools.Field(typeof(ItemSpawner), "pickUpCollider");
			itemSpawnerVisualsFillingObjectField = AccessTools.Field(typeof(ItemSpawnerVisuals), "fillingObj");
			itemSpawnerVisualsIdleObjectField = AccessTools.Field(typeof(ItemSpawnerVisuals), "idleObj");
			itemSpawnerVisualsFillRendererField = AccessTools.Field(typeof(ItemSpawnerVisuals), "fillMeshRenderer");
			itemSpawnerVisualsAnimatorField = AccessTools.Field(typeof(ItemSpawnerVisuals), "animator");
			checkpointVisualCenterField = AccessTools.Field(typeof(Checkpoint), "visualCenter");
			checkpointBaseMeshField = AccessTools.Field(typeof(Checkpoint), "baseMesh");
			checkpointScreenMeshField = AccessTools.Field(typeof(Checkpoint), "screenMesh");
			checkpointAnimatorField = AccessTools.Field(typeof(Checkpoint), "animator");
			scoreboardEntryStatsBackgroundField = AccessTools.Field(typeof(ScoreboardEntry), "statsBackground");
			scoreboardEntryNameField = AccessTools.Field(typeof(ScoreboardEntry), "name");
			scoreboardEntryParentField = AccessTools.Field(typeof(Scoreboard), "entryParent");
			scoreboardBestHoleScoreStatField = AccessTools.Field(typeof(Scoreboard), "bestHoleScore");
			scoreboardLongestChipInStatField = AccessTools.Field(typeof(Scoreboard), "longestChipIn");
			scoreboardItemPickupsStatField = AccessTools.Field(typeof(Scoreboard), "itemPickups");
			scoreboardKnockoutRatioStatField = AccessTools.Field(typeof(Scoreboard), "knockoutRatio");
			scoreboardStatLabelField = AccessTools.Field(typeof(ScoreboardStat), "label");
			golfBallIsInHoleField = AccessTools.Field(typeof(GolfBall), "isInHole");
			scoreboardMarkDirtyMethod = AccessTools.Method(typeof(Scoreboard), "MarkDirty", (Type[])null, (Type[])null);
			playerPopUpTextMethod = AccessTools.Method(typeof(PlayerInfo), "PopUpText", new Type[2]
			{
				typeof(string),
				typeof(bool)
			}, (Type[])null);
			harmony = new Harmony("codex.superbattlegolf.progolfplus");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Pro Golf Plus 0.1.43 loaded.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			DestroyTopAnnouncementStyles();
			DestroyReadyUpStyles();
			if (instance == this)
			{
				instance = null;
			}
		}

		private void OnGUI()
		{
			DrawTopAnnouncement();
		}

		private void Update()
		{
			PollLobbyCompatibility();
			PollReadyUpInput();
			PollReadyUpScoreboards();
			PollCartFlipStats();
			if (IsProGolfScoringActive())
			{
				TrackCurrentHolePar();
				ResetLongestDriveIfHoleChanged();
			}
			if (IsActiveProGolf() && !(Time.unscaledTime < nextGrantCheckTime))
			{
				nextGrantCheckTime = Time.unscaledTime + Mathf.Max(0.25f, grantCheckIntervalConfig.Value);
				TryEnsureAllPlayersHaveProGolfLoadout();
				TrySuppressAllItemSpawners();
				TrySuppressCheckpoints();
			}
		}

		private static bool IsActiveProGolf()
		{
			if ((Object)(object)instance == (Object)null || !instance.enabledConfig.Value)
			{
				return false;
			}
			if (NetworkServer.active && !allLobbyMembersCompatible)
			{
				return false;
			}
			if (!HostAllowsClientProGolf())
			{
				return false;
			}
			if (IsCurrentPresetProGolf())
			{
				return IsMatchUnderway();
			}
			return false;
		}

		private static bool IsMatchUnderway()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			MatchState matchState = CourseManager.MatchState;
			if ((int)matchState >= 1)
			{
				return (int)matchState < 6;
			}
			return false;
		}

		private static bool IsProGolfScoringActive()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			if ((Object)(object)instance == (Object)null || !instance.enabledConfig.Value)
			{
				return false;
			}
			if (NetworkServer.active && !allLobbyMembersCompatible)
			{
				return false;
			}
			if (!HostAllowsClientProGolf())
			{
				return false;
			}
			if (IsCurrentPresetProGolf())
			{
				return (int)CourseManager.MatchState >= 1;
			}
			return false;
		}

		private static bool IsCurrentPresetProGolf()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			MatchSetupRules val = FindMatchSetupRules();
			if ((Object)(object)val != (Object)null)
			{
				return (int)val.CurrentPreset == 1;
			}
			return false;
		}

		private static bool IsProGolfScoreboardState()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((Object)(object)instance != (Object)null && instance.enabledConfig.Value && IsCurrentPresetProGolf())
			{
				return (int)CourseManager.MatchState == 6;
			}
			return false;
		}

		private static bool HostAllowsClientProGolf()
		{
			if (NetworkClient.active && !NetworkServer.active && hasObservedActiveState)
			{
				return lastObservedActiveState;
			}
			return true;
		}

		private static void TrackCurrentHolePar()
		{
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			if (currentHoleGlobalIndex >= 0)
			{
				if (lastParTrackedHoleIndex != int.MinValue && currentHoleGlobalIndex < lastParTrackedHoleIndex)
				{
					parByHoleIndex.Clear();
				}
				lastParTrackedHoleIndex = currentHoleGlobalIndex;
				int currentHoleParSafe = GetCurrentHoleParSafe();
				if (currentHoleParSafe > 0)
				{
					parByHoleIndex[currentHoleGlobalIndex] = currentHoleParSafe;
				}
			}
		}

		private static void ResetLongestDriveIfHoleChanged()
		{
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			if (currentHoleGlobalIndex != longestDriveHoleIndex)
			{
				longestDriveHoleIndex = currentHoleGlobalIndex;
				longestDriveAnnounced = false;
				closestToPinAnnounced = false;
				holeStatsAnnounced = false;
				readyGateHoleIndex = int.MinValue;
				readyGateCountdownTriggeredHoleIndex = int.MinValue;
				localReadyHoleIndex = int.MinValue;
				observedReadyGateHoleIndex = int.MinValue;
				nextReadyGateLogTime = 0f;
				nextReadyStateBlockLogTime = 0f;
				activeDrives.Clear();
				firstDriveResults.Clear();
				closestToPinResults.Clear();
				perfectShotCounts.Clear();
				cartBestFlipStreaks.Clear();
				scoreboardRowRelativeScoreTexts.Clear();
				holeStatsLongestDriveDistances.Clear();
				holeStatsClosestToPinDistances.Clear();
				holeStatsChipInDistances.Clear();
				holeOutPopupsShown.Clear();
				cartFlipStates.Clear();
				suppressedItemSpawners.Clear();
				suppressedCheckpoints.Clear();
				cachedCarts.Clear();
				staleCarts.Clear();
			}
		}

		private static void PollLobbyCompatibility()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextLobbyPollTime)
			{
				return;
			}
			nextLobbyPollTime = Time.unscaledTime + 1f;
			Lobby lobby = default(Lobby);
			if (!BNetworkManager.TryGetSteamLobby(ref lobby))
			{
				if (!NetworkServer.active && !NetworkClient.active)
				{
					allLobbyMembersCompatible = true;
					incompatibleLobbyMembers = string.Empty;
					hasObservedActiveState = false;
					lastObservedActiveState = false;
				}
				return;
			}
			PublishLocalMemberVersion(lobby);
			PollActiveState(lobby);
			PollProGolfAnnouncement(lobby);
			PollProGolfHoleStats(lobby);
			PollReadyGateState(lobby);
			if (NetworkServer.active)
			{
				UpdateLobbyCompatibility(lobby);
				PublishActiveState(lobby, IsActiveProGolf() || IsProGolfScoreboardState());
			}
		}

		private static void PollReadyGateState(Lobby lobby)
		{
			string data = ((Lobby)(ref lobby)).GetData("codex_progolfplus_ready_gate_version");
			if (!string.IsNullOrEmpty(data) && !(data == lastObservedReadyGateVersion))
			{
				lastObservedReadyGateVersion = data;
				observedReadyGateHoleIndex = (int.TryParse(((Lobby)(ref lobby)).GetData("codex_progolfplus_ready_gate_hole"), out var result) ? result : int.MinValue);
				MarkScoreboardsDirty();
			}
		}

		private static void PollProGolfHoleStats(Lobby lobby)
		{
			string data = ((Lobby)(ref lobby)).GetData("codex_progolfplus_hole_stats_version");
			if (!string.IsNullOrEmpty(data) && !(data == lastObservedHoleStatsVersion))
			{
				lastObservedHoleStatsVersion = data;
				ApplyHoleStatsPayload(((Lobby)(ref lobby)).GetData("codex_progolfplus_hole_stats_payload"));
				MarkScoreboardsDirty();
			}
		}

		private static void PublishActiveState(Lobby lobby, bool active)
		{
			if (active != lastPublishedActiveState || string.IsNullOrEmpty(((Lobby)(ref lobby)).GetData("codex_progolfplus_active")))
			{
				lastPublishedActiveState = active;
				((Lobby)(ref lobby)).SetData("codex_progolfplus_active", active ? "1" : "0");
				((Lobby)(ref lobby)).SetData("codex_progolfplus_active_version", Time.unscaledTime.ToString("R"));
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Published Pro Golf Plus active lobby state: {active}.");
				}
			}
		}

		private static void PollActiveState(Lobby lobby)
		{
			string data = ((Lobby)(ref lobby)).GetData("codex_progolfplus_active_version");
			if (!string.IsNullOrEmpty(data) && !(data == lastObservedActiveVersion))
			{
				bool flag = ((Lobby)(ref lobby)).GetData("codex_progolfplus_active") == "1";
				hasObservedActiveState = true;
				lastObservedActiveState = flag;
				lastObservedActiveVersion = data;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Observed Pro Golf Plus active lobby state: {flag}.");
				}
			}
		}

		private static void PollProGolfAnnouncement(Lobby lobby)
		{
			string data = ((Lobby)(ref lobby)).GetData("codex_progolfplus_announcement_version");
			if (!string.IsNullOrEmpty(data) && !(data == lastObservedAnnouncementVersion))
			{
				lastObservedAnnouncementVersion = data;
				string data2 = ((Lobby)(ref lobby)).GetData("codex_progolfplus_announcement_text");
				if (!string.IsNullOrEmpty(data2))
				{
					ShowTopAnnouncement(data2);
				}
			}
		}

		private static void PublishLocalMemberVersion(Lobby lobby)
		{
			if (SteamClient.IsValid && !(Time.unscaledTime < nextLocalMemberVersionPublishTime))
			{
				nextLocalMemberVersionPublishTime = Time.unscaledTime + 2f;
				((Lobby)(ref lobby)).SetMemberData("codex_progolfplus_member_version", "0.1.43");
			}
		}

		private unsafe static void UpdateLobbyCompatibility(Lobby lobby)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (!string.Equals(((Lobby)(ref lobby)).GetData("codex_progolfplus_required_version"), "0.1.43", StringComparison.Ordinal))
			{
				((Lobby)(ref lobby)).SetData("codex_progolfplus_required_version", "0.1.43");
			}
			List<string> list = new List<string>();
			foreach (Friend member in ((Lobby)(ref lobby)).Members)
			{
				Friend current = member;
				string memberData = ((Lobby)(ref lobby)).GetMemberData(current, "codex_progolfplus_member_version");
				if (!string.Equals(memberData, "0.1.43", StringComparison.Ordinal))
				{
					string? text;
					if (!string.IsNullOrEmpty(((Friend)(ref current)).Name))
					{
						text = ((Friend)(ref current)).Name;
					}
					else
					{
						SteamId id = current.Id;
						text = ((object)(*(SteamId*)(&id))/*cast due to .constrained prefix*/).ToString();
					}
					string text2 = text;
					list.Add(string.IsNullOrEmpty(memberData) ? (text2 + " (missing Pro Golf Plus 0.1.43)") : (text2 + " (Pro Golf Plus " + memberData + ", needs 0.1.43)"));
				}
			}
			allLobbyMembersCompatible = list.Count == 0;
			incompatibleLobbyMembers = string.Join(", ", list);
			if (!allLobbyMembersCompatible && Time.unscaledTime >= nextCompatibilityWarningTime)
			{
				nextCompatibilityWarningTime = Time.unscaledTime + 10f;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogWarning((object)("Pro Golf Plus disabled until every lobby member is running Pro Golf Plus 0.1.43: " + incompatibleLobbyMembers));
				}
			}
		}

		private static MatchSetupRules FindMatchSetupRules()
		{
			if (SingletonNetworkBehaviour<MatchSetupRules>.HasInstance)
			{
				return SingletonNetworkBehaviour<MatchSetupRules>.Instance;
			}
			if (SingletonBehaviour<MatchSetupRules>.HasInstance)
			{
				return SingletonBehaviour<MatchSetupRules>.Instance;
			}
			return Object.FindFirstObjectByType<MatchSetupRules>((FindObjectsInactive)1);
		}

		private void TryEnsureAllPlayersHaveProGolfLoadout()
		{
			if (!NetworkServer.active)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			PlayerInventory[] array = Object.FindObjectsByType<PlayerInventory>((FindObjectsSortMode)0);
			foreach (PlayerInventory val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					num++;
					if (EnsureProGolfLoadout(val))
					{
						num2++;
					}
				}
			}
			if (num2 > 0)
			{
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Ensured Pro Golf loadout for {num2}/{num} player inventories.");
				}
			}
		}

		private static void TrySuppressAllItemSpawners()
		{
			if (!IsActiveProGolf())
			{
				return;
			}
			ItemSpawner[] array = Object.FindObjectsByType<ItemSpawner>((FindObjectsSortMode)0);
			foreach (ItemSpawner val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					SuppressItemSpawner(val);
				}
			}
		}

		private static void SuppressItemSpawner(ItemSpawner spawner)
		{
			if ((Object)(object)spawner == (Object)null)
			{
				return;
			}
			if (suppressedItemSpawners.Contains(spawner))
			{
				if (NetworkServer.active)
				{
					if (spawner.NetworkhasItemBox)
					{
						spawner.NetworkhasItemBox = false;
					}
					if (spawner.NetworkvisualsFill != 0f)
					{
						spawner.NetworkvisualsFill = 0f;
					}
				}
				return;
			}
			if (NetworkServer.active)
			{
				spawner.NetworkhasItemBox = false;
				spawner.NetworkvisualsFill = 0f;
			}
			object? obj = itemSpawnerPickupColliderField?.GetValue(spawner);
			Collider val = (Collider)((obj is Collider) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				val.enabled = false;
			}
			object obj2 = itemSpawnerVisualsField?.GetValue(spawner);
			object? obj3 = itemSpawnerVisualsFillingObjectField?.GetValue(obj2);
			SetSpawnerVisualObjectActive((GameObject)((obj3 is GameObject) ? obj3 : null), active: false);
			object? obj4 = itemSpawnerVisualsIdleObjectField?.GetValue(obj2);
			SetSpawnerVisualObjectActive((GameObject)((obj4 is GameObject) ? obj4 : null), active: false);
			object? obj5 = itemSpawnerVisualsFillRendererField?.GetValue(obj2);
			MeshRenderer val2 = (MeshRenderer)((obj5 is MeshRenderer) ? obj5 : null);
			if ((Object)(object)val2 != (Object)null)
			{
				((Renderer)val2).enabled = false;
			}
			object? obj6 = itemSpawnerVisualsAnimatorField?.GetValue(obj2);
			Behaviour val3 = (Behaviour)((obj6 is Behaviour) ? obj6 : null);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.enabled = false;
			}
			Renderer[] componentsInChildren = ((Component)spawner).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			suppressedItemSpawners.Add(spawner);
		}

		private static void SetSpawnerVisualObjectActive(GameObject gameObject, bool active)
		{
			if ((Object)(object)gameObject != (Object)null && gameObject.activeSelf != active)
			{
				gameObject.SetActive(active);
			}
		}

		private static void ShowTopAnnouncement(string text)
		{
			SplitAnnouncementText(text, out topAnnouncementText, out topAnnouncementDetailText);
			topAnnouncementVisibleUntil = Time.unscaledTime + (text.StartsWith("Hole Stats:", StringComparison.Ordinal) ? 8f : 6f);
		}

		private static void DrawTopAnnouncement()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(topAnnouncementText) && !(Time.unscaledTime >= topAnnouncementVisibleUntil))
			{
				EnsureTopAnnouncementStyles();
				float num = Mathf.Clamp((float)Screen.width * 0.78f, 620f, 1060f);
				int num2 = ((!string.IsNullOrEmpty(topAnnouncementDetailText)) ? topAnnouncementDetailText.Split(new char[1] { '\n' }).Length : 0);
				float num3 = (string.IsNullOrEmpty(topAnnouncementDetailText) ? 104f : (100f + Mathf.Max(42f, (float)num2 * 34f)));
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((float)Screen.width - num) * 0.5f, Mathf.Max(64f, (float)Screen.height * 0.28f), num, num3);
				GUI.Box(val, GUIContent.none, topAnnouncementBoxStyle);
				GUI.Label(new Rect(((Rect)(ref val)).x + 26f, ((Rect)(ref val)).y + 20f, ((Rect)(ref val)).width - 52f, 64f), topAnnouncementText, topAnnouncementTextStyle);
				if (!string.IsNullOrEmpty(topAnnouncementDetailText))
				{
					GUI.Label(new Rect(((Rect)(ref val)).x + 26f, ((Rect)(ref val)).y + 82f, ((Rect)(ref val)).width - 52f, ((Rect)(ref val)).height - 92f), topAnnouncementDetailText, topAnnouncementDetailStyle);
				}
			}
		}

		private static void EnsureTopAnnouncementStyles()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_008e: Expected O, but got Unknown
			//IL_0098: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			if (topAnnouncementBoxStyle == null)
			{
				topAnnouncementBoxTexture = CreateStripedGuiTexture(new Color(0.05f, 0.16f, 0.27f, 0.82f), new Color(0.12f, 0.3f, 0.47f, 0.82f));
				GUIStyle val = new GUIStyle(GUI.skin.box);
				val.normal.background = topAnnouncementBoxTexture;
				val.border = new RectOffset(14, 14, 14, 14);
				val.padding = new RectOffset(22, 22, 18, 18);
				topAnnouncementBoxStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 46,
					fontStyle = (FontStyle)1
				};
				val2.normal.textColor = Color.white;
				val2.wordWrap = false;
				val2.clipping = (TextClipping)1;
				topAnnouncementTextStyle = val2;
				GUIStyle val3 = new GUIStyle(topAnnouncementTextStyle)
				{
					fontSize = 34,
					wordWrap = true
				};
				val3.normal.textColor = new Color(0.82f, 0.86f, 0.9f, 1f);
				topAnnouncementDetailStyle = val3;
			}
		}

		private static void SplitAnnouncementText(string text, out string title, out string detail)
		{
			title = text;
			detail = string.Empty;
			int num = text.IndexOf(':');
			if (num >= 0 && num < text.Length - 1)
			{
				title = text.Substring(0, num + 1).Trim();
				detail = text.Substring(num + 1).Trim();
			}
		}

		private static Texture2D CreateGuiTexture(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static Texture2D CreateStripedGuiTexture(Color baseColor, Color stripeColor)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					bool flag = (j + i) / 8 % 2 == 0;
					val.SetPixel(j, i, flag ? stripeColor : baseColor);
				}
			}
			((Texture)val).wrapMode = (TextureWrapMode)0;
			val.Apply();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static void DestroyTopAnnouncementStyles()
		{
			if ((Object)(object)topAnnouncementBoxTexture != (Object)null)
			{
				Object.Destroy((Object)(object)topAnnouncementBoxTexture);
				topAnnouncementBoxTexture = null;
			}
			topAnnouncementBoxStyle = null;
			topAnnouncementTextStyle = null;
			topAnnouncementDetailStyle = null;
		}

		private static void PollReadyUpInput()
		{
			if (NetworkServer.active && IsReadyScoreboardWindowActive())
			{
				OpenReadyGateForCurrentHole();
			}
			if (!IsReadyUpWindowActive())
			{
				return;
			}
			if (WasReadyPressedThisFrame())
			{
				PublishLocalReadyForCurrentHole();
			}
			if (NetworkServer.active && readyGateHoleIndex == CourseManager.CurrentHoleGlobalIndex && readyGateCountdownTriggeredHoleIndex != readyGateHoleIndex && AreAllActivePlayersReadyForCurrentHole())
			{
				readyGateCountdownTriggeredHoleIndex = readyGateHoleIndex;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)"All Pro Golf players are ready; starting next hole.");
				}
				InvokeServerStartNextMatch();
			}
		}

		private static void PollReadyUpScoreboards()
		{
			if (!(Time.unscaledTime < nextReadyScoreboardRefreshTime))
			{
				nextReadyScoreboardRefreshTime = Time.unscaledTime + 0.25f;
				Scoreboard[] array = Object.FindObjectsByType<Scoreboard>((FindObjectsInactive)1, (FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					UpdateScoreboardReadyUpPanel(array[i]);
				}
				if (IsReadyUpWindowActive())
				{
					MarkScoreboardsDirty();
				}
			}
		}

		private static bool WasReadyPressedThisFrame()
		{
			try
			{
				return (Keyboard.current != null && (((ButtonControl)Keyboard.current.aKey).wasPressedThisFrame || ((ButtonControl)Keyboard.current.bKey).wasPressedThisFrame || ((ButtonControl)Keyboard.current.xKey).wasPressedThisFrame)) || (Gamepad.current != null && (Gamepad.current.buttonEast.wasPressedThisFrame || Gamepad.current.buttonWest.wasPressedThisFrame || Gamepad.current.buttonSouth.wasPressedThisFrame));
			}
			catch
			{
				return false;
			}
		}

		private static bool IsReadyUpWindowActive()
		{
			if ((Object)(object)instance != (Object)null && instance.readyUpBetweenHolesConfig.Value && IsProGolfScoringActive() && Scoreboard.IsVisible && (IsReadyScoreboardWindowActive() || IsReadyGateOpenForCurrentHole()))
			{
				return GetActivePlayerGuids().Count > 0;
			}
			return false;
		}

		private static bool IsReadyScoreboardWindowActive()
		{
			if ((Object)(object)instance != (Object)null && instance.readyUpBetweenHolesConfig.Value && IsProGolfScoringActive() && Scoreboard.IsVisible && AllActivePlayersResolvedForCurrentHole())
			{
				return GetActivePlayerGuids().Count > 0;
			}
			return false;
		}

		private static bool IsReadyGateOpenForCurrentHole()
		{
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			if (readyGateHoleIndex != currentHoleGlobalIndex)
			{
				return observedReadyGateHoleIndex == currentHoleGlobalIndex;
			}
			return true;
		}

		private static void OpenReadyGateForCurrentHole()
		{
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			if (readyGateHoleIndex != currentHoleGlobalIndex)
			{
				readyGateHoleIndex = currentHoleGlobalIndex;
				readyGateCountdownTriggeredHoleIndex = int.MinValue;
				PublishReadyGateState(currentHoleGlobalIndex);
				MarkScoreboardsDirty();
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Opened Pro Golf ready-up gate for hole {currentHoleGlobalIndex}.");
				}
			}
		}

		private static void PublishReadyGateState(int holeIndex)
		{
			Lobby val = default(Lobby);
			if (NetworkServer.active && BNetworkManager.TryGetSteamLobby(ref val))
			{
				observedReadyGateHoleIndex = holeIndex;
				((Lobby)(ref val)).SetData("codex_progolfplus_ready_gate_hole", holeIndex.ToString());
				((Lobby)(ref val)).SetData("codex_progolfplus_ready_gate_version", $"{holeIndex}:{Time.unscaledTime:R}");
			}
		}

		private static void PublishLocalReadyForCurrentHole()
		{
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			if (localReadyHoleIndex != currentHoleGlobalIndex)
			{
				localReadyHoleIndex = currentHoleGlobalIndex;
				Lobby val = default(Lobby);
				if (BNetworkManager.TryGetSteamLobby(ref val))
				{
					((Lobby)(ref val)).SetMemberData("codex_progolfplus_ready_hole", currentHoleGlobalIndex.ToString());
				}
				MarkScoreboardsDirty();
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Published local Pro Golf ready-up for hole {currentHoleGlobalIndex}.");
				}
			}
		}

		private static bool AreAllActivePlayersReadyForCurrentHole()
		{
			if (!IsReadyGateOpenForCurrentHole())
			{
				return false;
			}
			List<ulong> activePlayerGuids = GetActivePlayerGuids();
			if (activePlayerGuids.Count == 0)
			{
				return false;
			}
			foreach (ulong item in activePlayerGuids)
			{
				if (!IsPlayerReadyForCurrentHole(item))
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsPlayerReadyForCurrentHole(ulong playerGuid)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			if (playerGuid != 0L && playerGuid == GetLocalPlayerGuid() && localReadyHoleIndex == currentHoleGlobalIndex)
			{
				return true;
			}
			Lobby val = default(Lobby);
			if (!BNetworkManager.TryGetSteamLobby(ref val))
			{
				return false;
			}
			foreach (Friend member in ((Lobby)(ref val)).Members)
			{
				if (TryGetFriendSteamId(member, out var steamId) && steamId == playerGuid)
				{
					return string.Equals(((Lobby)(ref val)).GetMemberData(member, "codex_progolfplus_ready_hole"), currentHoleGlobalIndex.ToString(), StringComparison.Ordinal);
				}
			}
			return false;
		}

		private static ulong GetLocalPlayerGuid()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return CourseManager.GetLocalPlayerState().playerGuid;
		}

		private unsafe static bool TryGetFriendSteamId(Friend member, out ulong steamId)
		{
			return ulong.TryParse(((object)(*(SteamId*)(&member.Id))/*cast due to .constrained prefix*/).ToString(), out steamId);
		}

		private static bool TryHoldForReadyUp(CourseManager courseManager)
		{
			if ((Object)(object)instance == (Object)null || !instance.readyUpBetweenHolesConfig.Value || !NetworkServer.active || (Object)(object)courseManager == (Object)null)
			{
				return false;
			}
			int currentHoleGlobalIndex = CourseManager.CurrentHoleGlobalIndex;
			OpenReadyGateForCurrentHole();
			if (AreAllActivePlayersReadyForCurrentHole())
			{
				return false;
			}
			if (Time.unscaledTime >= nextReadyGateLogTime)
			{
				nextReadyGateLogTime = Time.unscaledTime + 4f;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Holding Pro Golf end-of-hole countdown for ready-up on hole {currentHoleGlobalIndex}: {BuildReadyStatusSummary()}.");
				}
			}
			return true;
		}

		private static bool ShouldBlockNativeEndCountdown(CourseManager courseManager)
		{
			if ((Object)(object)instance == (Object)null || !instance.readyUpBetweenHolesConfig.Value || !NetworkServer.active || (Object)(object)courseManager == (Object)null || !IsProGolfScoringActive())
			{
				return false;
			}
			if (!AllActivePlayersResolved(courseManager))
			{
				if (Time.unscaledTime >= nextReadyGateLogTime)
				{
					nextReadyGateLogTime = Time.unscaledTime + 4f;
					ProGolfPlugin proGolfPlugin = instance;
					if (proGolfPlugin != null)
					{
						((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)"Holding Pro Golf end-of-hole countdown because active players are still playing.");
					}
				}
				MatchEndCountdown.Hide();
				return true;
			}
			return false;
		}

		private static void MaintainReadyUpHold()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			if ((Object)(object)instance == (Object)null || !instance.readyUpBetweenHolesConfig.Value || !IsProGolfScoringActive())
			{
				return;
			}
			if (ShouldSuppressReadyCountdownUi())
			{
				MatchEndCountdown.Hide();
			}
			if (NetworkServer.active && SingletonNetworkBehaviour<CourseManager>.HasInstance)
			{
				CourseManager val = SingletonNetworkBehaviour<CourseManager>.Instance;
				if (!((Object)(object)val == (Object)null) && ShouldBlockNativeEndCountdown(val) && ((int)CourseManager.MatchState == 4 || (int)CourseManager.MatchState == 5))
				{
					RollBackReadyUpMatchState(val, (MatchState)3);
				}
			}
		}

		private static bool ShouldSuppressReadyCountdownUi()
		{
			if ((Object)(object)instance == (Object)null || !instance.readyUpBetweenHolesConfig.Value || !IsProGolfScoringActive())
			{
				return false;
			}
			if (Scoreboard.IsVisible && IsReadyGateOpenForCurrentHole())
			{
				return !AreAllActivePlayersReadyForCurrentHole();
			}
			return false;
		}

		private static void RollBackReadyUpMatchState(CourseManager courseManager, MatchState fallbackState)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)courseManager == (Object)null || suppressReadyMatchStateRollback)
			{
				return;
			}
			suppressReadyMatchStateRollback = true;
			try
			{
				courseManager.NetworkmatchState = fallbackState;
				MatchEndCountdown.Hide();
			}
			finally
			{
				suppressReadyMatchStateRollback = false;
			}
		}

		private static bool TryBlockReadyUpMatchStateChange(CourseManager courseManager, MatchState requestedState, ref MatchState replacementState)
		{
			return false;
		}

		private static bool IsReadyHoldState(MatchState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if ((int)state != 4 && (int)state != 5)
			{
				return (int)state == 6;
			}
			return true;
		}

		private static bool ShouldBlockNextMatchForReadyUp(CourseManager courseManager)
		{
			if ((Object)(object)instance == (Object)null || !instance.readyUpBetweenHolesConfig.Value || !NetworkServer.active || (Object)(object)courseManager == (Object)null || !IsProGolfScoringActive())
			{
				return false;
			}
			if (!Scoreboard.IsVisible && !IsReadyGateOpenForCurrentHole())
			{
				return false;
			}
			OpenReadyGateForCurrentHole();
			if (AreAllActivePlayersReadyForCurrentHole())
			{
				return false;
			}
			MatchEndCountdown.Hide();
			if (Time.unscaledTime >= nextReadyStateBlockLogTime)
			{
				nextReadyStateBlockLogTime = Time.unscaledTime + 2f;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)("Blocked Pro Golf next-hole start until scoreboard ready-up completes: " + BuildReadyStatusSummary() + "."));
				}
			}
			return true;
		}

		private static IEnumerator EmptyReadyUpHoldRoutine()
		{
			yield break;
		}

		private static void InvokeBeginCountdownToMatchEnd()
		{
			if (SingletonNetworkBehaviour<CourseManager>.HasInstance)
			{
				AccessTools.Method(typeof(CourseManager), "BeginCountdownToMatchEnd", (Type[])null, (Type[])null)?.Invoke(SingletonNetworkBehaviour<CourseManager>.Instance, Array.Empty<object>());
			}
		}

		private static void InvokeServerStartNextMatch()
		{
			if (!NetworkServer.active || !SingletonNetworkBehaviour<CourseManager>.HasInstance)
			{
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(CourseManager), "ServerStartNextMatch", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogWarning((object)"Could not find CourseManager.ServerStartNextMatch for Pro Golf ready-up.");
				}
			}
			else
			{
				methodInfo.Invoke(SingletonNetworkBehaviour<CourseManager>.Instance, new object[1] { false });
			}
		}

		private static string BuildReadyStatusSummary()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			foreach (PlayerState sortedActivePlayerState in GetSortedActivePlayerStates())
			{
				list.Add(GetPlayerName(null, sortedActivePlayerState.playerGuid) + "=" + (IsPlayerReadyForCurrentHole(sortedActivePlayerState.playerGuid) ? "ready" : "waiting"));
			}
			if (list.Count != 0)
			{
				return string.Join(", ", list);
			}
			return "no active players";
		}

		private static void DrawReadyUpOverlay()
		{
			//IL_0078: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			if (!IsReadyUpWindowActive())
			{
				return;
			}
			EnsureReadyUpStyles();
			List<PlayerState> sortedActivePlayerStates = GetSortedActivePlayerStates();
			float num = Mathf.Clamp((float)Screen.width * 0.3f, 360f, 520f);
			float num2 = 28f;
			float num3 = 118f + (float)Mathf.Max(1, sortedActivePlayerStates.Count) * num2;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)Screen.width - num - 32f, Mathf.Max(86f, (float)Screen.height * 0.18f), num, num3);
			GUI.Box(val, GUIContent.none, readyUpBoxStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 14f, ((Rect)(ref val)).width - 36f, 30f), "Ready for next hole", readyUpHeaderStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 18f, ((Rect)(ref val)).y + 46f, ((Rect)(ref val)).width - 36f, 28f), (localReadyHoleIndex == CourseManager.CurrentHoleGlobalIndex) ? "You are ready" : "Press X to ready up", readyUpPromptStyle);
			float num4 = ((Rect)(ref val)).y + 82f;
			foreach (PlayerState item in sortedActivePlayerStates)
			{
				string text = (IsPlayerReadyForCurrentHole(item.playerGuid) ? "[Ready]" : "[Waiting]");
				GUI.Label(new Rect(((Rect)(ref val)).x + 22f, num4, ((Rect)(ref val)).width - 44f, num2), text + " " + GetPlayerName(null, item.playerGuid), readyUpRowStyle);
				num4 += num2;
			}
		}

		private static void EnsureReadyUpStyles()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_008e: Expected O, but got Unknown
			//IL_0098: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			if (readyUpBoxStyle == null)
			{
				readyUpBoxTexture = CreateStripedGuiTexture(new Color(0.04f, 0.18f, 0.12f, 0.88f), new Color(0.08f, 0.3f, 0.19f, 0.88f));
				GUIStyle val = new GUIStyle(GUI.skin.box);
				val.normal.background = readyUpBoxTexture;
				val.border = new RectOffset(14, 14, 14, 14);
				val.padding = new RectOffset(16, 16, 14, 14);
				readyUpBoxStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 24,
					fontStyle = (FontStyle)1
				};
				val2.normal.textColor = Color.white;
				readyUpHeaderStyle = val2;
				GUIStyle val3 = new GUIStyle(readyUpHeaderStyle)
				{
					fontSize = 18,
					fontStyle = (FontStyle)1
				};
				val3.normal.textColor = new Color(0.78f, 1f, 0.72f, 1f);
				readyUpPromptStyle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)3,
					fontSize = 17,
					fontStyle = (FontStyle)1
				};
				val4.normal.textColor = Color.white;
				val4.clipping = (TextClipping)1;
				readyUpRowStyle = val4;
			}
		}

		private static void DestroyReadyUpStyles()
		{
			if ((Object)(object)readyUpBoxTexture != (Object)null)
			{
				Object.Destroy((Object)(object)readyUpBoxTexture);
				readyUpBoxTexture = null;
			}
			readyUpBoxStyle = null;
			readyUpHeaderStyle = null;
			readyUpRowStyle = null;
			readyUpPromptStyle = null;
			if ((Object)(object)proGolfReadyFlagTexture != (Object)null)
			{
				Object.Destroy((Object)(object)proGolfReadyFlagTexture);
				proGolfReadyFlagTexture = null;
				proGolfReadyFlagSprite = null;
			}
		}

		private static void TrySuppressCheckpoints()
		{
			if (IsActiveProGolf())
			{
				Checkpoint[] array = Object.FindObjectsByType<Checkpoint>((FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					SuppressCheckpointVisuals(array[i]);
				}
			}
		}

		private static void SuppressCheckpointVisuals(Checkpoint checkpoint)
		{
			if ((Object)(object)checkpoint == (Object)null || suppressedCheckpoints.Contains(checkpoint))
			{
				return;
			}
			object? obj = checkpointBaseMeshField?.GetValue(checkpoint);
			MeshRenderer val = (MeshRenderer)((obj is MeshRenderer) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				((Renderer)val).enabled = false;
			}
			object? obj2 = checkpointScreenMeshField?.GetValue(checkpoint);
			MeshRenderer val2 = (MeshRenderer)((obj2 is MeshRenderer) ? obj2 : null);
			if ((Object)(object)val2 != (Object)null)
			{
				((Renderer)val2).enabled = false;
			}
			object? obj3 = checkpointAnimatorField?.GetValue(checkpoint);
			Behaviour val3 = (Behaviour)((obj3 is Behaviour) ? obj3 : null);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.enabled = false;
			}
			object? obj4 = checkpointVisualCenterField?.GetValue(checkpoint);
			Transform val4 = (Transform)((obj4 is Transform) ? obj4 : null);
			if ((Object)(object)val4 != (Object)null)
			{
				Renderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
				Collider[] componentsInChildren2 = ((Component)val4).GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					componentsInChildren2[i].enabled = false;
				}
				suppressedCheckpoints.Add(checkpoint);
			}
			else
			{
				Renderer[] componentsInChildren = ((Component)checkpoint).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
				suppressedCheckpoints.Add(checkpoint);
			}
		}

		private static SyncList<InventorySlot> GetSlots(PlayerInventory inventory)
		{
			return inventorySlotsField?.GetValue(inventory) as SyncList<InventorySlot>;
		}

		private static void EnsureSlotCount(PlayerInventory inventory)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			SyncList<InventorySlot> slots = GetSlots(inventory);
			if (slots != null)
			{
				while (slots.Count < 3)
				{
					slots.Add(InventorySlot.Empty);
				}
				while (slots.Count > 3)
				{
					slots.RemoveAt(slots.Count - 1);
				}
			}
		}

		private static bool IsCart(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot.itemType == 6)
			{
				return slot.remainingUses > 0;
			}
			return false;
		}

		private static bool IsCoffee(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot.itemType == 1)
			{
				return slot.remainingUses > 0;
			}
			return false;
		}

		private static bool IsSpringBoots(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot.itemType == 5)
			{
				return slot.remainingUses > 0;
			}
			return false;
		}

		private static bool IsPistol(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot.itemType == 2)
			{
				return slot.remainingUses > 0;
			}
			return false;
		}

		private static bool IsEmpty(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot.itemType != 0)
			{
				return slot.remainingUses <= 0;
			}
			return true;
		}

		private static bool IsReservedPermanentSlot(PlayerInventory inventory, int index)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsActiveProGolf() || !TryGetSlot(inventory, index, out var slot))
			{
				return false;
			}
			if ((index != 0 || !IsCart(slot)) && (index != 1 || !IsCoffee(slot)))
			{
				if (index == 2)
				{
					return IsSpringBoots(slot);
				}
				return false;
			}
			return true;
		}

		private static bool TryGetSlot(PlayerInventory inventory, int index, out InventorySlot slot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			slot = InventorySlot.Empty;
			SyncList<InventorySlot> slots = GetSlots(inventory);
			if (slots == null || index < 0 || index >= slots.Count)
			{
				return false;
			}
			slot = slots[index];
			return true;
		}

		private static bool EnsureProGolfLoadout(PlayerInventory inventory)
		{
			if (!IsActiveProGolf() || !NetworkServer.active)
			{
				return false;
			}
			SyncList<InventorySlot> slots = GetSlots(inventory);
			if (slots == null)
			{
				return false;
			}
			EnsureSlotCount(inventory);
			return (byte)(0u | (SetSlotIfDifferent(slots, 0, (ItemType)6) ? 1u : 0u) | (SetSlotIfDifferent(slots, 1, (ItemType)1) ? 1u : 0u) | (SetSlotIfDifferent(slots, 2, (ItemType)5) ? 1u : 0u) | (ClearNonPermanentItems(slots) ? 1u : 0u)) != 0;
		}

		private static bool SetSlotIfDifferent(SyncList<InventorySlot> slots, int index, ItemType itemType)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			InventorySlot val = slots[index];
			if (val.itemType == itemType && val.remainingUses > 0)
			{
				return false;
			}
			slots[index] = new InventorySlot(itemType, 1);
			return true;
		}

		private static bool ClearNonPermanentItems(SyncList<InventorySlot> slots)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			for (int i = 0; i < slots.Count; i++)
			{
				if (!IsPermanentLoadoutSlot(i) && !IsEmpty(slots[i]))
				{
					slots[i] = InventorySlot.Empty;
					result = true;
				}
			}
			return result;
		}

		private static bool IsPermanentLoadoutSlot(int index)
		{
			if (index != 0 && index != 1)
			{
				return index == 2;
			}
			return true;
		}

		private static bool IsBlockedProGolfPickupItem(ItemType itemType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			if ((int)itemType != 6 && (int)itemType != 1 && (int)itemType != 5 && (int)itemType != 2)
			{
				return (int)itemType == 0;
			}
			return true;
		}

		private static void MarkBallRespawnForHazardElimination(PlayerGolfer golfer, EliminationReason immediateEliminationReason)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (IsActiveProGolf() && !((Object)(object)golfer == (Object)null) && IsHazardElimination(immediateEliminationReason))
			{
				PlayerInfo playerInfo = golfer.PlayerInfo;
				PlayerMovement val = ((playerInfo != null) ? playerInfo.Movement : null);
				GolfBall ownBall = golfer.OwnBall;
				if (!((Object)(object)val == (Object)null) && !((Object)(object)ownBall == (Object)null))
				{
					forceNextRespawnAtBall.Add(val);
				}
			}
		}

		private static bool IsHazardElimination(EliminationReason reason)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)reason != 5 && (int)reason != 6)
			{
				return (int)reason == 23;
			}
			return true;
		}

		private static void RedirectHazardRespawnToBall(PlayerMovement movement, ref RespawnTarget respawnTarget)
		{
			if (IsActiveProGolf() && !((Object)(object)movement == (Object)null) && (int)respawnTarget == 0 && forceNextRespawnAtBall.Remove(movement))
			{
				respawnTarget = (RespawnTarget)1;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)"Redirected Pro Golf Plus hazard respawn to player's ball.");
				}
			}
		}

		private static bool TryRespawnHazardEliminationAtBall(PlayerGolfer golfer, EliminationReason immediateEliminationReason)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (!IsActiveProGolf() || !IsHazardElimination(immediateEliminationReason))
			{
				return false;
			}
			object obj;
			if (golfer == null)
			{
				obj = null;
			}
			else
			{
				PlayerInfo playerInfo = golfer.PlayerInfo;
				obj = ((playerInfo != null) ? playerInfo.Movement : null);
			}
			PlayerMovement val = (PlayerMovement)obj;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (!val.TryBeginRespawn(false, (RespawnTarget)1))
			{
				return false;
			}
			ProGolfPlugin proGolfPlugin = instance;
			if (proGolfPlugin != null)
			{
				((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)"Converted Pro Golf Plus hazard elimination into a ball respawn without knockout/elimination reporting.");
			}
			return true;
		}

		private static bool IsProGolfScorePopupType(PlayerTextPopupType popupType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			if ((int)popupType != 1 && (int)popupType != 2 && (int)popupType != 3 && (int)popupType != 4 && (int)popupType != 5 && (int)popupType != 6 && (int)popupType != 7 && (int)popupType != 8 && (int)popupType != 9 && (int)popupType != 10 && (int)popupType != 11 && (int)popupType != 12 && (int)popupType != 13 && (int)popupType != 14 && (int)popupType != 15 && (int)popupType != 16 && (int)popupType != 17 && (int)popupType != 18)
			{
				return (int)popupType == 21;
			}
			return true;
		}

		private static bool HasPlayerScoredThisHole(PlayerGolfer golfer)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			PlayerState val = default(PlayerState);
			if ((Object)(object)golfer != (Object)null && CourseManager.TryGetPlayerState(golfer.PlayerInfo, ref val))
			{
				return (int)val.matchResolution == 1;
			}
			return false;
		}

		private static bool AllActivePlayersResolved(CourseManager courseManager)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_0041: 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)
			SyncList<PlayerState> playerStates = CourseManager.PlayerStates;
			if (playerStates == null)
			{
				return false;
			}
			int num = 0;
			int num2 = 0;
			Enumerator<PlayerState> enumerator = playerStates.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					PlayerState current = enumerator.Current;
					if (current.isConnected && !current.isSpectator && (int)current.matchResolution != -1)
					{
						num++;
						if ((int)current.matchResolution != 0)
						{
							num2++;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (num > 0)
			{
				return num == num2;
			}
			return false;
		}

		private static bool TryCompareProGolfPlayerStates(PlayerState self, PlayerState other, ref int result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (!IsProGolfScoringActive())
			{
				return false;
			}
			if (self.courseStrokes != other.courseStrokes)
			{
				result = self.courseStrokes.CompareTo(other.courseStrokes);
				return true;
			}
			if (self.courseScore != other.courseScore)
			{
				result = other.courseScore.CompareTo(self.courseScore);
				return true;
			}
			if (self.wins != other.wins)
			{
				result = other.wins.CompareTo(self.wins);
				return true;
			}
			if (self.finishes != other.finishes)
			{
				result = other.finishes.CompareTo(self.finishes);
				return true;
			}
			if (self.courseKnockouts != other.courseKnockouts)
			{
				result = other.courseKnockouts.CompareTo(self.courseKnockouts);
				return true;
			}
			if (self.losses != other.losses)
			{
				result = self.losses.CompareTo(other.losses);
				return true;
			}
			if (!self.scoreTimestamp.Equals(other.scoreTimestamp))
			{
				result = self.scoreTimestamp.CompareTo(other.scoreTimestamp);
				return true;
			}
			result = self.joinIndex.CompareTo(other.joinIndex);
			return true;
		}

		private static bool TryGetWeightedRandomAllowedPickupItem(ItemPool pool, out ItemType item)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected I4, but got Unknown
			item = (ItemType)0;
			if (!(itemPoolSpawnChancesField?.GetValue(pool) is Array { Length: not 0 } array))
			{
				return false;
			}
			float num = 0f;
			foreach (object item2 in array)
			{
				ItemType itemType = (ItemType)AccessTools.Field(item2.GetType(), "item").GetValue(item2);
				float num2 = (float)AccessTools.Field(item2.GetType(), "spawnChanceWeight").GetValue(item2);
				if (!IsBlockedProGolfPickupItem(itemType) && num2 > 0f)
				{
					num += num2;
				}
			}
			if (num <= 0f)
			{
				item = (ItemType)3;
				return true;
			}
			float num3 = Random.value * num;
			foreach (object item3 in array)
			{
				ItemType val = (ItemType)AccessTools.Field(item3.GetType(), "item").GetValue(item3);
				float num4 = (float)AccessTools.Field(item3.GetType(), "spawnChanceWeight").GetValue(item3);
				if (!IsBlockedProGolfPickupItem(val) && !(num4 <= 0f))
				{
					num3 -= num4;
					if (num3 <= 0f)
					{
						item = (ItemType)(int)val;
						return true;
					}
				}
			}
			item = (ItemType)3;
			return true;
		}

		private static void BeginDriveTracking(GolfBall ball)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && IsActiveProGolf() && !((Object)(object)ball == (Object)null) && !((Object)(object)ball.Owner == (Object)null) && !((Object)(object)ball.Owner.PlayerInfo == (Object)null) && !((Object)(object)ball.Owner.PlayerInfo.PlayerId == (Object)null))
			{
				ResetLongestDriveIfHoleChanged();
				ulong guid = ball.Owner.PlayerInfo.PlayerId.Guid;
				if (!firstDriveResults.ContainsKey(guid) && !HasActiveDriveForPlayer(guid))
				{
					activeDrives[ball] = new DriveCandidate
					{
						Player = ball.Owner.PlayerInfo,
						PlayerGuid = guid,
						StartPosition = ((Component)ball).transform.position
					};
				}
			}
		}

		private static void TryCompleteDriveTracking(GolfBall ball)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && IsActiveProGolf() && !((Object)(object)ball == (Object)null) && ball.IsStationary && activeDrives.TryGetValue(ball, out var value))
			{
				activeDrives.Remove(ball);
				if (!((Object)(object)value.Player == (Object)null) && !((Object)(object)value.Player.PlayerId == (Object)null) && !firstDriveResults.ContainsKey(value.PlayerGuid))
				{
					Vector3 val = ((Component)ball).transform.position - value.StartPosition;
					val.y = 0f;
					float magnitude = ((Vector3)(ref val)).magnitude;
					float num = Mathf.Max(0f, instance?.longestDriveMinimumMetersConfig.Value ?? 0f);
					firstDriveResults[value.PlayerGuid] = new FirstDriveResult
					{
						PlayerName = GetPlayerName(value.Player, value.PlayerGuid),
						Distance = magnitude,
						IsValid = (magnitude >= num)
					};
					TryAnnounceLongestDriveIfReady();
				}
			}
		}

		private static void TryCaptureClosestToPinFromStationaryBall(GolfBall ball)
		{
			if (!NetworkServer.active || !IsActiveProGolf() || (Object)(object)ball == (Object)null || !ball.IsStationary || (Object)(object)ball.Owner == (Object)null || (Object)(object)ball.Owner.PlayerInfo == (Object)null || (Object)(object)ball.Owner.PlayerInfo.PlayerId == (Object)null)
			{
				return;
			}
			ResetLongestDriveIfHoleChanged();
			PlayerInfo playerInfo = ball.Owner.PlayerInfo;
			ulong guid = playerInfo.PlayerId.Guid;
			if (!closestToPinResults.ContainsKey(guid) && !IsBallInHole(ball) && !HasPlayerScoredThisHole(playerInfo.AsGolfer) && TryGetDistanceToPinWithinRadius(ball, out var distanceToPin))
			{
				closestToPinResults[guid] = new ClosestToPinResult
				{
					PlayerName = GetPlayerName(playerInfo, guid),
					Distance = distanceToPin,
					IsValid = true
				};
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)("Captured Closest to Pin inside 10yd radius: " + GetPlayerName(playerInfo, guid) + " " + FormatDistanceFeet(distanceToPin) + "."));
				}
				TryAnnounceClosestToPinIfReady();
			}
		}

		private static void CaptureClosestToPinOnScore(PlayerGolfer player)
		{
			if (NetworkServer.active && IsActiveProGolf())
			{
				object obj;
				if (player == null)
				{
					obj = null;
				}
				else
				{
					PlayerInfo playerInfo = player.PlayerInfo;
					obj = ((playerInfo != null) ? playerInfo.PlayerId : null);
				}
				if (!((Object)obj == (Object)null))
				{
					ResetLongestDriveIfHoleChanged();
					_ = player.PlayerInfo.PlayerId.Guid;
					CaptureChipInOnScore(player);
				}
			}
		}

		private static void CaptureChipInOnScore(PlayerGolfer player)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !IsActiveProGolf())
			{
				return;
			}
			object obj;
			if (player == null)
			{
				obj = null;
			}
			else
			{
				PlayerInfo playerInfo = player.PlayerInfo;
				obj = ((playerInfo != null) ? playerInfo.PlayerId : null);
			}
			if ((Object)obj == (Object)null)
			{
				return;
			}
			GolfHole val = FindMainHole();
			GolfBall ownBall = player.OwnBall;
			if ((Object)(object)val == (Object)null || (Object)(object)ownBall == (Object)null)
			{
				return;
			}
			Vector3 serverLastStrokePosition = ownBall.ServerLastStrokePosition;
			Vector3 val2 = serverLastStrokePosition - ((Component)val).transform.position;
			val2.y = 0f;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			if (!(magnitude < 1f) && !val.IsPointInGreenTrigger(serverLastStrokePosition))
			{
				ulong guid = player.PlayerInfo.PlayerId.Guid;
				holeStatsChipInDistances[guid] = magnitude;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)("Tracked Pro Golf chip-in: " + GetPlayerName(player.PlayerInfo, guid) + " " + FormatDistanceYards(magnitude) + "."));
				}
			}
		}

		private static void FinalizeMissingClosestToPinResults(List<ulong> activePlayers)
		{
			if (!AllActivePlayersResolvedForCurrentHole())
			{
				return;
			}
			foreach (ulong activePlayer in activePlayers)
			{
				if (!closestToPinResults.ContainsKey(activePlayer))
				{
					closestToPinResults[activePlayer] = new ClosestToPinResult
					{
						PlayerName = CourseManager.GetPlayerName(activePlayer),
						Distance = float.PositiveInfinity,
						IsValid = false
					};
				}
			}
		}

		private static void TrackPerfectShot(PlayerGolfer player)
		{
			if (!NetworkServer.active || !IsActiveProGolf())
			{
				return;
			}
			object obj;
			if (player == null)
			{
				obj = null;
			}
			else
			{
				PlayerInfo playerInfo = player.PlayerInfo;
				obj = ((playerInfo != null) ? playerInfo.PlayerId : null);
			}
			if ((Object)obj == (Object)null)
			{
				return;
			}
			ResetLongestDriveIfHoleChanged();
			float swingNormalizedCharge = player.SwingNormalizedCharge;
			if (!(swingNormalizedCharge <= 0.99f) && !(swingNormalizedCharge > 1f))
			{
				ulong guid = player.PlayerInfo.PlayerId.Guid;
				perfectShotCounts.TryGetValue(guid, out var value);
				perfectShotCounts[guid] = value + 1;
				ProGolfPlugin proGolfPlugin = instance;
				if (proGolfPlugin != null)
				{
					((BaseUnityPlugin)proGolfPlugin).Logger.LogInfo((object)$"Tracked Pro Golf perfect shot: {GetPlayerName(player.PlayerInfo, guid)} ({value + 1}).");
				}
			}
		}

		private static void PollCartFlipStats()
		{
			if (!NetworkServer.active || !IsActiveProGolf())
			{
				cartFlipStates.Clear();
			}
			else
			{
				if (Time.unscaledTime < nextCartFlipPollTime)
				{
					return;
				}
				nextCartFlipPollTime = Time.unscaledTime + 0.25f;
				ResetLongestDriveIfHoleChanged();
				RefreshCachedCartsIfNeeded();
				foreach (GolfCartMovement cachedCart in cachedCarts)
				{
					if (!((Object)(object)cachedCart == (Object)null))
					{
						if (!cartFlipStates.TryGetValue(cachedCart, out var value))
						{
							value = new CartFlipState
							{
								Wheels = ((Component)cachedCart).GetComponentsInChildren<WheelCollider>(true)
							};
							cartFlipStates[cachedCart] = value;
						}
						UpdateCartFlipState(cachedCart, value);
					}
				}
				staleCarts.Clear();
				foreach (GolfCartMovement key in cartFlipStates.Keys)
				{
					if ((Object)(object)key == (Object)null || !cachedCarts.Contains(key))
					{
						staleCarts.Add(key);
					}
				}
				foreach (GolfCartMovement staleCart in staleCarts)
				{
					cartFlipStates.Remove(staleCart);
				}
			}
		}

		private static void RefreshCachedCartsIfNeeded()
		{
			if (Time.unscaledTime < nextCartDiscoveryPollTime)
			{
				return;
			}
			nextCartDiscoveryPollTime = Time.unscaledTime + 1f;
			cachedCarts.Clear();
			GolfCartMovement[] array = Object.FindObjectsByType<GolfCartMovement>((FindObjectsSortMode)0);
			foreach (GolfCartMoveme