Decompiled source of SpongeTweaks v1.0.1

plugins/SpongeMods.SpongeTweaks.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Timing;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SpongeMods.SpongeTweaks.Abilities;
using SpongeMods.SpongeTweaks.Cosmetic;
using SpongeMods.SpongeTweaks.Gameplay;
using SpongeMods.SpongeTweaks.Hud;
using SpongeMods.SpongeTweaks.Inventory;
using SpongeMods.SpongeTweaks.Multiplayer;
using SpongeMods.SpongeTweaks.Persistence;
using SpongeMods.SpongeTweaks.Progression;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("FishNet.Runtime")]
[assembly: AssemblyCompany("Merged community mod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("All-in-one How to Fish mod merging fourteen community mods.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+dbcdd0857e7f8d44cac85cf2506353d8ac92c331")]
[assembly: AssemblyProduct("SpongeTweaks")]
[assembly: AssemblyTitle("SpongeMods.SpongeTweaks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SpongeMods.SpongeTweaks
{
	[BepInPlugin("spongemods.howtofish.spongetweaks", "SpongeMods - SpongeTweaks", "1.0.0")]
	[BepInProcess("How to Fish.exe")]
	public sealed class CompendiumPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "spongemods.howtofish.spongetweaks";

		public const string PluginName = "SpongeMods - SpongeTweaks";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		private FileSystemWatcher _configWatcher;

		private readonly List<IFeatureModule> _modules = new List<IFeatureModule>();

		private readonly List<IFeatureModule> _updating = new List<IFeatureModule>();

		private readonly List<IFeatureModule> _lateUpdating = new List<IFeatureModule>();

		internal static CompendiumPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigFile Configuration { get; private set; }

		private void Awake()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Configuration = ((BaseUnityPlugin)this).Config;
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			_harmony = new Harmony("spongemods.howtofish.spongetweaks");
			SpongeRegister(new GiantCatchModule());
			SpongeRegister(new BossHealthModule());
			SpongeRegister(new BossTimerModule());
			SpongeRegister(new CreatureHealthModule());
			SpongeRegister(new AmmoCounterModule());
			SpongeRegister(new SwimmingModule());
			SpongeRegister(new ShotgunJumpModule());
			SpongeRegister(new FairSlotsModule());
			SpongeRegister(new LaserSightModule());
			SpongeRegister(new LobbySizeModule());
			SpongeRegister(new StackingModule());
			SpongeRegister(new DroppedItemModule());
			SpongeRegister(new SaveBackupModule());
			SpongeRegister(new VoidBeamModule());
			foreach (IFeatureModule module in _modules)
			{
				if (!module.Enabled)
				{
					Log.LogInfo((object)(module.DisplayName + " is disabled by config."));
					continue;
				}
				try
				{
					module.Initialise(_harmony);
					if (module.WantsUpdate)
					{
						_updating.Add(module);
					}
					if (module.WantsLateUpdate)
					{
						_lateUpdating.Add(module);
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)(module.DisplayName + " failed to start and was skipped: " + ex));
				}
			}
			Log.LogInfo((object)string.Format("{0} {1} loaded {2} live and {3} total features.", "SpongeMods - SpongeTweaks", "1.0.0", _updating.Count + _lateUpdating.Count, _modules.Count));
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
				((BaseUnityPlugin)this).Config.Save();
			}
			SetupConfigWatcher();
		}

		private void SetupConfigWatcher()
		{
			try
			{
				string fileName = Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath);
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath);
				if (!string.IsNullOrEmpty(directoryName) && Directory.Exists(directoryName))
				{
					_configWatcher = new FileSystemWatcher(directoryName, fileName);
					_configWatcher.Changed += OnConfigFileChanged;
					_configWatcher.Created += OnConfigFileChanged;
					_configWatcher.Renamed += OnConfigFileChanged;
					_configWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
					_configWatcher.IncludeSubdirectories = false;
					_configWatcher.EnableRaisingEvents = true;
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not watch the config file for changes: " + ex.Message));
			}
		}

		private void OnConfigFileChanged(object sender, FileSystemEventArgs eventArgs)
		{
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
				Log.LogInfo((object)"Config reloaded from disk.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("There was an issue reloading the config file: " + ex.Message));
				Log.LogError((object)"Please check your config entries for spelling and format.");
			}
		}

		private void SpongeRegister(IFeatureModule module)
		{
			module.BindConfiguration(((BaseUnityPlugin)this).Config);
			_modules.Add(module);
		}

		private void Update()
		{
			for (int i = 0; i < _updating.Count; i++)
			{
				try
				{
					_updating[i].Tick();
				}
				catch (Exception ex)
				{
					Log.LogError((object)(_updating[i].DisplayName + " threw during Update: " + ex));
				}
			}
		}

		private void LateUpdate()
		{
			for (int i = 0; i < _lateUpdating.Count; i++)
			{
				try
				{
					_lateUpdating[i].LateTick();
				}
				catch (Exception ex)
				{
					Log.LogError((object)(_lateUpdating[i].DisplayName + " threw during LateUpdate: " + ex));
				}
			}
		}

		private void OnDestroy()
		{
			if (_configWatcher != null)
			{
				_configWatcher.EnableRaisingEvents = false;
				_configWatcher.Changed -= OnConfigFileChanged;
				_configWatcher.Created -= OnConfigFileChanged;
				_configWatcher.Renamed -= OnConfigFileChanged;
				_configWatcher.Dispose();
				_configWatcher = null;
			}
			foreach (IFeatureModule module in _modules)
			{
				try
				{
					module.Shutdown();
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)(module.DisplayName + " threw while shutting down: " + ex));
				}
			}
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			((BaseUnityPlugin)this).Config.Save();
			Instance = null;
		}

		internal static Coroutine Run(IEnumerator routine)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				return ((MonoBehaviour)Instance).StartCoroutine(routine);
			}
			return null;
		}
	}
	internal interface IFeatureModule
	{
		string DisplayName { get; }

		bool Enabled { get; }

		bool WantsUpdate { get; }

		bool WantsLateUpdate { get; }

		void BindConfiguration(ConfigFile config);

		void Initialise(Harmony harmony);

		void Tick();

		void LateTick();

		void Shutdown();
	}
	internal abstract class FeatureModule : IFeatureModule
	{
		protected ConfigEntry<bool> ModuleEnabled;

		public abstract string DisplayName { get; }

		public virtual bool Enabled
		{
			get
			{
				if (ModuleEnabled != null)
				{
					return ModuleEnabled.Value;
				}
				return true;
			}
		}

		public virtual bool WantsUpdate => false;

		public virtual bool WantsLateUpdate => false;

		public abstract void BindConfiguration(ConfigFile config);

		public virtual void Initialise(Harmony harmony)
		{
		}

		public virtual void Tick()
		{
		}

		public virtual void LateTick()
		{
		}

		public virtual void Shutdown()
		{
		}
	}
	internal static class UiSupport
	{
		internal static readonly Vector2 TopLeft = new Vector2(0f, 1f);

		internal static readonly Vector2 TopCentre = new Vector2(0.5f, 1f);

		public static Color ResolveColour(string configured, Color fallback)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(configured) || string.IsNullOrWhiteSpace(configured))
			{
				return fallback;
			}
			if (string.Equals(configured.Trim(), "Default", StringComparison.OrdinalIgnoreCase))
			{
				return fallback;
			}
			string text = configured.Trim();
			if (!text.StartsWith("#", StringComparison.Ordinal))
			{
				text = "#" + text;
			}
			Color result = default(Color);
			if (!ColorUtility.TryParseHtmlString(text, ref result))
			{
				return fallback;
			}
			return result;
		}

		public static string RenderHp(int value)
		{
			return value.ToString("N0", CultureInfo.InvariantCulture);
		}

		public static bool GameplayHudVisible()
		{
			if (MainMenuManager.IsInMenu || PauseManager.IsPaused)
			{
				return false;
			}
			try
			{
				return !PlayerUI.UIDisabled;
			}
			catch
			{
				return true;
			}
		}

		public static bool BossHudVisible()
		{
			if (MainMenuManager.IsInMenu || PauseManager.IsPaused)
			{
				return false;
			}
			try
			{
				return PlayerUI.BossCanvasActive;
			}
			catch
			{
				return false;
			}
		}

		public static TextMeshProUGUI FindFontDonor()
		{
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val in array)
			{
				if ((Object)(object)val != (Object)null && ((TMP_Text)val).text != null && ((TMP_Text)val).text.IndexOf("Version", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return val;
				}
			}
			return null;
		}

		public static RectTransform MakeRect(string name, Transform parent)
		{
			//IL_0014: 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)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			return val.GetComponent<RectTransform>();
		}

		public static void SpongeStretchToParent(RectTransform rect)
		{
			//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)
			//IL_0021: 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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.pivot = new Vector2(0.5f, 0.5f);
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
			((Transform)rect).localScale = Vector3.one;
			((Transform)rect).localRotation = Quaternion.identity;
		}

		public static GameObject CreateOverlayCanvas(string name, int sortingOrder)
		{
			//IL_002e: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler)
			});
			Canvas component = val.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = sortingOrder;
			CanvasScaler component2 = val.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1920f, 1080f);
			component2.screenMatchMode = (ScreenMatchMode)0;
			component2.matchWidthOrHeight = 0.5f;
			return val;
		}

		internal static GameObject InsertPanel(Transform parent, string name, Vector2 anchor, Vector2 position, Vector2 size, Color colour)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004c: 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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = anchor;
			val2.anchorMax = anchor;
			val2.pivot = anchor;
			val2.anchoredPosition = position;
			val2.sizeDelta = size;
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = colour;
			((Graphic)component).raycastTarget = false;
			return val;
		}

		internal static TextMeshProUGUI InsertText(Transform parent, string name, string value, Vector2 anchor, Vector2 position, Vector2 size, float fontSize, FontStyles style, Color colour, TextAlignmentOptions alignment)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0073: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00a7: 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)
			TextMeshProUGUI val = null;
			try
			{
				val = PlayerUI.CanvasTextPrefab;
			}
			catch
			{
			}
			TextMeshProUGUI val2;
			if ((Object)(object)val != (Object)null)
			{
				val2 = Object.Instantiate<TextMeshProUGUI>(val, parent);
				((Object)((Component)val2).gameObject).name = name;
			}
			else
			{
				GameObject val3 = new GameObject(name, new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				});
				val3.transform.SetParent(parent, false);
				val2 = val3.GetComponent<TextMeshProUGUI>();
			}
			RectTransform rectTransform = ((TMP_Text)val2).rectTransform;
			rectTransform.anchorMin = anchor;
			rectTransform.anchorMax = anchor;
			rectTransform.pivot = anchor;
			rectTransform.anchoredPosition = position;
			rectTransform.sizeDelta = size;
			((TMP_Text)val2).text = value;
			((TMP_Text)val2).fontSize = fontSize;
			((TMP_Text)val2).fontStyle = style;
			((Graphic)val2).color = colour;
			((TMP_Text)val2).alignment = alignment;
			((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
			((Graphic)val2).raycastTarget = false;
			return val2;
		}

		internal static T Ensure<T>(GameObject target) where T : Component
		{
			return target.GetComponent<T>() ?? target.AddComponent<T>();
		}

		internal static Color WithAlpha(Color colour, float alpha)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			colour.a = alpha;
			return colour;
		}

		internal static void SetLayoutWidth(GameObject target, float width, bool flexible)
		{
			LayoutElement obj = UiSupport.Ensure<LayoutElement>(target);
			obj.minWidth = width;
			obj.preferredWidth = width;
			obj.flexibleWidth = (flexible ? 1f : 0f);
		}

		internal static void StripLocalisation(GameObject target)
		{
			MonoBehaviour[] componentsInChildren = target.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().Name.IndexOf("Localize", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
	}
}
namespace SpongeMods.SpongeTweaks.Progression
{
	internal static class LeaderboardHud
	{
		private const int Rows = 3;

		private static readonly Color Cyan = new Color(0.18f, 0.82f, 0.88f, 1f);

		private static readonly Color Muted = new Color(0.66f, 0.75f, 0.8f, 1f);

		private static readonly Color[] MedalColours = (Color[])(object)new Color[3]
		{
			new Color(1f, 0.72f, 0.22f, 1f),
			new Color(0.73f, 0.8f, 0.86f, 1f),
			new Color(0.8f, 0.48f, 0.27f, 1f)
		};

		private static GameObject _root;

		private static GameObject _canvasRoot;

		private static readonly TextMeshProUGUI[] RowNames = (TextMeshProUGUI[])(object)new TextMeshProUGUI[3];

		private static readonly TextMeshProUGUI[] RowSizes = (TextMeshProUGUI[])(object)new TextMeshProUGUI[3];

		private static string _lastSignature = string.Empty;

		public static void RequireVisible(IReadOnlyList<LeaderboardRow> entries)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI canvasTextPrefab;
			try
			{
				canvasTextPrefab = PlayerUI.CanvasTextPrefab;
			}
			catch
			{
				return;
			}
			if ((Object)(object)Player.LocalPlayer == (Object)null || (Object)(object)canvasTextPrefab == (Object)null)
			{
				return;
			}
			if ((Object)(object)_root == (Object)null || (Object)(object)_canvasRoot == (Object)null)
			{
				Teardown();
				Build();
			}
			string text = ComposeSignature(entries);
			if (text == _lastSignature)
			{
				return;
			}
			for (int i = 0; i < 3; i++)
			{
				bool flag = entries != null && i < entries.Count;
				string text2 = (flag ? (entries[i].DisplayName ?? "Angler") : "No catch");
				if (text2.Length > 18)
				{
					text2 = text2.Substring(0, 17) + "…";
				}
				((TMP_Text)RowNames[i]).text = text2;
				((Graphic)RowNames[i]).color = (Color)(flag ? Color.white : new Color(Muted.r, Muted.g, Muted.b, 0.65f));
				((TMP_Text)RowSizes[i]).text = (flag ? $"×{entries[i].Size:0.00}" : "—");
				((Graphic)RowSizes[i]).color = (Color)(flag ? Cyan : new Color(Muted.r, Muted.g, Muted.b, 0.65f));
			}
			_lastSignature = text;
		}

		public static void Teardown()
		{
			if ((Object)(object)_canvasRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasRoot);
			}
			_root = null;
			_canvasRoot = null;
			for (int i = 0; i < 3; i++)
			{
				RowNames[i] = null;
				RowSizes[i] = null;
			}
			_lastSignature = string.Empty;
		}

		private static void Build()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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)
			//IL_019e: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			_canvasRoot = UiSupport.CreateOverlayCanvas("SpongeMods_RankingCanvas", 5000);
			_root = new GameObject("SpongeMods_RankingHud", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Outline)
			});
			_root.transform.SetParent(_canvasRoot.transform, false);
			RectTransform val = (RectTransform)_root.transform;
			val.anchorMin = new Vector2(1f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(1f, 1f);
			val.anchoredPosition = new Vector2(-28f, -28f);
			val.sizeDelta = new Vector2(390f, 218f);
			Image component = _root.GetComponent<Image>();
			((Graphic)component).color = new Color(0.018f, 0.048f, 0.075f, 0.94f);
			((Graphic)component).raycastTarget = false;
			Outline component2 = _root.GetComponent<Outline>();
			((Shadow)component2).effectColor = new Color(Cyan.r, Cyan.g, Cyan.b, 0.72f);
			((Shadow)component2).effectDistance = new Vector2(2f, -2f);
			UiSupport.InsertPanel(_root.transform, "TopAccent", UiSupport.TopLeft, Vector2.zero, new Vector2(390f, 5f), Cyan);
			UiSupport.InsertPanel(_root.transform, "TitleMarker", UiSupport.TopLeft, new Vector2(18f, -18f), new Vector2(4f, 39f), Cyan);
			UiSupport.InsertText(_root.transform, "Title", "BIGGEST CATCHES", UiSupport.TopLeft, new Vector2(34f, -13f), new Vector2(330f, 27f), 19f, (FontStyles)1, Color.white, (TextAlignmentOptions)513);
			UiSupport.InsertText(_root.transform, "Subtitle", "RECORDS FOR THIS SAVE", UiSupport.TopLeft, new Vector2(34f, -39f), new Vector2(330f, 20f), 11f, (FontStyles)1, Muted, (TextAlignmentOptions)513);
			for (int i = 0; i < 3; i++)
			{
				float num = -72f - (float)i * 46f;
				Color colour = ((i == 0) ? new Color(0.07f, 0.16f, 0.2f, 0.92f) : new Color(0.045f, 0.105f, 0.14f, 0.86f));
				Transform transform = UiSupport.InsertPanel(_root.transform, $"RankRow{i + 1}", UiSupport.TopLeft, new Vector2(18f, num), new Vector2(354f, 38f), colour).transform;
				UiSupport.InsertPanel(transform, "RankBadge", UiSupport.TopLeft, Vector2.zero, new Vector2(38f, 38f), new Color(MedalColours[i].r, MedalColours[i].g, MedalColours[i].b, 0.2f));
				UiSupport.InsertText(transform, "Rank", (i + 1).ToString(), UiSupport.TopLeft, new Vector2(0f, -3f), new Vector2(38f, 31f), 18f, (FontStyles)1, MedalColours[i], (TextAlignmentOptions)514);
				RowNames[i] = UiSupport.InsertText(transform, "Player", "No catch", UiSupport.TopLeft, new Vector2(50f, -3f), new Vector2(210f, 31f), 17f, (FontStyles)0, Color.white, (TextAlignmentOptions)513);
				RowSizes[i] = UiSupport.InsertText(transform, "Size", "—", UiSupport.TopLeft, new Vector2(266f, -3f), new Vector2(72f, 31f), 18f, (FontStyles)1, Cyan, (TextAlignmentOptions)516);
			}
			GiantCatchModule.Instance?.SpongeLogRankingHudCreated();
		}

		private static string ComposeSignature(IReadOnlyList<LeaderboardRow> entries)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < 3; i++)
			{
				if (entries != null && i < entries.Count)
				{
					stringBuilder.Append(entries[i].DisplayName).Append('|').Append(entries[i].Size.ToString("0.00"));
				}
				stringBuilder.Append(';');
			}
			return stringBuilder.ToString();
		}
	}
	internal static class CatchToast
	{
		private static GameObject _currentCard;

		private static RenderTexture _currentTexture;

		private static readonly FieldInfo InventoryCameraField = AccessTools.Field(typeof(PlayerInventory), "_inventoryCamera");

		private static readonly FieldInfo ItemSlotsField = AccessTools.Field(typeof(PlayerInventory), "_itemSlots");

		private static readonly FieldInfo SlotFilterField = AccessTools.Field(typeof(InventorySlot), "_filter");

		private static readonly FieldInfo SlotRendererField = AccessTools.Field(typeof(InventorySlot), "_renderer");

		private static readonly FieldInfo SlotImageField = AccessTools.Field(typeof(InventorySlot), "_itemImage");

		public static void Show(MonoBehaviour runner, Creature creature, string catcherName)
		{
			Cleanup();
			Transform fXCanvasTrans = PlayerUI.FXCanvasTrans;
			if (!((Object)(object)fXCanvasTrans == (Object)null))
			{
				_currentCard = ComposeCard(fXCanvasTrans, creature, catcherName);
				runner.StartCoroutine(TweenCard(_currentCard));
			}
		}

		private static GameObject ComposeCard(Transform parent, Creature creature, string catcherName)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0058: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SpongeMods_CatchCard", new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasGroup),
				typeof(Image),
				typeof(Outline)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(0.5f, 1f);
			val2.anchorMax = new Vector2(0.5f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.anchoredPosition = new Vector2(0f, -28f);
			val2.sizeDelta = new Vector2(460f, 148f);
			((Graphic)val.GetComponent<Image>()).color = new Color(0.018f, 0.048f, 0.075f, 0.96f);
			Outline component = val.GetComponent<Outline>();
			((Shadow)component).effectColor = new Color(0.18f, 0.82f, 0.88f, 0.72f);
			((Shadow)component).effectDistance = new Vector2(2f, -2f);
			UiSupport.InsertPanel(val.transform, "TopAccent", UiSupport.TopCentre, Vector2.zero, new Vector2(460f, 4f), new Color(0.18f, 0.82f, 0.88f, 1f));
			Transform transform = UiSupport.InsertPanel(val.transform, "PreviewPanel", UiSupport.TopCentre, new Vector2(-166f, -20f), new Vector2(112f, 108f), new Color(0.045f, 0.105f, 0.14f, 0.94f)).transform;
			UiSupport.InsertText(val.transform, "CaptureLabel", "NEW CATCH", UiSupport.TopCentre, new Vector2(42f, -14f), new Vector2(272f, 20f), 11f, (FontStyles)1, new Color(0.62f, 0.75f, 0.81f), (TextAlignmentOptions)513);
			UiSupport.InsertText(val.transform, "Size", $"×{FishSizeService.ObtainDisplaySize(creature):0.00}", UiSupport.TopCentre, new Vector2(42f, -33f), new Vector2(272f, 36f), 29f, (FontStyles)1, new Color(0.38f, 0.94f, 1f), (TextAlignmentOptions)513);
			UiSupport.InsertText(val.transform, "Catcher", "CAUGHT BY  -  " + catcherName, UiSupport.TopCentre, new Vector2(42f, -72f), new Vector2(272f, 22f), 14f, (FontStyles)1, Color.white, (TextAlignmentOptions)513);
			UiSupport.InsertPanel(val.transform, "Divider", UiSupport.TopCentre, new Vector2(42f, -99f), new Vector2(272f, 1f), new Color(0.18f, 0.82f, 0.88f, 0.35f));
			int num = (((Object)(object)creature != (Object)null) ? ((Item)creature).TotalWorth : 0);
			UiSupport.InsertText(val.transform, "SaleValue", $"SALE VALUE  -  ${num:N0}", UiSupport.TopCentre, new Vector2(42f, -108f), new Vector2(272f, 22f), 14f, (FontStyles)1, new Color(0.96f, 0.76f, 0.28f), (TextAlignmentOptions)513);
			Player player = RodTierService.ObtainCatcherForCreature(creature);
			int num2 = RodTierService.ObtainLevel(player);
			UiSupport.InsertText(val.transform, "RodBonuses", $"ROD {num2}  -  LUCK {RodTierService.ObtainLuck(player)}  -  " + $"REEL +{num2 * 5}%  -  SALE +{RodTierService.ObtainSaleBonus(player)}%", UiSupport.TopCentre, new Vector2(42f, -130f), new Vector2(272f, 16f), 9.5f, (FontStyles)1, new Color(0.62f, 0.75f, 0.81f), (TextAlignmentOptions)513);
			GameObject val3 = new GameObject("FishPreview", new Type[2]
			{
				typeof(RectTransform),
				typeof(RawImage)
			});
			val3.transform.SetParent(transform, false);
			RectTransform val4 = (RectTransform)val3.transform;
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(6f, 6f);
			val4.offsetMax = new Vector2(-6f, -6f);
			_currentTexture = ComposeFishPreview(creature, out var previewUv);
			RawImage component2 = val3.GetComponent<RawImage>();
			component2.texture = (Texture)(object)_currentTexture;
			component2.uvRect = previewUv;
			val.transform.localScale = Vector3.zero;
			return val;
		}

		private static RenderTexture ComposeFishPreview(Creature creature, out Rect previewUv)
		{
			//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_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: 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_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: 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)
			previewUv = new Rect(0f, 0f, 1f, 1f);
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.Inventory == (Object)null)
			{
				GiantCatchModule.Instance?.SpongeLogPreviewWarning("Local inventory was unavailable for the catch preview.");
				return null;
			}
			PlayerInventory inventory = localPlayer.Inventory;
			Camera val = (Camera)InventoryCameraField.GetValue(inventory);
			List<InventorySlot> list = (List<InventorySlot>)ItemSlotsField.GetValue(inventory);
			if ((Object)(object)val == (Object)null || list == null)
			{
				GiantCatchModule.Instance?.SpongeLogPreviewWarning("Inventory camera or slots were unavailable for the catch preview.");
				return null;
			}
			InventorySlot val2 = null;
			MeshFilter val3 = null;
			Renderer val4 = null;
			RawImage val5 = null;
			foreach (InventorySlot item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					MeshFilter val6 = (MeshFilter)SlotFilterField.GetValue(item);
					Renderer val7 = (Renderer)SlotRendererField.GetValue(item);
					RawImage val8 = (RawImage)SlotImageField.GetValue(item);
					if (!((Object)(object)val6 == (Object)null) && !((Object)(object)val7 == (Object)null) && !((Object)(object)val8 == (Object)null))
					{
						val2 = item;
						val3 = val6;
						val4 = val7;
						val5 = val8;
						break;
					}
				}
			}
			RenderTexture targetTexture = val.targetTexture;
			Mesh val9 = ((creature.IsDrip && (Object)(object)((Item)creature).DripMesh != (Object)null) ? ((Item)creature).DripMesh : ((Item)creature).Mesh);
			if ((Object)(object)val2 == (Object)null || (Object)(object)targetTexture == (Object)null || (Object)(object)val9 == (Object)null)
			{
				GiantCatchModule.Instance?.SpongeLogPreviewWarning("Inventory preview resources were incomplete for " + ((Item)creature).GetName() + ".");
				return null;
			}
			previewUv = val5.uvRect;
			RenderTexture val10 = new RenderTexture(((Texture)targetTexture).width, ((Texture)targetTexture).height, targetTexture.depth, targetTexture.format)
			{
				name = "SpongeMods_CatchPreview",
				antiAliasing = Mathf.Max(1, targetTexture.antiAliasing)
			};
			val10.Create();
			Mesh sharedMesh = val3.sharedMesh;
			Vector3 localPosition = ((Component)val3).transform.localPosition;
			Quaternion localRotation = ((Component)val3).transform.localRotation;
			Vector3 localScale = ((Component)val3).transform.localScale;
			bool enabled = val4.enabled;
			bool fog = RenderSettings.fog;
			try
			{
				val3.sharedMesh = val9;
				((Component)val3).transform.localPosition = ((Item)creature).InventoryMeshPos;
				((Component)val3).transform.localEulerAngles = ((Item)creature).InventoryMeshRot;
				((Component)val3).transform.localScale = Vector3.one * ((Item)creature).InventoryMeshScale;
				val4.enabled = true;
				RenderSettings.fog = false;
				val.targetTexture = val10;
				val.Render();
				return val10;
			}
			finally
			{
				val.targetTexture = targetTexture;
				RenderSettings.fog = fog;
				val4.enabled = enabled;
				val3.sharedMesh = sharedMesh;
				((Component)val3).transform.localPosition = localPosition;
				((Component)val3).transform.localRotation = localRotation;
				((Component)val3).transform.localScale = localScale;
			}
		}

		private static IEnumerator TweenCard(GameObject card)
		{
			CanvasGroup group = card.GetComponent<CanvasGroup>();
			float elapsed = 0f;
			while (elapsed < 0.28f && (Object)(object)card != (Object)null)
			{
				elapsed += Time.unscaledDeltaTime;
				float num = Mathf.Clamp01(elapsed / 0.28f);
				card.transform.localScale = Vector3.one * (1f - Mathf.Pow(1f - num, 3f));
				yield return null;
			}
			yield return (object)new WaitForSecondsRealtime(4.5f);
			elapsed = 0f;
			while (elapsed < 0.6f && (Object)(object)card != (Object)null)
			{
				elapsed += Time.unscaledDeltaTime;
				group.alpha = 1f - Mathf.Clamp01(elapsed / 0.6f);
				yield return null;
			}
			if ((Object)(object)card == (Object)(object)_currentCard)
			{
				Cleanup();
			}
		}

		private static void Cleanup()
		{
			if ((Object)(object)_currentCard != (Object)null)
			{
				Object.Destroy((Object)(object)_currentCard);
			}
			if ((Object)(object)_currentTexture != (Object)null)
			{
				_currentTexture.Release();
				Object.Destroy((Object)(object)_currentTexture);
			}
			_currentCard = null;
			_currentTexture = null;
		}
	}
	internal static class SizeRewardToast
	{
		private static GameObject _canvasRoot;

		public static void Show(MonoBehaviour runner, float size)
		{
			//IL_0065: 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_008f: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			Cleanup();
			if (!((Object)(object)runner == (Object)null) && !((Object)(object)PlayerUI.CanvasTextPrefab == (Object)null))
			{
				_canvasRoot = UiSupport.CreateOverlayCanvas("SpongeMods_SizeRewardCanvas", 5001);
				TextMeshProUGUI obj = Object.Instantiate<TextMeshProUGUI>(PlayerUI.CanvasTextPrefab, _canvasRoot.transform);
				((Object)((Component)obj).gameObject).name = "SizeRewardRow";
				RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
				rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
				rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
				rectTransform.pivot = new Vector2(0.5f, 0.5f);
				rectTransform.anchoredPosition = new Vector2(0f, -181f);
				rectTransform.sizeDelta = new Vector2(620f, 42f);
				((TMP_Text)obj).text = $"<color=#ff6a00>{size:0.00}x</color>  Size";
				((TMP_Text)obj).fontSize = 27f;
				((TMP_Text)obj).fontStyle = (FontStyles)0;
				((Graphic)obj).color = Color.white;
				((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
				((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)obj).richText = true;
				((Graphic)obj).raycastTarget = false;
				CanvasGroup val = _canvasRoot.AddComponent<CanvasGroup>();
				runner.StartCoroutine(ConcealAfterDelay(val));
			}
		}

		private static IEnumerator ConcealAfterDelay(CanvasGroup group)
		{
			yield return (object)new WaitForSecondsRealtime(3.7f);
			float elapsed = 0f;
			while (elapsed < 0.5f && (Object)(object)group != (Object)null)
			{
				elapsed += Time.unscaledDeltaTime;
				group.alpha = 1f - Mathf.Clamp01(elapsed / 0.5f);
				yield return null;
			}
			Cleanup();
		}

		private static void Cleanup()
		{
			if ((Object)(object)_canvasRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasRoot);
			}
			_canvasRoot = null;
		}
	}
	internal sealed class FishHealthReadout : MonoBehaviour
	{
		private Creature _creature;

		private GameObject _root;

		private Image _fill;

		private RectTransform _fillRect;

		private TextMeshProUGUI _numbers;

		private Renderer[] _renderers;

		private float _nextRendererRefresh;

		private Bounds _bounds;

		private float _displayedRatio = 1f;

		private const float NearRange = 12f;

		private const float FarRange = 28f;

		private const float NearRangeSquared = 144f;

		private const float FarRangeSquared = 784f;

		private const float RendererRefreshInterval = 1.5f;

		private void Awake()
		{
			_creature = ((Component)this).GetComponent<Creature>();
			_renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
		}

		private void LateUpdate()
		{
			//IL_0094: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: 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_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_creature == (Object)null || ((Object)(object)_root == (Object)null && !AttemptCreate()))
			{
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			Camera val = (((Object)(object)localPlayer != (Object)null) ? localPlayer.CurCam : Camera.main);
			if ((Object)(object)val == (Object)null)
			{
				_root.SetActive(false);
				return;
			}
			int num = Mathf.Max(1, _creature.MaxHp);
			int num2 = Mathf.Clamp(_creature.Hp, 0, num);
			if (num2 <= 0)
			{
				_root.SetActive(false);
				return;
			}
			Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position;
			float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
			bool flag = num2 < num || (Object)(object)((Item)_creature).AttachedRod != (Object)null;
			if (sqrMagnitude > (flag ? 784f : 144f))
			{
				_root.SetActive(false);
				return;
			}
			if (!AnyRendererVisible())
			{
				_root.SetActive(false);
				return;
			}
			_root.SetActive(true);
			if (Time.unscaledTime >= _nextRendererRefresh)
			{
				_renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
				_nextRendererRefresh = Time.unscaledTime + 1.5f;
			}
			RedrawBounds();
			float num3 = Mathf.Clamp(((Bounds)(ref _bounds)).extents.y + 0.28f, 0.45f, 4.5f);
			_root.transform.position = new Vector3(((Bounds)(ref _bounds)).center.x, ((Bounds)(ref _bounds)).max.y + num3 * 0.18f, ((Bounds)(ref _bounds)).center.z);
			_root.transform.rotation = ((Component)val).transform.rotation;
			float num4 = Mathf.Clamp(Mathf.Sqrt(sqrMagnitude) * 0.00032f, 0.0024f, 0.0075f);
			_root.transform.localScale = Vector3.one * num4;
			float num5 = (float)num2 / (float)num;
			_displayedRatio = Mathf.MoveTowards(_displayedRatio, num5, Time.unscaledDeltaTime * 2.5f);
			_fillRect.anchorMax = new Vector2(_displayedRatio, 1f);
			_fillRect.offsetMax = new Vector2((_displayedRatio > 0.025f) ? (-4f) : 0f, -4f);
			((Behaviour)_fill).enabled = _displayedRatio > 0.001f;
			((Graphic)_fill).color = ((num5 > 0.55f) ? new Color(0.22f, 0.86f, 0.42f, 0.96f) : ((num5 > 0.25f) ? new Color(1f, 0.7f, 0.16f, 0.96f) : new Color(0.95f, 0.2f, 0.18f, 0.96f)));
			((TMP_Text)_numbers).text = num2 + " / " + num;
		}

		private bool AttemptCreate()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI canvasTextPrefab;
			try
			{
				canvasTextPrefab = PlayerUI.CanvasTextPrefab;
			}
			catch
			{
				return false;
			}
			if ((Object)(object)canvasTextPrefab == (Object)null)
			{
				return false;
			}
			_root = new GameObject("SpongeMods_CreatureHealthBar", new Type[2]
			{
				typeof(RectTransform),
				typeof(Canvas)
			});
			Canvas component = _root.GetComponent<Canvas>();
			component.renderMode = (RenderMode)2;
			component.sortingOrder = 45;
			((RectTransform)_root.transform).sizeDelta = new Vector2(230f, 42f);
			AssignRect(MakeImage(_root.transform, "Shadow", new Color(0f, 0f, 0f, 0.72f)).GetComponent<RectTransform>(), Vector2.zero, Vector2.one, new Vector2(-5f, -5f), new Vector2(5f, 5f));
			GameObject obj2 = MakeImage(_root.transform, "Track", new Color(0.035f, 0.055f, 0.065f, 0.96f));
			AssignRect(obj2.GetComponent<RectTransform>(), Vector2.zero, Vector2.one, new Vector2(2f, 2f), new Vector2(-2f, -2f));
			GameObject val = MakeImage(obj2.transform, "Fill", Color.green);
			_fillRect = val.GetComponent<RectTransform>();
			AssignRect(_fillRect, Vector2.zero, Vector2.one, new Vector2(4f, 4f), new Vector2(-4f, -4f));
			_fill = val.GetComponent<Image>();
			_fill.type = (Type)0;
			_numbers = Object.Instantiate<TextMeshProUGUI>(canvasTextPrefab, _root.transform);
			((Object)((Component)_numbers).gameObject).name = "HealthNumbers";
			AssignRect(((TMP_Text)_numbers).rectTransform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero);
			((TMP_Text)_numbers).fontSize = 24f;
			((TMP_Text)_numbers).fontStyle = (FontStyles)1;
			((TMP_Text)_numbers).alignment = (TextAlignmentOptions)514;
			((Graphic)_numbers).color = Color.white;
			((TMP_Text)_numbers).textWrappingMode = (TextWrappingModes)0;
			((Graphic)_numbers).raycastTarget = false;
			return true;
		}

		private bool AnyRendererVisible()
		{
			if (_renderers == null || _renderers.Length == 0)
			{
				return true;
			}
			for (int i = 0; i < _renderers.Length; i++)
			{
				if ((Object)(object)_renderers[i] != (Object)null && _renderers[i].isVisible)
				{
					return true;
				}
			}
			return false;
		}

		private void RedrawBounds()
		{
			//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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			bool flag = false;
			for (int i = 0; i < _renderers.Length; i++)
			{
				Renderer val = _renderers[i];
				if (!((Object)(object)val == (Object)null) && val.enabled)
				{
					if (flag)
					{
						((Bounds)(ref _bounds)).Encapsulate(val.bounds);
						continue;
					}
					_bounds = val.bounds;
					flag = true;
				}
			}
			if (!flag)
			{
				_bounds = new Bounds(((Component)this).transform.position, Vector3.one);
			}
		}

		private static GameObject MakeImage(Transform parent, string name, Color colour)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = colour;
			((Graphic)component).raycastTarget = false;
			return val;
		}

		private static void AssignRect(RectTransform rect, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//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)
			//IL_000f: 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)
			rect.anchorMin = anchorMin;
			rect.anchorMax = anchorMax;
			rect.offsetMin = offsetMin;
			rect.offsetMax = offsetMax;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
		}
	}
	internal static class FishHealthReadoutSystem
	{
		private static float _nextScan;

		public static void Tick()
		{
			if (!(Time.unscaledTime < _nextScan) && !((Object)(object)Player.LocalPlayer == (Object)null))
			{
				_nextScan = Time.unscaledTime + 1.5f;
				Creature[] array = Object.FindObjectsByType<Creature>();
				for (int i = 0; i < array.Length; i++)
				{
					Attach(array[i]);
				}
			}
		}

		public static void Attach(Creature creature)
		{
			if (!((Object)(object)creature == (Object)null) && !FishSizeService.IsFlyingCreature(creature) && !((Object)(object)((Component)creature).GetComponent<FishHealthReadout>() != (Object)null))
			{
				((Component)creature).gameObject.AddComponent<FishHealthReadout>();
			}
		}

		public static void Shutdown()
		{
			FishHealthReadout[] array = Object.FindObjectsByType<FishHealthReadout>();
			foreach (FishHealthReadout fishHealthReadout in array)
			{
				if ((Object)(object)fishHealthReadout != (Object)null)
				{
					Object.Destroy((Object)(object)fishHealthReadout);
				}
			}
		}
	}
	internal static class UnboundedWeaponTiers
	{
		public const int MaximumIndex = 255;

		private const int TableLength = 256;

		private static readonly FieldInfo SharpnessTable = AccessTools.Field(typeof(Melee), "_sharpnessUpgrades");

		private static readonly FieldInfo BulletTable = AccessTools.Field(typeof(Attachments), "_bulletUpgrades");

		private static readonly FieldInfo SharpnessDamage = AccessTools.Field(typeof(SharpnessUpgrade), "_damage");

		private static readonly FieldInfo SharpnessCost = AccessTools.Field(typeof(SharpnessUpgrade), "_cost");

		private static readonly FieldInfo BulletDamage = AccessTools.Field(typeof(BulletUpgrade), "_damage");

		private static readonly FieldInfo BulletCost = AccessTools.Field(typeof(BulletUpgrade), "_cost");

		private static readonly FieldInfo MaximumSharpness = AccessTools.Field(typeof(SharpnessPurchasable), "_maxSharpnessUpgrade");

		private static readonly FieldInfo MaximumBullets = AccessTools.Field(typeof(BulletPurchasable), "_maxBulletUpgrade");

		private static bool _logged;

		public static void Ensure(Melee melee)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			if ((Object)(object)melee == (Object)null || SharpnessTable == null)
			{
				return;
			}
			SharpnessUpgrade[] array = (SharpnessUpgrade[])SharpnessTable.GetValue(melee);
			if (array != null && array.Length != 0 && array.Length < 256)
			{
				int damage = array[^1].Damage;
				int cost = array[^1].Cost;
				int num = ((array.Length > 1) ? Math.Max(1, damage - array[^2].Damage) : Math.Max(1, damage / 4));
				int step = ((array.Length > 1) ? Math.Max(10, cost - array[^2].Cost) : Math.Max(10, cost / 2));
				SharpnessUpgrade[] array2 = (SharpnessUpgrade[])(object)new SharpnessUpgrade[256];
				Array.Copy(array, array2, array.Length);
				for (int i = array.Length; i < array2.Length; i++)
				{
					long num2 = i - ((long)array.Length - 1L);
					SharpnessUpgrade val = new SharpnessUpgrade();
					SharpnessDamage.SetValue(val, SpongeSaturate(damage + num * num2));
					SharpnessCost.SetValue(val, SpongeProgressiveCost(cost, step, num2));
					array2[i] = val;
				}
				SharpnessTable.SetValue(melee, array2);
				SpongeLogOnce();
			}
		}

		public static void Ensure(Attachments attachments)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			if ((Object)(object)attachments == (Object)null || BulletTable == null)
			{
				return;
			}
			BulletUpgrade[] array = (BulletUpgrade[])BulletTable.GetValue(attachments);
			if (array != null && array.Length != 0 && array.Length < 256)
			{
				int damage = array[^1].Damage;
				int cost = array[^1].Cost;
				int num = ((array.Length > 1) ? Math.Max(1, damage - array[^2].Damage) : Math.Max(1, damage / 4));
				int step = ((array.Length > 1) ? Math.Max(10, cost - array[^2].Cost) : Math.Max(10, cost / 2));
				BulletUpgrade[] array2 = (BulletUpgrade[])(object)new BulletUpgrade[256];
				Array.Copy(array, array2, array.Length);
				for (int i = array.Length; i < array2.Length; i++)
				{
					long num2 = i - ((long)array.Length - 1L);
					BulletUpgrade val = new BulletUpgrade();
					BulletDamage.SetValue(val, SpongeSaturate(damage + num * num2));
					BulletCost.SetValue(val, SpongeProgressiveCost(cost, step, num2));
					array2[i] = val;
				}
				BulletTable.SetValue(attachments, array2);
				SpongeLogOnce();
			}
		}

		public static void Unlock(SharpnessPurchasable purchasable)
		{
			if ((Object)(object)purchasable != (Object)null && MaximumSharpness != null)
			{
				MaximumSharpness.SetValue(purchasable, byte.MaxValue);
			}
		}

		public static void Unlock(BulletPurchasable purchasable)
		{
			if ((Object)(object)purchasable != (Object)null && MaximumBullets != null)
			{
				MaximumBullets.SetValue(purchasable, byte.MaxValue);
			}
		}

		private static int SpongeProgressiveCost(int lastCost, int step, long extra)
		{
			return SpongeSaturate(lastCost + step * extra * (extra + 1) / 2);
		}

		private static int SpongeSaturate(long value)
		{
			return (int)Math.Max(1L, Math.Min(2000000000L, value));
		}

		private static void SpongeLogOnce()
		{
			if (!_logged)
			{
				_logged = true;
				GiantCatchModule.Instance?.SpongeLogInfiniteWeaponUpgrades();
			}
		}
	}
	[HarmonyPatch]
	internal static class MeleeTierTablePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Melee), "Awake", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Melee), "GetCurSharpness", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Melee), "GetNextSharpnessUpgrade", (Type[])null, (Type[])null);
		}

		private static void Prefix(Melee __instance)
		{
			UnboundedWeaponTiers.Ensure(__instance);
		}
	}
	[HarmonyPatch]
	internal static class BulletTierTablePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Attachments), "Awake", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Attachments), "GetCurBulletUpgrade", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Attachments), "GetNextBulletUpgrade", (Type[])null, (Type[])null);
		}

		private static void Prefix(Attachments __instance)
		{
			UnboundedWeaponTiers.Ensure(__instance);
		}
	}
	[HarmonyPatch]
	internal static class SharpnessBenchCapPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(SharpnessPurchasable), "Hover", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(SharpnessPurchasable), "OnStartHover", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(SharpnessPurchasable), "Interact", (Type[])null, (Type[])null);
		}

		private static void Prefix(SharpnessPurchasable __instance)
		{
			UnboundedWeaponTiers.Unlock(__instance);
		}
	}
	[HarmonyPatch]
	internal static class BulletBenchCapPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(BulletPurchasable), "Hover", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(BulletPurchasable), "OnStartHover", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(BulletPurchasable), "Interact", (Type[])null, (Type[])null);
		}

		private static void Prefix(BulletPurchasable __instance)
		{
			UnboundedWeaponTiers.Unlock(__instance);
		}
	}
	internal static class FishSizeService
	{
		private static readonly FieldInfo WeightField = AccessTools.Field(typeof(Item), "_syncedRandomWeight");

		private static readonly FieldInfo HpField = AccessTools.Field(typeof(Creature), "_hp");

		private static readonly FieldInfo SkipWeightField = AccessTools.Field(typeof(Creature), "_skipRandomizedWeight");

		public static float ObtainSize(Creature creature)
		{
			if (!HasScalableCatch(creature))
			{
				return 1f;
			}
			return Mathf.Clamp(((SyncVar<float>)WeightField.GetValue(creature)).Value, 1f, 25f);
		}

		public static bool IsFlyingCreature(Creature creature)
		{
			if (!(creature is Bird))
			{
				return creature is Albatross;
			}
			return true;
		}

		public static bool HasScalableCatch(Creature creature)
		{
			if ((Object)(object)creature == (Object)null || IsFlyingCreature(creature))
			{
				return false;
			}
			if (IsBoss(creature) || (Object)(object)((Item)creature).AttachedRod != (Object)null)
			{
				return true;
			}
			FishScaleTracker component = ((Component)creature).GetComponent<FishScaleTracker>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (!component.WasHooked)
			{
				return component.LoadedFromSave;
			}
			return true;
		}

		public static bool IsBoss(Creature creature)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			if ((Object)(object)creature != (Object)null)
			{
				return (int)creature.BossType > 0;
			}
			return false;
		}

		public static float ObtainDisplaySize(Creature creature)
		{
			if ((Object)(object)creature == (Object)null)
			{
				return 1f;
			}
			return Mathf.Clamp(ObtainRawWeight(creature), 1f, 25f);
		}

		public static float ObtainRawWeight(Creature creature)
		{
			return ((SyncVar<float>)WeightField.GetValue(creature)).Value;
		}

		public static void AssignSize(Creature creature, float size)
		{
			size = Mathf.Clamp(size, 1f, 25f);
			((SyncVar<float>)WeightField.GetValue(creature)).Value = size;
		}

		public static bool SpongeSkipsRandomWeight(Creature creature)
		{
			return (bool)SkipWeightField.GetValue(creature);
		}

		public static void SpongeRefillHealth(Creature creature)
		{
			SyncVar<int> val = (SyncVar<int>)HpField.GetValue(creature);
			if (val.Value > 0)
			{
				val.Value = creature.MaxHp;
			}
		}

		public static void SpongeMarkLoadedFromSave(Creature creature)
		{
			ObtainOrCreateState(creature).LoadedFromSave = true;
		}

		public static void SpongeRecordCatcher(Creature creature, FishingRod rod)
		{
			if (!((Object)(object)creature == (Object)null) && !((Object)(object)rod == (Object)null))
			{
				FishScaleTracker fishScaleTracker = ObtainOrCreateState(creature);
				fishScaleTracker.WasHooked = true;
				fishScaleTracker.CatcherRod = rod;
				Player val = (((Object)(object)((Item)rod).SyncedHolder != (Object)null) ? ((Item)rod).SyncedHolder : ((Item)rod).Holder);
				if ((Object)(object)val != (Object)null)
				{
					fishScaleTracker.Catcher = val;
					fishScaleTracker.AnglerName = val.SteamName;
				}
				if (InstanceFinder.IsServerStarted && !fishScaleTracker.LuckRollApplied && !fishScaleTracker.LoadedFromSave && !IsBoss(creature))
				{
					int luck = RodTierService.ObtainLuck(val);
					AssignSize(creature, SizeCurve.Roll(((NetworkBehaviour)creature).ObjectId, luck));
					fishScaleTracker.LuckRollApplied = true;
					SpongeRefillHealth(creature);
					SetVisualScale(creature);
					GiantCatchModule.Instance?.SpongeLogLuckRoll(creature, val, luck);
				}
			}
		}

		public static bool AttemptClaimBossInitialRefill(Creature creature)
		{
			if ((Object)(object)creature == (Object)null || !IsBoss(creature))
			{
				return false;
			}
			FishScaleTracker fishScaleTracker = ObtainOrCreateState(creature);
			if (fishScaleTracker.BossHealthInitialized)
			{
				return false;
			}
			fishScaleTracker.BossHealthInitialized = true;
			return true;
		}

		public static bool IsDead(Creature creature)
		{
			if ((Object)(object)creature == (Object)null)
			{
				return false;
			}
			return ((SyncVar<int>)HpField.GetValue(creature)).Value <= 0;
		}

		public static bool AttemptClaimLocalNotification(Creature creature, out string catcherName)
		{
			catcherName = string.Empty;
			if ((Object)(object)creature == (Object)null)
			{
				return false;
			}
			FishScaleTracker component = ((Component)creature).GetComponent<FishScaleTracker>();
			if ((Object)(object)component == (Object)null || component.NotificationShown || (Object)(object)component.CatcherRod == (Object)null)
			{
				return false;
			}
			Player val = component.Catcher;
			if ((Object)(object)val == (Object)null)
			{
				val = (((Object)(object)((Item)component.CatcherRod).SyncedHolder != (Object)null) ? ((Item)component.CatcherRod).SyncedHolder : ((Item)component.CatcherRod).Holder);
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if ((!((Object)(object)localPlayer != (Object)null) || !((Object)(object)val == (Object)(object)localPlayer)) && !((NetworkBehaviour)val).Owner.IsLocalClient)
			{
				return false;
			}
			component.NotificationShown = true;
			catcherName = ((!string.IsNullOrWhiteSpace(component.AnglerName)) ? component.AnglerName : (((Object)(object)val != (Object)null) ? val.SteamName : localPlayer.SteamName));
			return true;
		}

		public static bool SpongeWasLoadedFromSave(Creature creature)
		{
			FishScaleTracker component = ((Component)creature).GetComponent<FishScaleTracker>();
			if ((Object)(object)component != (Object)null)
			{
				return component.LoadedFromSave;
			}
			return false;
		}

		public static void SetVisualScale(Creature creature)
		{
			//IL_0017: 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)
			if (HasScalableCatch(creature))
			{
				FishScaleTracker fishScaleTracker = ObtainOrCreateState(creature);
				((Component)creature).transform.localScale = fishScaleTracker.OriginalScale * ObtainSize(creature);
			}
		}

		private static FishScaleTracker ObtainOrCreateState(Creature creature)
		{
			//IL_0025: 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)
			FishScaleTracker component = ((Component)creature).GetComponent<FishScaleTracker>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = ((Component)creature).gameObject.AddComponent<FishScaleTracker>();
			component.OriginalScale = ((Component)creature).transform.localScale;
			return component;
		}

		public static int SpongeScaledInt(int original, Creature creature)
		{
			double value = (double)original * (double)ObtainSize(creature);
			return (int)Math.Min(2147483647.0, Math.Max(1.0, Math.Round(value, MidpointRounding.AwayFromZero)));
		}
	}
	internal sealed class GiantCatchModule : FeatureModule
	{
		private ConfigEntry<bool> _healthBars;

		internal static GiantCatchModule Instance { get; private set; }

		public override string DisplayName => "Giant Catches";

		public override bool WantsUpdate => true;

		public override void BindConfiguration(ConfigFile config)
		{
			ModuleEnabled = config.Bind<bool>("Giant Catches", "Enabled", true, "Random fish sizes, catch records, rod upgrades and creature health bars.");
			_healthBars = config.Bind<bool>("Giant Catches", "CreatureHealthBars", true, "Show a floating health bar above every creature.");
			LeaderboardService.Initialize(config);
			RodTierService.Initialize(config);
		}

		public override void Initialise(Harmony harmony)
		{
			Instance = this;
			harmony.PatchAll(typeof(FishServerStartPatch));
			harmony.PatchAll(typeof(FishClientStartPatch));
			harmony.PatchAll(typeof(FishMaxHpPatch));
			harmony.PatchAll(typeof(FishRestorePatch));
			harmony.PatchAll(typeof(CatchLeaderboardPatch));
			harmony.PatchAll(typeof(CatchOwnerPatch));
			harmony.PatchAll(typeof(CatchDeathAnnouncePatch));
			harmony.PatchAll(typeof(AggressiveFishStrengthPatch));
			harmony.PatchAll(typeof(PufferStrengthPatch));
			harmony.PatchAll(typeof(BowheadStrengthPatch));
			harmony.PatchAll(typeof(RodSaleValuePatch));
			harmony.PatchAll(typeof(RodSaleScopePatch));
			harmony.PatchAll(typeof(MeleeTierTablePatch));
			harmony.PatchAll(typeof(BulletTierTablePatch));
			harmony.PatchAll(typeof(SharpnessBenchCapPatch));
			harmony.PatchAll(typeof(BulletBenchCapPatch));
			CompendiumPlugin.Log.LogInfo((object)"Giant Catches active.");
		}

		public override void Tick()
		{
			LeaderboardService.Tick();
			RodTierService.Tick();
			if (_healthBars.Value)
			{
				FishHealthReadoutSystem.Tick();
			}
		}

		public override void Shutdown()
		{
			LeaderboardService.Shutdown();
			RodTierService.Shutdown();
			FishHealthReadoutSystem.Shutdown();
			Instance = null;
		}

		internal void DisplayCatchCard(Creature creature, string catcherName)
		{
			CatchToast.Show((MonoBehaviour)(object)CompendiumPlugin.Instance, creature, catcherName);
			SizeRewardToast.Show((MonoBehaviour)(object)CompendiumPlugin.Instance, FishSizeService.ObtainDisplaySize(creature));
		}

		internal void DisplayGlobalRankedCatch(Creature creature, string catcherName, float size, bool isLocalCatcher)
		{
			CatchToast.Show((MonoBehaviour)(object)CompendiumPlugin.Instance, creature, catcherName);
			if (isLocalCatcher)
			{
				SizeRewardToast.Show((MonoBehaviour)(object)CompendiumPlugin.Instance, size);
			}
		}

		internal void SpongeScheduleBossHealthRefill(Creature creature)
		{
			CompendiumPlugin.Run(SpongeRefillBossHealthAfterInitialization(creature));
		}

		private static IEnumerator SpongeRefillBossHealthAfterInitialization(Creature creature)
		{
			yield return null;
			yield return null;
			if ((Object)(object)creature != (Object)null && FishSizeService.AttemptClaimBossInitialRefill(creature))
			{
				FishSizeService.SpongeRefillHealth(creature);
			}
		}

		internal void SpongeLogPreviewWarning(string message)
		{
			CompendiumPlugin.Log.LogWarning((object)message);
		}

		internal void SpongeLogCatchSize(Creature creature)
		{
			CompendiumPlugin.Log.LogInfo((object)$"Scaled catch {((Item)creature).GetName()} to x{FishSizeService.ObtainDisplaySize(creature):0.00}.");
		}

		internal void SpongeLogRankingError(string operation, Exception error)
		{
			CompendiumPlugin.Log.LogError((object)$"Ranking {operation} failed safely: {error}");
		}

		internal void SpongeLogRankingHudCreated()
		{
			CompendiumPlugin.Log.LogInfo((object)"Ranking HUD created on its independent overlay canvas.");
		}

		internal void SpongeLogLuckRoll(Creature creature, Player catcher, int luck)
		{
			CompendiumPlugin.Log.LogInfo((object)(string.Format("Applied catcher luck {0} for {1}: ", luck, ((catcher != null) ? catcher.SteamName : null) ?? "Angler") + $"{((Item)creature).GetName()} rolled x{FishSizeService.ObtainDisplaySize(creature):0.00}."));
		}

		internal void SpongeLogUpgradePurchase(Player player, int cost, int newLevel)
		{
			CompendiumPlugin.Log.LogInfo((object)(string.Format("Server charged ${0} to {1} ", cost, ((player != null) ? player.SteamName : null) ?? "Angler") + $"and applied rod upgrade level {newLevel}."));
		}

		internal void SpongeLogPersonalWalletCompatibility()
		{
			CompendiumPlugin.Log.LogInfo((object)"NoSharedMoney detected: rod upgrades will use each player's personal wallet.");
		}

		internal void SpongeLogUpgradeError(string operation, Exception error)
		{
			CompendiumPlugin.Log.LogError((object)$"Rod upgrade failed while {operation}: {error}");
		}

		internal void SpongeLogInfiniteWeaponUpgrades()
		{
			CompendiumPlugin.Log.LogInfo((object)"Expanded melee and bullet upgrade tables to 255 persistent levels.");
		}

		internal void SpongeLogUpgradeRejection(string reason)
		{
			CompendiumPlugin.Log.LogWarning((object)("Rod upgrade rejected: " + reason));
		}
	}
	[HarmonyPatch(typeof(Creature), "OnStartServer")]
	internal static class FishServerStartPatch
	{
		private static void Prefix(Creature __instance, out byte __state)
		{
			__state = 0;
			if (!FishSizeService.HasScalableCatch(__instance) || (FishSizeService.SpongeSkipsRandomWeight(__instance) && !FishSizeService.IsBoss(__instance)))
			{
				return;
			}
			if (FishSizeService.IsBoss(__instance) && !FishSizeService.SpongeWasLoadedFromSave(__instance))
			{
				__state = 3;
			}
			else if (!(Math.Abs(FishSizeService.ObtainRawWeight(__instance) - 1f) >= 0.0001f))
			{
				if (FishSizeService.SpongeWasLoadedFromSave(__instance))
				{
					FishSizeService.AssignSize(__instance, 1.0001f);
					__state = 2;
				}
				else
				{
					__state = 1;
				}
			}
		}

		private static void Postfix(Creature __instance, byte __state)
		{
			if (!FishSizeService.HasScalableCatch(__instance) || (FishSizeService.SpongeSkipsRandomWeight(__instance) && !FishSizeService.IsBoss(__instance)))
			{
				return;
			}
			switch (__state)
			{
			case 1:
			case 3:
				FishSizeService.AssignSize(__instance, SizeCurve.Roll(((NetworkBehaviour)__instance).ObjectId, RodTierService.ObtainLuckForCreature(__instance)));
				break;
			case 2:
				FishSizeService.AssignSize(__instance, 1f);
				break;
			default:
				if (FishSizeService.ObtainRawWeight(__instance) < 1f)
				{
					FishSizeService.AssignSize(__instance, 1f);
				}
				break;
			}
			FishSizeService.SpongeRefillHealth(__instance);
			if (FishSizeService.IsBoss(__instance))
			{
				GiantCatchModule.Instance?.SpongeScheduleBossHealthRefill(__instance);
			}
			FishSizeService.SetVisualScale(__instance);
			GiantCatchModule.Instance?.SpongeLogCatchSize(__instance);
			LeaderboardService.SpongeRecordCatch(__instance);
		}
	}
	[HarmonyPatch(typeof(Creature), "OnStartClient")]
	internal static class FishClientStartPatch
	{
		private static void Postfix(Creature __instance)
		{
			FishSizeService.SetVisualScale(__instance);
			FishHealthReadoutSystem.Attach(__instance);
		}
	}
	[HarmonyPatch(typeof(Creature), "get_MaxHp")]
	internal static class FishMaxHpPatch
	{
		private static void Postfix(Creature __instance, ref int __result)
		{
			if (FishSizeService.HasScalableCatch(__instance))
			{
				__result = FishSizeService.SpongeScaledInt(__result, __instance);
			}
		}
	}
	[HarmonyPatch(typeof(Creature), "LoadFromSave")]
	internal static class FishRestorePatch
	{
		private static void Prefix(Creature __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !FishSizeService.IsFlyingCreature(__instance))
			{
				FishSizeService.SpongeMarkLoadedFromSave(__instance);
			}
		}

		private static void Postfix(Creature __instance)
		{
			if (FishSizeService.HasScalableCatch(__instance) && FishSizeService.ObtainRawWeight(__instance) < 1f)
			{
				FishSizeService.AssignSize(__instance, 1f);
			}
			FishSizeService.SetVisualScale(__instance);
		}
	}
	[HarmonyPatch(typeof(Creature), "ServerChangeHp")]
	internal static class CatchLeaderboardPatch
	{
		private static void Postfix(Creature __instance)
		{
			try
			{
				if (FishSizeService.IsDead(__instance))
				{
					LeaderboardService.SpongeRecordCatch(__instance);
					LeaderboardService.BroadcastRankedDeath(__instance);
				}
			}
			catch (Exception error)
			{
				GiantCatchModule.Instance?.SpongeLogRankingError("death hook", error);
			}
		}
	}
	[HarmonyPatch(typeof(Item), "OnAttachedRodChange")]
	internal static class CatchOwnerPatch
	{
		private static void Postfix(Item __instance, FishingRod next)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.Creature == (Object)null) && !((Object)(object)next == (Object)null))
			{
				FishSizeService.SpongeRecordCatcher(__instance.Creature, next);
				FishSizeService.SetVisualScale(__instance.Creature);
			}
		}
	}
	[HarmonyPatch(typeof(Creature), "OnDeath")]
	internal static class CatchDeathAnnouncePatch
	{
		private static void Postfix(Creature __instance)
		{
			if (!LeaderboardAnnouncement.SpongeWasAnnounced(((NetworkBehaviour)__instance).ObjectId) && GiantCatchModule.Instance != null && FishSizeService.AttemptClaimLocalNotification(__instance, out var catcherName))
			{
				GiantCatchModule.Instance.DisplayCatchCard(__instance, catcherName);
			}
		}
	}
	[HarmonyPatch(typeof(AttackingFish), "DamageOnCollision")]
	internal static class AggressiveFishStrengthPatch
	{
		private static readonly FieldInfo DamageField = AccessTools.Field(typeof(AttackingFish), "_onHitDamage");

		private static void Prefix(AttackingFish __instance, out int __state)
		{
			__state = (int)DamageField.GetValue(__instance);
			DamageField.SetValue(__instance, FishSizeService.SpongeScaledInt(__state, (Creature)(object)__instance));
		}

		private static Exception Finalizer(AttackingFish __instance, int __state, Exception __exception)
		{
			DamageField.SetValue(__instance, __state);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(Pufferfish), "OnCollisionEnter")]
	internal static class PufferStrengthPatch
	{
		private static readonly FieldInfo DamageField = AccessTools.Field(typeof(Pufferfish), "_onHitDamage");

		private static void Prefix(Pufferfish __instance, out int __state)
		{
			__state = (int)DamageField.GetValue(__instance);
			DamageField.SetValue(__instance, FishSizeService.SpongeScaledInt(__state, (Creature)(object)__instance));
		}

		private static Exception Finalizer(Pufferfish __instance, int __state, Exception __exception)
		{
			DamageField.SetValue(__instance, __state);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(BowheadWhale), "DamageOnCollision")]
	internal static class BowheadStrengthPatch
	{
		private static readonly FieldInfo DamageField = AccessTools.Field(typeof(AttackingFish), "_onHitDamage");

		private static void Prefix(BowheadWhale __instance, out int __state)
		{
			__state = (int)DamageField.GetValue(__instance);
			DamageField.SetValue(__instance, FishSizeService.SpongeScaledInt(__state, (Creature)(object)__instance));
		}

		private static Exception Finalizer(BowheadWhale __instance, int __state, Exception __exception)
		{
			DamageField.SetValue(__instance, __state);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(Item), "get_TotalWorth")]
	internal static class RodSaleValuePatch
	{
		private static void Postfix(ref int __result)
		{
			__result = RodSaleBonusService.Apply(__result);
		}
	}
	[HarmonyPatch(typeof(MoneyManager), "SellItem")]
	internal static class RodSaleScopePatch
	{
		private static void Prefix()
		{
			RodSaleBonusService.Begin(Player.LocalPlayer);
		}

		private static Exception Finalizer(Exception __exception)
		{
			RodSaleBonusService.End();
			return __exception;
		}
	}
	internal sealed class LeaderboardRow
	{
		public string World;

		public string SteamId;

		public string DisplayName;

		public float Size;
	}
	internal struct LeaderboardMessage : IBroadcast
	{
		public string Payload;
	}
	internal struct CatchRecordMessage : IBroadcast
	{
		public int FishNetworkId;

		public float Size;

		public ulong AnglerSteamId;

		public string AnglerName;
	}
	internal static class LeaderboardService
	{
		private const int RecordsPerWorld = 50;

		private const int DisplayedRows = 3;

		private const float BroadcastInterval = 4f;

		private static readonly List<LeaderboardRow> AllEntries = new List<LeaderboardRow>();

		private static readonly List<LeaderboardRow> CurrentEntries = new List<LeaderboardRow>();

		private static ConfigEntry<string> _savedData;

		private static NetworkManager _registeredNetworkManager;

		private static string _currentWorld = string.Empty;

		private static bool _serializersReady;

		private static bool _initialized;

		private static bool _wasServerStarted;

		private static float _nextBroadcastTime;

		public static void Initialize(ConfigFile config)
		{
			if (!_initialized)
			{
				_savedData = config.Bind<string>("Giant Catches", "RankingRecords", string.Empty, "Persistent biggest-catch records. Managed by the mod.");
				SpongeLoadSavedData();
				AssignupSerializers();
				_initialized = true;
			}
		}

		public static void Tick()
		{
			RequireNetworkRegistration();
			bool isServerStarted = InstanceFinder.IsServerStarted;
			if (isServerStarted)
			{
				SpongeSelectCurrentWorld();
				if (!_wasServerStarted || Time.unscaledTime >= _nextBroadcastTime)
				{
					SpongeBroadcastCurrent();
					_nextBroadcastTime = Time.unscaledTime + 4f;
				}
			}
			_wasServerStarted = isServerStarted;
			LeaderboardHud.RequireVisible(CurrentEntries);
		}

		public static void Shutdown()
		{
			if ((Object)(object)_registeredNetworkManager != (Object)null)
			{
				try
				{
					_registeredNetworkManager.ClientManager.UnregisterBroadcast<LeaderboardMessage>((Action<LeaderboardMessage, Channel>)SpongeOnRankingBroadcast);
					_registeredNetworkManager.ClientManager.UnregisterBroadcast<CatchRecordMessage>((Action<CatchRecordMessage, Channel>)SpongeOnRankedCatchBroadcast);
				}
				catch
				{
				}
			}
			_registeredNetworkManager = null;
			_wasServerStarted = false;
			LeaderboardHud.Teardown();
		}

		public static void SpongeRecordCatch(Creature creature)
		{
			try
			{
				SpongeRecordCatchInternal(creature);
			}
			catch (Exception error)
			{
				GiantCatchModule.Instance?.SpongeLogRankingError("record", error);
			}
		}

		private static void SpongeRecordCatchInternal(Creature creature)
		{
			if (!_initialized || !InstanceFinder.IsServerStarted || (Object)(object)creature == (Object)null)
			{
				return;
			}
			FishScaleTracker component = ((Component)creature).GetComponent<FishScaleTracker>();
			if ((Object)(object)component == (Object)null || !component.WasHooked || component.RankingSubmitted)
			{
				return;
			}
			component.RankingSubmitted = true;
			Player val = component.Catcher;
			if ((Object)(object)val == (Object)null && (Object)(object)component.CatcherRod != (Object)null)
			{
				val = (((Object)(object)((Item)component.CatcherRod).SyncedHolder != (Object)null) ? ((Item)component.CatcherRod).SyncedHolder : ((Item)component.CatcherRod).Holder);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			SpongeSelectCurrentWorld();
			float size = FishSizeService.ObtainDisplaySize(creature);
			string text = ((val.SteamID != 0L) ? val.SteamID.ToString(CultureInfo.InvariantCulture) : ("connection-" + ((NetworkBehaviour)val).OwnerId.ToString(CultureInfo.InvariantCulture)));
			string displayName = (string.IsNullOrWhiteSpace(val.SteamName) ? "Angler" : val.SteamName.Trim());
			LeaderboardRow leaderboardRow = new LeaderboardRow();
			leaderboardRow.World = _currentWorld;
			leaderboardRow.SteamId = text + "-" + DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture) + "-" + ((NetworkBehaviour)creature).ObjectId.ToString(CultureInfo.InvariantCulture);
			leaderboardRow.DisplayName = displayName;
			leaderboardRow.Size = size;
			LeaderboardRow leaderboardRow2 = leaderboardRow;
			AllEntries.Add(leaderboardRow2);
			component.RankingEntryId = leaderboardRow2.SteamId;
			foreach (LeaderboardRow item in (from candidate in AllEntries
				where candidate != null && candidate.World == _currentWorld
				orderby candidate.Size descending
				select candidate).Skip(50).ToList())
			{
				AllEntries.Remove(item);
			}
			RedrawCurrentEntries();
			SpongeSaveData();
			SpongeBroadcastCurrent();
		}

		public static void BroadcastRankedDeath(Creature creature)
		{
			try
			{
				if (!_initialized || !InstanceFinder.IsServerStarted || (Object)(object)creature == (Object)null)
				{
					return;
				}
				FishScaleTracker state = ((Component)creature).GetComponent<FishScaleTracker>();
				if ((Object)(object)state == (Object)null || state.RankingAnnouncementSent || string.IsNullOrEmpty(state.RankingEntryId))
				{
					return;
				}
				SpongeSelectCurrentWorld();
				LeaderboardRow leaderboardRow = CurrentEntries.FirstOrDefault((LeaderboardRow candidate) => candidate.SteamId == state.RankingEntryId);
				if (leaderboardRow != null)
				{
					Player val = state.Catcher;
					if ((Object)(object)val == (Object)null && (Object)(object)state.CatcherRod != (Object)null)
					{
						val = (((Object)(object)((Item)state.CatcherRod).SyncedHolder != (Object)null) ? ((Item)state.CatcherRod).SyncedHolder : ((Item)state.CatcherRod).Holder);
					}
					state.RankingAnnouncementSent = true;
					CatchRecordMessage catchRecordMessage = new CatchRecordMessage
					{
						FishNetworkId = ((NetworkBehaviour)creature).ObjectId,
						Size = leaderboardRow.Size,
						AnglerSteamId = (((Object)(object)val != (Object)null) ? val.SteamID : 0),
						AnglerName = leaderboardRow.DisplayName
					};
					if (InstanceFinder.IsClientStarted)
					{
						LeaderboardAnnouncement.SpongeReceive(catchRecordMessage);
					}
					InstanceFinder.ServerManager.Broadcast<CatchRecordMessage>(catchRecordMessage, true, (Channel)0);
				}
			}
			catch (Exception error)
			{
				GiantCatchModule.Instance?.SpongeLogRankingError("global announcement", error);
			}
		}

		public static void SpongeBroadcastCurrent()
		{
			try
			{
				if (_initialized && InstanceFinder.IsServerStarted && !((Object)(object)InstanceFinder.ServerManager == (Object)null))
				{
					SpongeSelectCurrentWorld();
					InstanceFinder.ServerManager.Broadcast<LeaderboardMessage>(new LeaderboardMessage
					{
						Payload = ComposeNetworkPayload(CurrentEntries)
					}, true, (Channel)0);
				}
			}
			catch (Exception error)
			{
				GiantCatchModule.Instance?.SpongeLogRankingError("broadcast", error);
			}
		}

		private static void AssignupSerializers()
		{
			if (!_serializersReady)
			{
				GenericWriter<LeaderboardMessage>.SetWrite((Action<Writer, LeaderboardMessage>)delegate(Writer writer, LeaderboardMessage value)
				{
					writer.WriteString(value.Payload);
				});
				GenericReader<LeaderboardMessage>.SetRead((Func<Reader, LeaderboardMessage>)((Reader reader) => new LeaderboardMessage
				{
					Payload = reader.ReadStringAllocated()
				}));
				GenericWriter<CatchRecordMessage>.SetWrite((Action<Writer, CatchRecordMessage>)delegate(Writer writer, CatchRecordMessage value)
				{
					writer.WriteInt32(value.FishNetworkId);
					writer.WriteSingle(value.Size);
					writer.WriteUInt64(value.AnglerSteamId);
					writer.WriteString(value.AnglerName);
				});
				GenericReader<CatchRecordMessage>.SetRead((Func<Reader, CatchRecordMessage>)((Reader reader) => new CatchRecordMessage
				{
					FishNetworkId = reader.ReadInt32(),
					Size = reader.ReadSingle(),
					AnglerSteamId = reader.ReadUInt64(),
					AnglerName = reader.ReadStringAllocated()
				}));
				_serializersReady = true;
			}
		}

		private static void RequireNetworkRegistration()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if ((Object)(object)networkManager == (Object)(object)_registeredNetworkManager)
			{
				return;
			}
			if ((Object)(object)_registeredNetworkManager != (Object)null)
			{
				try
				{
					_registeredNetworkManager.ClientManager.UnregisterBroadcast<LeaderboardMessage>((Action<LeaderboardMessage, Channel>)SpongeOnRankingBroadcast);
					_registeredNetworkManager.ClientManager.UnregisterBroadcast<CatchRecordMessage>((Action<CatchRecordMessage, Channel>)SpongeOnRankedCatchBroadcast);
				}
				catch
				{
				}
			}
			_registeredNetworkManager = networkManager;
			if (!((Object)(object)networkManager == (Object)null))
			{
				networkManager.ClientManager.RegisterBroadcast<LeaderboardMessage>((Action<LeaderboardMessage, Channel>)SpongeOnRankingBroadcast);
				networkManager.ClientManager.RegisterBroadcast<CatchRecordMessage>((Action<CatchRecordMessage, Channel>)SpongeOnRankedCatchBroadcast);
			}
		}

		private static void SpongeOnRankingBroadcast(LeaderboardMessage message, Channel channel)
		{
			try
			{
				if (!InstanceFinder.IsServerStarted)
				{
					CurrentEntries.Clear();
					SpongeParseNetworkPayload(message.Payload, CurrentEntries);
				}
			}
			catch (Exception error)
			{
				GiantCatchModule.Instance?.SpongeLogRankingError("receive", error);
			}
		}

		private static void SpongeOnRankedCatchBroadcast(CatchRecordMessage message, Channel channel)
		{
			LeaderboardAnnouncement.SpongeReceive(message);
		}

		private static void SpongeSelectCurrentWorld()
		{
			string text = ((SaveManager.CurServerSave != null && !string.IsNullOrWhiteSpace(SaveManager.CurServerSave.Name)) ? SaveManager.CurServerSave.Name.Trim() : "Current game");
			if (!(text == _currentWorld))
			{
				_currentWorld = text;
				RedrawCurrentEntries();
			}
		}

		private static void RedrawCurrentEntries()
		{
			CurrentEntries.Clear();
			CurrentEntries.AddRange((from entry in AllEntries
				where entry != null && entry.World == _currentWorld
				orderby entry.Size descending
				select entry).ThenBy<LeaderboardRow, string>((LeaderboardRow entry) => entry.DisplayName, StringComparer.OrdinalIgnoreCase).Take(3));
		}

		private static void SpongeLoadSavedData()
		{
			AllEntries.Clear();
			if (_savedData == null || string.IsNullOrWhiteSpace(_savedData.Value))
			{
				return;
			}
			string[] array = _savedData.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(',');
				if (array2.Length == 4 && float.TryParse(array2[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					try
					{
						AllEntries.Add(new LeaderboardRow
						{
							World = Decode(array2[0]),
							SteamId = Decode(array2[1]),
							DisplayName = Decode(array2[2]),
							Size = result
						});
					}
					catch (FormatException)
					{
					}
				}
			}
		}

		private static void SpongeSaveData()
		{
			if (_savedData != null)
			{
				_savedData.Value = string.Join(";", from entry in AllEntries
					where entry != null
					select Encode(entry.World) + "," + Encode(entry.SteamId) + "," + Encode(entry.DisplayName) + "," + entry.Size.ToString("0.00", CultureInfo.InvariantCulture));
			}
		}

		private static string ComposeNetworkPayload(IEnumerable<LeaderboardRow> entries)
		{
			return string.Join(";", from entry in entries
				where entry != null
				select Encode(entry.DisplayName) + "," + entry.Size.ToString("0.00", CultureInfo.InvariantCulture));
		}

		private static void SpongeParseNetworkPayload(string payload, List<LeaderboardRow> destination)
		{
			if (string.IsNullOrWhiteSpace(payload))
			{
				return;
			}
			string[] array = payload.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(',');
				if (array2.Length == 2 && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					try
					{
						destination.Add(new LeaderboardRow
						{
							DisplayName = Decode(array2[0]),
							Size = result
						});
					}
					catch (FormatException)
					{
					}
				}
			}
		}

		private static string Encode(string value)
		{
			return Convert.ToBase64String(Encoding.UTF8.GetBytes(value ?? string.Empty));
		}

		private static string Decode(string value)
		{
			return Encoding.UTF8.GetString(Convert.FromBase64String(value));
		}
	}
	internal static class LeaderboardAnnouncement
	{
		private static readonly Dictionary<int, float> AnnouncedObjects = new Dictionary<int, float>();

		public static void SpongeReceive(CatchRecordMessage message)
		{
			if (GiantCatchModule.Instance != null && !SpongeWasAnnounced(message.FishNetworkId))
			{
				AnnouncedObjects[message.FishNetworkId] = Time.unscaledTime + 12f;
				CompendiumPlugin.Run(DisplayWhenAvailable(message));
			}
		}

		public static bool SpongeWasAnnounced(int objectId)
		{
			if (!AnnouncedObjects.TryGetValue(objectId, out var value))
			{
				return false;
			}
			if (Time.unscaledTime <= value)
			{
				return true;
			}
			AnnouncedObjects.Remove(objectId);
			return false;
		}

		private static IEnumerator DisplayWhenAvailable(CatchRecordMessage message)
		{
			float deadline = Time.unscaledTime + 2f;
			Creature found = null;
			while ((Object)(object)found == (Object)null && Time.unscaledTime < deadline)
			{
				Creature[] array = Object.FindObjectsByType<Creature>();
				foreach (Creature val in array)
				{
					if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).ObjectId == message.FishNetworkId)
					{
						found = val;
						break;
					}
				}
				if ((Object)(object)found == (Object)null)
				{
					yield return null;
				}
			}
			if (!((Object)(object)found == (Object)null) && GiantCatchModule.Instance != null)
			{
				Player localPlayer = Player.LocalPlayer;
				bool isLocalCatcher = (Object)(object)localPlayer != (Object)null && message.AnglerSteamId != 0L && localPlayer.SteamID == message.AnglerSteamId;
				GiantCatchModule.Instance.DisplayGlobalRankedCatch(found, string.IsNullOrWhiteSpace(message.AnglerName) ? "Angler" : message.AnglerName, message.Size, isLocalCatcher);
			}
		}
	}
	internal sealed class RodTierBench : MonoBehaviour
	{
		private static readonly Color Wood = new Color(0.34f, 0.19f, 0.1f);

		private static readonly Color DarkWood = new Color(0.19f, 0.09f, 0.045f);

		private static Material _sceneMaterial;

		private float _nextNativeRodRetry;

		public static RodTierBench Create(Vector3 position, float yaw)
		{
			//IL_0005: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0024: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SpongeMods_RodUpgradeTable");
			val.SetActive(false);
			RodTierBench result = val.AddComponent<RodTierBench>();
			val.transform.position = position;
			val.transform.rotation = Quaternion.Euler(0f, yaw, 0f);
			ComposeFurniture(val.transform);
			val.SetActive(true);
			return result;
		}

		private static GameObject ComposeFurniture(Transform root)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0053: 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_006c: Unknown result type (might be due