Decompiled source of Speedchoice v1.1.0

plugins/Speedchoice.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Speedchoice")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6b4d3aa769faa5cf7af6ab27c7f126dcd9a1f8a3")]
[assembly: AssemblyProduct("Speedchoice")]
[assembly: AssemblyTitle("Speedchoice")]
[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 Speedchoice
{
	[BepInPlugin("com.lukkster.Speedchoice", "Speedchoice", "1.1.0")]
	public class Speedchoice : BaseUnityPlugin
	{
		private struct Settings
		{
			public float boatSpeed;

			public float timeToRest;

			public float trophyOdds;

			public bool bossReveals;

			public bool bossSkills;

			public bool cheatDeath;

			public bool dropMaterials;

			public bool fastCrops;

			public bool fastFermenters;

			public bool harmlessPieces;

			public bool increasedExp;

			public bool instantUpgrades;

			public bool lootlessBosses;

			public bool noBuildStations;

			public bool noCraftCost;

			public bool noCraftLevels;

			public bool showDeaths;

			public bool showLogouts;

			public bool showTimer;

			public bool structureLoot;

			public bool wherePortal;

			public bool alwaysRocky;

			public float runSpeed;

			public float jumpForce;

			public float sailForce;

			public float restOverride;

			public float trophyOverride;

			public bool unlockPieces;

			public bool unlockRecipes;

			public int time;

			public bool isTimerRunning;

			public Settings()
			{
				boatSpeed = 0f;
				timeToRest = 0f;
				trophyOdds = 0f;
				bossReveals = false;
				bossSkills = false;
				cheatDeath = false;
				dropMaterials = false;
				fastCrops = false;
				fastFermenters = false;
				harmlessPieces = false;
				increasedExp = false;
				instantUpgrades = false;
				lootlessBosses = false;
				noBuildStations = false;
				noCraftCost = false;
				noCraftLevels = false;
				showDeaths = false;
				showLogouts = false;
				showTimer = false;
				structureLoot = false;
				wherePortal = false;
				alwaysRocky = false;
				runSpeed = 1f;
				jumpForce = 1f;
				sailForce = 1f;
				restOverride = -1f;
				trophyOverride = -1f;
				unlockPieces = false;
				unlockRecipes = false;
				time = 0;
				isTimerRunning = false;
			}
		}

		private struct Profile
		{
			public List<string> keys;

			public string toolTip;

			public Dictionary<string, float> ranges;

			public Dictionary<string, bool> checkBoxes;

			public Profile(List<string> keys, string toolTip, Dictionary<string, float> ranges, Dictionary<string, bool> checkBoxes)
			{
				this.keys = keys;
				this.toolTip = toolTip;
				this.ranges = ranges;
				this.checkBoxes = checkBoxes;
			}
		}

		private struct RangeOption
		{
			public string name;

			public string toolTip;

			public RangeOption(string name, string toolTip)
			{
				this.name = name;
				this.toolTip = toolTip;
			}
		}

		private struct Range
		{
			public Func<float> Get;

			public Action<float> Set;

			public string toolTip;

			public List<RangeOption> rangeOptions;

			public Range(Func<float> getter, Action<float> setter, string toolTip, List<RangeOption> rangeOptions)
			{
				Get = getter;
				Set = setter;
				this.toolTip = toolTip;
				this.rangeOptions = rangeOptions;
			}
		}

		private struct CheckBox
		{
			public Func<bool> Get;

			public Action<bool> Set;

			public string toolTip;

			public CheckBox(Func<bool> getter, Action<bool> setter, string toolTip)
			{
				Get = getter;
				Set = setter;
				this.toolTip = toolTip;
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "OnServerOptions")]
		private class FejdStartup_OnServerOptions
		{
			private static float profileSep;

			private static float rangeSep;

			private static float checkBoxSep;

			private static GameObject serverOptions;

			private static void Postfix(FejdStartup __instance)
			{
				if ((Object)(object)GameObject.Find(checkBoxes.Keys.First()) == (Object)null)
				{
					serverOptions = GameObject.Find("StartGui_ServerOptions");
					profileSep = GetSeperation("Presets/Easy", "Presets/Casual");
					rangeSep = GetSeperation("Modifiers/Combat", "Modifiers/Death");
					checkBoxSep = GetSeperation("Modifiers/NoBuildCost", "Modifiers/Passivemobs");
					int num = 1;
					int num2 = 0;
					foreach (KeyValuePair<string, Profile> profile in profiles)
					{
						num2++;
						if (num2 > 3)
						{
							num2 = 1;
							num++;
						}
						AddProfile(num, num2, profile);
					}
					float num3 = (float)num * profileSep;
					string[] array = new string[2] { "Presets/Default", "Modifiers" };
					for (int i = 0; i < array.Length; i++)
					{
						MoveDown(array[i], num3);
					}
					num = 0;
					foreach (KeyValuePair<string, Range> range in ranges)
					{
						num++;
						AddRange(num, range);
					}
					array = new string[5] { "Modifiers/NoBuildCost", "Modifiers/PlayerBasedEvents", "Modifiers/Fire", "Modifiers/Passivemobs", "Modifiers/Nomap" };
					for (int i = 0; i < array.Length; i++)
					{
						MoveDown(array[i], (float)num * rangeSep);
					}
					num3 += (float)num * rangeSep;
					num = 2;
					num2 = 0;
					foreach (KeyValuePair<string, CheckBox> checkBox in checkBoxes)
					{
						num2++;
						if (num2 > 3)
						{
							num2 = 1;
							num++;
						}
						AddCheckBox(num, num2, checkBox);
					}
					ExpandPanel(num3 + (float)(num - 1) * checkBoxSep);
				}
				Load(__instance.m_world);
				foreach (KeyValuePair<string, Range> range2 in ranges)
				{
					GameObject.Find(range2.Key).GetComponentInChildren<Slider>().value = range2.Value.Get();
				}
				foreach (KeyValuePair<string, CheckBox> checkBox2 in checkBoxes)
				{
					GameObject.Find(checkBox2.Key).GetComponentInChildren<Toggle>().isOn = checkBox2.Value.Get();
				}
			}

			private static float GetSeperation(string a, string b)
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				Transform val = serverOptions.transform.Find("panel/" + a);
				Transform obj = serverOptions.transform.Find("panel/" + b);
				float y = ((Component)val).GetComponent<RectTransform>().anchoredPosition.y;
				float y2 = ((Component)obj).GetComponent<RectTransform>().anchoredPosition.y;
				return Math.Abs(y - y2);
			}

			private static void AddProfile(int row, int col, KeyValuePair<string, Profile> entry)
			{
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				Transform val = serverOptions.transform.Find("panel/Presets");
				GameObject obj = Object.Instantiate<GameObject>(((Component)(col switch
				{
					1 => ((Component)val).transform.Find("Casual"), 
					2 => ((Component)val).transform.Find("Hammer"), 
					_ => ((Component)val).transform.Find("Immersive"), 
				})).gameObject, val);
				Transform obj2 = obj.transform.Find("Text");
				((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null).text = entry.Key;
				((Object)obj).name = entry.Key;
				KeyButton obj3 = ((obj != null) ? obj.GetComponent<KeyButton>() : null);
				obj3.m_keys = entry.Value.keys;
				obj3.m_preset = (WorldPresets)0;
				obj3.m_toolTip = entry.Value.toolTip;
				MoveDown("Presets/" + entry.Key, profileSep * (float)row);
			}

			private static void AddRange(int row, KeyValuePair<string, Range> entry)
			{
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Expected O, but got Unknown
				Transform val = serverOptions.transform.Find("panel/Modifiers");
				GameObject obj = Object.Instantiate<GameObject>(((Component)((Component)val).transform.Find("Portals")).gameObject, val);
				Transform obj2 = obj.transform.Find("label");
				((TMP_Text)((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null)).text = entry.Key;
				((Object)obj).name = entry.Key;
				MoveDown("Modifiers/" + entry.Key, rangeSep * (float)row);
				Transform obj3 = obj.transform.Find("slider");
				Slider obj4 = ((obj3 != null) ? ((Component)obj3).GetComponent<Slider>() : null);
				obj4.maxValue = entry.Value.rangeOptions.Count() - 1;
				obj4.value = 0f;
				KeySlider val2 = ((obj3 != null) ? ((Component)obj3).GetComponent<KeySlider>() : null);
				val2.m_toolTip = entry.Value.toolTip;
				val2.m_settings = new List<SliderSetting>();
				foreach (RangeOption rangeOption in entry.Value.rangeOptions)
				{
					val2.m_settings.Add(new SliderSetting
					{
						m_name = rangeOption.name,
						m_toolTip = rangeOption.toolTip
					});
				}
			}

			private static void AddCheckBox(int row, int col, KeyValuePair<string, CheckBox> entry)
			{
				Transform val = serverOptions.transform.Find("panel/Modifiers");
				GameObject obj = Object.Instantiate<GameObject>(((Component)(col switch
				{
					1 => ((Component)val).transform.Find("NoBuildCost"), 
					2 => ((Component)val).transform.Find("PlayerBasedEvents"), 
					_ => ((Component)val).transform.Find("Fire"), 
				})).gameObject, val);
				Transform obj2 = obj.transform.Find("Label");
				((TMP_Text)((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null)).text = entry.Key;
				((Object)obj).name = entry.Key;
				MoveDown("Modifiers/" + entry.Key, checkBoxSep * (float)row);
				obj.GetComponent<KeyToggle>().m_toolTip = entry.Value.toolTip;
			}

			private static void MoveDown(string objectId, float distance)
			{
				//IL_0016: 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_0026: Unknown result type (might be due to invalid IL or missing references)
				RectTransform component = GameObject.Find("GuiRoot/GUI/StartGui/StartGame/StartGui_ServerOptions/panel/" + objectId).GetComponent<RectTransform>();
				component.anchoredPosition -= new Vector2(0f, distance);
			}

			private static void ExpandPanel(float distance, int max = -10, int min = -1070)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: 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_009d: 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_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				RectTransform component = ((Component)serverOptions.transform.Find("panel")).GetComponent<RectTransform>();
				component.offsetMax += new Vector2(0f, distance / 2f);
				float num = 0f;
				if (component.offsetMax.y > (float)max)
				{
					num = component.offsetMax.y - (float)max;
					component.offsetMax = new Vector2(component.offsetMax.x, (float)max);
				}
				component.offsetMin -= new Vector2(0f, distance / 2f + num);
				if (component.offsetMin.y < (float)min)
				{
					num = (float)min - component.offsetMin.y;
					component.offsetMin = new Vector2(component.offsetMin.x, (float)min);
				}
				MoveDown("Modifiers", -1f * distance - num / 2f);
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "OnServerOptionsDone")]
		private class FejdStartup_OnServerOptionsDone
		{
			private static void Prefix(FejdStartup __instance)
			{
				bool isUpdated = false;
				foreach (KeyValuePair<string, Range> range in ranges)
				{
					Assign(range, ref isUpdated);
				}
				foreach (KeyValuePair<string, CheckBox> checkBox in checkBoxes)
				{
					Assign(checkBox, ref isUpdated);
				}
				if (isUpdated)
				{
					Save(__instance.m_world);
				}
			}

			private static void Assign(KeyValuePair<string, Range> entry, ref bool isUpdated)
			{
				float value = GameObject.Find(entry.Key).GetComponentInChildren<Slider>().value;
				isUpdated = isUpdated || value != entry.Value.Get();
				entry.Value.Set(value);
			}

			private static void Assign(KeyValuePair<string, CheckBox> entry, ref bool isUpdated)
			{
				bool isOn = GameObject.Find(entry.Key).GetComponentInChildren<Toggle>().isOn;
				isUpdated = isUpdated || isOn != entry.Value.Get();
				entry.Value.Set(isOn);
			}
		}

		[HarmonyPatch(typeof(ServerOptionsGUI), "OnPresetButton")]
		private class ServerOptionsGUI_OnPresetButton
		{
			private static void Postfix(KeyButton button)
			{
				foreach (KeyValuePair<string, Range> range in ranges)
				{
					GameObject.Find(range.Key).GetComponentInChildren<Slider>().value = 0f;
				}
				foreach (KeyValuePair<string, CheckBox> checkBox in checkBoxes)
				{
					GameObject.Find(checkBox.Key).GetComponentInChildren<Toggle>().isOn = false;
				}
				if (!profiles.TryGetValue(button.GetName(), out var value))
				{
					return;
				}
				foreach (KeyValuePair<string, float> range2 in value.ranges)
				{
					GameObject.Find(range2.Key).GetComponentInChildren<Slider>().value = range2.Value;
				}
				foreach (KeyValuePair<string, bool> checkBox2 in value.checkBoxes)
				{
					GameObject.Find(checkBox2.Key).GetComponentInChildren<Toggle>().isOn = checkBox2.Value;
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "UpdateWorldList")]
		private class FejdStartup_UpdateWorldList
		{
			private static void UpdateToolTip(UITooltip toolTip, string add)
			{
				toolTip.m_topic = "$menu_serveroptions";
				if (toolTip.m_text != "")
				{
					toolTip.m_text += "\n";
				}
				toolTip.m_text += add;
			}

			private static void Postfix(FejdStartup __instance)
			{
				for (int i = 0; i < __instance.m_worlds.Count; i++)
				{
					Load(__instance.m_worlds[i]);
					List<string> list = profiles.Keys.ToList();
					HashSet<string> hashSet = new HashSet<string>();
					foreach (string startingGlobalKey in __instance.m_worlds[i].m_startingGlobalKeys)
					{
						hashSet.Add(startingGlobalKey);
					}
					HashSet<string> hashSet2 = hashSet;
					hashSet2.Remove("noworkbench");
					hashSet2.RemoveWhere((string x) => x.StartsWith("preset "));
					for (int num = list.Count - 1; num >= 0; num--)
					{
						if (!profiles[list[num]].keys.ToHashSet().SetEquals(hashSet2))
						{
							list.RemoveAt(num);
						}
					}
					bool flag = false;
					UITooltip component = __instance.m_worldListElements[i].GetComponent<UITooltip>();
					foreach (KeyValuePair<string, Range> range in ranges)
					{
						float num2 = range.Value.Get();
						for (int num3 = list.Count - 1; num3 >= 0; num3--)
						{
							if (profiles[list[num3]].ranges[range.Key] != num2)
							{
								list.RemoveAt(num3);
							}
						}
						if (num2 != 0f)
						{
							flag = true;
							UpdateToolTip(component, range.Key + ": " + range.Value.rangeOptions[(int)num2].name);
						}
					}
					foreach (KeyValuePair<string, CheckBox> checkBox in checkBoxes)
					{
						for (int num4 = list.Count - 1; num4 >= 0; num4--)
						{
							if (profiles[list[num4]].checkBoxes[checkBox.Key] != checkBox.Value.Get())
							{
								list.RemoveAt(num4);
							}
						}
						if (checkBox.Value.Get())
						{
							flag = true;
							UpdateToolTip(component, checkBox.Key);
						}
					}
					TextMeshProUGUI component2 = ((Component)__instance.m_worldListElements[i].transform.Find("modifiers")).GetComponent<TextMeshProUGUI>();
					if (list.Count > 0)
					{
						((TMP_Text)component2).text = list[0];
					}
					else if (flag)
					{
						((TMP_Text)component2).text = Localization.instance.Localize("$menu_modifier_custom");
					}
				}
			}
		}

		[HarmonyPatch(typeof(World), "RemoveWorld")]
		private class World_RemoveWorld
		{
			private static void Postfix(string name)
			{
				File.Delete(GetSavePath(name));
			}
		}

		private struct Prefab
		{
			public string name;

			public string aoe;

			public DamageTypes damage;

			public Prefab(string name, string aoe, DamageTypes damage)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.aoe = aoe;
				this.damage = damage;
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		private class ZoneSystem_Start
		{
			private static void Postfix(ZoneSystem __instance)
			{
				if (ZNet.instance.IsServer())
				{
					Load(ZNet.m_world);
					HarmlessPieces();
					if (settings.noBuildStations)
					{
						__instance.SetGlobalKey((GlobalKeys)27);
					}
					else
					{
						__instance.RemoveGlobalKey((GlobalKeys)27);
					}
					if (settings.unlockPieces)
					{
						__instance.SetGlobalKey((GlobalKeys)26);
					}
					else
					{
						__instance.RemoveGlobalKey((GlobalKeys)26);
					}
				}
				ZRoutedRpc.instance.Register<string>("FromServer", (Action<long, string>)FromServer);
				ZRoutedRpc.instance.Register<string>("StartTimer", (Action<long, string>)StartTimer);
				ZRoutedRpc.instance.Register<string>("GetTimer", (Action<long, string>)GetTimer);
				ZRoutedRpc.instance.Register<int>("SetTimer", (Action<long, int>)SetTimer);
				ZRoutedRpc.instance.Register<string>("RequestPois", (Action<long, string>)RequestPois);
				ZRoutedRpc.instance.Register<string>("RevealPois", (Action<long, string>)RevealPois);
				ZRoutedRpc.instance.Register<int>("LevelUp", (Action<long, int>)LevelUp);
				ZRoutedRpc.instance.Register<string>("PlacePortal", (Action<long, string>)PlacePortal);
			}

			private static void HarmlessPieces()
			{
				//IL_0079: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				foreach (Prefab harmingPrefab in harmingPrefabs)
				{
					if (settings.harmlessPieces)
					{
						((Component)ZNetScene.instance.GetPrefab(harmingPrefab.name).transform.Find(harmingPrefab.aoe)).GetComponent<Aoe>().m_damage = default(DamageTypes);
					}
					else
					{
						((Component)ZNetScene.instance.GetPrefab(harmingPrefab.name).transform.Find(harmingPrefab.aoe)).GetComponent<Aoe>().m_damage = harmingPrefab.damage;
					}
				}
			}

			private static void FromServer(long sender, string json)
			{
				ToSettings(json);
				HarmlessPieces();
				if (settings.isTimerRunning)
				{
					((MonoBehaviour)speedchoice).StartCoroutine(TimerUpdate());
				}
			}

			private static void StartTimer(long sender, string json)
			{
				if (!settings.isTimerRunning)
				{
					settings.isTimerRunning = true;
					((MonoBehaviour)speedchoice).StartCoroutine(TimerUpdate());
				}
			}

			private static void GetTimer(long sender, string json)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SetTimer", new object[1] { settings.time });
			}

			private static void SetTimer(long sender, int time)
			{
				settings.time = time;
			}

			private static void RequestPois(long sender, string json)
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: 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_006d: 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_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				List<Poi> list = JsonConvert.DeserializeObject<List<Poi>>(json);
				List<Poi> list2 = new List<Poi>();
				foreach (Poi item in list)
				{
					foreach (KeyValuePair<Vector2s, LocationInstance> locationInstance in ZoneSystem.instance.m_locationInstances)
					{
						if (locationInstance.Value.m_location.m_prefabName == item.prefabName)
						{
							list2.Add(new Poi(item, locationInstance.Value.m_position.x, locationInstance.Value.m_position.y, locationInstance.Value.m_position.z));
						}
					}
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "RevealPois", new object[1] { JsonConvert.SerializeObject((object)list2) });
			}

			private static void RevealPois(long sender, string json)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: 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)
				Vector3 val = default(Vector3);
				foreach (Poi item in JsonConvert.DeserializeObject<List<Poi>>(json))
				{
					((Vector3)(ref val))..ctor(item.x, item.y, item.z);
					Minimap.instance.DiscoverLocation(val, item.pinType, item.name, false);
					Minimap.instance.Explore(val, item.radius);
				}
			}

			private static void LevelUp(long sender, int level)
			{
				if (!((Object)(object)Player.m_localPlayer != (Object)null))
				{
					return;
				}
				foreach (KeyValuePair<SkillType, Skill> skillDatum in ((Character)Player.m_localPlayer).GetSkills().m_skillData)
				{
					if (skillDatum.Value.m_level < (float)level)
					{
						skillDatum.Value.m_level = level;
					}
				}
			}

			private static void PlacePortal(long sender, string json)
			{
				//IL_002d: 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_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)
				PortalPin portalPin = JsonConvert.DeserializeObject<PortalPin>(json);
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(portalPin.x, portalPin.y, portalPin.z);
				if (portalPin.remove)
				{
					Minimap.instance.RemovePin(val, 0.1f);
				}
				if (portalPin.add)
				{
					Minimap.instance.AddPin(val, (PinType)6, portalPin.text, true, false, 0L, default(PlatformUserID));
				}
			}
		}

		[HarmonyPatch(typeof(ZRoutedRpc), "AddPeer")]
		private class ZRoutedRpc_AddPeer
		{
			private static void Postfix(ZRoutedRpc __instance, ZNetPeer peer)
			{
				if (__instance.m_server)
				{
					__instance.InvokeRoutedRPC(peer.m_uid, "FromServer", new object[1] { FromSettings() });
				}
			}
		}

		[HarmonyPatch(typeof(ZRoutedRpc), "RemovePeer")]
		private class ZRoutedRpc_RemovePeer
		{
			private static void Postfix(ZRoutedRpc __instance)
			{
				if (__instance.m_server && ZNet.instance.IsDedicated() && __instance.m_peers.Count < 1)
				{
					((MonoBehaviour)speedchoice).StopAllCoroutines();
					settings.isTimerRunning = false;
				}
			}
		}

		[HarmonyPatch(typeof(Ship), "GetSailForce")]
		public class Ship_GetSailForce
		{
			private static void Postfix(ref Vector3 __result)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: 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_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				if (boatSpeeds.TryGetValue(settings.boatSpeed, out var value))
				{
					__result *= value;
				}
				__result *= settings.sailForce;
			}
		}

		[HarmonyPatch(typeof(Ship), "Awake")]
		public class Ship_Awake
		{
			private static void Postfix(Ship __instance)
			{
				if (boatSpeeds.TryGetValue(settings.boatSpeed, out var value))
				{
					__instance.m_backwardForce *= value * 0.8f;
				}
				__instance.m_backwardForce *= settings.sailForce;
			}
		}

		[HarmonyPatch(typeof(SE_Cozy), "Setup", new Type[] { typeof(Character) })]
		public static class SE_Cozy_Setup
		{
			private static void Postfix(SE_Cozy __instance)
			{
				float value;
				if (settings.restOverride >= 0f)
				{
					__instance.m_delay = settings.restOverride;
				}
				else if (restDelays.TryGetValue(settings.timeToRest, out value))
				{
					__instance.m_delay = value;
				}
			}
		}

		[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
		private class CharacterDrop_GenerateDropList
		{
			private static void Postfix(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result)
			{
				float value;
				if (settings.lootlessBosses && levels.ContainsKey(((Component)__instance).GetComponent<Character>().m_name))
				{
					__result = new List<KeyValuePair<GameObject, int>>();
				}
				else if (settings.trophyOverride >= 0f)
				{
					AddTrophy(__instance, ref __result, settings.trophyOverride / 100f);
				}
				else if (trophyOdds.TryGetValue(settings.trophyOdds, out value))
				{
					AddTrophy(__instance, ref __result, value);
				}
			}

			private static void AddTrophy(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result, float odds)
			{
				Drop val = __instance.m_drops.Find((Drop drop) => drop.m_chance > 0f && ((Object)drop.m_prefab).name.StartsWith("Trophy"));
				if (val != null && !GotTrophy(val, __result) && Random.value <= odds)
				{
					__result.Add(new KeyValuePair<GameObject, int>(val.m_prefab, 1));
				}
			}

			private static bool GotTrophy(Drop trophy, List<KeyValuePair<GameObject, int>> __result)
			{
				foreach (KeyValuePair<GameObject, int> item in __result)
				{
					if (((Object)trophy.m_prefab).name == ((Object)item.Key).name)
					{
						return true;
					}
				}
				return false;
			}
		}

		private struct Poi
		{
			public string prefabName;

			public PinType pinType;

			public string name;

			public float radius;

			public float x;

			public float y;

			public float z;

			public Poi(string prefabName, PinType pinType, string name, float radius)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				this.prefabName = prefabName;
				this.pinType = pinType;
				this.name = name;
				this.radius = radius;
				x = 0f;
				y = 0f;
				z = 0f;
			}

			public Poi(Poi poi, float x, float y, float z)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				prefabName = poi.prefabName;
				pinType = poi.pinType;
				name = poi.name;
				radius = poi.radius;
				this.x = x;
				this.y = y;
				this.z = z;
			}
		}

		[HarmonyPatch(typeof(Character), "OnDeath")]
		private class Character_OnDeath
		{
			private static void Postfix(Character __instance)
			{
				if (settings.bossReveals && reveals.TryGetValue(__instance.m_name, out var value))
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "RequestPois", new object[1] { JsonConvert.SerializeObject((object)value) });
				}
				if (settings.bossSkills && levels.TryGetValue(__instance.m_name, out var value2))
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(0L, "LevelUp", new object[1] { value2 });
				}
			}
		}

		[HarmonyPatch(typeof(Skill), "Raise")]
		private class Skills_Skill_Raise
		{
			private static void Prefix(ref float factor)
			{
				if (settings.increasedExp)
				{
					factor *= 6f;
				}
			}

			private static void Postfix(Skill __instance, ref bool __result)
			{
				if (!settings.bossSkills)
				{
					return;
				}
				foreach (KeyValuePair<string, int> level in levels)
				{
					if (ZoneSystem.instance.GetGlobalKey("defeated_" + level.Key.Substring(7)))
					{
						if (__instance.m_level < (float)level.Value)
						{
							__instance.m_level = level.Value;
							__instance.m_accumulator = 0f;
							__result = true;
						}
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(PlayerProfile), "SaveLogoutPoint")]
		private class PlayerProfile_SaveLogoutPoint
		{
			private static bool Prefix(PlayerProfile __instance)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if (!settings.cheatDeath)
				{
					return true;
				}
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Character)Player.m_localPlayer).InIntro())
				{
					__instance.SetLogoutPoint(((Component)Player.m_localPlayer).transform.position);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		private class Inventory_AddItem
		{
			private static void Postfix(Inventory __instance, ItemData item)
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null && ((Humanoid)Player.m_localPlayer).GetInventory() == __instance)
				{
					RemoveItem(__instance, item);
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		private class Inventory_AddItem_4
		{
			private static void Postfix(Inventory __instance, ItemData item)
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null && ((Humanoid)Player.m_localPlayer).GetInventory() == __instance)
				{
					RemoveItem(__instance, item);
				}
			}
		}

		[HarmonyPatch(typeof(Plant), "TimeSincePlanted")]
		private class Plant_TimeSincePlanted
		{
			private static void Postfix(Plant __instance, ref double __result)
			{
				if (settings.fastCrops)
				{
					__result = (double)__instance.m_growTimeMax + 1.0;
				}
			}
		}

		[HarmonyPatch(typeof(Fermenter), "Awake")]
		private class Fermenter_Awake
		{
			private static void Postfix(Fermenter __instance)
			{
				if (settings.fastFermenters)
				{
					__instance.m_fermentationDuration = 10f;
				}
			}
		}

		[HarmonyPatch(typeof(Fermenter), "DelayedTap")]
		private class Fermenter_DelayedTap
		{
			private static void Prefix(Fermenter __instance)
			{
				if (settings.fastFermenters)
				{
					__instance.GetItemConversion(__instance.m_delayedTapItem).m_producedItems = 10;
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private class ObjectDB_Awake
		{
			private static void Postfix()
			{
				upgradeAbles.Clear();
				foreach (Recipe recipe in ObjectDB.instance.m_recipes)
				{
					if ((Object)(object)recipe.m_item != (Object)null && recipe.m_item.m_itemData.m_shared.m_maxQuality > 1)
					{
						upgradeAbles.Add(recipe.m_item.m_itemData.m_shared.m_name, recipe);
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "SetupCrafting")]
		private class InventoryGui_SetupCrafting
		{
			private static void Prefix()
			{
				UpgradeInventory(Player.m_localPlayer);
			}
		}

		[HarmonyPatch(typeof(Trader), "GetAvailableItems")]
		private class Trader_GetAvailableItems
		{
			private static bool Prefix(Trader __instance, ref List<TradeItem> __result)
			{
				if (!settings.lootlessBosses)
				{
					return true;
				}
				__result = new List<TradeItem>();
				foreach (TradeItem item in __instance.m_items)
				{
					if ((string.IsNullOrEmpty(item.m_requiredGlobalKey) || (!trader_boss_keys.Contains(item.m_requiredGlobalKey) && ZoneSystem.instance.GetGlobalKey(item.m_requiredGlobalKey))) && (string.IsNullOrEmpty(item.m_buyKey) || !((Humanoid)Player.m_localPlayer).HaveUniqueKey(item.m_buyKey)))
					{
						__result.Add(item);
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Hud), "SetupPieceInfo")]
		private class Hud_SetupPieceInfo
		{
			private static void Postfix(Hud __instance, Piece piece)
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				if (settings.noBuildStations)
				{
					GameObject obj = __instance.m_requirementItems[piece.m_resources.Length];
					Image component = ((Component)obj.transform.Find("res_icon")).GetComponent<Image>();
					TMP_Text component2 = ((Component)obj.transform.Find("res_amount")).GetComponent<TMP_Text>();
					((Graphic)component).color = Color.white;
					component2.text = "";
					((Graphic)component2).color = Color.white;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "HaveRequirementItems")]
		private class Player_HaveRequirementItems
		{
			private static void Postfix(bool discover, ref bool __result)
			{
				if (settings.noCraftCost && !discover)
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
		private class InventoryGui_SetupRequirement
		{
			private static void Postfix(Transform elementRoot)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				if (settings.noCraftCost)
				{
					((Graphic)((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TMP_Text>()).color = Color.white;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private class InventoryGui_DoCrafting
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				MethodInfo targetMethod = typeof(Player).GetMethod("NoCostCheat");
				MethodInfo replacementMethod = typeof(InventoryGui_DoCrafting).GetMethod("NoCostCheat");
				foreach (CodeInstruction instruction in instructions)
				{
					if (CodeInstructionExtensions.Calls(instruction, targetMethod))
					{
						yield return new CodeInstruction(OpCodes.Call, (object)replacementMethod);
					}
					else
					{
						yield return instruction;
					}
				}
			}

			public bool NoCostCheat()
			{
				if (settings.noCraftCost)
				{
					return true;
				}
				return Player.m_localPlayer.m_noPlacementCost;
			}

			private static void Postfix(Player player)
			{
				UpgradeInventory(player);
			}
		}

		[HarmonyPatch(typeof(Player), "RequiredCraftingStation")]
		private class Player_RequiredCraftingStation
		{
			private static void Prefix(ref bool checkLevel)
			{
				if (settings.noCraftLevels)
				{
					checkLevel = false;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")]
		private class InventoryGui_UpdateRecipe
		{
			private static void Postfix(InventoryGui __instance)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				if (settings.noCraftLevels)
				{
					((Graphic)__instance.m_minStationLevelText).color = __instance.m_minStationLevelBasecolor;
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "Start")]
		private class FejdStartup_Start
		{
			private static void Postfix()
			{
				font = ((TMP_Text)GameObject.Find("GuiRoot/GUI/StartGui/EULA/Popup/Scroll View/Viewport/Content/EulaImportantFirstText").GetComponent<TextMeshProUGUI>()).font;
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private class Player_OnSpawned
		{
			private static Transform healthpanel;

			private static GameObject LeftOf(string name, Transform parent, RectTransform from)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_0026: 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_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: 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: Expected O, but got Unknown
				GameObject val = new GameObject(name);
				val.transform.SetParent(parent);
				RectTransform obj = val.AddComponent<RectTransform>();
				obj.sizeDelta = from.sizeDelta;
				obj.anchoredPosition = from.anchoredPosition - new Vector2(from.sizeDelta.x + 1f, 0f);
				obj.anchorMax = from.anchorMax;
				obj.anchorMin = from.anchorMin;
				return val;
			}

			private static void DefaultFont(ref TextMeshProUGUI tmpGui, Color color, float ratio)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				((TMP_Text)tmpGui).font = font;
				((Graphic)tmpGui).material = ((TMP_Asset)font).material;
				((Graphic)tmpGui).color = color;
				((TMP_Text)tmpGui).alignment = (TextAlignmentOptions)514;
				((TMP_Text)tmpGui).fontMaterial.EnableKeyword("OUTLINE_ON");
				((TMP_Text)tmpGui).outlineColor = Color32.op_Implicit(Color.black);
				((TMP_Text)tmpGui).outlineWidth = 0.1f;
				((TMP_Text)tmpGui).fontStyle = (FontStyles)1;
				((TMP_Text)tmpGui).fontSize = ((Component)((Component)Hud.instance).transform.Find("hudroot/healthpanel/food0")).GetComponent<RectTransform>().sizeDelta.x * ratio;
			}

			private static TextMeshProUGUI AddCounter(string name, string item, int y)
			{
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				Transform val = ((Component)Hud.instance).transform.Find("hudroot/healthpanel");
				RectTransform component = ((Component)((Component)val).transform.Find("food" + y)).GetComponent<RectTransform>();
				GameObject val2 = LeftOf(name + "Bkg", val, component);
				JsonUtility.FromJsonOverwrite(JsonUtility.ToJson((object)((Component)component).GetComponent<Image>()), (object)val2.AddComponent<Image>());
				LeftOf(name + "Icon", val, component).AddComponent<Image>().sprite = GetItemIcon(item);
				GameObject obj = LeftOf(name + "Text", val, component);
				obj.SetActive(false);
				TextMeshProUGUI tmpGui = obj.AddComponent<TextMeshProUGUI>();
				DefaultFont(ref tmpGui, Color.white, 0.5f);
				obj.SetActive(true);
				((TMP_Text)tmpGui).alignment = (TextAlignmentOptions)1028;
				return tmpGui;
			}

			private static TextMeshProUGUI AddTimer()
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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_0043: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: 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_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				Transform val = ((Component)Hud.instance).transform.Find("hudroot");
				RectTransform component = ((Component)val.Find("healthpanel")).GetComponent<RectTransform>();
				GameObject val2 = new GameObject("timer");
				val2.SetActive(false);
				val2.transform.SetParent(val);
				RectTransform obj = val2.AddComponent<RectTransform>();
				obj.sizeDelta = new Vector2(1000f, 0f);
				obj.anchoredPosition = component.anchoredPosition + new Vector2(71f * component.sizeDelta.x / 100f, -112f * component.sizeDelta.y / 100f);
				obj.anchorMax = component.anchorMax;
				obj.anchorMin = component.anchorMin;
				TextMeshProUGUI tmpGui = val2.AddComponent<TextMeshProUGUI>();
				DefaultFont(ref tmpGui, new Color(1f, 0.717f, 0.36f, 1f), 2f / 3f);
				val2.SetActive(true);
				((TMP_Text)tmpGui).text = $"<mspace=0.5em>{TimeSpan.FromSeconds(settings.time)}</mspace>";
				return tmpGui;
			}

			private static void Postfix(Player __instance)
			{
				healthpanel = ((Component)Hud.instance).transform.Find("hudroot/healthpanel");
				int y = 0;
				if (settings.showDeaths && (Object)(object)deaths == (Object)null)
				{
					deaths = AddCounter("deaths", "Charredskull", y);
					UpdateDeaths();
					y = 1;
				}
				if (settings.showLogouts && (Object)(object)logouts == (Object)null)
				{
					logouts = AddCounter("logouts", "RoundLog", y);
					UpdateLogouts();
				}
				if (settings.showTimer && (Object)(object)timer == (Object)null)
				{
					timer = AddTimer();
				}
				if (settings.unlockRecipes && !unlockedRecipes)
				{
					unlockedRecipes = true;
					foreach (GameObject item in ObjectDB.instance.m_items)
					{
						ItemDrop component = item.GetComponent<ItemDrop>();
						if (!((Object)(object)component == (Object)null) && component.m_itemData != null)
						{
							string name = component.m_itemData.m_shared.m_name;
							if (!__instance.m_knownMaterial.Contains(name))
							{
								__instance.m_knownMaterial.Add(name);
							}
						}
					}
					__instance.UpdateKnownRecipesList();
					MessageHud.instance.m_unlockMsgQueue.Clear();
					MessageHud.instance.m_unlockMsgCount = 0;
				}
				((Character)__instance).m_runSpeed = ((Character)__instance).m_runSpeed * settings.runSpeed;
				((Character)__instance).m_jumpForce = ((Character)__instance).m_jumpForce * settings.jumpForce;
			}
		}

		[HarmonyPatch(typeof(Player), "OnDeath")]
		private class Player_OnDeath
		{
			private static void Postfix()
			{
				UpdateDeaths();
			}
		}

		[HarmonyPatch(typeof(Game), "Shutdown")]
		private class Game_Shutdown
		{
			private static void Prefix()
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					Dictionary<string, string> customData = Player.m_localPlayer.m_customData;
					int result = 1;
					if (customData.TryGetValue(logoutsKey, out var value))
					{
						int.TryParse(value, out result);
						result++;
					}
					customData[logoutsKey] = result.ToString();
				}
				((MonoBehaviour)speedchoice).StopAllCoroutines();
				settings.isTimerRunning = false;
				rockyied = false;
				isSynced = false;
				if (ZNet.instance.IsServer())
				{
					Save(ZNet.m_world);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Update")]
		private class Player_Update
		{
			private static void Postfix(Player __instance)
			{
				if (Object.op_Implicit((Object)(object)Game.instance) && ((Character)__instance).TakeInput() && Input.anyKeyDown)
				{
					if (!ZRoutedRpc.instance.m_server && !isSynced)
					{
						isSynced = true;
						ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "GetTimer", new object[1] { "GetTimer" });
					}
					if (!settings.isTimerRunning)
					{
						settings.isTimerRunning = true;
						((MonoBehaviour)speedchoice).StartCoroutine(TimerUpdate());
						ZRoutedRpc.instance.InvokeRoutedRPC(0L, "StartTimer", new object[1] { "StartTimer" });
					}
				}
			}
		}

		private struct PortalPin
		{
			public float x;

			public float y;

			public float z;

			public string text;

			public bool add;

			public bool remove;

			public PortalPin(Vector3 vector, string text, bool add, bool remove)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: 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)
				x = vector.x;
				y = vector.y;
				z = vector.z;
				this.text = text;
				this.add = add;
				this.remove = remove;
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece", new Type[]
		{
			typeof(Piece),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(bool),
			typeof(bool)
		})]
		private class Player_PlacePiece
		{
			private static void Postfix(Piece piece, Vector3 pos)
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				if (settings.wherePortal && (Object)(object)piece != (Object)null && (((Object)piece).name == "portal_wood" || ((Object)piece).name == "portal_stone"))
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PlacePortal", new object[1] { PortalPinJson(pos, "", add: true, remove: false) });
				}
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "SetText")]
		private class TeleportWorld_SetText
		{
			private static void Postfix(TeleportWorld __instance, string text)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				if (settings.wherePortal)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PlacePortal", new object[1] { PortalPinJson(((Component)__instance).transform.position, text, add: true, remove: true) });
				}
			}
		}

		[HarmonyPatch(typeof(Piece), "DropResources")]
		private class Piece_DropResources
		{
			private static void Prefix(Piece __instance)
			{
				if (settings.structureLoot && !__instance.IsPlacedByPlayer())
				{
					overridePieceDrops = true;
				}
			}

			private static void Postfix(Piece __instance)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				overridePieceDrops = false;
				if (settings.wherePortal && (Object)(object)((Component)__instance).GetComponent<TeleportWorld>() != (Object)null)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PlacePortal", new object[1] { PortalPinJson(((Component)__instance).transform.position, "", add: false, remove: true) });
				}
			}
		}

		[HarmonyPatch(typeof(Piece), "FreeBuildKey")]
		private class Piece_FreeBuildKey
		{
			private static bool Prefix(Piece __instance, ref GlobalKeys __result)
			{
				if (settings.structureLoot && overridePieceDrops && !__instance.IsPlacedByPlayer())
				{
					__result = (GlobalKeys)2;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "PlaceVegetation")]
		private class ZoneSystem_PlaceVegetation
		{
			private static void Prefix(ZoneSystem __instance)
			{
				if (!settings.alwaysRocky || rockyied)
				{
					return;
				}
				foreach (ZoneVegetation item in __instance.m_vegetation)
				{
					if ((Object)(object)item.m_prefab != (Object)null && ((Object)item.m_prefab).name == "Pickable_Stone")
					{
						item.m_prefab = ZNetScene.instance.GetPrefab("Pickable_StoneRock");
					}
				}
				rockyied = true;
			}
		}

		[HarmonyPatch(typeof(Pickable), "Awake")]
		private class Pickable_Awake
		{
			private static void Prefix(Pickable __instance)
			{
				if (settings.alwaysRocky && ((Object)__instance.m_itemPrefab).name == "Stone")
				{
					__instance.m_itemPrefab = ObjectDB.instance.GetItemPrefab("StoneRock");
				}
			}
		}

		public const string PluginGUID = "com.lukkster.Speedchoice";

		public const string PluginName = "Speedchoice";

		public const string PluginVersion = "1.1.0";

		private readonly Harmony harmony = new Harmony("com.lukkster.Speedchoice");

		private static Speedchoice speedchoice;

		private static Settings settings = new Settings();

		private static readonly Dictionary<string, Profile> profiles = new Dictionary<string, Profile>
		{
			{
				"Speedchoice",
				new Profile(new List<string>(3) { "eventrate 0", "teleportall", "nobuildcost" }, "Recommended Speedchoice settings. Faster gameplay, no grinding required, and Boss Reveals make the whole game completable in one sitting.", new Dictionary<string, float>
				{
					{ "Boat Speed", 2f },
					{ "Time to Rest", 2f },
					{ "Trophy Odds", 2f }
				}, new Dictionary<string, bool>
				{
					{ "Boss Reveals", true },
					{ "Boss Skills", true },
					{ "Cheat Death", true },
					{ "Drop Materials", true },
					{ "Fast Crops", true },
					{ "Fast Fermenters", true },
					{ "Harmless Pieces", false },
					{ "Increased Exp", false },
					{ "Instant Upgrades", true },
					{ "Lootless Bosses", false },
					{ "No Build Stations", true },
					{ "No Craft Cost", true },
					{ "No Craft Levels", false },
					{ "Show Deaths", true },
					{ "Show Logouts", true },
					{ "Show Timer", true },
					{ "Structure Loot", true },
					{ "Where's my Portal?", true }
				})
			},
			{
				"Trailblazer",
				new Profile(new List<string>(6) { "deathkeepequip", "skillreductionrate 15", "resourcerate 200", "eventrate 0", "teleportall", "nobuildcost" }, "OatHorse's Trailblazer settings, without the trophy hunt aspect.", new Dictionary<string, float>
				{
					{ "Boat Speed", 2f },
					{ "Time to Rest", 1f },
					{ "Trophy Odds", 4f }
				}, new Dictionary<string, bool>
				{
					{ "Boss Reveals", true },
					{ "Boss Skills", true },
					{ "Cheat Death", true },
					{ "Drop Materials", false },
					{ "Fast Crops", true },
					{ "Fast Fermenters", true },
					{ "Harmless Pieces", false },
					{ "Increased Exp", true },
					{ "Instant Upgrades", false },
					{ "Lootless Bosses", false },
					{ "No Build Stations", true },
					{ "No Craft Cost", true },
					{ "No Craft Levels", true },
					{ "Show Deaths", true },
					{ "Show Logouts", true },
					{ "Show Timer", true },
					{ "Structure Loot", true },
					{ "Where's my Portal?", true }
				})
			},
			{
				"Randomizer",
				new Profile(new List<string>(3) { "eventrate 0", "teleportall", "nobuildcost" }, "Recommended settings for playing Speedchoice Randomizer.", new Dictionary<string, float>
				{
					{ "Boat Speed", 2f },
					{ "Time to Rest", 1f },
					{ "Trophy Odds", 2f }
				}, new Dictionary<string, bool>
				{
					{ "Boss Reveals", false },
					{ "Boss Skills", true },
					{ "Cheat Death", true },
					{ "Drop Materials", true },
					{ "Fast Crops", true },
					{ "Fast Fermenters", true },
					{ "Harmless Pieces", true },
					{ "Increased Exp", false },
					{ "Instant Upgrades", true },
					{ "Lootless Bosses", false },
					{ "No Build Stations", true },
					{ "No Craft Cost", true },
					{ "No Craft Levels", false },
					{ "Show Deaths", false },
					{ "Show Logouts", false },
					{ "Show Timer", false },
					{ "Structure Loot", true },
					{ "Where's my Portal?", true }
				})
			}
		};

		private static readonly SortedDictionary<string, Range> ranges = new SortedDictionary<string, Range>
		{
			{
				"Boat Speed",
				new Range(() => settings.boatSpeed, delegate(float val)
				{
					settings.boatSpeed = val;
				}, "Changes the speed at which ships sail.", new List<RangeOption>(4)
				{
					new RangeOption("Normal", "Boats travel normally."),
					new RangeOption("Fast", "Boats are 2.5 times faster, 2 times faster while paddling."),
					new RangeOption("Dangerous", "Boats are 10 times faster, 8 times faster while paddling."),
					new RangeOption("Capsize", "Boats travel ... faster.")
				})
			},
			{
				"Time to Rest",
				new Range(() => settings.timeToRest, delegate(float val)
				{
					settings.timeToRest = val;
				}, "Adjusts how long it takes to become rested.", new List<RangeOption>(3)
				{
					new RangeOption("Normal", "The default of 20 seconds."),
					new RangeOption("Fast", "Spend 10 seconds to become rested."),
					new RangeOption("Instant", "Resting happens instantly.")
				})
			},
			{
				"Trophy Odds",
				new Range(() => settings.trophyOdds, delegate(float val)
				{
					settings.trophyOdds = val;
				}, "Adds an extra reroll for trophy drops to all enemies.", new List<RangeOption>(5)
				{
					new RangeOption("Normal", "Vanilla drop rates."),
					new RangeOption("More", "Trophies drop 25%, multiplicity, more often. Thus a Deer trophy would have 62.5% drop rate, boosted from it's vanilla 50%. A Deathsquito trophy would have 28.75%, from 5%."),
					new RangeOption("Often", "Trophies drop 50%, multiplicity, more often. Thus 50% -> 75%, and 5% -> 52.5"),
					new RangeOption("Frequently", "Trophies drop 75%, multiplicity, more often. Thus 50% -> 87.5%, and 5% -> 76.25%"),
					new RangeOption("Always", "All creatures that can drop trophies, will drop trophies.")
				})
			}
		};

		private static readonly Dictionary<string, CheckBox> checkBoxes = new Dictionary<string, CheckBox>
		{
			{
				"Boss Reveals",
				new CheckBox(() => settings.bossReveals, delegate(bool val)
				{
					settings.bossReveals = val;
				}, "Upon defeating a Forsaken, the next Forsaken's locations are revealed.")
			},
			{
				"Boss Skills",
				new CheckBox(() => settings.bossSkills, delegate(bool val)
				{
					settings.bossSkills = val;
				}, "Upon defeating a Forsaken, all skills will be leveled up.")
			},
			{
				"Lootless Bosses",
				new CheckBox(() => settings.lootlessBosses, delegate(bool val)
				{
					settings.lootlessBosses = val;
				}, "Forsaken do not drop items, including both their Trophies, and their \"progressive\" materials.")
			},
			{
				"Cheat Death",
				new CheckBox(() => settings.cheatDeath, delegate(bool val)
				{
					settings.cheatDeath = val;
				}, "If one logs out shortly after dying, they'll log in where they died rather than their spawn point.")
			},
			{
				"Drop Materials",
				new CheckBox(() => settings.dropMaterials, delegate(bool val)
				{
					settings.dropMaterials = val;
				}, "Materials, items used for crafting exclusively, are immediately removed from the inventory.")
			},
			{
				"Harmless Pieces",
				new CheckBox(() => settings.harmlessPieces, delegate(bool val)
				{
					settings.harmlessPieces = val;
				}, "Player built structures, such as campfires or spikes, do no damage to creatures.")
			},
			{
				"Fast Crops",
				new CheckBox(() => settings.fastCrops, delegate(bool val)
				{
					settings.fastCrops = val;
				}, "Crops grow quickly.")
			},
			{
				"Fast Fermenters",
				new CheckBox(() => settings.fastFermenters, delegate(bool val)
				{
					settings.fastFermenters = val;
				}, "Fermenters brew quickly.")
			},
			{
				"Increased Exp",
				new CheckBox(() => settings.increasedExp, delegate(bool val)
				{
					settings.increasedExp = val;
				}, "Increases Skill experience gains by 500%.")
			},
			{
				"Instant Upgrades",
				new CheckBox(() => settings.instantUpgrades, delegate(bool val)
				{
					settings.instantUpgrades = val;
				}, "Instantly upgrades any upgradeable tool or armor.")
			},
			{
				"Structure Loot",
				new CheckBox(() => settings.structureLoot, delegate(bool val)
				{
					settings.structureLoot = val;
				}, "Naturally occurring structures, such as houses, will drop into materials when deconstructed with a hammer in \"No Build Cost\".")
			},
			{
				"Where's my Portal?",
				new CheckBox(() => settings.wherePortal, delegate(bool val)
				{
					settings.wherePortal = val;
				}, "Adds a portal pin to the map upon placing a portal.")
			},
			{
				"No Build Stations",
				new CheckBox(() => settings.noBuildStations, delegate(bool val)
				{
					settings.noBuildStations = val;
				}, "Player built pieces can be constructed without the required nearby crafting stations. For instance a Portal can be built without a nearby Workbench.")
			},
			{
				"No Craft Cost",
				new CheckBox(() => settings.noCraftCost, delegate(bool val)
				{
					settings.noCraftCost = val;
				}, "Items can be crafted without consuming or requiring the materials to do so.")
			},
			{
				"No Craft Levels",
				new CheckBox(() => settings.noCraftLevels, delegate(bool val)
				{
					settings.noCraftLevels = val;
				}, "Items can be crafted without the prerequisite Crafting Station Level to do so.")
			},
			{
				"Show Deaths",
				new CheckBox(() => settings.showDeaths, delegate(bool val)
				{
					settings.showDeaths = val;
				}, "Adds an UI element showing the number of Deaths.")
			},
			{
				"Show Logouts",
				new CheckBox(() => settings.showLogouts, delegate(bool val)
				{
					settings.showLogouts = val;
				}, "Adds an UI element showing the number of Logouts.")
			},
			{
				"Show Timer",
				new CheckBox(() => settings.showTimer, delegate(bool val)
				{
					settings.showTimer = val;
				}, "Adds an UI element showing how long there has been activity in the world. Starts on first input, and pauses when the game pauses.")
			}
		};

		private static readonly List<Prefab> harmingPrefabs = new List<Prefab>(11)
		{
			new Prefab("piece_sharpstakes", "HIT AREA", new DamageTypes
			{
				m_pierce = 15f
			}),
			new Prefab("piece_dvergr_sharpstakes", "Colliders/HIT AREA", new DamageTypes
			{
				m_pierce = 15f
			}),
			new Prefab("piece_stakewall_blackwood", "HIT AREA", new DamageTypes
			{
				m_pierce = 120f
			}),
			new Prefab("piece_brazierfloor02", "_enabled_high/FireBurn", new DamageTypes
			{
				m_fire = 10f
			}),
			new Prefab("bonfire", "_enabled/FireBurn", new DamageTypes
			{
				m_fire = 20f
			}),
			new Prefab("fire_pit", "_enabled_high/FireBurn", new DamageTypes
			{
				m_fire = 10f
			}),
			new Prefab("piece_brazierceiling01", "_enabled_high/FireBurn", new DamageTypes
			{
				m_fire = 10f
			}),
			new Prefab("hearth", "_enabled_high/FireBurn", new DamageTypes
			{
				m_fire = 10f
			}),
			new Prefab("fire_pit_iron", "_enabled_high/FireBurn", new DamageTypes
			{
				m_fire = 10f
			}),
			new Prefab("piece_brazierfloor01", "_enabled_high/FireBurn", new DamageTypes
			{
				m_fire = 10f
			}),
			new Prefab("piece_trap_troll", "Damage Area", new DamageTypes
			{
				m_blunt = 50f,
				m_pierce = 50f,
				m_chop = 50f
			})
		};

		private static readonly Dictionary<float, float> boatSpeeds = new Dictionary<float, float>
		{
			{ 1f, 2.5f },
			{ 2f, 10f },
			{ 3f, 100f }
		};

		private static readonly Dictionary<float, float> restDelays = new Dictionary<float, float>
		{
			{ 1f, 10f },
			{ 2f, 0f }
		};

		private static readonly Dictionary<float, float> trophyOdds = new Dictionary<float, float>
		{
			{ 1f, 0.25f },
			{ 2f, 0.5f },
			{ 3f, 0.75f },
			{ 4f, 1f }
		};

		private const float bossRadius = 500f;

		private const float vendorRadius = 100f;

		private static readonly Dictionary<string, List<Poi>> reveals = new Dictionary<string, List<Poi>>
		{
			{
				"$enemy_eikthyr",
				new List<Poi>
				{
					new Poi("GDKing", (PinType)9, "$enemy_gdking", 500f),
					new Poi("Vendor_BlackForest", (PinType)3, "Haldor", 100f)
				}
			},
			{
				"$enemy_gdking",
				new List<Poi>
				{
					new Poi("Bonemass", (PinType)9, "$enemy_bonemass", 500f),
					new Poi("BogWitch_Camp", (PinType)3, "BogWitch", 100f)
				}
			},
			{
				"$enemy_bonemass",
				new List<Poi>
				{
					new Poi("Dragonqueen", (PinType)9, "$enemy_dragon", 500f),
					new Poi("AncientUpgradeStation", (PinType)3, "Forge of Potential", 100f)
				}
			},
			{
				"$enemy_dragon",
				new List<Poi>
				{
					new Poi("GoblinKing", (PinType)9, "$enemy_goblinking", 500f),
					new Poi("Hildir_camp", (PinType)3, "Hildir", 100f)
				}
			},
			{
				"$enemy_goblinking",
				new List<Poi>
				{
					new Poi("Mistlands_DvergrBossEntrance1", (PinType)9, "$enemy_seekerqueen", 500f)
				}
			},
			{
				"$enemy_seekerqueen",
				new List<Poi>
				{
					new Poi("FaderLocation", (PinType)9, "$enemy_fader_codename", 500f),
					new Poi("PlaceofMystery1", (PinType)3, "Mysterious Location", 100f)
				}
			},
			{
				"$enemy_fader",
				new List<Poi>
				{
					new Poi("DN_Bossroom", (PinType)9, "$hud_pin_dnboss", 500f)
				}
			}
		};

		private static readonly Dictionary<string, int> levels = new Dictionary<string, int>
		{
			{ "$enemy_frozenking_p3", 100 },
			{ "$enemy_fader", 80 },
			{ "$enemy_seekerqueen", 70 },
			{ "$enemy_goblinking", 60 },
			{ "$enemy_dragon", 50 },
			{ "$enemy_bonemass", 40 },
			{ "$enemy_gdking", 30 },
			{ "$enemy_eikthyr", 20 }
		};

		private static readonly List<ItemType> drops = new List<ItemType>(4)
		{
			(ItemType)21,
			(ItemType)1,
			(ItemType)16,
			(ItemType)13
		};

		private static readonly List<string> keeps = new List<string>(164)
		{
			"$item_blackmetalscrap", "$item_flametalore", "$item_goldore", "$item_catapult_ammo", "$item_catapult_training_ammo", "$item_catapult_bloodgold_ammo", "$item_finewood", "$item_roundlog", "$item_wood", "$item_eitr",
			"$item_sap", "$item_softtissue", "$item_barleywinebase", "$item_meadbasebugrepellent", "$item_meadbasebzerker", "$item_meadbaseeitr_lingering", "$item_meadbaseeitr", "$item_meadbasefrostresist", "$item_meadbasehasty", "$item_meadbasehealth_lingering",
			"$item_meadbasehealth_major", "$item_meadbasehealth_medium", "$item_meadbasehealth", "$item_meadbaselightfoot", "$item_meadbasepoisonresist", "$item_meadbasestamina_lingering", "$item_meadbasestamina_medium", "$item_meadbasestamina", "$item_meadbasestrength", "$item_meadbaseswimmer",
			"$item_meadbasetamer", "$item_meadbasetasty", "$item_blackcore", "$item_fireworkrocket_blue", "$item_fireworkrocket_cyan", "$item_fireworkrocket_green", "$item_fireworkrocket_purple", "$item_fireworkrocket_red", "$item_fireworkrocket_white", "$item_fireworkrocket_yellow",
			"$item_surtlingcore", "$item_thunderstone", "$item_ancientseed", "$item_bell", "$item_dragonegg", "$item_dvergrkey", "$item_goblintotem", "$item_hatefulblood", "$item_trophy_deer", "$item_trophy_seeker_brute",
			"$item_witheredbone", "$item_ice", "$item_chest_heavy_gold_uncooked", "$item_helmet_heavy_gold_uncooked", "$item_legs_heavy_gold_uncooked", "$item_chest_mage_gold_uncooked", "$item_helmet_mage_gold_uncooked", "$item_legs_mage_gold_uncooked", "$item_chest_medium_gold_uncooked", "$item_helmet_medium_gold_uncooked",
			"$item_legs_medium_gold_uncooked", "$item_atgeir_gold_uncooked", "$item_axe_gold_uncooked", "$item_battleaxe_gold_uncooked", "$item_bow_gold_uncooked", "$item_crossbow_gold_uncooked", "$item_fistweapon_gold_uncooked", "$item_frozenfuel", "$item_keys_gold_uncooked", "$item_knife_gold_uncooked",
			"$item_mace_gold_uncooked", "$item_shield_buckler_gold_uncooked", "$item_shield_round_gold_uncooked", "$item_shield_tower_gold_uncooked", "$item_sledge_gold_uncooked", "$item_spear_gold_uncooked", "$item_frostorbs_uncooked", "$item_staff_orbofahri_uncooked", "$item_staff_spiritcaller_uncooked", "$item_staff_thunderblood_uncooked",
			"$item_sword_gold_uncooked", "$item_sword2h_gold_uncooked", "$item_chest_hildir1", "$item_chest_hildir2", "$item_chest_hildir3", "$item_memorialcoal", "$item_bloodgoldkey", "$item_frozenking_drop", "$item_trophy_bonemass", "$item_trophy_dragonqueen",
			"$item_trophy_eikthyr", "$item_trophy_fader", "$item_trophy_goblinking", "$item_trophy_seekerqueen", "$item_trophy_elder", "$item_saddleasksvin", "$item_saddlelox", "$item_saddlemoose", "$item_bonefragments", "$item_charredbone",
			"$item_bronzescrap", "$item_coal", "$item_copperore", "$item_copperscrap", "$item_ironore", "$item_ironscrap", "$item_silverore", "$item_tinore", "$item_flax", "$item_cryptkey",
			"$item_asksvin_egg", "$item_beechseeds", "$item_birchseeds", "$item_carrotseeds", "$item_chicken_egg", "$item_dandelion", "$item_onionseeds", "$item_turnip", "$item_turnipseeds", "$item_greydwarfeye",
			"$item_guck", "$item_resin", "$item_asksvin_meat", "$item_bakedpoteitr_uncooked", "$item_bjorn_meat", "$item_bonemawmeat", "$item_breaddough", "$item_bug_meat", "$item_chicken_meat", "$item_deer_meat",
			"$item_fishandbreaduncooked", "$item_fish_raw", "$item_fish_raw", "$item_hare_meat", "$item_honeyglazedchickenuncooked", "$item_kalechips_uncooked", "$item_loxmeat", "$item_loxpie_uncooked", "$item_magicallystuffedmushroomuncooked", "$item_meatplatteruncooked",
			"$item_mistharesupremeuncooked", "$item_moose_meat", "$item_necktail", "$item_ovenpancake_uncooked", "$item_piquantpie_uncooked", "$item_boar_meat", "$item_roastedcrustpie_uncooked", "$item_blubber", "$item_serpentmeat", "$item_vikingcupcake_uncooked",
			"$item_volture_meat", "$item_wolf_meat", "$item_amber", "$item_amberpearl", "$item_ancientcoin", "$item_ancientgemstone_black", "$item_ancientgemstone_green", "$item_ancientgemstone_orange", "$item_ancientgemstone_purple", "$item_coins",
			"$item_ruby", "$item_silvernecklace", "$item_barley", "$item_oatseeds"
		};

		private static readonly Dictionary<string, Recipe> upgradeAbles = new Dictionary<string, Recipe>();

		private static readonly List<string> trader_boss_keys = new List<string>(6) { "defeated_gdking", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader", "defeated_frozenking_p3" };

		private static TMP_FontAsset font;

		private static TextMeshProUGUI deaths;

		private static readonly string logoutsKey = "logouts";

		private static TextMeshProUGUI logouts;

		private static TextMeshProUGUI timer;

		private static bool unlockedRecipes = false;

		private static bool isSynced = false;

		private static bool overridePieceDrops = false;

		private static bool rockyied = false;

		private void Start()
		{
			harmony.PatchAll();
			speedchoice = this;
		}

		private static string GetSavePath(World world)
		{
			return GetSavePath(world.m_name);
		}

		private static string GetSavePath(string name)
		{
			return Path.Combine(Path.Combine(Utils.GetSaveDataPath((FileSource)2), "worlds"), name + "_speedchoice.json");
		}

		private static string FromSettings()
		{
			return JsonConvert.SerializeObject((object)settings, (Formatting)1);
		}

		private static void ToSettings(string json)
		{
			settings = JsonConvert.DeserializeObject<Settings>(json);
		}

		private static void Save(World world)
		{
			File.WriteAllText(GetSavePath(world), FromSettings());
		}

		private static void Load(World world)
		{
			if (File.Exists(GetSavePath(world)))
			{
				ToSettings(File.ReadAllText(GetSavePath(world)));
			}
			else
			{
				settings = new Settings();
			}
		}

		private static void RemoveItem(Inventory inventory, ItemData itemData)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (settings.dropMaterials && drops.Contains(itemData.m_shared.m_itemType) && !keeps.Contains(itemData.m_shared.m_name))
			{
				inventory.RemoveItem(itemData);
			}
		}

		private static void UpgradeInventory(Player player)
		{
			if (!settings.instantUpgrades)
			{
				return;
			}
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			if ((Object)(object)currentCraftingStation == (Object)null)
			{
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (upgradeAbles.TryGetValue(allItem.m_shared.m_name, out var value) && (((Object)(object)value.m_craftingStation != (Object)null && currentCraftingStation.m_name == value.m_craftingStation.m_name) || ((Object)(object)value.m_craftingStation == (Object)null && currentCraftingStation.m_name == "$piece_workbench")))
				{
					int num = MaxLevel(currentCraftingStation, value);
					if (allItem.m_quality < num)
					{
						allItem.m_quality = num;
						allItem.m_durability = allItem.m_shared.m_maxDurability + allItem.m_shared.m_durabilityPerLevel * (float)(allItem.m_quality - 1);
					}
				}
			}
		}

		private static int MaxLevel(CraftingStation station, Recipe recipe)
		{
			int maxQuality = recipe.m_item.m_itemData.m_shared.m_maxQuality;
			if (settings.noCraftLevels)
			{
				return maxQuality;
			}
			int num = 1;
			if ((Object)(object)station != (Object)null)
			{
				num = station.GetLevel(true);
			}
			int num2 = num - recipe.m_minStationLevel;
			if (recipe.m_minStationLevel != 0)
			{
				num2++;
			}
			if (num2 > maxQuality)
			{
				num2 = maxQuality;
			}
			return num2;
		}

		private static Sprite GetItemIcon(string itemPrefab)
		{
			return ObjectDB.instance.GetItemPrefab(itemPrefab).GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0];
		}

		private static void UpdateDeaths()
		{
			TextMeshProUGUI obj = deaths;
			if (obj != null)
			{
				((TMP_Text)obj).text = Game.instance.GetPlayerProfile().GetStat((PlayerStatType)0).ToString();
			}
		}

		private static void UpdateLogouts()
		{
			if (Player.m_localPlayer.m_customData.TryGetValue(logoutsKey, out var value))
			{
				((TMP_Text)logouts).text = value;
			}
			else
			{
				((TMP_Text)logouts).text = "0";
			}
		}

		private static IEnumerator TimerUpdate()
		{
			while (true)
			{
				if (!Game.IsPaused())
				{
					TextMeshProUGUI obj = timer;
					if (obj != null)
					{
						((TMP_Text)obj).text = $"<mspace=0.5em>{TimeSpan.FromSeconds(settings.time)}</mspace>";
					}
					settings.time++;
				}
				yield return (object)new WaitForSeconds(1f);
			}
		}

		private static string PortalPinJson(Vector3 vector, string text, bool add, bool remove)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return JsonConvert.SerializeObject((object)new PortalPin(vector, text, add, remove));
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}