Decompiled source of Sharks and Minnows v0.5.2

com.github.glarmer.SharksAndMinnows.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Gamemode_Lib;
using Gamemode_Lib.ConfigSync;
using Gamemode_Lib.Events;
using Gamemode_Lib.Patches.Features;
using Gamemode_Lib.Teams;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using SharksAndMinnows.Configuration;
using SharksAndMinnows.Patches;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("GameAssembly")]
[assembly: IgnoresAccessChecksTo("SharedAssembly")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.glarmer.SharksAndMinnows")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.5.1.0")]
[assembly: AssemblyInformationalVersion("0.5.1+65949ddd2fd8a6850fd772a5548740279b70bc85")]
[assembly: AssemblyProduct("com.github.glarmer.SharksAndMinnows")]
[assembly: AssemblyTitle("SharksAndMinnows")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace SharksAndMinnows
{
	public class MinnowManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <ConvertMinnowToSharkAfterDelay>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerInfo victim;

			public PlayerTeam victimTeam;

			public TeamManager teamManager;

			public MinnowManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ConvertMinnowToSharkAfterDelay>d__21(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)victim == (Object)null || (Object)(object)victimTeam == (Object)null || (Object)(object)teamManager == (Object)null)
					{
						return false;
					}
					victimTeam.SetLocalTeam(SharksAndMinnows.SHARKS_TEAM);
					teamManager.SendTeamToClients(victim, SharksAndMinnows.SHARKS_TEAM);
					<>4__this.AddMinnowTagged(victim.PlayerId.guid);
					victim.Movement.TryBeginRespawn(false, (RespawnTarget)0);
					Plugin.Log.LogInfo((object)$"[MinnowManager] Conversion complete. victimGuid={victim.PlayerId.guid} tagged={<>4__this._minnowsThatHaveBeenTagged.Count}/{<>4__this._originalMinnowRoster.Count} scored={<>4__this._minnowsThatScored.Count}/{<>4__this._originalMinnowRoster.Count}");
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private readonly HashSet<ulong> _originalMinnowRoster = new HashSet<ulong>();

		private readonly HashSet<ulong> _minnowsThatScored = new HashSet<ulong>();

		private readonly HashSet<ulong> _minnowsThatHaveBeenTagged = new HashSet<ulong>();

		public static MinnowManager Instance;

		public void Awake()
		{
			Plugin.Log.LogInfo((object)"[MinnowManager] Awake() called");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)Instance);
				Plugin.Log.LogInfo((object)"[MinnowManager] Instance set + DontDestroyOnLoad");
				SceneEvents.OnNextHole += OnNextHole;
				SceneEvents.OnReturnToLobby += OnReturnToLobby;
				PlayerTag.PlayerTagged += OnPlayerTagged;
				Plugin.Log.LogInfo((object)"[MinnowManager] Subscribed: PlayerTag.PlayerTagged");
				if ((Object)(object)TeamManager.Instance != (Object)null)
				{
					TeamManager.Instance.AllPlayersOnOneTeam += OnAllPlayersOnOneTeam;
					Plugin.Log.LogInfo((object)"[MinnowManager] Subscribed: TeamManager.AllPlayersOnOneTeam");
				}
				else
				{
					Plugin.Log.LogInfo((object)"[MinnowManager] TeamManager.Instance was null in Awake(); AllPlayersOnOneTeam not subscribed (yet?)");
				}
			}
			else
			{
				Plugin.Log.LogInfo((object)"[MinnowManager] Duplicate instance detected; destroying the old component");
				Object.Destroy((Object)(object)Instance);
				Instance = this;
			}
		}

		public bool HasMinnowBeenCaptured(ulong minnow)
		{
			return _minnowsThatHaveBeenTagged.Contains(minnow);
		}

		public bool HasMinnowScored(ulong minnow)
		{
			return _minnowsThatScored.Contains(minnow);
		}

		public void Start()
		{
			Plugin.Log.LogInfo((object)"[MinnowManager] Start() called; initializing minnow roster");
			SetInitialMinnowRoster();
			Plugin.Log.LogInfo((object)$"[MinnowManager] Initial roster loaded. originalMinnowRoster={_originalMinnowRoster.Count}");
		}

		public void OnDestroy()
		{
			Plugin.Log.LogInfo((object)"[MinnowManager] OnDestroy() called; unsubscribing events");
			PlayerTag.PlayerTagged -= OnPlayerTagged;
			SceneEvents.OnNextHole -= OnNextHole;
			SceneEvents.OnReturnToLobby -= OnReturnToLobby;
			if ((Object)(object)TeamManager.Instance != (Object)null)
			{
				TeamManager.Instance.AllPlayersOnOneTeam -= OnAllPlayersOnOneTeam;
				Plugin.Log.LogInfo((object)"[MinnowManager] Unsubscribed: TeamManager.AllPlayersOnOneTeam");
			}
			else
			{
				Plugin.Log.LogInfo((object)"[MinnowManager] TeamManager.Instance was null in OnDestroy(); skipping AllPlayersOnOneTeam unsubscribe");
			}
			Plugin.Log.LogInfo((object)"[MinnowManager] Unsubscribed: PlayerTag.PlayerTagged");
		}

		private void OnAllPlayersOnOneTeam(TeamData teamData)
		{
			Plugin.Log.LogInfo((object)$"[MinnowManager] OnAllPlayersOnOneTeam(teamId={teamData?.ID}) called");
			if (teamData != null && teamData.ID == SharksAndMinnows.SHARKS_TEAM)
			{
				Plugin.Log.LogInfo((object)$"[MinnowManager] AllPlayersOnOneTeam -> Sharks. originalMinnowRoster={_originalMinnowRoster.Count} tagged={_minnowsThatHaveBeenTagged.Count} scored={_minnowsThatScored.Count}. Ending game");
				SharksAndMinnows.EndCurrentHole(isEndGame: true);
			}
		}

		private void OnNextHole(Scene scenePrev, Scene sceneNew)
		{
			Plugin.Log.LogInfo((object)"On Next Hole Reset Zone Timer");
			PlayerMovementPatches.ResetZoneTimer();
			ClearMinnowsThatHaveScored();
		}

		public void Update()
		{
			if (_originalMinnowRoster.Count == 0)
			{
				SetInitialMinnowRoster();
			}
			if (_minnowsThatScored.Count != 0 && _minnowsThatScored.Count + _minnowsThatHaveBeenTagged.Count >= _originalMinnowRoster.Count)
			{
				Plugin.Log.LogInfo((object)$"[MinnowManager] All Minnows accounted for (scored/tagged). originalMinnowRoster={_originalMinnowRoster.Count} tagged={_minnowsThatHaveBeenTagged.Count} scored={_minnowsThatScored.Count}. Ending hole");
				SharksAndMinnows.EndCurrentHole(isEndGame: false);
				ClearMinnowsThatHaveScored();
			}
		}

		public void SetInitialMinnowRoster()
		{
			if ((Object)(object)TeamManager.Instance == (Object)null)
			{
				Plugin.Log.LogInfo((object)"[MinnowManager] TeamManager.Instance is null; cannot build initial roster");
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (KeyValuePair<ulong, int> item in TeamManager.Instance.SavedTeamIdByGuid)
			{
				num++;
				if (item.Value == SharksAndMinnows.MINNOWS_TEAM)
				{
					_originalMinnowRoster.Add(item.Key);
					num2++;
					Plugin.Log.LogInfo((object)$"[MinnowManager] Added initial minnow guid={item.Key}");
				}
			}
		}

		private void OnReturnToLobby(Scene scene, Scene scene1)
		{
			Plugin.Log.LogInfo((object)"[MinnowManager] OnReturnToLobby() called");
			ClearAllMinnows();
		}

		private void ClearAllMinnows()
		{
			_minnowsThatHaveBeenTagged.Clear();
			_minnowsThatScored.Clear();
			_originalMinnowRoster.Clear();
		}

		public void ClearMinnowsThatHaveScored()
		{
			Plugin.Log.LogInfo((object)$"[MinnowManager] ClearMinnowsThatHaveScored() clearing {_minnowsThatScored.Count} scored minnows (tagged={_minnowsThatHaveBeenTagged.Count} roster={_originalMinnowRoster.Count})");
			_minnowsThatScored.Clear();
		}

		public void ClearMinnowsThatHaveBeenTagged()
		{
			Plugin.Log.LogInfo((object)$"[MinnowManager] ClearMinnowsThatHaveBeenTagged() clearing {_minnowsThatHaveBeenTagged.Count} tagged minnows (scored={_minnowsThatScored.Count} roster={_originalMinnowRoster.Count})");
			_minnowsThatHaveBeenTagged.Clear();
		}

		public void ClearOriginalMinnowRoster()
		{
			_originalMinnowRoster.Clear();
			Plugin.Log.LogInfo((object)"[MinnowManager] ClearOriginalMinnowRoster() cleared roster");
		}

		public void AddMinnowTagged(ulong minnow)
		{
			if (_minnowsThatScored.Contains(minnow))
			{
				Plugin.Log.LogInfo((object)$"[MinnowManager] AddMinnowTagged(guid={minnow}) already scored; skipping");
				return;
			}
			bool flag = _minnowsThatHaveBeenTagged.Add(minnow);
			Plugin.Log.LogInfo((object)$"[MinnowManager] AddMinnowTagged(guid={minnow}) added={flag} tagged={_minnowsThatHaveBeenTagged.Count} scored={_minnowsThatScored.Count} roster={_originalMinnowRoster.Count}");
		}

		public void AddMinnowScored(ulong minnow)
		{
			if (_minnowsThatHaveBeenTagged.Contains(minnow))
			{
				Plugin.Log.LogInfo((object)$"[MinnowManager] AddMinnowScored(guid={minnow}) already tagged; skipping");
				return;
			}
			bool flag = _minnowsThatScored.Add(minnow);
			Plugin.Log.LogInfo((object)$"[MinnowManager] AddMinnowScored(guid={minnow}) added={flag} scored={_minnowsThatScored.Count} tagged={_minnowsThatHaveBeenTagged.Count} roster={_originalMinnowRoster.Count}");
		}

		private void OnPlayerTagged(PlayerInfo victim, PlayerInfo hitter, TagHitType hitType)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)string.Format("[MinnowManager] OnPlayerTagged(victim={0}, hitter={1}, hitType={2}, serverActive={3})", ((Object)(object)victim == (Object)null) ? "null" : victim.PlayerId.guid.ToString(), ((Object)(object)hitter == (Object)null) ? "null" : hitter.PlayerId.guid.ToString(), hitType, NetworkServer.active));
			if ((Object)(object)victim == (Object)null || (Object)(object)hitter == (Object)null)
			{
				return;
			}
			TeamManager instance = TeamManager.Instance;
			PlayerTeam val = instance.EnsurePlayerTeam(victim);
			PlayerTeam val2 = instance.EnsurePlayerTeam(hitter);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogInfo((object)$"[MinnowManager] EnsurePlayerTeam failed. victimTeamNull={(Object)(object)val == (Object)null} hitterTeamNull={(Object)(object)val2 == (Object)null}");
			}
			else
			{
				if (HasMinnowScored(victim.PlayerId.guid))
				{
					return;
				}
				if (((NetworkBehaviour)victim).isLocalPlayer && val.teamId == SharksAndMinnows.MINNOWS_TEAM && val2.teamId == SharksAndMinnows.SHARKS_TEAM)
				{
					Plugin.Log.LogInfo((object)$"[MinnowManager] Victim is local player; applying slow (minnows speed multiplier / 2) victimGuid={victim.PlayerId.guid}");
					SharksAndMinnows.SetMoveSpeedsShark();
				}
				if (!NetworkServer.active)
				{
					return;
				}
				if ((Object)(object)instance == (Object)null)
				{
					Plugin.Log.LogInfo((object)"[MinnowManager] TeamManager.Instance is null; aborting tag handling");
					return;
				}
				if (val2.teamId != SharksAndMinnows.SHARKS_TEAM)
				{
					Plugin.Log.LogInfo((object)$"[MinnowManager] Tag ignored; hitter not a shark. hitterTeam={val2.teamId} expectedSharks={SharksAndMinnows.SHARKS_TEAM}");
					return;
				}
				if (val.teamId != SharksAndMinnows.MINNOWS_TEAM)
				{
					Plugin.Log.LogInfo((object)$"[MinnowManager] Tag ignored; victim not a minnow. victimTeam={val.teamId} expectedMinnows={SharksAndMinnows.MINNOWS_TEAM}");
					return;
				}
				if ((Object)(object)SingletonNetworkBehaviour<InfoFeed>.Instance != (Object)null)
				{
					SingletonNetworkBehaviour<InfoFeed>.Instance.ServerShowMessageForAllClients(new EliminationMessaqeData(hitter.PlayerId.Guid, victim.PlayerId.Guid, (InfoFeedIconType)1));
				}
				Plugin.Log.LogInfo((object)$"[MinnowManager] Valid tag: minnow->shark conversion. victimGuid={victim.PlayerId.guid} hitterGuid={hitter.PlayerId.guid}");
				((MonoBehaviour)this).StartCoroutine(ConvertMinnowToSharkAfterDelay(victim, val, instance));
			}
		}

		[IteratorStateMachine(typeof(<ConvertMinnowToSharkAfterDelay>d__21))]
		private IEnumerator ConvertMinnowToSharkAfterDelay(PlayerInfo victim, PlayerTeam victimTeam, TeamManager teamManager)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ConvertMinnowToSharkAfterDelay>d__21(0)
			{
				<>4__this = this,
				victim = victim,
				victimTeam = victimTeam,
				teamManager = teamManager
			};
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.github.glarmer.SharksAndMinnows", "SharksAndMinnows", "0.5.1")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigurationHandler ConfigurationHandler;

		public const string Id = "com.github.glarmer.SharksAndMinnows";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "SharksAndMinnows";

		public static string Version => "0.5.1";

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigurationHandler = new ConfigurationHandler(((BaseUnityPlugin)this).Config);
			GameModeUtilities.RegisterGameMode((IGamemode)(object)new SharksAndMinnows());
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}
	}
	public class ProximityTag : MonoBehaviour
	{
		private PlayerMovement owner;

		private Rigidbody ownerRigidbody;

		private readonly HashSet<Hittable> hitThisOverlap = new HashSet<Hittable>();

		public void Initialize(PlayerMovement ownerMovement)
		{
			owner = ownerMovement;
			if ((Object)(object)owner != (Object)null)
			{
				ownerRigidbody = ((Component)owner).GetComponent<Rigidbody>();
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			TryTriggerDiveHit(other, "enter");
		}

		private void OnTriggerStay(Collider other)
		{
			TryTriggerDiveHit(other, "stay");
		}

		private void OnTriggerExit(Collider other)
		{
			Hittable hittable = GetHittable(other);
			if (!((Object)(object)hittable == (Object)null))
			{
				hitThisOverlap.Remove(hittable);
			}
		}

		private void TryTriggerDiveHit(Collider other, string triggerEvent)
		{
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)owner == (Object)null || !((NetworkBehaviour)owner).isLocalPlayer || (Object)(object)other == (Object)null)
			{
				return;
			}
			Entity entity = GetEntity(other);
			if ((Object)(object)entity == (Object)null || !entity.IsPlayer || !entity.IsHittable || (Object)(object)entity == (Object)(object)owner.PlayerInfo.AsEntity)
			{
				return;
			}
			Hittable asHittable = entity.AsHittable;
			if (!((Object)(object)asHittable == (Object)null) && asHittable.DiveSettings.CanBeHit)
			{
				PlayerTeam component = ((Component)owner).GetComponent<PlayerTeam>();
				PlayerTeam component2 = ((Component)entity).GetComponent<PlayerTeam>();
				ulong guid = component2.playerInfo.PlayerId.guid;
				if (!((Object)(object)MinnowManager.Instance == (Object)null) && !MinnowManager.Instance.HasMinnowBeenCaptured(guid) && !MinnowManager.Instance.HasMinnowScored(guid) && !((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null) && component.teamId != component2.teamId && !hitThisOverlap.Contains(asHittable))
				{
					hitThisOverlap.Add(asHittable);
					Vector3 val = default(Vector3);
					((Vector3)(ref val))..ctor(0f, 0f, 0f);
					Plugin.Log.LogInfo((object)("Player tag aura triggered dive hit | event=" + triggerEvent + " | owner=" + GetPlayerName(owner.PlayerInfo) + " | target=" + GetEntityName(entity) + " | " + $"velocity={val} | " + $"speed={((Vector3)(ref val)).magnitude:F2}"));
					asHittable.HitWithDive(val, owner);
				}
			}
		}

		private static Entity GetEntity(Collider other)
		{
			if ((Object)(object)other == (Object)null)
			{
				return null;
			}
			return ((Object)(object)other.attachedRigidbody != (Object)null) ? ((Component)other.attachedRigidbody).GetComponentInParent<Entity>(true) : ((Component)other).GetComponentInParent<Entity>(true);
		}

		private static Hittable GetHittable(Collider other)
		{
			Entity entity = GetEntity(other);
			if ((Object)(object)entity == (Object)null)
			{
				return null;
			}
			if (!entity.IsHittable)
			{
				return null;
			}
			return entity.AsHittable;
		}

		private static string GetEntityName(Entity entity)
		{
			if ((Object)(object)entity == (Object)null)
			{
				return "null";
			}
			if (entity.IsPlayer && (Object)(object)entity.PlayerInfo != (Object)null)
			{
				return GetPlayerName(entity.PlayerInfo);
			}
			return ((Object)entity).name;
		}

		private static string GetPlayerName(PlayerInfo playerInfo)
		{
			if ((Object)(object)playerInfo == (Object)null)
			{
				return "null";
			}
			return $"{playerInfo.PlayerId.PlayerName} ({playerInfo.PlayerId.guid})";
		}
	}
	public class SharksAndMinnows : IGamemode
	{
		public static int SHARKS_TEAM = 0;

		public static int MINNOWS_TEAM = 1;

		private static bool _cached = false;

		private static float _defaultMoveSpeed;

		private static float _walkMoveSpeed;

		private static float _wadingSpeed;

		private static float _speedBoostFactor;

		private static float _diveHorizontalSpeed;

		private static float _diveUpwardsSpeed;

		private static float _diveGetUpDuration;

		private static float _jumpUpwardsSpeed;

		private static float _swingChargingSpeed;

		private static float _swingAimingSpeed;

		public Harmony GamemodeHarmony { get; init; }

		public string Name { get; } = "SharksAndMinnows";


		public string ModId { get; } = "com.github.glarmer.SharksAndMinnows";


		public int MinPlayers { get; } = 2;


		public int MaxPlayers { get; } = 200;


		public bool IsTeamBased { get; } = true;


		public bool IsNormalStartProcedure { get; } = true;


		public int TeamCount { get; } = 2;


		public string Description { get; } = "The Minnows must score their ball at all costs, but can they do it with the Sharks hunting them? Only time will tell!";


		public bool IsTaggingEnabled { get; } = true;


		public SharksAndMinnows()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			GamemodeHarmony = new Harmony(((IGamemode)this).GameModeId);
		}

		public void OnGameStart()
		{
			Plugin.Log.LogInfo((object)"[SharksAndMinnows] OnGameStart");
			StopAutoNextHole.END_GAME = false;
			GamemodeHarmony.PatchAll(typeof(ItemSpawnerPatches));
			GamemodeHarmony.PatchAll(typeof(HoleProgressBarUIPatches));
			GamemodeHarmony.PatchAll(typeof(StopCountdownToMatchEnd));
			GamemodeHarmony.PatchAll(typeof(StopAutoNextHole));
			GamemodeHarmony.PatchAll(typeof(PlayerMovementPatches));
			GamemodeHarmony.PatchAll(typeof(AheadOfBallMessagePatches));
			GamemodeHarmony.PatchAll(typeof(PlayerGolferPatches));
			GamemodeHarmony.PatchAll(typeof(InfoFeedPatches));
			GamemodeHarmony.PatchAll(typeof(TeeOffCountdownPatches));
			GamemodeHarmony.PatchAll(typeof(DiveHitboxPatches));
			GamemodeHarmony.PatchAll(typeof(ProximityTagPatches));
			ConfigurationHandler.Instance.MovementConfigChanged += ApplyLocalPlayerMovementSpeeds;
			ConfigurationHandler.Instance.SyncConfiguration();
			GameObject val = GameObject.Find("Hole progress bar");
			if ((Object)(object)val != (Object)null)
			{
				val.SetActive(false);
			}
			TeamManager instance = TeamManager.Instance;
			ApplyLocalPlayerMovementSpeeds();
			((Component)SingletonBehaviour<GameManager>.Instance).gameObject.AddComponent<MinnowManager>();
		}

		public void OnGameEnd()
		{
			Plugin.Log.LogInfo((object)"[SharksAndMinnows] OnGameEnd");
			if (ConfigurationHandler.Instance != null)
			{
				ConfigurationHandler.Instance.MovementConfigChanged -= ApplyLocalPlayerMovementSpeeds;
			}
			RestoreMovementSpeeds();
			ProximityTagPatches.DestroyProximityColliders();
			if ((Object)(object)MinnowManager.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)MinnowManager.Instance);
			}
			GamemodeHarmony.UnpatchSelf();
		}

		private void ApplyLocalPlayerMovementSpeeds()
		{
			TeamManager instance = TeamManager.Instance;
			if ((Object)(object)instance.LocalPlayerTeam != (Object)null && instance.LocalPlayerTeam.teamId == SHARKS_TEAM)
			{
				SetMoveSpeedsShark();
			}
			else
			{
				SetMoveSpeedsMinnow();
			}
		}

		public bool CanStart(int playerCount)
		{
			return true;
		}

		public static void EndCurrentHole(bool isEndGame)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && !((Object)(object)SingletonNetworkBehaviour<CourseManager>.Instance == (Object)null))
			{
				Plugin.Log.LogInfo((object)"[SharksAndMinnows] Ending this hole");
				StopAutoNextHole.END_GAME = isEndGame;
				if ((int)SingletonNetworkBehaviour<CourseManager>.Instance.matchState != 6)
				{
					MatchState matchState = SingletonNetworkBehaviour<CourseManager>.Instance.matchState;
					SingletonNetworkBehaviour<CourseManager>.Instance.matchState = (MatchState)6;
					SingletonNetworkBehaviour<CourseManager>.Instance.OnMatchStateChanged(matchState, (MatchState)6);
					Plugin.Log.LogInfo((object)"[SharksAndMinnows] Ending this hole");
				}
			}
		}

		private static void CacheOriginalSpeeds()
		{
			if (!_cached)
			{
				PlayerMovementSettings playerMovementSettings = SingletonBehaviour<GameManager>.Instance.playerMovementSettings;
				_defaultMoveSpeed = playerMovementSettings.DefaultMoveSpeed;
				_walkMoveSpeed = playerMovementSettings.WalkMoveSpeed;
				_wadingSpeed = playerMovementSettings.WadingInWaterSpeed;
				_speedBoostFactor = playerMovementSettings.SpeedBoostSpeedFactor;
				_diveHorizontalSpeed = playerMovementSettings.DiveHorizontalSpeed;
				_diveUpwardsSpeed = playerMovementSettings.DiveUpwardsSpeed;
				_diveGetUpDuration = playerMovementSettings.DiveGetUpDuration;
				_jumpUpwardsSpeed = playerMovementSettings.JumpUpwardsSpeed;
				_swingChargingSpeed = playerMovementSettings.SwingChargingSpeed;
				_swingAimingSpeed = playerMovementSettings.SwingAimingSpeed;
				_cached = true;
			}
		}

		private void RestoreMovementSpeeds()
		{
			PlayerMovementSettings playerMovementSettings = SingletonBehaviour<GameManager>.Instance.playerMovementSettings;
			playerMovementSettings.DefaultMoveSpeed = _defaultMoveSpeed;
			playerMovementSettings.WalkMoveSpeed = _walkMoveSpeed;
			playerMovementSettings.WadingInWaterSpeed = _wadingSpeed;
			playerMovementSettings.SpeedBoostSpeedFactor = _speedBoostFactor;
			playerMovementSettings.DiveHorizontalSpeed = _diveHorizontalSpeed;
			playerMovementSettings.DiveUpwardsSpeed = _diveUpwardsSpeed;
			playerMovementSettings.DiveGetUpDuration = _diveGetUpDuration;
			playerMovementSettings.JumpUpwardsSpeed = _jumpUpwardsSpeed;
			playerMovementSettings.SwingChargingSpeed = _swingChargingSpeed;
			playerMovementSettings.SwingAimingSpeed = _swingAimingSpeed;
		}

		private void SetMoveSpeedsMinnow()
		{
			CacheOriginalSpeeds();
			PlayerMovementSettings playerMovementSettings = SingletonBehaviour<GameManager>.Instance.playerMovementSettings;
			ConfigurationHandler instance = ConfigurationHandler.Instance;
			playerMovementSettings.DefaultMoveSpeed = _defaultMoveSpeed * instance.MinnowDefaultMoveSpeedMultiplier;
			playerMovementSettings.WalkMoveSpeed = _walkMoveSpeed * instance.MinnowWalkMoveSpeedMultiplier;
			playerMovementSettings.WadingInWaterSpeed = _wadingSpeed * instance.MinnowWadingInWaterSpeedMultiplier;
			playerMovementSettings.SpeedBoostSpeedFactor = _speedBoostFactor * instance.MinnowSpeedBoostSpeedFactorMultiplier;
			playerMovementSettings.DiveHorizontalSpeed = _diveHorizontalSpeed * instance.MinnowDiveHorizontalSpeedMultiplier;
			playerMovementSettings.DiveGetUpDuration = _diveGetUpDuration * instance.MinnowDiveGetUpDurationMultiplier;
			playerMovementSettings.JumpUpwardsSpeed = _jumpUpwardsSpeed * instance.MinnowJumpUpwardsSpeedMultiplier;
		}

		public static void SetMoveSpeedsShark()
		{
			CacheOriginalSpeeds();
			PlayerMovementSettings playerMovementSettings = SingletonBehaviour<GameManager>.Instance.playerMovementSettings;
			ConfigurationHandler instance = ConfigurationHandler.Instance;
			playerMovementSettings.DefaultMoveSpeed = _defaultMoveSpeed * instance.SharkDefaultMoveSpeedMultiplier;
			playerMovementSettings.WalkMoveSpeed = _walkMoveSpeed * instance.SharkWalkMoveSpeedMultiplier;
			playerMovementSettings.WadingInWaterSpeed = _wadingSpeed * instance.SharkWadingInWaterSpeedMultiplier;
			playerMovementSettings.SpeedBoostSpeedFactor = _speedBoostFactor * instance.SharkSpeedBoostSpeedFactorMultiplier;
			playerMovementSettings.DiveUpwardsSpeed = _diveUpwardsSpeed * instance.SharkDiveUpwardsSpeedMultiplier;
			playerMovementSettings.DiveHorizontalSpeed = _diveHorizontalSpeed * instance.SharkDiveHorizontalSpeedMultiplier;
			playerMovementSettings.SwingChargingSpeed = _swingChargingSpeed * instance.SharkSwingChargingSpeedMultiplier;
			playerMovementSettings.SwingAimingSpeed = _swingAimingSpeed * instance.SharkSwingAimingSpeedMultiplier;
		}

		void IGamemode.set_GamemodeHarmony(Harmony value)
		{
			GamemodeHarmony = value;
		}
	}
}
namespace SharksAndMinnows.Patches
{
	public class AheadOfBallMessagePatches
	{
		[HarmonyPatch(typeof(AheadOfBallMessage), "Update")]
		[HarmonyPrefix]
		public static void Update_Prefix(AheadOfBallMessage __instance)
		{
			if (TeamManager.Instance.LocalPlayerTeam.teamId == SharksAndMinnows.SHARKS_TEAM)
			{
				if (SingletonBehaviour<RestartPrompt>.HasInstance)
				{
					RestartPrompt instance = SingletonBehaviour<RestartPrompt>.Instance;
					Object.Destroy((Object)(object)instance);
				}
				Transform val = ((Component)__instance).transform.Find("Background");
				if (PlayerMovementPatches.IsInZone)
				{
					TextMeshProUGUI component = ((Component)val.Find("Message")).GetComponent<TextMeshProUGUI>();
					int num = Mathf.CeilToInt(PlayerMovementPatches.GetRemainingZoneBudget());
					((TMP_Text)component).text = $"Turn back Sharky!\n{num}";
					__instance.ShowInternal();
				}
				else
				{
					__instance.HideInternal();
				}
			}
		}
	}
	public class DiveHitboxPatches
	{
		private static readonly Dictionary<PlayerMovement, DiveTagTrigger> DiveTagTriggers = new Dictionary<PlayerMovement, DiveTagTrigger>();

		private const float MinimumDiveHitSpeed = 7f;

		[HarmonyPatch(typeof(PlayerMovement), "OnDivingStateChanged")]
		[HarmonyPostfix]
		public static void OnDivingStateChanged_Postfix(PlayerMovement __instance, DivingState previousState, DivingState currentState)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			if (!NetworkClient.active || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isLocalPlayer)
			{
				return;
			}
			CapsuleCollider divingCollider = __instance.DivingCollider;
			if (!((Object)(object)divingCollider == (Object)null))
			{
				if ((int)currentState == 1)
				{
					ApplyDiveTagTrigger(__instance, divingCollider);
					Plugin.Log.LogInfo((object)"Dive tag trigger enabled");
				}
				else
				{
					RestoreDiveTagTrigger(__instance);
					Plugin.Log.LogInfo((object)"Dive tag trigger disabled");
				}
			}
		}

		private static void ApplyDiveTagTrigger(PlayerMovement movement, CapsuleCollider divingCollider)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b1: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (!DiveTagTriggers.ContainsKey(movement))
			{
				ConfigurationHandler instance = ConfigurationHandler.Instance;
				float num = instance?.DiveHorizontalDiscMultiplier ?? 10f;
				float num2 = instance?.DiveVerticalDiscMultiplier ?? 1f;
				float num3 = instance?.DiveForwardCenterOffset ?? 0.15f;
				float num4 = instance?.DiveMinDiscHeight ?? 0.15f;
				GameObject val = new GameObject("SharksAndMinnows_DiveTagTrigger");
				val.transform.SetParent(((Component)divingCollider).transform, false);
				val.transform.localPosition = divingCollider.center + new Vector3(0f, 0f, num3);
				val.transform.localRotation = Quaternion.identity;
				val.transform.localScale = Vector3.one;
				val.layer = ((Component)divingCollider).gameObject.layer;
				BoxCollider val2 = val.AddComponent<BoxCollider>();
				((Collider)val2).isTrigger = true;
				float num5 = divingCollider.radius * 2f;
				float num6 = num5 * num;
				float num7 = Mathf.Max(num5 * num2, num4);
				val2.size = new Vector3(num6, num7, num6);
				val2.center = Vector3.zero;
				DiveTagTrigger diveTagTrigger = val.AddComponent<DiveTagTrigger>();
				diveTagTrigger.Initialize(movement, 7f);
				DiveTagTriggers[movement] = diveTagTrigger;
			}
		}

		private static void RestoreDiveTagTrigger(PlayerMovement movement)
		{
			if (DiveTagTriggers.TryGetValue(movement, out DiveTagTrigger value))
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				DiveTagTriggers.Remove(movement);
			}
		}
	}
	public class DiveTagTrigger : MonoBehaviour
	{
		private PlayerMovement owner;

		private Rigidbody ownerRigidbody;

		private float minimumDiveHitSpeed;

		private readonly HashSet<Hittable> hitThisDive = new HashSet<Hittable>();

		public void Initialize(PlayerMovement ownerMovement, float minimumSpeed)
		{
			owner = ownerMovement;
			minimumDiveHitSpeed = minimumSpeed;
			if ((Object)(object)owner != (Object)null)
			{
				ownerRigidbody = ((Component)owner).GetComponent<Rigidbody>();
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			TryTag(other, "enter");
		}

		private void OnTriggerStay(Collider other)
		{
			TryTag(other, "stay");
		}

		private void TryTag(Collider other, string triggerEvent)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)owner == (Object)null || !((NetworkBehaviour)owner).isLocalPlayer || (int)owner.DivingState != 1 || (Object)(object)other == (Object)null)
			{
				return;
			}
			Entity val = (((Object)(object)other.attachedRigidbody != (Object)null) ? ((Component)other.attachedRigidbody).GetComponentInParent<Entity>(true) : ((Component)other).GetComponentInParent<Entity>(true));
			if ((Object)(object)val == (Object)null || !val.IsHittable || (Object)(object)val == (Object)(object)owner.PlayerInfo.AsEntity)
			{
				return;
			}
			Hittable asHittable = val.AsHittable;
			if (!((Object)(object)asHittable == (Object)null) && asHittable.DiveSettings.CanBeHit && !hitThisDive.Contains(asHittable))
			{
				hitThisDive.Add(asHittable);
				Vector3 val2 = ((Component)val).transform.position - ((Component)owner).transform.position;
				val2.y = 0f;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.001f)
				{
					val2 = ((Component)owner).transform.forward;
				}
				else
				{
					((Vector3)(ref val2)).Normalize();
				}
				Vector3 val3 = (((Object)(object)ownerRigidbody != (Object)null) ? ownerRigidbody.linearVelocity : owner.SyncedVelocity);
				Vector3 networkedVelocity = val.GetNetworkedVelocity();
				Vector3 val4 = val3 - networkedVelocity;
				float num = Vector3.Dot(val4, val2);
				float num2 = num;
				if (num2 < minimumDiveHitSpeed)
				{
					num2 = minimumDiveHitSpeed;
				}
				Vector3 val5 = val2 * num2;
				string playerName = GetPlayerName(owner.PlayerInfo);
				string entityName = GetEntityName(val);
				Plugin.Log.LogInfo((object)("Dive tag trigger hit player/entity | event=" + triggerEvent + " | owner=" + playerName + " | target=" + entityName + " | " + $"rawSpeed={num:F2} | " + $"appliedSpeed={num2:F2} | " + $"ownerVelocity={val3} | " + $"targetVelocity={networkedVelocity} | " + $"direction={val2}"));
				asHittable.HitWithDive(val5, owner);
			}
		}

		private static string GetEntityName(Entity entity)
		{
			if ((Object)(object)entity == (Object)null)
			{
				return "null";
			}
			if (entity.IsPlayer && (Object)(object)entity.PlayerInfo != (Object)null)
			{
				return GetPlayerName(entity.PlayerInfo);
			}
			return ((Object)entity).name;
		}

		private static string GetPlayerName(PlayerInfo playerInfo)
		{
			if ((Object)(object)playerInfo == (Object)null)
			{
				return "null";
			}
			return $"{playerInfo.PlayerId.PlayerName} ({playerInfo.PlayerId.guid})";
		}
	}
	public class HoleProgressBarUIPatches
	{
		[HarmonyPatch(typeof(HoleProgressBarUi), "Awake")]
		[HarmonyPrefix]
		public static bool Awake_Prefix(HoleProgressBarUi __instance)
		{
			((Component)((Component)__instance).transform).gameObject.SetActive(false);
			return false;
		}

		[HarmonyPatch(typeof(HoleProgressBarUi), "Start")]
		[HarmonyPrefix]
		public static bool Start_Prefix(HoleProgressBarUi __instance)
		{
			((Component)((Component)__instance).transform).gameObject.SetActive(false);
			return false;
		}
	}
	public class InfoFeedPatches
	{
		[HarmonyPatch(typeof(InfoFeed), "ShowKnockoutMessage")]
		[HarmonyPrefix]
		public static bool StartOrCancelMatch_Prefix(PlayerInfo responsiblePlayer, PlayerInfo knockedOutPlayer, KnockoutType knockoutType)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			if ((Object)(object)responsiblePlayer == (Object)null || (Object)(object)knockedOutPlayer == (Object)null)
			{
				return true;
			}
			PlayerTeam val = TeamManager.Instance.EnsurePlayerTeam(responsiblePlayer);
			PlayerTeam val2 = TeamManager.Instance.EnsurePlayerTeam(knockedOutPlayer);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return true;
			}
			if (val.teamId == SharksAndMinnows.SHARKS_TEAM && val2.teamId == SharksAndMinnows.MINNOWS_TEAM)
			{
				return (int)knockoutType > 0;
			}
			return true;
		}

		[HarmonyPatch(typeof(InfoFeed), "ColorizePlayerName")]
		[HarmonyPrefix]
		public static bool ColorizePlayerName_Prefix(string playerName, Color playerColor, ref string __result)
		{
			//IL_0055: 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)
			if (TryGetTeamColorForPlayerName(playerName, out var color))
			{
				__result = "<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">" + playerName + "</color>";
				return false;
			}
			__result = "<color=#" + ColorUtility.ToHtmlStringRGB(playerColor) + ">" + playerName + "</color>";
			return false;
		}

		private static bool TryGetTeamColorForPlayerName(string playerName, out Color color)
		{
			//IL_0002: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			color = default(Color);
			if (string.IsNullOrEmpty(playerName))
			{
				return false;
			}
			if ((Object)(object)TeamManager.Instance == (Object)null)
			{
				return false;
			}
			foreach (PlayerTeam player in TeamManager.Instance.Players)
			{
				if ((Object)(object)player == (Object)null)
				{
					continue;
				}
				ulong guid = player.playerInfo.PlayerId.Guid;
				if (CourseManager.GetPlayerName(guid) != playerName)
				{
					continue;
				}
				PlayerTeam val = TeamManager.Instance.EnsurePlayerTeam(player.playerInfo);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				color = TeamManager.Instance.Teams[val.teamId].Color;
				return true;
			}
			return false;
		}
	}
	public class ItemSpawnerPatches
	{
		[HarmonyPatch(typeof(ItemSpawner), "OnTriggerEnter")]
		[HarmonyPrefix]
		public static bool OnTriggerEnter_Prefix(ItemSpawner __instance, Collider other)
		{
			PlayerTeam val = default(PlayerTeam);
			ComponentExtensions.TryGetComponentInParent<PlayerTeam>((Component)(object)other, ref val, true);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			if (val.teamId == SharksAndMinnows.MINNOWS_TEAM)
			{
				return false;
			}
			return true;
		}
	}
	public class PlayerGolferPatches
	{
		[HarmonyPatch(typeof(PlayerGolfer), "InformScored")]
		[HarmonyPrefix]
		public static void InformScored_Prefix(PlayerGolfer __instance)
		{
			TeamManager instance = TeamManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)MinnowManager.Instance == (Object)null || MinnowManager.Instance.HasMinnowBeenCaptured(__instance.PlayerInfo.PlayerId.guid))
			{
				return;
			}
			PlayerInfo val = (((Object)(object)__instance != (Object)null) ? __instance.PlayerInfo : null);
			if (!((Object)(object)val == (Object)null))
			{
				PlayerTeam val2 = instance.EnsurePlayerTeam(val);
				if (!((Object)(object)val2 == (Object)null) && val2.teamId == SharksAndMinnows.MINNOWS_TEAM)
				{
					MinnowManager.Instance.AddMinnowScored(val.PlayerId.guid);
				}
			}
		}
	}
	public class PlayerMovementPatches
	{
		internal static float ZoneBudget = 30f;

		internal static float TimeSpentInZone = 0f;

		internal static float ZoneEnterTime = -1f;

		internal static bool IsInZone = false;

		internal static float LastForcedRespawnTime = -999f;

		private const float ForcedRespawnCooldownSeconds = 1f;

		internal static bool MustExitZoneAfterForcedRespawn = false;

		[HarmonyPatch(typeof(PlayerMovement), "Start")]
		[HarmonyPostfix]
		public static void Start_Prefix(PlayerMovement __instance)
		{
			if (!((Object)(object)__instance.PlayerInfo == (Object)null) && ((NetworkBehaviour)__instance.PlayerInfo).isLocalPlayer)
			{
				ResetZoneTimer();
			}
		}

		public static void ResetZoneTimer()
		{
			Plugin.Log.LogInfo((object)"Resetting shark zone budget for new hole");
			ZoneBudget = 30f;
			TimeSpentInZone = 0f;
			ZoneEnterTime = -1f;
			IsInZone = false;
			LastForcedRespawnTime = -999f;
			MustExitZoneAfterForcedRespawn = false;
		}

		internal static float GetCurrentTimeSpentInZone()
		{
			if (IsInZone && ZoneEnterTime >= 0f)
			{
				return TimeSpentInZone + (Time.time - ZoneEnterTime);
			}
			return TimeSpentInZone;
		}

		internal static float GetRemainingZoneBudget()
		{
			return Mathf.Max(ZoneBudget - GetCurrentTimeSpentInZone(), 0f);
		}

		private static bool IsOnGreen(PlayerMovement movement)
		{
			//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)
			TerrainLayer groundTerrainDominantGlobalLayer = movement.GroundTerrainDominantGlobalLayer;
			if (((object)(TerrainLayer)(ref groundTerrainDominantGlobalLayer)).ToString().ToLower().Contains("green"))
			{
				return true;
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerMovement), "Update")]
		[HarmonyPostfix]
		public static void Update_Prefix(PlayerMovement __instance)
		{
			if ((Object)(object)__instance.PlayerInfo == (Object)null || (Object)(object)TeamManager.Instance.LocalPlayerTeam == (Object)null || !((NetworkBehaviour)__instance.PlayerInfo).isLocalPlayer || TeamManager.Instance.LocalPlayerTeam.teamId != SharksAndMinnows.SHARKS_TEAM)
			{
				return;
			}
			if (IsOnGreen(__instance))
			{
				if (!MustExitZoneAfterForcedRespawn)
				{
					if (!IsInZone)
					{
						IsInZone = true;
						ZoneEnterTime = Time.time;
						Plugin.Log.LogInfo((object)"Shark entered the protected area.");
					}
					float currentTimeSpentInZone = GetCurrentTimeSpentInZone();
					if (currentTimeSpentInZone >= ZoneBudget && Time.time - LastForcedRespawnTime >= 1f)
					{
						__instance.TryBeginRespawn(false, (RespawnTarget)0);
						LastForcedRespawnTime = Time.time;
						TimeSpentInZone = ZoneBudget;
						ZoneEnterTime = -1f;
						IsInZone = false;
						MustExitZoneAfterForcedRespawn = true;
						Plugin.Log.LogInfo((object)"Shark used entire protected-area budget, teleporting back.");
					}
				}
			}
			else
			{
				if (MustExitZoneAfterForcedRespawn)
				{
					MustExitZoneAfterForcedRespawn = false;
				}
				if (IsInZone)
				{
					TimeSpentInZone += Time.time - ZoneEnterTime;
					ZoneEnterTime = -1f;
					IsInZone = false;
					Plugin.Log.LogInfo((object)$"Shark left protected area. Total used: {TimeSpentInZone:0.00}s / {ZoneBudget:0.00}s");
				}
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "StartKnockoutImmunity")]
		[HarmonyPostfix]
		public static void StartKnockoutImmunity_Postfix(PlayerMovement __instance)
		{
			try
			{
				if (((NetworkBehaviour)__instance).isLocalPlayer && TeamManager.Instance.LocalPlayerTeam.teamId == SharksAndMinnows.MINNOWS_TEAM)
				{
					__instance.CancelKnockoutImmunity();
				}
			}
			catch
			{
				Plugin.Log.LogError((object)"Failed to cancel knockout immunity, ignoring, probably just too early.");
			}
		}
	}
	public class ProximityTagPatches
	{
		private static readonly Dictionary<PlayerMovement, ProximityTag> CreatedAuras = new Dictionary<PlayerMovement, ProximityTag>();

		[HarmonyPatch(typeof(PlayerMovement), "UpdateEnabledColliders")]
		[HarmonyPostfix]
		public static void UpdateEnabledColliders_Postfix(PlayerMovement __instance)
		{
			if (NetworkClient.active && !((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).isLocalPlayer && !CreatedAuras.ContainsKey(__instance))
			{
				CreateAura(__instance);
			}
		}

		private static void CreateAura(PlayerMovement movement)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			float radius = ConfigurationHandler.Instance?.ProximityTagAuraRadius ?? 3f;
			GameObject val = new GameObject("SharksAndMinnows_PlayerTagAura");
			val.transform.SetParent(((Component)movement).transform, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			val.layer = ((Component)movement).gameObject.layer;
			SphereCollider val2 = val.AddComponent<SphereCollider>();
			((Collider)val2).isTrigger = true;
			val2.radius = radius;
			ProximityTag proximityTag = val.AddComponent<ProximityTag>();
			CreatedAuras.Add(movement, proximityTag);
			proximityTag.Initialize(movement);
			Plugin.Log.LogInfo((object)("Player tag aura created for " + GetPlayerName(movement.PlayerInfo)));
		}

		private static string GetPlayerName(PlayerInfo playerInfo)
		{
			if ((Object)(object)playerInfo == (Object)null)
			{
				return "null";
			}
			return $"{playerInfo.PlayerId.PlayerName} ({playerInfo.PlayerId.guid})";
		}

		public static void DestroyProximityColliders()
		{
			try
			{
				foreach (KeyValuePair<PlayerMovement, ProximityTag> createdAura in CreatedAuras)
				{
					Object.Destroy((Object)(object)createdAura.Value);
				}
			}
			catch
			{
				Plugin.Log.LogError((object)"Failed to destroy proximity colliders");
			}
		}
	}
	public class TeeOffCountdownPatches
	{
		private static int _lastHoleIndex = -1;

		[HarmonyPatch(typeof(TeeOffCountdown), "ApplyVisibility")]
		[HarmonyPrefix]
		public static void Show_Prefix(TeeOffCountdown __instance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			if (!NetworkServer.active || (int)CourseManager.MatchState != 2)
			{
				return;
			}
			Plugin.Log.LogInfo((object)"Shark spawn server");
			if (!((Object)(object)TeamManager.Instance == (Object)null) && !((Object)(object)SingletonNetworkBehaviour<CheckpointManager>.Instance == (Object)null) && SingletonNetworkBehaviour<CheckpointManager>.Instance.allCheckpoints != null && SingletonNetworkBehaviour<CheckpointManager>.Instance.allCheckpoints.Count != 0 && GolfHoleManager.HasMaxReferenceDistance)
			{
				var list = (from x in SingletonNetworkBehaviour<CheckpointManager>.Instance.allCheckpoints.Where((Checkpoint checkpoint) => (Object)(object)checkpoint != (Object)null).Select(delegate(Checkpoint checkpoint)
					{
						//IL_0007: 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)
						//IL_0012: 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_0022: 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)
						Vector3 position = ((Component)checkpoint).transform.position;
						Vector3 val5 = position - ((Component)GolfHoleManager.MainHole).transform.position;
						float progress = 1f - BMath.Clamp01(((Vector3)(ref val5)).magnitude / GolfHoleManager.MaxReferenceDistance);
						return new
						{
							Checkpoint = checkpoint,
							Progress = progress
						};
					})
					orderby x.Progress descending
					select x).ToList();
				int val = Math.Max(1, (int)Math.Floor((float)list.Count / 2f));
				TeamData val2 = TeamManager.Instance.Teams[SharksAndMinnows.SHARKS_TEAM];
				HashSet<PlayerTeam> members = val2.Members;
				List<PlayerTeam> list2 = (from shark in members
					where (Object)(object)shark != (Object)null && (Object)(object)shark.playerInfo != (Object)null
					orderby shark.playerInfo.PlayerId.guid
					select shark).ToList();
				Random random = new Random();
				for (int num = list2.Count - 1; num > 0; num--)
				{
					int num2 = random.Next(num + 1);
					List<PlayerTeam> list3 = list2;
					int index = num;
					int index2 = num2;
					PlayerTeam value = list2[num2];
					PlayerTeam value2 = list2[num];
					list3[index] = value;
					list2[index2] = value2;
				}
				int val3 = Math.Min(val, list2.Count);
				val3 = Math.Max(1, val3);
				for (int i = 0; i < list2.Count; i++)
				{
					PlayerTeam val4 = list2[i];
					int num3 = i % val3;
					Checkpoint checkpoint2 = list[num3].Checkpoint;
					CheckpointManager.TryActivate(checkpoint2, val4.playerInfo);
					Plugin.Log.LogInfo((object)$"Shark spawn server assigned {val4.playerInfo.PlayerId.guid} to checkpoint {num3}");
				}
				Plugin.Log.LogInfo((object)"Shark spawn server done");
			}
		}

		[HarmonyPatch(typeof(TeeOffCountdown), "ApplyVisibility")]
		[HarmonyPostfix]
		public static void Show_Postfix(TeeOffCountdown __instance)
		{
			if ((Object)(object)MinnowManager.Instance != (Object)null)
			{
				MinnowManager.Instance.SetInitialMinnowRoster();
			}
			if (NetworkClient.active)
			{
				int currentHoleCourseIndex = CourseManager.CurrentHoleCourseIndex;
				if (currentHoleCourseIndex != _lastHoleIndex && !((Object)(object)TeamManager.Instance == (Object)null) && !((Object)(object)TeamManager.Instance.LocalPlayerTeam == (Object)null) && !((Object)(object)GameManager.LocalPlayerInfo == (Object)null) && TeamManager.Instance.LocalPlayerTeam.teamId == SharksAndMinnows.SHARKS_TEAM)
				{
					GameManager.LocalPlayerInfo.Movement.TryBeginRespawn(false, (RespawnTarget)0);
					_lastHoleIndex = currentHoleCourseIndex;
					Plugin.Log.LogInfo((object)"Shark spawn client respawned local shark");
				}
			}
		}
	}
}
namespace SharksAndMinnows.Configuration
{
	public class ConfigurationHandler
	{
		private ConfigFile _config;

		private BepInExConfigSync _bepInExConfigSync;

		private ConfigEntry<float> ConfigMinnowDefaultMoveSpeedMultiplier;

		private ConfigEntry<float> ConfigMinnowWalkMoveSpeedMultiplier;

		private ConfigEntry<float> ConfigMinnowWadingInWaterSpeedMultiplier;

		private ConfigEntry<float> ConfigMinnowSpeedBoostSpeedFactorMultiplier;

		private ConfigEntry<float> ConfigMinnowDiveHorizontalSpeedMultiplier;

		private ConfigEntry<float> ConfigMinnowDiveGetUpDurationMultiplier;

		private ConfigEntry<float> ConfigMinnowJumpUpwardsSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkDefaultMoveSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkWalkMoveSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkWadingInWaterSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkSpeedBoostSpeedFactorMultiplier;

		private ConfigEntry<float> ConfigSharkDiveUpwardsSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkDiveHorizontalSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkSwingChargingSpeedMultiplier;

		private ConfigEntry<float> ConfigSharkSwingAimingSpeedMultiplier;

		private ConfigEntry<float> ConfigDiveHorizontalDiscMultiplier;

		private ConfigEntry<float> ConfigDiveVerticalDiscMultiplier;

		private ConfigEntry<float> ConfigDiveForwardCenterOffset;

		private ConfigEntry<float> ConfigDiveMinDiscHeight;

		private ConfigEntry<float> ConfigProximityTagAuraRadius;

		public static ConfigurationHandler Instance { get; private set; }

		public float MinnowDefaultMoveSpeedMultiplier => ConfigMinnowDefaultMoveSpeedMultiplier.Value;

		public float MinnowWalkMoveSpeedMultiplier => ConfigMinnowWalkMoveSpeedMultiplier.Value;

		public float MinnowWadingInWaterSpeedMultiplier => ConfigMinnowWadingInWaterSpeedMultiplier.Value;

		public float MinnowSpeedBoostSpeedFactorMultiplier => ConfigMinnowSpeedBoostSpeedFactorMultiplier.Value;

		public float MinnowDiveHorizontalSpeedMultiplier => ConfigMinnowDiveHorizontalSpeedMultiplier.Value;

		public float MinnowDiveGetUpDurationMultiplier => ConfigMinnowDiveGetUpDurationMultiplier.Value;

		public float MinnowJumpUpwardsSpeedMultiplier => ConfigMinnowJumpUpwardsSpeedMultiplier.Value;

		public float SharkDefaultMoveSpeedMultiplier => ConfigSharkDefaultMoveSpeedMultiplier.Value;

		public float SharkWalkMoveSpeedMultiplier => ConfigSharkWalkMoveSpeedMultiplier.Value;

		public float SharkWadingInWaterSpeedMultiplier => ConfigSharkWadingInWaterSpeedMultiplier.Value;

		public float SharkSpeedBoostSpeedFactorMultiplier => ConfigSharkSpeedBoostSpeedFactorMultiplier.Value;

		public float SharkDiveUpwardsSpeedMultiplier => ConfigSharkDiveUpwardsSpeedMultiplier.Value;

		public float SharkDiveHorizontalSpeedMultiplier => ConfigSharkDiveHorizontalSpeedMultiplier.Value;

		public float SharkSwingChargingSpeedMultiplier => ConfigSharkSwingChargingSpeedMultiplier.Value;

		public float SharkSwingAimingSpeedMultiplier => ConfigSharkSwingAimingSpeedMultiplier.Value;

		public float DiveHorizontalDiscMultiplier => ConfigDiveHorizontalDiscMultiplier.Value;

		public float DiveVerticalDiscMultiplier => ConfigDiveVerticalDiscMultiplier.Value;

		public float DiveForwardCenterOffset => ConfigDiveForwardCenterOffset.Value;

		public float DiveMinDiscHeight => ConfigDiveMinDiscHeight.Value;

		public float ProximityTagAuraRadius => ConfigProximityTagAuraRadius.Value;

		public event Action MovementConfigChanged;

		public ConfigurationHandler(ConfigFile configFile)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			Instance = this;
			_config = configFile;
			Plugin.Log.LogInfo((object)$"ConfigurationHandler initialising {configFile}");
			BindMovementSpeedConfigurations();
			BindDivingHitboxConfigurations();
			BindProximityTagConfigurations();
			_bepInExConfigSync = new BepInExConfigSync(_config, "com.github.glarmer.SharksAndMinnows:SharksAndMinnows");
			_bepInExConfigSync.SyncedValueChanged += delegate
			{
				this.MovementConfigChanged?.Invoke();
			};
			Plugin.Log.LogInfo((object)"ConfigurationHandler initialised");
		}

		private void BindMovementSpeedConfigurations()
		{
			ConfigMinnowDefaultMoveSpeedMultiplier = Bind("Movement Minnows", "MinnowDefaultMoveSpeedMultiplier", 2f, "Multiplier for minnow default move speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigMinnowWalkMoveSpeedMultiplier = Bind("Movement Minnows", "MinnowWalkMoveSpeedMultiplier", 2f, "Multiplier for minnow walk move speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigMinnowWadingInWaterSpeedMultiplier = Bind("Movement Minnows", "MinnowWadingInWaterSpeedMultiplier", 2f, "Multiplier for minnow wading in water speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigMinnowSpeedBoostSpeedFactorMultiplier = Bind("Movement Minnows", "MinnowSpeedBoostSpeedFactorMultiplier", 2f, "Multiplier for minnow speed boost factor", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigMinnowDiveHorizontalSpeedMultiplier = Bind("Movement Minnows", "MinnowDiveHorizontalSpeedMultiplier", 1.5f, "Multiplier for minnow dive horizontal speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigMinnowDiveGetUpDurationMultiplier = Bind("Movement Minnows", "MinnowDiveGetUpDurationMultiplier", 0.75f, "Multiplier for minnow dive get up duration", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigMinnowJumpUpwardsSpeedMultiplier = Bind("Movement Minnows", "MinnowJumpUpwardsSpeedMultiplier", 1.25f, "Multiplier for minnow jump upwards speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkDefaultMoveSpeedMultiplier = Bind("Movement Sharks", "SharkDefaultMoveSpeedMultiplier", 1f, "Multiplier for shark default move speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkWalkMoveSpeedMultiplier = Bind("Movement Sharks", "SharkWalkMoveSpeedMultiplier", 1f, "Multiplier for shark walk move speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkWadingInWaterSpeedMultiplier = Bind("Movement Sharks", "SharkWadingInWaterSpeedMultiplier", 1f, "Multiplier for shark wading in water speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkSpeedBoostSpeedFactorMultiplier = Bind("Movement Sharks", "SharkSpeedBoostSpeedFactorMultiplier", 1f, "Multiplier for shark speed boost factor", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkDiveUpwardsSpeedMultiplier = Bind("Movement Sharks", "SharkDiveUpwardsSpeedMultiplier", 1f, "Multiplier for shark dive upwards speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkDiveHorizontalSpeedMultiplier = Bind("Movement Sharks", "SharkDiveHorizontalSpeedMultiplier", 2.5f, "Multiplier for shark dive horizontal speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkSwingChargingSpeedMultiplier = Bind("Movement Sharks", "SharkSwingChargingSpeedMultiplier", 1.5f, "Multiplier for shark swing charging speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
			ConfigSharkSwingAimingSpeedMultiplier = Bind("Movement Sharks", "SharkSwingAimingSpeedMultiplier", 1.5f, "Multiplier for shark swing aiming speed", delegate
			{
				this.MovementConfigChanged?.Invoke();
			}, (float v) => Mathf.Clamp(v, 0.1f, 100f));
		}

		private void BindDivingHitboxConfigurations()
		{
			ConfigDiveHorizontalDiscMultiplier = Bind("Diving Hitbox", "HorizontalDiscMultiplier", 10f, "Multiplier applied to diving collider diameter for hitbox width/depth", null, (float v) => Mathf.Clamp(v, 0.01f, 100f));
			ConfigDiveVerticalDiscMultiplier = Bind("Diving Hitbox", "VerticalDiscMultiplier", 1f, "Multiplier applied to diving collider diameter for hitbox height", null, (float v) => Mathf.Clamp(v, 0.01f, 100f));
			ConfigDiveForwardCenterOffset = Bind("Diving Hitbox", "ForwardCenterOffset", 0.15f, "Forward (local Z) offset applied to the dive hitbox center", null, (float v) => Mathf.Clamp(v, -10f, 10f));
			ConfigDiveMinDiscHeight = Bind("Diving Hitbox", "MinDiscHeight", 0.15f, "Minimum height of the dive hitbox (prevents extremely thin hitboxes)", null, (float v) => Mathf.Clamp(v, 0.01f, 10f));
		}

		private void BindProximityTagConfigurations()
		{
			ConfigProximityTagAuraRadius = Bind("Proximity Tag", "TagAuraRadius", 3f, "Radius of the proximity tag aura trigger (in meters)", null, (float v) => Mathf.Clamp(v, 0.1f, 100f));
		}

		public void SyncConfiguration()
		{
			if (NetworkServer.active)
			{
				_bepInExConfigSync.PushHostConfigToScope();
			}
			else if (NetworkClient.active)
			{
				_bepInExConfigSync.RequestFromHost();
			}
		}

		private ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, Action onChanged = null, Func<T, T> clamp = null)
		{
			Func<T, T> clamp2 = clamp;
			Action onChanged2 = onChanged;
			ConfigEntry<T> entry = _config.Bind<T>(section, key, defaultValue, description);
			if (clamp2 != null)
			{
				entry.Value = clamp2(entry.Value);
			}
			Plugin.Log.LogInfo((object)$"{key} set to: {entry.Value}");
			if (onChanged2 != null)
			{
				entry.SettingChanged += delegate
				{
					if (clamp2 != null)
					{
						T val = clamp2(entry.Value);
						if (!object.Equals(entry.Value, val))
						{
							entry.Value = val;
							return;
						}
					}
					onChanged2();
				};
			}
			return entry;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}