API.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 ATS_API;
using ATS_API.Ascension;
using ATS_API.Biomes;
using ATS_API.Buildings;
using ATS_API.Decorations;
using ATS_API.Difficulties;
using ATS_API.Effects;
using ATS_API.Goods;
using ATS_API.Helpers;
using ATS_API.Localization;
using ATS_API.MetaRewards;
using ATS_API.NaturalResource;
using ATS_API.Needs;
using ATS_API.Orders;
using ATS_API.Races;
using ATS_API.Recipes;
using ATS_API.Recipes.Builders;
using ATS_API.Relics;
using ATS_API.Traders;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.CompilerServices;
using Eremite;
using Eremite.Buildings;
using Eremite.Characters.Villagers;
using Eremite.Controller;
using Eremite.Controller.Events;
using Eremite.Controller.Generator;
using Eremite.Controllers.Generator;
using Eremite.MapObjects;
using Eremite.MapTools;
using Eremite.Model;
using Eremite.Model.Configs;
using Eremite.Model.Configs.CustomGame;
using Eremite.Model.Effects;
using Eremite.Model.Effects.Hooked;
using Eremite.Model.Goals;
using Eremite.Model.Meta;
using Eremite.Model.Needs;
using Eremite.Model.Orders;
using Eremite.Model.SaveSupport;
using Eremite.Model.Sound;
using Eremite.Model.State;
using Eremite.Model.Trade;
using Eremite.Services;
using Eremite.Services.Meta;
using Eremite.Services.World;
using Eremite.View;
using Eremite.View.HUD;
using Eremite.View.Popups;
using Eremite.View.Popups.GameMenu;
using Eremite.View.SaveSupport;
using Eremite.View.UI;
using Eremite.View.Utils;
using Eremite.WorldMap;
using Eremite.WorldMap.Model;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Networking;
using UnityEngine.Pool;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("API")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Mod that adds helper methods for other mods and fixes/QOL changes for the game")]
[assembly: AssemblyFileVersion("3.1.0.0")]
[assembly: AssemblyInformationalVersion("3.1.0+ba3aa9422065c524a7c2c5fe480245bad020c807")]
[assembly: AssemblyProduct("API")]
[assembly: AssemblyTitle("API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class BuildingVisualData
{
	public Building Prefab;

	public Sprite Icon;
}
[HarmonyPatch]
public static class ModMenuTab
{
	internal static Action OptionsMenuEnabled;

	[HarmonyPatch(typeof(OptionsPopup), "Initialize")]
	[HarmonyPrefix]
	public static void Initialize(OptionsPopup __instance)
	{
		GameObject val = ((BaseMB)__instance).FindChild("Content/GeneralContent");
		GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent);
		val2.AddComponent<ModPanel>();
		GameObject val3 = ((Component)(object)__instance).FindChild("Content/Tabs");
		Transform val4 = val3.transform.FindChild("GeneralButton");
		GameObject go = Object.Instantiate<GameObject>(((Component)val4).gameObject, val3.transform);
		TabsButton button = go.SafeGetComponentInChildren<TabsButton>(includeInactive: false);
		button.content = val2;
		Object.Destroy((Object)(object)((Component)(object)button).FindChild<TextFontFeaturesHelper>("Text", errorIfNotFound: true));
		((MonoBehaviour)Plugin.Instance).StartCoroutine(MethodName());
		TabsPanel val5 = ((Component)(object)__instance).SafeGetComponentInChildren<TabsPanel>();
		val5.buttons = CollectionExtensions.AddToArray<TabsButton>(val5.buttons, button);
		((HorizontalOrVerticalLayoutGroup)((Component)val5).GetComponent<HorizontalLayoutGroup>()).childForceExpandWidth = true;
		((HorizontalOrVerticalLayoutGroup)((Component)val5).GetComponent<HorizontalLayoutGroup>()).childControlWidth = true;
		ScrollRect val6 = val2.SafeGetComponentInChildren<ScrollRect>(includeInactive: false);
		GameObject gameObject = ((Component)val6.content).gameObject;
		for (int i = 1; i < gameObject.transform.childCount; i++)
		{
			Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(i)).gameObject);
		}
		GameObject gameObject2 = ((Component)gameObject.transform.GetChild(0)).gameObject;
		gameObject2.SetActive(false);
		GameObject val7 = Object.Instantiate<GameObject>(gameObject2, gameObject2.transform.parent);
		for (int j = 2; j < val7.transform.childCount; j++)
		{
			((Component)val7.transform.GetChild(j)).gameObject.SetActive(false);
		}
		GameObject labelTemplate = gameObject2.FindChild("GPU");
		GameObject val8 = gameObject2.FindChild("Resolution");
		GameObject toggleTemplate = gameObject2.FindChild("FPSCounter");
		GameObject sliderTemplate = gameObject2.FindChild("UISize");
		GameObject gameObject3 = ((Component)((BaseMB)__instance).FindChild("Content/TwitchContent").SafeGetComponentInChildren<TMP_InputField>(includeInactive: true)).gameObject;
		Sprite sprite = val8.FindChild<Image>("Dropdown", errorIfNotFound: true).sprite;
		foreach (PluginInfo item in Chainloader.PluginInfos.Values.OrderBy(GetModName))
		{
			PluginInfoExtensions.PluginManifest pluginManifest = item.Manifest();
			string modName = GetModName(item);
			Version version = ((pluginManifest != null && pluginManifest.ManifestVersion() != null) ? pluginManifest.ManifestVersion() : item.Metadata.Version);
			string text = ((pluginManifest == null || string.IsNullOrEmpty(pluginManifest.description)) ? "" : (pluginManifest.description + "\n\n"));
			GameObject val9 = Object.Instantiate<GameObject>(val7, gameObject.transform);
			GameObject val10 = val9.FindChild("Header");
			Object.Destroy((Object)(object)val10.SafeGetComponent<LocalizationText>());
			val10.SafeGetComponent<TMP_Text>().text = modName + ((version != null && version.ToString() != "0.0") ? (" v" + version) : "");
			((Object)val9).name = val10.GetComponent<TMP_Text>().text;
			string text2 = Keys.GUID.ToLocaText().GetText();
			string text3 = Keys.Dependencies.ToLocaText().GetText();
			SimpleTooltipTrigger orAdd = val10.GetOrAdd<SimpleTooltipTrigger>();
			orAdd.target = val10.GetComponent<RectTransform>();
			orAdd.descKey = "<align=\"left\">" + text + "<b>" + text2 + ":</b> " + item.Metadata.GUID + "\n\n<b>" + text3 + ":</b>\n" + GetDependencies(item, pluginManifest) + "</align>";
			AddConfigsToModSection(item, val8, val9, sliderTemplate, toggleTemplate, gameObject3, sprite, labelTemplate);
			val9.SetActive(true);
		}
		OptionsMenuEnabled?.Invoke();
		IEnumerator MethodName()
		{
			yield return null;
			((Component)(object)button).FindChild<LocalizationText>("Text", errorIfNotFound: true).key = Keys.OptionsUI_ModsTab_Text_Key;
			((Component)(object)button).FindChild<LocalizationText>("Text", errorIfNotFound: true).SetText();
		}
	}

	private static string GetModName(PluginInfo plugin)
	{
		PluginInfoExtensions.PluginManifest pluginManifest = plugin.Manifest();
		return (pluginManifest != null) ? pluginManifest.name : plugin.Metadata.Name;
	}

	private static string GetDependencies(PluginInfo plugin, PluginInfoExtensions.PluginManifest pluginManifest)
	{
		Dictionary<string, Version> dictionary = new Dictionary<string, Version>();
		Extensions.AddRange<string, Version>(dictionary, plugin.Dependencies.ToDictionary((BepInDependency a) => a.DependencyGUID, (BepInDependency a) => a.MinimumVersion));
		if (pluginManifest != null)
		{
			PluginInfoExtensions.PluginManifest.Dependency[] array = pluginManifest.Dependencies();
			for (int i = 0; i < array.Length; i++)
			{
				PluginInfoExtensions.PluginManifest.Dependency dependency = array[i];
				if (dictionary.TryGetValue(dependency.Name, out var value))
				{
					dictionary[dependency.Name] = ((dependency.Version == null || value > dependency.Version) ? value : dependency.Version);
				}
				else
				{
					dictionary[dependency.Name] = dependency.Version;
				}
			}
		}
		dictionary.Remove("BepInExPack");
		string wrongVersion = Keys.WrongVersion.ToLocaText().GetText();
		string missing = Keys.Missing.ToLocaText().GetText();
		string text = "";
		if (dictionary.Count > 0)
		{
			return string.Join("\n", dictionary.Select(delegate(KeyValuePair<string, Version> pair)
			{
				//IL_00f2: 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)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				string key = pair.Key;
				Version value2 = pair.Value;
				string text2 = key + ((value2 != null && value2.ToString() != "0.0") ? (" v" + value2) : "");
				bool flag = false;
				if (Chainloader.PluginInfos.TryGetValue(key, out var value3))
				{
					text2 = value3.Metadata.Name + " v" + value3.Metadata.Version;
					flag = value3.Metadata.Version >= value2;
					if (!flag)
					{
						text2 = text2 + " (" + wrongVersion + ")";
					}
				}
				else
				{
					text2 = text2 + " (" + missing + ")";
				}
				Color val = (flag ? Color.green : Color.red);
				string text3 = ColorUtility.ToHtmlStringRGB(val);
				return "<color=#" + text3 + ">" + text2 + "</color>";
			}));
		}
		return Keys.None.ToLocaText().GetText();
	}

	private static void AddConfigsToModSection(PluginInfo pluginInfo, GameObject dropdownTemplate, GameObject modSection, GameObject sliderTemplate, GameObject toggleTemplate, GameObject inputFieldTemplate, Sprite textFieldBackground, GameObject labelTemplate)
	{
		ConfigFile config = pluginInfo.Instance.Config;
		if (config == null || config.Keys.Count == 0)
		{
			return;
		}
		ConfigEntryBase[] configEntries = config.GetConfigEntries();
		foreach (ConfigEntryBase val in configEntries)
		{
			Type settingType = val.SettingType;
			AcceptableValueBase acceptableValues = val.Description.AcceptableValues;
			if (acceptableValues != null)
			{
				if (((object)acceptableValues).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueList<>))
				{
					Type type = ((object)acceptableValues).GetType().GetGenericArguments()[0];
					object obj = ((object)acceptableValues).GetType().GetProperty("AcceptableValues").GetGetMethod()
						.Invoke(acceptableValues, null);
					if (type == typeof(int))
					{
						Dictionary<int, int> dictionary = new Dictionary<int, int>();
						int[] array = (int[])obj;
						foreach (int num in array)
						{
							dictionary[num] = num;
						}
						Dropdown(settingType, dictionary, dropdownTemplate, modSection, val);
						continue;
					}
					if (type == typeof(float))
					{
						Dictionary<float, float> dictionary2 = new Dictionary<float, float>();
						float[] array2 = (float[])obj;
						foreach (float num2 in array2)
						{
							dictionary2[num2] = num2;
						}
						Dropdown(settingType, dictionary2, dropdownTemplate, modSection, val);
						continue;
					}
					if (type == typeof(string))
					{
						Dictionary<string, string> dictionary3 = new Dictionary<string, string>();
						string[] array3 = (string[])obj;
						foreach (string text in array3)
						{
							dictionary3[text] = text;
						}
						Dropdown(settingType, dictionary3, dropdownTemplate, modSection, val);
						continue;
					}
					if (type.IsEnum)
					{
						Dictionary<string, string> dictionary4 = new Dictionary<string, string>();
						string[] array4 = (string[])obj;
						foreach (string text2 in array4)
						{
							dictionary4[text2] = text2;
						}
						Dropdown(settingType, dictionary4, dropdownTemplate, modSection, val);
						continue;
					}
				}
				else if (((object)acceptableValues).GetType().GetGenericTypeDefinition() == typeof(AcceptableValueRange<>))
				{
					if (settingType == typeof(int))
					{
						int min = (int)((object)acceptableValues).GetType().GetProperty("MinValue").GetValue(acceptableValues);
						int max = (int)((object)acceptableValues).GetType().GetProperty("MaxValue").GetValue(acceptableValues);
						AddIntSlider(sliderTemplate, modSection, val, min, max);
						continue;
					}
					if (settingType == typeof(float))
					{
						float min2 = (float)((object)acceptableValues).GetType().GetProperty("MinValue").GetGetMethod()
							.Invoke(acceptableValues, null);
						float max2 = (float)((object)acceptableValues).GetType().GetProperty("MaxValue").GetGetMethod()
							.Invoke(acceptableValues, null);
						AddFloatSlider(sliderTemplate, modSection, val, min2, max2);
						continue;
					}
				}
				else
				{
					Plugin.Log.LogError((object)("Unsupported acceptableValues type " + ((object)acceptableValues).GetType().FullName + " for " + val.Definition.Key));
				}
			}
			if (settingType == typeof(bool))
			{
				AddToggle(toggleTemplate, modSection, val);
			}
			else if (settingType == typeof(int))
			{
				AddInputField<int>(inputFieldTemplate, modSection.transform, val, textFieldBackground);
			}
			else if (settingType == typeof(float))
			{
				AddInputField<float>(inputFieldTemplate, modSection.transform, val, textFieldBackground);
			}
			else if (settingType == typeof(string))
			{
				AddInputField<string>(inputFieldTemplate, modSection.transform, val, textFieldBackground);
			}
			else if (settingType.IsEnum)
			{
				EnumDropdown(settingType, dropdownTemplate, modSection, val);
			}
			else
			{
				AddUnknownType(labelTemplate, modSection, val);
			}
		}
	}

	private static void Dropdown<K, V>(Type type, Dictionary<K, V> values, GameObject dropdownTemplate, GameObject modSection, ConfigEntryBase entry)
	{
		GameObject val = Object.Instantiate<GameObject>(dropdownTemplate, modSection.transform);
		((Object)val).name = entry.Definition.Key;
		PopulateToolTip(val, entry);
		Object.Destroy((Object)(object)val.FindChild<LocalizationText>("Label", errorIfNotFound: true));
		val.FindChild("Label").SafeGetComponent<TMP_Text>().text = entry.Definition.Key;
		List<string> list = values.Keys.Select((K a) => a.ToString()).ToList();
		List<V> valuesList = values.Keys.Select((K a) => values[a]).ToList();
		TMP_Dropdown dropdownComponent = val.SafeGetComponentInChildren<TMP_Dropdown>(includeInactive: false);
		dropdownComponent.ClearOptions();
		dropdownComponent.AddOptions(list);
		((UnityEvent<int>)(object)dropdownComponent.onValueChanged).AddListener((UnityAction<int>)delegate
		{
			int value3 = dropdownComponent.value;
			entry.BoxedValue = valuesList[value3];
		});
		OptionsMenuEnabled = (Action)Delegate.Combine(OptionsMenuEnabled, (Action)delegate
		{
			int value2 = valuesList.IndexOf((V)entry.BoxedValue);
			dropdownComponent.value = value2;
		});
	}

	private static void EnumDropdown(Type type, GameObject dropdownTemplate, GameObject modSection, ConfigEntryBase entry)
	{
		Dictionary<string, Enum> dictionary = new Dictionary<string, Enum>();
		foreach (Enum value in Enum.GetValues(type))
		{
			dictionary[value.ToString()] = value;
		}
		Dropdown(type, dictionary, dropdownTemplate, modSection, entry);
	}

	private static void AddUnknownType(GameObject labelTemplate, GameObject modSection, ConfigEntryBase entry)
	{
		string text2 = entry.Definition.Key + "(" + entry.SettingType.Name + ")";
		GameObject val = Object.Instantiate<GameObject>(labelTemplate, modSection.transform);
		((Object)val).name = text2;
		PopulateToolTip(val, entry);
		Object.Destroy((Object)(object)val.FindChild<LocalizationText>("Label ", errorIfNotFound: true));
		val.FindChild("Label ").SafeGetComponent<TMP_Text>().text = text2;
		TMP_Text text = val.FindChild("Value").SafeGetComponent<TMP_Text>();
		OptionsMenuEnabled = (Action)Delegate.Combine(OptionsMenuEnabled, (Action)delegate
		{
			text.text = entry.BoxedValue?.ToString();
		});
	}

	private static void AddInputField<T>(GameObject inputFieldTemplate, Transform parent, ConfigEntryBase entry, Sprite background)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: 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)
		ContentType contentType = (ContentType)0;
		if (typeof(T) == typeof(int))
		{
			contentType = (ContentType)2;
		}
		else if (typeof(T) == typeof(float))
		{
			contentType = (ContentType)3;
		}
		else if (typeof(T) == typeof(string))
		{
			contentType = (ContentType)0;
		}
		else
		{
			Plugin.Log.LogError((object)("Unsupported type " + typeof(T).FullName + " for input field!"));
		}
		GameObject val = Object.Instantiate<GameObject>(((Component)inputFieldTemplate.transform.parent).gameObject, parent);
		((Object)val).name = entry.Definition.Key;
		PopulateToolTip(val, entry);
		Object.Destroy((Object)(object)val.FindChild<LocalizationText>("Label ", errorIfNotFound: true));
		val.FindChild("Label ").SafeGetComponent<TMP_Text>().text = entry.Definition.Key;
		TMP_InputField input = val.SafeGetComponentInChildren<TMP_InputField>(includeInactive: false);
		ComponentExtensions.GetRectTransform((Component)(object)input).sizeDelta = new Vector2(290f, ComponentExtensions.GetRectTransform((Component)(object)input).sizeDelta.y);
		((Component)(object)input).FindChild("Text Area").AddComponent<RectMask2D>();
		input.contentType = contentType;
		if (typeof(T) == typeof(string))
		{
			TMP_Text val2 = ((Component)(object)input).FindChild<TMP_Text>("Text Area/Text", errorIfNotFound: true);
			val2.alignment = (TextAlignmentOptions)513;
		}
		((UnityEvent<string>)(object)input.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
		{
			Plugin.Log.LogInfo((object)("Setting " + entry.Definition.Key + " to " + value));
			entry.BoxedValue = (T)Convert.ChangeType(value, typeof(T));
		});
		OptionsMenuEnabled = (Action)Delegate.Combine(OptionsMenuEnabled, (Action)delegate
		{
			Plugin.Log.LogInfo((object)$"Setting {entry.Definition.Key} to {entry.BoxedValue}");
			input.SetTextWithoutNotify(entry.BoxedValue?.ToString());
		});
	}

	private static void PopulateToolTip(GameObject gameObject, ConfigEntryBase entry)
	{
		SimpleTooltipTrigger val = default(SimpleTooltipTrigger);
		if (!gameObject.TryGetComponent<SimpleTooltipTrigger>(ref val))
		{
			val = gameObject.AddComponent<SimpleTooltipTrigger>();
			val.target = gameObject.GetComponent<RectTransform>();
		}
		val.descKey = entry.Description.Description + "\nDefault: " + entry.DefaultValue;
	}

	private static void AddFloatSlider(GameObject sliderTemplate, GameObject modSection, ConfigEntryBase entry, float min, float max)
	{
		GameObject val = Object.Instantiate<GameObject>(sliderTemplate, modSection.transform);
		((Object)val).name = entry.Definition.Key;
		PopulateToolTip(val, entry);
		Object.Destroy((Object)(object)val.FindChild<LocalizationText>("Label", errorIfNotFound: true));
		TMP_Text label = val.FindChild<TMP_Text>("Label", errorIfNotFound: true);
		label.text = entry.Definition.Key;
		Slider sliderComponent = val.SafeGetComponentInChildren<Slider>(includeInactive: false);
		sliderComponent.minValue = min;
		sliderComponent.maxValue = max;
		((UnityEvent<float>)(object)sliderComponent.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
		{
			entry.BoxedValue = value;
			label.text = entry.Definition.Key + " (" + entry.BoxedValue?.ToString() + ")";
		});
		OptionsMenuEnabled = (Action)Delegate.Combine(OptionsMenuEnabled, (Action)delegate
		{
			sliderComponent.value = (float)entry.BoxedValue;
			label.text = entry.Definition.Key + " (" + entry.BoxedValue?.ToString() + ")";
		});
	}

	private static void AddIntSlider(GameObject sliderTemplate, GameObject modSection, ConfigEntryBase entry, int min, int max)
	{
		GameObject val = Object.Instantiate<GameObject>(sliderTemplate, modSection.transform);
		((Object)val).name = entry.Definition.Key;
		PopulateToolTip(val, entry);
		Object.Destroy((Object)(object)val.FindChild<LocalizationText>("Label", errorIfNotFound: true));
		TMP_Text label = val.FindChild("Label").SafeGetComponent<TMP_Text>();
		label.text = entry.Definition.Key;
		Slider sliderComponent = val.SafeGetComponentInChildren<Slider>(includeInactive: false);
		sliderComponent.minValue = min;
		sliderComponent.maxValue = max;
		((UnityEvent<float>)(object)sliderComponent.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
		{
			entry.BoxedValue = (int)value;
			label.text = entry.Definition.Key + " (" + entry.BoxedValue?.ToString() + ")";
		});
		OptionsMenuEnabled = (Action)Delegate.Combine(OptionsMenuEnabled, (Action)delegate
		{
			sliderComponent.value = (int)entry.BoxedValue;
			label.text = entry.Definition.Key + " (" + entry.BoxedValue?.ToString() + ")";
		});
	}

	private static void AddToggle(GameObject toggleTemplate, GameObject modSection, ConfigEntryBase entry)
	{
		GameObject val = Object.Instantiate<GameObject>(toggleTemplate, modSection.transform);
		((Object)val).name = entry.Definition.Key;
		PopulateToolTip(val, entry);
		Object.Destroy((Object)(object)val.FindChild<TextFontFeaturesHelper>("Label ", errorIfNotFound: true));
		Object.Destroy((Object)(object)val.FindChild<LocalizationText>("Label ", errorIfNotFound: true));
		val.FindChild<TMP_Text>("Label ", errorIfNotFound: true).text = entry.Definition.Key;
		Toggle toggleComponent = val.SafeGetComponentInChildren<Toggle>(includeInactive: false);
		((UnityEvent<bool>)(object)toggleComponent.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
		{
			entry.BoxedValue = value;
		});
		OptionsMenuEnabled = (Action)Delegate.Combine(OptionsMenuEnabled, (Action)delegate
		{
			Toggle obj = toggleComponent;
			object boxedValue = entry.BoxedValue;
			bool flag = default(bool);
			int num;
			if (boxedValue is bool)
			{
				flag = (bool)boxedValue;
				num = 1;
			}
			else
			{
				num = 0;
			}
			obj.isOn = (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		});
	}

	private static TMP_InputField CreateInputField(Transform parent, Sprite background)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_003c: 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_0068: 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_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Expected O, but got Unknown
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: 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_0250: 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_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_030c: Expected O, but got Unknown
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0375: Unknown result type (might be due to invalid IL or missing references)
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("InputField (Created)");
		val.transform.SetParent(parent);
		val.layer = LayerMask.NameToLayer("UI");
		RectTransform val2 = val.AddComponent<RectTransform>();
		val2.anchorMin = new Vector2(0f, 0f);
		val2.anchorMax = new Vector2(1f, 1f);
		val2.anchoredPosition = new Vector2(0f, 0f);
		val2.offsetMin = new Vector2(0f, 0f);
		val2.offsetMax = new Vector2(0f, 0f);
		((Transform)val2).localPosition = Vector3.zero;
		((Transform)val2).localRotation = Quaternion.identity;
		((Transform)val2).localScale = Vector3.one;
		val.AddComponent<CanvasRenderer>();
		Image val3 = val.AddComponent<Image>();
		val3.sprite = background;
		TMP_InputField val4 = val.AddComponent<TMP_InputField>();
		((Selectable)val4).targetGraphic = (Graphic)(object)val3;
		GameObject val5 = new GameObject("Text Area");
		val5.transform.SetParent(val.transform);
		val5.layer = LayerMask.NameToLayer("UI");
		RectTransform val6 = val5.AddComponent<RectTransform>();
		val6.anchorMin = new Vector2(0f, 0f);
		val6.anchorMax = new Vector2(1f, 1f);
		val6.anchoredPosition = new Vector2(0f, 0f);
		val6.offsetMin = new Vector2(10f, 6f);
		val6.offsetMax = new Vector2(-10f, -7f);
		((Transform)val6).localPosition = Vector3.zero;
		((Transform)val6).localRotation = Quaternion.identity;
		((Transform)val6).localScale = Vector3.one;
		val5.AddComponent<RectMask2D>();
		GameObject val7 = new GameObject("Placeholder");
		val7.transform.SetParent(val5.transform);
		val7.layer = LayerMask.NameToLayer("UI");
		RectTransform val8 = val7.AddComponent<RectTransform>();
		val8.anchorMin = new Vector2(0f, 0f);
		val8.anchorMax = new Vector2(1f, 1f);
		val8.anchoredPosition = new Vector2(0f, 0f);
		val8.offsetMin = new Vector2(0f, 0f);
		val8.offsetMax = new Vector2(0f, 0f);
		((Transform)val8).localPosition = Vector3.zero;
		((Transform)val8).localRotation = Quaternion.identity;
		((Transform)val8).localScale = Vector3.one;
		val7.AddComponent<CanvasRenderer>();
		TextMeshProUGUI val9 = val7.AddComponent<TextMeshProUGUI>();
		((Graphic)val9).color = new Color(1f, 1f, 1f, 0.5f);
		((TMP_Text)val9).fontSize = 14f;
		((TMP_Text)val9).text = "Enter text...";
		((TMP_Text)val9).fontStyle = (FontStyles)2;
		LayoutElement val10 = val7.AddComponent<LayoutElement>();
		val10.ignoreLayout = true;
		GameObject val11 = new GameObject("Text");
		val11.transform.SetParent(val5.transform);
		val11.layer = LayerMask.NameToLayer("UI");
		RectTransform val12 = val11.AddComponent<RectTransform>();
		val12.anchorMin = new Vector2(0f, 0f);
		val12.anchorMax = new Vector2(1f, 1f);
		val12.anchoredPosition = new Vector2(0f, 0f);
		val12.offsetMin = new Vector2(0f, 0f);
		val12.offsetMax = new Vector2(0f, 0f);
		((Transform)val12).localPosition = Vector3.zero;
		((Transform)val12).localRotation = Quaternion.identity;
		((Transform)val12).localScale = Vector3.one;
		val11.AddComponent<CanvasRenderer>();
		TextMeshProUGUI val13 = val11.AddComponent<TextMeshProUGUI>();
		((Graphic)val13).color = new Color(1f, 1f, 1f, 1f);
		((TMP_Text)val13).fontSize = 14f;
		((TMP_Text)val13).extraPadding = true;
		val4.textViewport = val6;
		val4.textComponent = val11.GetComponent<TMP_Text>();
		val4.placeholder = (Graphic)(object)val7.GetComponent<TMP_Text>();
		val4.textViewport = val6;
		return val4;
	}
}
public class ModPanel : MonoBehaviour
{
	private void OnEnable()
	{
		ModMenuTab.OptionsMenuEnabled?.Invoke();
	}
}
public class ResolveEffectBuilder : AResolveEffectBuilder<ResolveEffectModel>
{
	public ResolveEffectBuilder(string guid, string name, string iconPath)
		: base(guid, name, iconPath)
	{
	}
}
public static class EffectExtensions
{
	public static List<EffectDrop> ToEffectDrops(this IEnumerable<NameToAmount> collection)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Expected O, but got Unknown
		List<EffectDrop> list = new List<EffectDrop>();
		foreach (NameToAmount item in collection)
		{
			if (SO.Settings.ContainsEffect(item.Name))
			{
				EffectModel effect = SO.Settings.GetEffect(item.Name);
				EffectDrop val = new EffectDrop();
				val.reward = effect;
				val.chance = item.Weight;
				list.Add(val);
			}
			else
			{
				Plugin.Log.LogWarning((object)("Can't find effect " + item.Name));
			}
		}
		return list;
	}
}
public static class EffectFactory
{
	public static T NewHookedEffect<T>(IEffectBuilder builder) where T : EffectModel
	{
		T val = ScriptableObject.CreateInstance<T>();
		((EffectModel)val).description = builder.Model.description;
		((EffectModel)val).displayName = builder.Model.displayName;
		((EffectModel)val).label = builder.Model.label;
		((EffectModel)val).blockedBy = Array.Empty<EffectModel>();
		((EffectModel)val).usabilityTags = Array.Empty<ModelTag>();
		return val;
	}

	public static GlobalResolveEffectEffectModel AddHookedEffect_IncreaseResolve(IEffectBuilder builder, int resolveAmount = 1, ResolveEffectType type = 3)
	{
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		GlobalResolveEffectEffectModel val = EffectFactory.NewHookedEffect<GlobalResolveEffectEffectModel>(builder);
		val.effect = EffectManager.CreateResolveEffect<ResolveEffectModel>(builder.GUID, builder.Name + "_resolve_effect_model").Model;
		val.effect.resolve = resolveAmount;
		val.effect.description = builder.Model.description;
		val.effect.displayName = builder.Model.displayName;
		val.effect.label = builder.Model.label;
		val.effect.icon = builder.Model.GetIcon();
		val.effect.stacks = true;
		val.effect.removedByStack = false;
		val.effect.displayAsInfinite = false;
		val.effect.type = type;
		return val;
	}

	public static HostilityEffectModel AddHookedEffect_AddHostility(IEffectBuilder builder, int amount = 1)
	{
		HostilityEffectModel val = EffectFactory.NewHookedEffect<HostilityEffectModel>(builder);
		val.amount = amount;
		((EffectModel)val).description = builder.Model.description;
		((EffectModel)val).displayName = builder.Model.displayName;
		((EffectModel)val).label = builder.Model.label;
		return val;
	}
}
public class ASyncable<ATS>
{
	public virtual bool Sync()
	{
		return true;
	}

	public virtual void PostSync()
	{
	}
}
public class GenericPopupTask
{
	public enum Decision
	{
		QuitGame,
		Continue
	}

	public enum ButtonTypes
	{
		Normal,
		CTA
	}

	public class ButtonInfo
	{
		public LocaText Key;

		public LocaText OptionKey;

		public ButtonTypes Type;

		public Action OnPressed;
	}

	[CompilerGenerated]
	private sealed class <WaitForDecisionAsync>d__15 : IAsyncStateMachine
	{
		public int <>1__state;

		public AsyncUniTaskMethodBuilder <>t__builder;

		public ButtonInfo[] buttons;

		public GenericPopupTask <>4__this;

		private ReactiveProperty<GenericPopupTask> <CorruptionTask>5__1;

		private Awaiter <>u__1;

		private void MoveNext()
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			try
			{
				Awaiter awaiter;
				if (num != 0)
				{
					Plugin.Log.LogInfo((object)("Waiting for decision with " + buttons.Length + " buttons"));
					<>4__this.buttons.Clear();
					<>4__this.buttons.AddRange(buttons);
					<>4__this.decisionButton = null;
					<CorruptionTask>5__1 = Task;
					<CorruptionTask>5__1.Value = <>4__this;
					UniTask task = <>4__this.completionSource.Task;
					awaiter = ((UniTask)(ref task)).GetAwaiter();
					if (!((Awaiter)(ref awaiter)).IsCompleted)
					{
						num = (<>1__state = 0);
						<>u__1 = awaiter;
						<WaitForDecisionAsync>d__15 <WaitForDecisionAsync>d__ = this;
						((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<Awaiter, <WaitForDecisionAsync>d__15>(ref awaiter, ref <WaitForDecisionAsync>d__);
						return;
					}
				}
				else
				{
					awaiter = <>u__1;
					<>u__1 = default(Awaiter);
					num = (<>1__state = -1);
				}
				((Awaiter)(ref awaiter)).GetResult();
				<CorruptionTask>5__1.Value = null;
			}
			catch (Exception exception)
			{
				<>1__state = -2;
				<CorruptionTask>5__1 = null;
				((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
				return;
			}
			<>1__state = -2;
			<CorruptionTask>5__1 = null;
			((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult();
		}

		void IAsyncStateMachine.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			this.MoveNext();
		}

		[DebuggerHidden]
		private void SetStateMachine(IAsyncStateMachine stateMachine)
		{
		}

		void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
		{
			//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
			this.SetStateMachine(stateMachine);
		}
	}

	public static ReactiveProperty<GenericPopupTask> Task = new ReactiveProperty<GenericPopupTask>();

	public string headerKey = Keys.GenericPopup_Header_Key;

	public string descKey = Keys.GenericPopup_Description_Key;

	public object[] descArgs = new object[0];

	public string modGUID;

	public string stackTrace;

	public List<ButtonInfo> buttons = new List<ButtonInfo>();

	public ButtonInfo decisionButton;

	public UniTaskCompletionSource completionSource;

	public static GenericPopupTask ShowException(string modGUID, string description, Exception exception)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		GenericPopupTask genericPopupTask = new GenericPopupTask();
		genericPopupTask.modGUID = modGUID;
		genericPopupTask.descKey = Keys.GenericPopup_ExceptionDescription_Key;
		genericPopupTask.descArgs = new object[1] { description };
		genericPopupTask.stackTrace = exception.ToString();
		genericPopupTask.completionSource = new UniTaskCompletionSource();
		return genericPopupTask;
	}

	public static GenericPopupTask Show(string modGUID, LocaText header, LocaText description, params object[] descriptionArgs)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		GenericPopupTask genericPopupTask = new GenericPopupTask();
		genericPopupTask.modGUID = modGUID;
		genericPopupTask.headerKey = header.key;
		genericPopupTask.descKey = description.key;
		genericPopupTask.descArgs = descriptionArgs;
		genericPopupTask.completionSource = new UniTaskCompletionSource();
		return genericPopupTask;
	}

	public void WaitForDecision(params ButtonInfo[] buttons)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		UniTaskExtensions.Forget(WaitForDecisionAsync(buttons));
	}

	[AsyncStateMachine(typeof(<WaitForDecisionAsync>d__15))]
	[DebuggerStepThrough]
	public UniTask WaitForDecisionAsync(params ButtonInfo[] buttons)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		<WaitForDecisionAsync>d__15 <WaitForDecisionAsync>d__ = new <WaitForDecisionAsync>d__15();
		<WaitForDecisionAsync>d__.<>t__builder = AsyncUniTaskMethodBuilder.Create();
		<WaitForDecisionAsync>d__.<>4__this = this;
		<WaitForDecisionAsync>d__.buttons = buttons;
		<WaitForDecisionAsync>d__.<>1__state = -1;
		((AsyncUniTaskMethodBuilder)(ref <WaitForDecisionAsync>d__.<>t__builder)).Start<<WaitForDecisionAsync>d__15>(ref <WaitForDecisionAsync>d__);
		return ((AsyncUniTaskMethodBuilder)(ref <WaitForDecisionAsync>d__.<>t__builder)).Task;
	}
}
public static class Placeholders
{
	private static Sprite EffectIconCache = TextureHelper.GetWhiteTexture(TextureHelper.SpriteType.EffectIcon).ConvertTexture(TextureHelper.SpriteType.EffectIcon, (FilterMode)0);

	private static Texture2D BlackTextureCache = TextureHelper.GetTexture(Color.black, 1, 1);

	public static readonly string DisplayNameKey = LocalizationManager.NewString("API", "placeHolders", "displayName", "Missing DisplayName", (SystemLanguage)10);

	public static readonly string PluralDisplayNameKey = LocalizationManager.NewString("API", "placeHolders", "pluralDisplayName", "Missing PluralDisplayName", (SystemLanguage)10);

	public static readonly string DescriptionKey = LocalizationManager.NewString("API", "placeHolders", "description", "Missing Description", (SystemLanguage)10);

	public static readonly string LabelKey = LocalizationManager.NewString("API", "placeHolders", "label", "Missing Label", (SystemLanguage)10);

	public static readonly string PassiveEffectDescKey = "Common_None_NoDash";

	public static readonly string TownNameKey = LocalizationManager.NewString("API", "placeHolders", "label", "Missing Town Name", (SystemLanguage)10);

	public static readonly string TownDescriptionKey = LocalizationManager.NewString("API", "placeHolders", "label", "Missing Town Description", (SystemLanguage)10);

	public static Sprite EffectIcon => EffectIconCache;

	public static Texture2D BlackTexture => BlackTextureCache;

	public static LocaText DisplayName => DisplayNameKey.ToLocaText();

	public static LocaText PluralDisplayName => PluralDisplayNameKey.ToLocaText();

	public static LocaText Description => DescriptionKey.ToLocaText();

	public static LocaText LabelLocaText => LabelKey.ToLocaText();

	public static LabelModel Label => LocalizationManager.ToLabelModel(LabelKey);

	public static LocaText PassiveEffectDesc => PassiveEffectDescKey.ToLocaText();

	public static LocaText TownName => TownNameKey.ToLocaText();

	public static LocaText TownDescription => TownDescriptionKey.ToLocaText();

	public static SoundRef SoundRef
	{
		get
		{
			SoundRef val = ScriptableObject.CreateInstance<SoundRef>();
			((Object)val).name = "SoundRef Placeholder";
			val.sounds = Array.Empty<SoundModel>();
			val.indexes = Array.Empty<int>();
			return val;
		}
	}

	public static RacialSound RacialSound(RaceModel model)
	{
		RacialSound val = ScriptableObject.CreateInstance<RacialSound>();
		((Object)val).name = "RacialSound Placeholder";
		val.race = model;
		val.negativeSound = SoundRef;
		val.positiveSound = SoundRef;
		val.neutralSound = SoundRef;
		return val;
	}
}
public static class PluginInfoExtensions
{
	public class PluginManifest
	{
		public struct Dependency
		{
			public string Team;

			public string Name;

			public Version Version;
		}

		public string name;

		[JsonProperty]
		private string version_number;

		public string website_url;

		public string description;

		[JsonProperty]
		private string[] dependencies;

		public Version ManifestVersion()
		{
			Version result = new Version();
			Version.TryParse(version_number, out result);
			return result;
		}

		public Dependency[] Dependencies()
		{
			Dependency[] array = new Dependency[dependencies.Length];
			for (int i = 0; i < dependencies.Length; i++)
			{
				string[] array2 = dependencies[i].Split(new char[1] { '-' });
				Dependency dependency = default(Dependency);
				dependency.Team = array2[0];
				dependency.Name = array2[1];
				Version.TryParse(array2[2], out dependency.Version);
				array[i] = dependency;
			}
			return array;
		}
	}

	public static PluginManifest Manifest(this PluginInfo plugin)
	{
		string directoryName = Path.GetDirectoryName(plugin.Location);
		string[] files = Directory.GetFiles(directoryName, "manifest.json", SearchOption.AllDirectories);
		if (files.Length != 0)
		{
			string text = File.ReadAllText(files[0]);
			return JsonConvert.DeserializeObject<PluginManifest>(text);
		}
		return null;
	}
}
public class NaturalResourcePrefabBuilder
{
	protected readonly string m_guid;

	protected readonly string m_name;

	private NaturalResourcePrefabs m_prefabTemplate;

	private NaturalResource m_customPrefab;

	private Texture2D m_textureOverride;

	public string Name => m_name;

	public string GUID => m_guid;

	public NaturalResourcePrefabBuilder(string guid, string name)
	{
		m_guid = guid;
		m_name = name;
	}

	public NaturalResourcePrefabBuilder SetPrefabTemplate(NaturalResourcePrefabs prefabTemplate)
	{
		m_prefabTemplate = prefabTemplate;
		return this;
	}

	public void SetTexture(string texture)
	{
		m_textureOverride = TextureHelper.GetImageAsTexture(texture, (FilterMode)1);
	}

	public NaturalResource CreatePrefab()
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		NaturalResource val = null;
		if ((Object)(object)m_customPrefab != (Object)null)
		{
			SyncCustomPrefab();
			val = m_customPrefab;
		}
		else
		{
			val = m_prefabTemplate.ToNaturalResource();
		}
		string text = m_guid + "_" + m_name;
		NaturalResourcePrefabs key = GUIDManager.Get<NaturalResourcePrefabs>(m_guid, m_name);
		NaturalResourcePrefabsExtensions.TypeToInternalName[key] = text;
		NaturalResource val2 = Object.Instantiate<NaturalResource>(val, Plugin.PrefabContainer);
		((Object)val2).name = text;
		((Component)val2).transform.localPosition = Vector3.zero;
		((Component)val2).transform.localRotation = Quaternion.identity;
		((Component)val2).transform.localScale = Vector3.one;
		if ((Object)(object)m_textureOverride != (Object)null)
		{
			MeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val3 in componentsInChildren)
			{
				Material val4 = new Material(((Renderer)val3).material);
				val4.SetTexture("Texture2D_46400E5F", (Texture)(object)m_textureOverride);
				((Renderer)val3).material = val4;
			}
		}
		return val2;
	}

	public NaturalResourcePrefabBuilder CreateNewPrefab(AssetBundle bundle, string prefabName)
	{
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		if (!AssetBundleHelper.TryGet<GameObject>(bundle, prefabName, out GameObject prefab))
		{
			Plugin.Log.LogError((object)("Failed to load prefab " + prefabName + " from asset bundle " + ((Object)bundle).name));
			return this;
		}
		GameObject val = Object.Instantiate<GameObject>(prefab, Plugin.PrefabContainer);
		((Object)val).name = m_guid + "_" + m_name;
		MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
		foreach (MeshRenderer val2 in componentsInChildren)
		{
			MeshShadowController orAdd = ((Component)val2).gameObject.GetOrAdd<MeshShadowController>();
			orAdd.render = (Renderer)(object)val2;
			orAdd.disableAll = false;
		}
		NaturalResource orAdd2 = val.GetOrAdd<NaturalResource>();
		NaturalResourceView orAdd3 = val.GetOrAdd<NaturalResourceView>();
		Animator orAdd4 = val.GetOrAdd<Animator>();
		Plugin.Log.LogInfo((object)$"Created animator {orAdd4} on {((Object)(object)orAdd4).FullName()}");
		GameObject gameObject = ((Component)val.transform.FindChildRecursive("Deco")).gameObject;
		MeshShadowController[] componentsInChildren2 = gameObject.GetComponentsInChildren<MeshShadowController>();
		foreach (MeshShadowController val3 in componentsInChildren2)
		{
			val3.disableAll = true;
		}
		GameObject gameObject2 = ((Component)val.transform.FindChildRecursive("AnimationsHooks")).gameObject;
		VillagersPositioner orAdd5 = gameObject2.GetOrAdd<VillagersPositioner>();
		orAdd5.hooks = (AnimationHook[])(object)new AnimationHook[gameObject2.transform.childCount];
		for (int k = 0; k < gameObject2.transform.childCount; k++)
		{
			Transform child = gameObject2.transform.GetChild(k);
			AnimationHook orAdd6 = ((Component)child).gameObject.GetOrAdd<AnimationHook>();
			orAdd6.type = (AnimHookType)40;
			orAdd5.hooks[k] = orAdd6;
		}
		orAdd2.view = orAdd3;
		orAdd2.villagersPositioner = orAdd5;
		orAdd2.depletionAnimLength = 3f;
		orAdd3.toRotate = val.transform.FindChildRecursive("ToRotate");
		orAdd3.uiParent = val.transform.FindChildRecursive("UI");
		orAdd3.animator = orAdd4;
		Plugin.Log.LogInfo((object)("Assigned animator to view on " + ((Object)(object)orAdd3).FullName()));
		orAdd3.elements = ((Component)orAdd3.toRotate.FindChildRecursive("Elements")).gameObject;
		orAdd3.meshRenderers = orAdd3.elements.GetComponentsInChildren<MeshShadowController>(true);
		orAdd3.randomRotation = true;
		orAdd3.minScale = 0.9f;
		orAdd3.maxScale = 1.2f;
		orAdd3.minXPos = -0.1f;
		orAdd3.maxXPos = 0.1f;
		orAdd3.minZPos = -0.1f;
		orAdd3.maxZPos = 0.1f;
		orAdd3.dustPrefab = null;
		orAdd3.dustLocalScale = new Vector3(1.25f, 0.8f, 1.25f);
		orAdd3.dustPosition = new Vector3(0.95f, 0f, 0f);
		orAdd3.dustDelay = 1f;
		m_customPrefab = orAdd2;
		return this;
	}

	private void SyncCustomPrefab()
	{
		Animator component = ((Component)m_customPrefab).GetComponent<Animator>();
		if ((Object)(object)component.runtimeAnimatorController == (Object)null)
		{
			Plugin.Log.LogInfo((object)("Syncing animator on " + ((Object)(object)component).FullName()));
			NaturalResource go = NaturalResourcePrefabs.Bay_Tree_1.ToNaturalResource();
			component.runtimeAnimatorController = ((Component)(object)go).SafeGetComponent<Animator>().runtimeAnimatorController;
		}
		NaturalResourceView val = ((Component)(object)m_customPrefab).SafeGetComponent<NaturalResourceView>();
		if ((Object)(object)val.dustPrefab == (Object)null)
		{
			Plugin.Log.LogInfo((object)("Syncing dust prefab on " + ((Object)(object)val).FullName()));
			NaturalResource go2 = NaturalResourcePrefabs.Bay_Tree_1.ToNaturalResource();
			val.dustPrefab = ((Component)(object)go2).SafeGetComponent<NaturalResourceView>().dustPrefab;
		}
		Plugin.Log.LogInfo((object)"Synced Custom prefab!");
	}
}
public class RaceCharacteristicRef
{
	public BuildingTagTypes Tag;

	public VillagerPerkTypes Effect;

	public EffectTypes GlobalEffect;

	public BuildingPerkTypes BuildingPerk;
}
public class CSVBuilder
{
	public struct Header
	{
		public string Name;

		public int Order;
	}

	private List<Dictionary<string, string>> values = new List<Dictionary<string, string>>();

	public List<Header> orderedHeaders = new List<Header>();

	public Dictionary<string, string> currentRow = new Dictionary<string, string>();

	public int columnIndex = 0;

	public void AddValue(string header, string value, int order)
	{
		if (((columnIndex < orderedHeaders.Count) ? orderedHeaders[columnIndex] : default(Header)).Name != header)
		{
			int num = orderedHeaders.FindIndex((Header a) => a.Name == header);
			if (num == -1)
			{
				Header item = default(Header);
				item.Name = header;
				item.Order = order;
				int i;
				for (i = 0; i < orderedHeaders.Count && orderedHeaders[i].Order <= order; i++)
				{
				}
				orderedHeaders.Insert(i, item);
				columnIndex = i;
			}
			else
			{
				columnIndex = num;
			}
		}
		currentRow[header] = value;
		columnIndex++;
	}

	public void NextRow()
	{
		values.Add(currentRow);
		currentRow = new Dictionary<string, string>();
		columnIndex = 0;
	}

	public void SaveAsCSV(string path)
	{
		if (currentRow.Count > 0)
		{
			NextRow();
		}
		string directoryName = Path.GetDirectoryName(path);
		if (!Directory.Exists(directoryName))
		{
			Directory.CreateDirectory(directoryName);
		}
		Plugin.Log.LogInfo((object)("Saving CSV to: " + path));
		using StreamWriter streamWriter = new StreamWriter(path);
		streamWriter.WriteLine(string.Join(",", orderedHeaders.Select((Header a) => a.Name)));
		for (int i = 0; i < values.Count; i++)
		{
			Dictionary<string, string> dictionary = values[i];
			string text = "";
			for (int j = 0; j < orderedHeaders.Count; j++)
			{
				if (!dictionary.TryGetValue(orderedHeaders[j].Name, out var value) || value == null)
				{
					value = "";
				}
				if (value.IndexOf(",") >= 0)
				{
					value = "\"" + value + "\"";
				}
				if (j > 0)
				{
					text += ",";
				}
				text += value;
			}
			streamWriter.WriteLine(text);
		}
	}
}
namespace ATS_API
{
	[HarmonyPatch]
	[BepInPlugin("API", "API", "3.1.0")]
	internal class Plugin : BaseUnityPlugin
	{
		public static string PluginDirectory;

		public static Plugin Instance;

		public static ManualLogSource Log;

		private Harmony harmony;

		internal static AssetBundle ATS_API_Bundle;

		internal static AssetBundle ATS_API_TerrainBundle;

		internal static Transform PrefabContainer;

		public static string ExportPath => Path.Combine(PluginDirectory, "Exports");

		public static bool CoreGameLoaded { get; internal set; }

		public static event Action PostTick;

		private void Awake()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Against the Storm v" + Application.version));
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "API");
			PluginDirectory = ((BaseUnityPlugin)this).Info.Location.Replace("API.dll", "");
			string text = "2021.3.27f1";
			Assert.IsEqual(Application.unityVersion, text, "The Unity Version has changed! Expected: " + text + ", Got: " + Application.unityVersion);
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			PrefabContainer = new GameObject("ATS_API_PrefabContainer").transform;
			PrefabContainer.SetParent(((Component)this).transform);
			ComponentExtensions.SetActive((Component)(object)PrefabContainer, false);
			AssetBundleHelper.TryLoadAssetBundleFromFile("ats_api", out ATS_API_Bundle);
			AssetBundleHelper.TryLoadAssetBundleFromFile("customterrain", out ATS_API_TerrainBundle);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin API is loaded!");
		}

		private void LateUpdate()
		{
			if (CoreGameLoaded)
			{
				Hotkeys.Update();
				DecorationManager.Tick();
				DifficultyManager.Tick();
				GoodsManager.Tick();
				EffectManager.Tick();
				TraderManager.Tick();
				OrdersManager.Tick();
				NaturalResourceManager.Tick();
				BiomeManager.Tick();
				TextMeshProManager.Tick();
				RecipeManager.Tick();
				RaceManager.Tick();
				BuildingManager.Tick();
				RaceNeedManager.Tick();
				MetaRewardManager.Tick();
				LocalizationManager.Tick();
				if (Plugin.PostTick != null)
				{
					Plugin.PostTick();
					Plugin.PostTick = null;
				}
			}
		}

		[HarmonyPatch(typeof(MainController), "InitReferences")]
		[HarmonyPostfix]
		private static void PostSetupMainController()
		{
			LocalizationManager.Instantiate();
			DecorationManager.Instantiate();
			DifficultyManager.Instantiate();
			RecipeManager.Instantiate();
			GoodsManager.Instantiate();
			EffectManager.Instantiate();
			TraderManager.Instantiate();
			OrdersManager.Instantiate();
			NaturalResourceManager.Instantiate();
			BiomeManager.Instantiate();
			TextMeshProManager.Instantiate();
			BuildingManager.Instantiate();
			RaceManager.Instantiate();
			RaceNeedManager.Instantiate();
			MetaRewardManager.Instantiate();
			EventBus.OnInitReferences.Invoke();
		}

		[HarmonyPatch(typeof(MetaStateService), "CheckForInitialLevel")]
		[HarmonyPostfix]
		private static void MetaStateServiceSetup(MetaStateService __instance)
		{
			foreach (NewBuildingData newBuilding in BuildingManager.NewBuildings)
			{
				if (!__instance.Content.buildings.Contains(((Object)newBuilding.BuildingModel).name))
				{
					__instance.Content.buildings.Add(((Object)newBuilding.BuildingModel).name);
				}
				if (!__instance.Content.essentialBuildings.Contains(((Object)newBuilding.BuildingModel).name))
				{
					__instance.Content.essentialBuildings.Add(((Object)newBuilding.BuildingModel).name);
				}
			}
		}

		[HarmonyPatch(typeof(GameController), "StartGame")]
		[HarmonyPostfix]
		private static void HookEveryGameStart()
		{
			bool t = MB.GameSaveService.IsNewGame();
			EventBus.OnStartGame.Invoke(t);
		}

		[HarmonyPatch(typeof(GameContentService), "GetOptionalBuildings")]
		[HarmonyPostfix]
		private static void GetOptionalBuildings(GameContentService __instance, ref IEnumerable<BuildingModel> __result)
		{
			List<BuildingModel> list = new List<BuildingModel>(__result);
			foreach (NewBuildingData newBuilding in BuildingManager.NewBuildings)
			{
				if (!list.Contains(newBuilding.BuildingModel))
				{
					list.Add(newBuilding.BuildingModel);
				}
			}
			__result = list;
		}
	}
	internal static class Configs
	{
		private static ConfigEntry<bool> m_ExportEnumTypes = Bind("Exporting", "Export Enum classes", defaultValue: false, "When set to true the API will export all types of data as .cs files when the game opens for the API to use in the project.\nThe files will be exported to 'BepInEx/plugins/ATS_API_Devs-API/Exports'");

		private static ConfigEntry<bool> m_ExportCSVs = Bind("Exporting", "Export CSVs", defaultValue: false, "When set to true the API will export various kinds of data when the game opens as .csv files for anyone to browse.\nThe files will be exported to 'BepInEx/plugins/ATS_API_Devs-API/Exports'");

		public static bool ExportEnumTypes
		{
			get
			{
				return m_ExportEnumTypes.Value;
			}
			set
			{
				m_ExportEnumTypes.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool ExportCSVs
		{
			get
			{
				return m_ExportCSVs.Value;
			}
			set
			{
				m_ExportCSVs.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		private static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			return ((BaseUnityPlugin)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[HarmonyPatch]
	public static class Hotkeys
	{
		public class Hotkey
		{
			public string keyName;

			public string displayName;

			public List<string> codes;

			public Action<CallbackContext> onCallback;

			public InputAction action;
		}

		[Serializable]
		private class SavedInputMap
		{
			public string modName;

			public string actionMap;

			public string bindings;
		}

		public static InputActionAsset MasterInputAsset;

		private static Dictionary<string, List<Hotkey>> pendingHotkeys = new Dictionary<string, List<Hotkey>>();

		private static Dictionary<string, InputActionMap> modNameToActionMaps = new Dictionary<string, InputActionMap>();

		private static Dictionary<string, Hotkey> modNameActionNameToAddedHotkey = new Dictionary<string, Hotkey>();

		private static HashSet<InputAction> activeActions = new HashSet<InputAction>();

		private static HashSet<string> activeActionMaps = new HashSet<string>();

		private static readonly Dictionary<KeyCode, string> KeyCodeToPathMap = new Dictionary<KeyCode, string>
		{
			{
				(KeyCode)32,
				"<Keyboard>/space"
			},
			{
				(KeyCode)306,
				"<Keyboard>/leftCtrl"
			},
			{
				(KeyCode)305,
				"<Keyboard>/rightCtrl"
			},
			{
				(KeyCode)304,
				"<Keyboard>/leftShift"
			},
			{
				(KeyCode)303,
				"<Keyboard>/rightShift"
			},
			{
				(KeyCode)97,
				"<Keyboard>/a"
			},
			{
				(KeyCode)98,
				"<Keyboard>/b"
			},
			{
				(KeyCode)99,
				"<Keyboard>/c"
			},
			{
				(KeyCode)100,
				"<Keyboard>/d"
			},
			{
				(KeyCode)101,
				"<Keyboard>/e"
			},
			{
				(KeyCode)102,
				"<Keyboard>/f"
			},
			{
				(KeyCode)103,
				"<Keyboard>/g"
			},
			{
				(KeyCode)104,
				"<Keyboard>/h"
			},
			{
				(KeyCode)105,
				"<Keyboard>/i"
			},
			{
				(KeyCode)106,
				"<Keyboard>/j"
			},
			{
				(KeyCode)107,
				"<Keyboard>/k"
			},
			{
				(KeyCode)108,
				"<Keyboard>/l"
			},
			{
				(KeyCode)109,
				"<Keyboard>/m"
			},
			{
				(KeyCode)110,
				"<Keyboard>/n"
			},
			{
				(KeyCode)111,
				"<Keyboard>/o"
			},
			{
				(KeyCode)112,
				"<Keyboard>/p"
			},
			{
				(KeyCode)113,
				"<Keyboard>/q"
			},
			{
				(KeyCode)114,
				"<Keyboard>/r"
			},
			{
				(KeyCode)115,
				"<Keyboard>/s"
			},
			{
				(KeyCode)116,
				"<Keyboard>/t"
			},
			{
				(KeyCode)117,
				"<Keyboard>/u"
			},
			{
				(KeyCode)118,
				"<Keyboard>/v"
			},
			{
				(KeyCode)119,
				"<Keyboard>/w"
			},
			{
				(KeyCode)120,
				"<Keyboard>/x"
			},
			{
				(KeyCode)121,
				"<Keyboard>/y"
			},
			{
				(KeyCode)122,
				"<Keyboard>/z"
			},
			{
				(KeyCode)27,
				"<Keyboard>/escape"
			},
			{
				(KeyCode)13,
				"<Keyboard>/enter"
			},
			{
				(KeyCode)8,
				"<Keyboard>/backspace"
			},
			{
				(KeyCode)9,
				"<Keyboard>/tab"
			},
			{
				(KeyCode)127,
				"<Keyboard>/delete"
			},
			{
				(KeyCode)273,
				"<Keyboard>/upArrow"
			},
			{
				(KeyCode)274,
				"<Keyboard>/downArrow"
			},
			{
				(KeyCode)276,
				"<Keyboard>/leftArrow"
			},
			{
				(KeyCode)275,
				"<Keyboard>/rightArrow"
			},
			{
				(KeyCode)308,
				"<Keyboard>/leftAlt"
			},
			{
				(KeyCode)307,
				"<Keyboard>/rightAlt"
			},
			{
				(KeyCode)277,
				"<Keyboard>/insert"
			},
			{
				(KeyCode)278,
				"<Keyboard>/home"
			},
			{
				(KeyCode)279,
				"<Keyboard>/end"
			},
			{
				(KeyCode)280,
				"<Keyboard>/pageUp"
			},
			{
				(KeyCode)281,
				"<Keyboard>/pageDown"
			},
			{
				(KeyCode)300,
				"<Keyboard>/numLock"
			},
			{
				(KeyCode)301,
				"<Keyboard>/capsLock"
			},
			{
				(KeyCode)302,
				"<Keyboard>/scrollLock"
			},
			{
				(KeyCode)282,
				"<Keyboard>/f1"
			},
			{
				(KeyCode)283,
				"<Keyboard>/f2"
			},
			{
				(KeyCode)284,
				"<Keyboard>/f3"
			},
			{
				(KeyCode)285,
				"<Keyboard>/f4"
			},
			{
				(KeyCode)286,
				"<Keyboard>/f5"
			},
			{
				(KeyCode)287,
				"<Keyboard>/f6"
			},
			{
				(KeyCode)288,
				"<Keyboard>/f7"
			},
			{
				(KeyCode)289,
				"<Keyboard>/f8"
			},
			{
				(KeyCode)290,
				"<Keyboard>/f9"
			},
			{
				(KeyCode)291,
				"<Keyboard>/f10"
			},
			{
				(KeyCode)292,
				"<Keyboard>/f11"
			},
			{
				(KeyCode)293,
				"<Keyboard>/f12"
			},
			{
				(KeyCode)19,
				"<Keyboard>/pause"
			},
			{
				(KeyCode)316,
				"<Keyboard>/printScreen"
			},
			{
				(KeyCode)256,
				"<Keyboard>/numpad0"
			},
			{
				(KeyCode)257,
				"<Keyboard>/numpad1"
			},
			{
				(KeyCode)258,
				"<Keyboard>/numpad2"
			},
			{
				(KeyCode)259,
				"<Keyboard>/numpad3"
			},
			{
				(KeyCode)260,
				"<Keyboard>/numpad4"
			},
			{
				(KeyCode)261,
				"<Keyboard>/numpad5"
			},
			{
				(KeyCode)262,
				"<Keyboard>/numpad6"
			},
			{
				(KeyCode)263,
				"<Keyboard>/numpad7"
			},
			{
				(KeyCode)264,
				"<Keyboard>/numpad8"
			},
			{
				(KeyCode)265,
				"<Keyboard>/numpad9"
			},
			{
				(KeyCode)271,
				"<Keyboard>/numpadEnter"
			},
			{
				(KeyCode)270,
				"<Keyboard>/numpadPlus"
			},
			{
				(KeyCode)269,
				"<Keyboard>/numpadMinus"
			},
			{
				(KeyCode)268,
				"<Keyboard>/numpadMultiply"
			},
			{
				(KeyCode)267,
				"<Keyboard>/numpadDivide"
			},
			{
				(KeyCode)266,
				"<Keyboard>/numpadPeriod"
			},
			{
				(KeyCode)272,
				"<Keyboard>/numpadEquals"
			},
			{
				(KeyCode)126,
				"<Keyboard>/backquote"
			},
			{
				(KeyCode)45,
				"<Keyboard>/minus"
			},
			{
				(KeyCode)61,
				"<Keyboard>/equals"
			},
			{
				(KeyCode)91,
				"<Keyboard>/leftBracket"
			},
			{
				(KeyCode)93,
				"<Keyboard>/rightBracket"
			},
			{
				(KeyCode)59,
				"<Keyboard>/semicolon"
			},
			{
				(KeyCode)39,
				"<Keyboard>/quote"
			},
			{
				(KeyCode)44,
				"<Keyboard>/comma"
			},
			{
				(KeyCode)46,
				"<Keyboard>/period"
			},
			{
				(KeyCode)47,
				"<Keyboard>/slash"
			},
			{
				(KeyCode)92,
				"<Keyboard>/backslash"
			},
			{
				(KeyCode)49,
				"<Keyboard>/1"
			},
			{
				(KeyCode)50,
				"<Keyboard>/2"
			},
			{
				(KeyCode)51,
				"<Keyboard>/3"
			},
			{
				(KeyCode)52,
				"<Keyboard>/4"
			},
			{
				(KeyCode)53,
				"<Keyboard>/5"
			},
			{
				(KeyCode)54,
				"<Keyboard>/6"
			},
			{
				(KeyCode)55,
				"<Keyboard>/7"
			},
			{
				(KeyCode)56,
				"<Keyboard>/8"
			},
			{
				(KeyCode)57,
				"<Keyboard>/9"
			},
			{
				(KeyCode)48,
				"<Keyboard>/0"
			}
		};

		private static string CustomBindingsPath => Path.Combine(Application.persistentDataPath, "API");

		public static InputAction GetHotkeyAction(string modName, string actionName)
		{
			if (modNameToActionMaps.TryGetValue(modName, out var value))
			{
				return value.FindAction(actionName, false);
			}
			return null;
		}

		public static void Update()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if ((Object)(object)MasterInputAsset == (Object)null || pendingHotkeys.Count == 0)
			{
				return;
			}
			MasterInputAsset.Disable();
			foreach (KeyValuePair<string, List<Hotkey>> pendingHotkey in pendingHotkeys)
			{
				activeActionMaps.Add(pendingHotkey.Key);
				InputActionMap val = MasterInputAsset.FindActionMap(pendingHotkey.Key, false);
				if (val == null)
				{
					val = new InputActionMap(pendingHotkey.Key);
					InputActionSetupExtensions.AddActionMap(MasterInputAsset, val);
				}
				modNameToActionMaps[pendingHotkey.Key] = val;
				foreach (Hotkey item in pendingHotkey.Value)
				{
					AddHotkey(pendingHotkey.Key, val, item);
				}
			}
			pendingHotkeys.Clear();
			MasterInputAsset.Enable();
		}

		public static Hotkey New(string guid, string keyName, string displayName, List<KeyCode> codes, Action onPress = null, Action onRelease = null)
		{
			Action<CallbackContext> onCallback = null;
			if (onPress != null || onRelease != null)
			{
				onCallback = delegate(CallbackContext ctx)
				{
					if (((CallbackContext)(ref ctx)).performed)
					{
						onPress?.Invoke();
					}
					else if (((CallbackContext)(ref ctx)).canceled)
					{
						onRelease?.Invoke();
					}
				};
			}
			Hotkey hotkey = new Hotkey();
			hotkey.keyName = keyName;
			hotkey.displayName = displayName;
			hotkey.codes = KeyCodesToString(codes);
			hotkey.onCallback = onCallback;
			return Add(guid, hotkey);
		}

		public static Hotkey New(string modName, string keyName, string displayName, List<KeyCode> codes, Action<CallbackContext> callback = null)
		{
			Hotkey hotkey = new Hotkey();
			hotkey.keyName = keyName;
			hotkey.displayName = displayName;
			hotkey.codes = KeyCodesToString(codes);
			hotkey.onCallback = callback;
			Add(modName, hotkey);
			return hotkey;
		}

		public static Hotkey Add(string modName, Hotkey hotkey)
		{
			LogInfo("Registering key " + hotkey.keyName + " with code " + string.Join(",", hotkey.codes));
			if (!pendingHotkeys.TryGetValue(modName, out var value))
			{
				value = new List<Hotkey>();
				pendingHotkeys.Add(modName, value);
			}
			value.Add(hotkey);
			return hotkey;
		}

		private static void AddHotkey(string modName, InputActionMap actionMap, Hotkey hotkey)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			List<string> codes = hotkey.codes;
			string keyName = hotkey.keyName;
			Action<CallbackContext> onCallback = hotkey.onCallback;
			string key = modName + "_" + keyName;
			modNameActionNameToAddedHotkey[key] = hotkey;
			InputAction val = ((IEnumerable<InputAction>)(object)actionMap.actions).FirstOrDefault((Func<InputAction, bool>)((InputAction a) => a.name == keyName));
			if (val == null)
			{
				CompositeSyntax val2;
				if (codes.Count == 1)
				{
					val = InputActionSetupExtensions.AddAction(actionMap, keyName, (InputActionType)0, codes[0] ?? "", (string)null, (string)null, (string)null, (string)null);
				}
				else if (codes.Count == 2)
				{
					val = InputActionSetupExtensions.AddAction(actionMap, keyName, (InputActionType)0, (string)null, (string)null, (string)null, (string)null, (string)null);
					val2 = InputActionSetupExtensions.AddCompositeBinding(val, "OneModifier", (string)null, (string)null);
					val2 = ((CompositeSyntax)(ref val2)).With("Modifier", codes[0] ?? "", (string)null, (string)null);
					((CompositeSyntax)(ref val2)).With("Binding", codes[1] ?? "", (string)null, (string)null);
				}
				else
				{
					if (codes.Count != 3)
					{
						LogError("More than 3 key codes are not supported.");
						return;
					}
					val = InputActionSetupExtensions.AddAction(actionMap, keyName, (InputActionType)0, (string)null, (string)null, (string)null, (string)null, (string)null);
					val2 = InputActionSetupExtensions.AddCompositeBinding(val, "TwoModifiers", (string)null, (string)null);
					val2 = ((CompositeSyntax)(ref val2)).With("Modifier1", codes[0] ?? "", (string)null, (string)null);
					val2 = ((CompositeSyntax)(ref val2)).With("Modifier2", codes[1] ?? "", (string)null, (string)null);
					((CompositeSyntax)(ref val2)).With("Binding", codes[2] ?? "", (string)null, (string)null);
				}
			}
			if (onCallback != null)
			{
				CallbackAction(val, keyName, onCallback);
			}
			hotkey.action = val;
			activeActions.Add(val);
		}

		private static void CallbackAction(InputAction action, string keyName, Action<CallbackContext> callback)
		{
			action.performed += delegate(CallbackContext ctx)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				LogInfo(keyName + " action performed!");
				callback(ctx);
			};
			action.canceled += delegate(CallbackContext ctx)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				LogInfo(keyName + " action canceled!");
				callback(ctx);
			};
			action.started += delegate(CallbackContext ctx)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				LogInfo(keyName + " action started!");
				callback(ctx);
			};
		}

		private static List<string> KeyCodesToString(List<KeyCode> codes)
		{
			//IL_0013: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			foreach (KeyCode code in codes)
			{
				KeyCode current = code;
				if (KeyCodeToPathMap.TryGetValue(current, out var value))
				{
					list.Add(value);
				}
				else
				{
					list.Add(((object)(KeyCode)(ref current)).ToString());
				}
			}
			return list;
		}

		public static bool IsActionActive(InputAction action)
		{
			return activeActions.Contains(action);
		}

		private static void LogError(string message)
		{
			Plugin.Log.LogError((object)message);
		}

		private static void LogInfo(string message)
		{
			Plugin.Log.LogInfo((object)message);
		}

		private static void LogWarning(string message)
		{
			Plugin.Log.LogWarning((object)message);
		}

		[Obsolete("Use Hotkeys.New() instead")]
		public static void RegisterKey(string modName, string keyName, string displayName, List<KeyCode> codes, Action<CallbackContext> callback = null)
		{
			New(modName, keyName, displayName, codes, callback);
		}

		[Obsolete("Use Hotkeys.New() instead")]
		public static void RegisterKey(string modName, string keyName, string displayName, List<KeyCode> codes, Action onPress = null, Action onRelease = null)
		{
			New(modName, keyName, displayName, codes, onPress, onRelease);
		}

		[Obsolete("Use Hotkeys.New() instead")]
		public static void RegisterKey(string modName, Hotkey hotkey)
		{
			Add(modName, hotkey);
		}

		[HarmonyPatch(typeof(KeyBindingsPanel), "OnEnable")]
		[HarmonyPrefix]
		public static void KeyBindingsPanel_Start_Postfix(KeyBindingsPanel __instance)
		{
			//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)
			ModdedKeyboardSlots[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ModdedKeyboardSlots>(true);
			foreach (KeyValuePair<string, InputActionMap> pair in modNameToActionMaps)
			{
				if (!activeActionMaps.Contains(pair.Key))
				{
					continue;
				}
				InputActionMap val = MasterInputAsset.FindActionMap(pair.Key, false);
				if (val != null && val.actions.Count != 0)
				{
					ModdedKeyboardSlots moddedKeyboardSlots = componentsInChildren.FirstOrDefault((ModdedKeyboardSlots a) => a.ModName == pair.Key);
					if ((Object)(object)moddedKeyboardSlots == (Object)null)
					{
						Transform parent = ((Component)__instance.slots[0]).transform.parent;
						Transform val2 = Object.Instantiate<Transform>(parent, parent.parent);
						((Object)((Component)val2).gameObject).name = "Modded";
						moddedKeyboardSlots = ((Component)val2).gameObject.AddComponent<ModdedKeyboardSlots>();
						moddedKeyboardSlots.Initialize(pair.Key, val2);
						Transform val3 = val2.Find("Header");
						TMP_Text component = ((Component)val3).GetComponent<TMP_Text>();
						Object.Destroy((Object)(object)((Component)val3).GetComponent<LocalizationText>());
						Object.Destroy((Object)(object)((Component)val3).GetComponent<TextFontFeaturesHelper>());
						component.text = pair.Key;
					}
				}
			}
		}

		[HarmonyPatch(typeof(KeyBindingsPanel), "SetUpSlots")]
		[HarmonyPostfix]
		public static void KeyBindingsPanel_SetUpSlots_Postfix(KeyBindingsPanel __instance)
		{
			ModdedKeyboardSlots[] source = ((Component)(object)__instance).SafeGetComponentsInChildren<ModdedKeyboardSlots>(includeInactive: true);
			foreach (KeyValuePair<string, InputActionMap> pair in modNameToActionMaps)
			{
				InputActionMap val = MasterInputAsset.FindActionMap(pair.Key, false);
				if (val != null)
				{
					ModdedKeyboardSlots moddedKeyboardSlots = source.FirstOrDefault((ModdedKeyboardSlots a) => a.ModName == pair.Key);
					if (!((Object)(object)moddedKeyboardSlots == (Object)null))
					{
						moddedKeyboardSlots.SetupKeyboardSlots(val, __instance);
					}
				}
			}
		}

		[HarmonyPatch(typeof(KeyBindingsPanel), "ResetCounter")]
		[HarmonyPostfix]
		private static void KeyBindingsPanel_ResetCounter(KeyBindingsPanel __instance)
		{
			ModdedKeyboardSlots[] array = ((Component)(object)__instance).SafeGetComponentsInChildren<ModdedKeyboardSlots>(includeInactive: true);
			if (array != null)
			{
				ModdedKeyboardSlots[] array2 = array;
				foreach (ModdedKeyboardSlots moddedKeyboardSlots in array2)
				{
					moddedKeyboardSlots.ResetCounter();
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static void HookMainControllerSetup(InputConfig __instance)
		{
			MasterInputAsset = __instance.asset;
		}

		[HarmonyPatch(typeof(KeyBindingsPanel), "EnableInput")]
		[HarmonyPostfix]
		private static void KeyBindingsPanel_EnableInput()
		{
			foreach (InputActionMap value in modNameToActionMaps.Values)
			{
				value.Enable();
			}
		}

		[HarmonyPatch(typeof(KeyBindingsPanel), "DisableInput")]
		[HarmonyPostfix]
		private static void KeyBindingsPanel_DisableInput()
		{
			foreach (InputActionMap value in modNameToActionMaps.Values)
			{
				value.Disable();
			}
		}

		[HarmonyPatch(typeof(InputService), "GetShortcutLabel")]
		[HarmonyPrefix]
		private static bool InputService_GetShortcutLabel(InputAction action, ref string __result)
		{
			string key = action.actionMap.name + "_" + action.name;
			if (modNameActionNameToAddedHotkey.TryGetValue(key, out var value))
			{
				__result = value.displayName;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(ClientPrefsService), "Reset")]
		[HarmonyPrefix]
		private static void ClientPrefsService_Reset()
		{
			foreach (InputActionMap value in modNameToActionMaps.Values)
			{
				LogInfo("Resetting input config for " + value.name);
				InputActionRebindingExtensions.RemoveAllBindingOverrides((IInputActionCollection2)(object)value);
			}
		}

		[HarmonyPatch(typeof(ClientPrefsService), "SaveInputConfig")]
		[HarmonyPostfix]
		private static void ClientPrefsService_SaveInputConfig()
		{
			if (!Directory.Exists(CustomBindingsPath))
			{
				Directory.CreateDirectory(CustomBindingsPath);
			}
			foreach (KeyValuePair<string, InputActionMap> modNameToActionMap in modNameToActionMaps)
			{
				string text = InputActionRebindingExtensions.SaveBindingOverridesAsJson((IInputActionCollection2)(object)modNameToActionMap.Value);
				LogInfo("Saving input config for " + modNameToActionMap.Key + " with value " + text);
				SavedInputMap savedInputMap = new SavedInputMap
				{
					modName = modNameToActionMap.Key,
					actionMap = modNameToActionMap.Value.ToJson(),
					bindings = text
				};
				string text2 = Path.Combine(CustomBindingsPath, modNameToActionMap.Key + ".custombindings");
				LogInfo("Saving keybinds for " + modNameToActionMap.Key + " to " + text2);
				JsonIO.SaveToFile((object)savedInputMap, text2, 3);
			}
		}

		[HarmonyPatch(typeof(ClientPrefsService), "LoadInputConfig")]
		[HarmonyPostfix]
		private static void ClientPrefsService_LoadInputConfig()
		{
			if (Serviceable.CommandLineArgsService.HasKey("-resetkeybinds"))
			{
				LogError("Clearing keybinds!");
				return;
			}
			if (!Directory.Exists(CustomBindingsPath))
			{
				LogInfo("No custombindings folder found.");
				return;
			}
			string[] files = Directory.GetFiles(CustomBindingsPath, "*.custombindings");
			if (files.Length == 0)
			{
				LogInfo("No saved custombindings files found.");
				return;
			}
			MasterInputAsset.Disable();
			string[] array = files;
			foreach (string text in array)
			{
				if (!File.Exists(text))
				{
					LogError("No saved inputs found.");
					continue;
				}
				SavedInputMap fromFile = JsonIO.GetFromFile<SavedInputMap>(text, 3);
				if (fromFile == null)
				{
					LogError("Couldn't load custom input json at path " + text);
					continue;
				}
				string actionMap = fromFile.actionMap;
				InputActionMap[] array2 = InputActionMap.FromJson(actionMap);
				if (array2.Length == 0)
				{
					LogError("Failed to load " + fromFile.modName + " action map from json: " + actionMap);
					continue;
				}
				if (array2.Length > 1)
				{
					LogWarning($"Loaded {array2.Length} action maps for {fromFile.modName}, using the first one.");
				}
				InputActionMap val = array2[0];
				if (MasterInputAsset.FindActionMap(val.name, false) == null)
				{
					InputActionSetupExtensions.AddActionMap(MasterInputAsset, val);
					InputActionRebindingExtensions.LoadBindingOverridesFromJson((IInputActionCollection2)(object)val, fromFile.bindings, true);
				}
				else
				{
					LogWarning("Action map " + val.name + " already exists. Likely another mod already loaded this so your hotkeys may differ!");
				}
				modNameToActionMaps[fromFile.modName] = val;
			}
			MasterInputAsset.Enable();
		}
	}
	[HarmonyPatch]
	public class ModdedKeyboardSlots : MonoBehaviour
	{
		public string ModName = "Hotkey";

		public List<KeyBindingSlot> slots = new List<KeyBindingSlot>();

		public int usedSlots = 0;

		public void Initialize(string hotkeyName, Transform clone)
		{
			ModName = hotkeyName;
			slots.AddRange(((Component)clone).GetComponentsInChildren<KeyBindingSlot>(true));
		}

		public void ResetCounter()
		{
			usedSlots = 0;
		}

		public void SetupKeyboardSlots(InputActionMap actionMap, KeyBindingsPanel panel)
		{
			//IL_0003: 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_000b: 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)
			Enumerator<InputAction> enumerator = actionMap.actions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					InputAction current = enumerator.Current;
					if (Hotkeys.IsActionActive(current))
					{
						KeyBindingSlot orCreate = ((BaseMB)panel).GetOrCreate<KeyBindingSlot>(slots, usedSlots++);
						orCreate.SetUp(current, (Action<InputAction>)panel.OnChangeRequested);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}
	}
	[HarmonyPatch]
	public static class TextMeshProManager
	{
		private static List<Texture2D> m_pendingSpriteAssets = new List<Texture2D>();

		private static List<TMP_SpriteAsset> m_spriteAssetLooking = new List<TMP_SpriteAsset>();

		private static bool s_instantiated = false;

		private static bool s_dirty = false;

		public static void Add(Texture2D texture, string imageName)
		{
			s_dirty = true;
			((Object)texture).name = imageName.ToLower();
			m_pendingSpriteAssets.Add(texture);
		}

		public static void Replace(Texture2D texture, string imageName)
		{
			s_dirty = true;
			((Object)texture).name = imageName.ToLower();
			m_pendingSpriteAssets.Add(texture);
		}

		public static void Instantiate()
		{
			s_instantiated = true;
			m_spriteAssetLooking.Add(TMP_Settings.defaultSpriteAsset);
		}

		public static void Tick()
		{
			if (s_dirty)
			{
				Sync();
			}
		}

		public static void Sync()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			if (!s_instantiated)
			{
				return;
			}
			Plugin.Log.LogInfo((object)("Syncing TextMeshPro sprites " + m_pendingSpriteAssets.Count));
			HashSet<Texture2D> hashSet = new HashSet<Texture2D>();
			List<Texture2D> list = new List<Texture2D>();
			foreach (Texture2D pendingSpriteAsset in m_pendingSpriteAssets)
			{
				bool flag = false;
				foreach (TMP_SpriteAsset item in m_spriteAssetLooking)
				{
					if (ReplaceAsset(item, ((Object)pendingSpriteAsset).name, pendingSpriteAsset))
					{
						flag = true;
						hashSet.Add((Texture2D)item.spriteSheet);
						break;
					}
				}
				if (!flag)
				{
					list.Add(pendingSpriteAsset);
				}
			}
			foreach (Texture2D item2 in hashSet)
			{
				item2.Apply();
			}
			if (list.Count > 0)
			{
				TMP_SpriteAsset val = TMPHelpers.CreateSpriteAsset(list);
				((Object)val).name = "FallbackSpriteAsset_" + m_spriteAssetLooking.Count;
				TMP_Settings.defaultSpriteAsset.fallbackSpriteAssets.Add(val);
				m_spriteAssetLooking.Add(val);
			}
			m_pendingSpriteAssets.Clear();
			s_dirty = false;
		}

		private static bool ReplaceAsset(TMP_SpriteAsset asset, string spriteName, Texture2D texture2D)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00a2: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			foreach (TMP_SpriteCharacter item in asset.spriteCharacterTable)
			{
				if (item.name != spriteName)
				{
					continue;
				}
				Texture2D val = (Texture2D)asset.spriteSheet;
				if (!((Texture)val).isReadable)
				{
					Texture2D readableTexture = TextureHelper.GetReadableTexture(val);
					((Object)readableTexture).name = ((Object)val).name;
					val = (Texture2D)(object)(asset.spriteSheet = (Texture)(object)readableTexture);
					((TMP_Asset)asset).material.SetTexture("_MainTex", (Texture)(object)readableTexture);
				}
				Glyph glyph = ((TMP_TextElement)item).glyph;
				GlyphRect glyphRect = glyph.glyphRect;
				int x = ((GlyphRect)(ref glyphRect)).x;
				glyphRect = glyph.glyphRect;
				int y = ((GlyphRect)(ref glyphRect)).y;
				glyphRect = glyph.glyphRect;
				int width = ((GlyphRect)(ref glyphRect)).width;
				glyphRect = glyph.glyphRect;
				int height = ((GlyphRect)(ref glyphRect)).height;
				Texture2D val2 = null;
				val2 = ((((Texture)texture2D).width != width || ((Texture)texture2D).height != height) ? TextureHelper.ResizeTexture(texture2D, width, height) : texture2D);
				val.SetPixels(x, y, width, height, val2.GetPixels());
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch]
	public class WIKI
	{
		private class NameComparer : IEqualityComparer<(string name, string enu, string locale)>
		{
			public bool Equals((string name, string enu, string locale) x, (string name, string enu, string locale) y)
			{
				return x.name == y.name;
			}

			public int GetHashCode((string name, string enu, string locale) obj)
			{
				return obj.name.GetHashCode();
			}
		}

		[Serializable]
		public class GoodsExport
		{
			[Serializable]
			public class TraderDetails
			{
				public string Name;

				public int Amount;

				public int Weight;
			}

			public GoodModel Good;

			public List<TraderDetails> TradersAvailable = new List<TraderDetails>();
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass3_0<T>
		{
			public Func<T, string> nameGetter;

			public Func<T, Dictionary<string, string>> comment;

			public Func<string, string> enumParser;

			public Func<T, int> orderBy;

			public int DictionaryCharacterCount;

			public string EnumName;

			public int enumValue;

			public Func<T, (string getter, string enu, Dictionary<string, string> locale)> <>9__6;

			internal (string getter, string enu, Dictionary<string, string> locale) <CreateEnumTypesCSharpScript>b__6(T a)
			{
				string text = nameGetter(a);
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				if (comment != null)
				{
					try
					{
						Dictionary<string, string> dictionary2 = comment(a);
						if (dictionary2 != null)
						{
							foreach (KeyValuePair<string, string> item2 in dictionary2)
							{
								if (item2.Value != ">Missing key<")
								{
									if (item2.Key == "name")
									{
										dictionary[item2.Key] = item2.Value;
									}
									else
									{
										dictionary[item2.Key] = CleanComment(item2.Value);
									}
								}
							}
						}
					}
					catch (Exception ex)
					{
						Plugin.Log.LogError((object)("Failed to get comment for " + text + "\n" + ex?.ToString() + "\n" + Environment.StackTrace));
					}
				}
				string item = ((enumParser != null) ? enumParser(text) : text.ToEnumString());
				return (text, item, dictionary);
			}
		}

		private static string exportCSScriptsPath = "";

		public static void ExportWikiInformation()
		{
			Assembly assembly = typeof(HookLogic).Assembly;
			string text = "|Effect Name|Is Perk";
			text += "\n|---|---|\n";
			foreach (Type item in from a in assembly.GetTypes()
				where a.IsSubclassOf(typeof(EffectModel))
				orderby a.Name
				select a)
			{
				if (!item.IsAbstract)
				{
					ScriptableObject val = ScriptableObject.CreateInstance(item);
					PropertyInfo property = ((object)val).GetType().GetProperty("IsPerk");
					bool flag = (bool)property.GetMethod.Invoke(val, null);
					text = text + "|" + item.Name + "|" + flag + "|\n";
				}
			}
			File.WriteAllText("C:\\GitProjects\\ATS_API\\ATS_API\\WIKI\\EFFECTS.md", text);
			text = "|Hook Name|";
			text += "\n|---|\n";
			foreach (Type item2 in from a in assembly.GetTypes()
				where a.IsSubclassOf(typeof(HookLogic))
				orderby a.Name
				select a)
			{
				text = text + "|" + item2.Name + "|\n";
			}
			File.WriteAllText("C:\\GitProjects\\ATS_API\\ATS_API\\WIKI\\HOOKS.md", text);
		}

		public static void CreateEnumTypesCSharpScript<T>(string EnumName, string modelGetter, IEnumerable<T> list, Func<T, string> nameGetter, Func<T, Dictionary<string, string>> comment, List<string> extraUsings = null, Func<string, string> enumParser = null, Func<T, string> groupEnumsBy = null, bool includeNamespaceInType = false, Func<T, int> orderBy = null)
		{
			if (!Directory.Exists(exportCSScriptsPath))
			{
				Directory.CreateDirectory(exportCSScriptsPath);
			}
			HashSet<T> hashSet = new HashSet<T>(list);
			Dictionary<string, List<T>> dictionary = new Dictionary<string, List<T>>();
			if (groupEnumsBy != null)
			{
				foreach (T item3 in hashSet)
				{
					string key = groupEnumsBy(item3);
					if (!dictionary.ContainsKey(key))
					{
						dictionary[key] = new List<T>();
					}
					dictionary[key].Add(item3);
				}
			}
			else
			{
				dictionary["__default"] = hashSet.ToList();
			}
			Dictionary<string, List<(string, string, Dictionary<string, string>)>> dictionary2 = new Dictionary<string, List<(string, string, Dictionary<string, string>)>>();
			foreach (KeyValuePair<string, List<T>> pair in dictionary)
			{
				List<(string, string, Dictionary<string, string>)> list2 = pair.Value.Select(delegate(T a)
				{
					string text9 = nameGetter(a);
					Dictionary<string, string> dictionary3 = new Dictionary<string, string>();
					if (comment != null)
					{
						try
						{
							Dictionary<string, string> dictionary4 = comment(a);
							if (dictionary4 != null)
							{
								foreach (KeyValuePair<string, string> item4 in dictionary4)
								{
									if (item4.Value != ">Missing key<")
									{
										if (item4.Key == "name")
										{
											dictionary3[item4.Key] = item4.Value;
										}
										else
										{
											dictionary3[item4.Key] = CleanComment(item4.Value);
										}
									}
								}
							}
						}
						catch (Exception ex)
						{
							Plugin.Log.LogError((object)("Failed to get comment for " + text9 + "\n" + ex?.ToString() + "\n" + Environment.StackTrace));
						}
					}
					string item2 = ((enumParser != null) ? enumParser(text9) : text9.ToEnumString());
					return (text9, item2, dictionary3);
				}).ToList();
				if (orderBy != null)
				{
					list2.Sort(delegate((string name, string enu, Dictionary<string, string> locale) a, (string name, string enu, Dictionary<string, string> locale) b)
					{
						T arg = pair.Value.First((T c) => nameGetter(c) == a.name);
						T arg2 = pair.Value.First((T c) => nameGetter(c) == b.name);
						return orderBy(arg).CompareTo(orderBy(arg2));
					});
				}
				else
				{
					list2 = list2.OrderBy<(string, string, Dictionary<string, string>), string>(((string name, string enu, Dictionary<string, string> locale) a) => a.enu).ToList();
				}
				dictionary2[pair.Key] = list2;
			}
			List<string> list3 = dictionary.Keys.OrderBy((string a) => a).ToList();
			string fullName = typeof(T).FullName;
			string name = typeof(T).Name;
			string version = Application.version;
			string newValue = "/// <summary>\n/// Generated using Version " + version + "\n/// </summary>";
			string item = dictionary2[list3[0]][0].Item2;
			string newValue2 = "";
			if (extraUsings != null && extraUsings.Count > 0)
			{
				newValue2 = string.Join("\n", extraUsings.Select((string a) => "using " + a + ";")) + "\n";
			}
			int num = dictionary2.Max<KeyValuePair<string, List<(string, string, Dictionary<string, string>)>>>((KeyValuePair<string, List<(string name, string enu, Dictionary<string, string> locale)>> a) => a.Value.Max(((string name, string enu, Dictionary<string, string> locale) b) => b.enu.Length));
			int DictionaryCharacterCount = dictionary2.Max<KeyValuePair<string, List<(string, string, Dictionary<string, string>)>>>((KeyValuePair<string, List<(string name, string enu, Dictionary<string, string> locale)>> a) => a.Value.Max(((string name, string enu, Dictionary<string, string> locale) b) => b.enu.Length + b.name.Length));
			string text = "";
			string text2 = "";
			int enumValue2 = 1;
			foreach (string group2 in list3)
			{
				List<(string, string, Dictionary<string, string>)> source = dictionary2[group2];
				if (group2 != "__default")
				{
					text += "\n\t//";
					text = text + "\n\t// " + group2;
					text += "\n\t//\n\n";
					text2 = text2 + "\n\t\t// " + group2 + "\n";
				}
				text = text + string.Join("\n", source.Select<(string, string, Dictionary<string, string>), string>(delegate((string name, string enu, Dictionary<string, string> locale) a)
				{
					string group3 = group2;
					int num3 = enumValue2;
					enumValue2 = num3 + 1;
					return GetEnumLine(a, group3, num3);
				})) + "\n";
				text2 = text2 + string.Join("\n", source.Select(ToDictionaryRow)) + "\n";
			}
			string text3 = Util.ReadEmbeddedResource(typeof(WIKI).Assembly, "EnumTemplate.txt");
			string contents = text3.Replace("{USINGS}", newValue2).Replace("{CLASS_HEADER}", newValue).Replace("{CLASSNAME}", EnumName)
				.Replace("{ENUMS}", text)
				.Replace("{TOTAL_ENUMS}", hashSet.Count.ToString())
				.Replace("{FIRST_ENUM}", item)
				.Replace("{FULLMODELNAME}", fullName)
				.Replace("{MODELNAME}", name)
				.Replace("{COLLECTION}", modelGetter)
				.Replace("{ENUM_TO_NAME}", text2);
			File.WriteAllText(Path.Combine(exportCSScriptsPath, EnumName + ".cs"), contents);
			static string GetEnumLine((string name, string enu, Dictionary<string, string> locale) a, string group, int enumValue)
			{
				if (a.locale.Count == 0)
				{
					return "\t" + a.enu + " = " + enumValue + ",\n";
				}
				string text5 = "";
				if (a.locale.TryGetValue("summary", out var value2) && !string.IsNullOrEmpty(value2))
				{
					string text6 = CleanComment(value2);
					if (text6.Contains("\n"))
					{
						string text7 = "";
						for (int num2 = 0; num2 < text6.Split(new char[1] { '\n' }).Length; num2++)
						{
							string text8 = text6.Split(new char[1] { '\n' })[num2].Trim();
							if (!string.IsNullOrEmpty(text8))
							{
								if (text7.Length > 0)
								{
									text7 += "</p>\n";
								}
								text7 = text7 + "\t/// <p>" + text8;
							}
						}
						text6 = text7 + "</p>";
					}
					else
					{
						text6 = "\t/// " + text6;
					}
					text5 = "\t/// <summary>\n" + text6 + "\n\t/// </summary>\n";
				}
				else
				{
					text5 = "\t/// <summary></summary>\n";
				}
				foreach (KeyValuePair<string, string> item5 in a.locale)
				{
					if (!(item5.Key == "summary"))
					{
						text5 = text5 + "\t/// <" + item5.Key + ">" + item5.Value + "</" + item5.Key + ">\n";
					}
				}
				return text5 + "\t" + a.enu + " = " + enumValue + ",\n";
			}
			string ToDictionaryRow((string name, string enu, Dictionary<string, string> locale) a)
			{
				int count = ((<>c__DisplayClass3_0<T>)this).DictionaryCharacterCount - (a.enu.Length + a.name.Length);
				string text4 = "\t\t{ " + ((<>c__DisplayClass3_0<T>)this).EnumName + "." + a.enu + ", \"" + a.name + "\" }, ";
				if (a.locale.TryGetValue("summary", out var value) && !string.IsNullOrEmpty(value))
				{
					text4 = text4 + new string(' ', count) + "// " + CleanComment(value).Replace("\n", " ");
				}
				return text4;
			}
		}

		private static string CleanComment(string text)
		{
			text = text.Replace(">Missing key<", "Missing key");
			for (int num = text.IndexOf("<"); num != -1; num = text.IndexOf("<", num + 1))
			{
				int num2 = text.IndexOf(">", num);
				if (num2 != -1 && text[num2 - 1] != '/')
				{
					string s = text.Substring(num, num2 - num + 1);
					string text2 = ParseTag(s);
					text = text.Substring(0, num) + text2 + text.Substring(num2 + 1);
				}
			}
			return text;
		}

		private static string ParseTag(string s)
		{
			int num = 1;
			if (s[1] == '/')
			{
				num++;
			}
			int num2 = s.IndexOf(" ");
			if (num2 == -1)
			{
				num2 = s.IndexOf(">");
			}
			string text = s.Substring(num, num2 - num);
			int num3 = text.IndexOf("=");
			if (num3 != -1)
			{
				text = text.Substring(0, num3);
			}
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			int num4 = s.IndexOf("=");
			while (num4 != -1)
			{
				int num5 = s.LastIndexOf(" ", num4);
				int num6 = s.IndexOf(">", num4);
				string key = s.Substring(num5 + 1, num4 - num5 - 1);
				string value = s.Substring(num4 + 1, num6 - num4 - 1);
				dictionary[key] = value;
				num4 = s.IndexOf("=", num6);
			}
			switch (text)
			{
			case "sprite":
				return dictionary["name"];
			case "color":
				return "";
			default:
				if (!(text == "u"))
				{
					string text2 = string.Join(", ", dictionary.Select((KeyValuePair<string, string> a) => a.Key + "=" + a.Value));
					Plugin.Log.LogInfo((object)("Unhandled tag: '" + text + "' with args: '" + text2 + "'"));
					return s;
				}
				goto case "b";
			case "b":
			case "i":
				return s;
			}
		}

		public static void CreateAllEnumTypes(string csExportPath)
		{
			exportCSScriptsPath = csExportPath;
			Func<string, string> enumParser = (string a) => a.ToEnumString(stripNumbersFromBeginning: true);
			CreateEnumTypesCSharpScript("BuildingCategoriesTypes", "SO.Settings.BuildingCategories", SO.Settings.BuildingCategories, (BuildingCategoryModel a) => ((Object)a).name, NameAndDescription, new List<string>(1) { "Eremite.Buildings" });
			CreateEnumTypesCSharpScript("BuildingTagTypes", "SO.Settings.buildingsTags", SO.Settings.buildingsTags, (BuildingTagModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Buildings" });
			CreateEnumTypesCSharpScript("BuildingTypes", "SO.Settings.Buildings", SO.Settings.Buildings, (BuildingModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Buildings" });
			CreateEnumTypesCSharpScript("WorkshopTypes", "SO.Settings.workshops", SO.Settings.workshops, (WorkshopModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Buildings" });
			CreateEnumTypesCSharpScript("NeedTypes", "SO.Settings.Needs", SO.Settings.Needs, (NeedModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("GoodsTypes", "SO.Settings.Goods", SO.Settings.Goods, (GoodModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("GoodsCategoriesTypes", "SO.Settings.GoodsCategories", SO.Settings.GoodsCategories, (GoodCategoryModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("ProfessionTypes", "SO.Settings.Professions", SO.Settings.Professions, (ProfessionModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("RaceTypes", "SO.Settings.Races", SO.Settings.Races, (RaceModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("TagTypes", "SO.Settings.tags", SO.Settings.tags, (ModelTag a) => ((SO)a).Name, null, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("TraderTypes", "SO.Settings.traders", SO.Settings.traders, (TraderModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model.Trade" });
			CreateEnumTypesCSharpScript("DecorationTierTypes", "SO.Settings.decorationsTiers", SO.Settings.decorationsTiers, (DecorationTier a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Buildings" }, GetPredefinedDecorationEnumNames);
			Func<EffectModel, string> groupEnumsBy = EffectGroup;
			CreateEnumTypesCSharpScript("EffectTypes", "SO.Settings.effects", SO.Settings.effects, (EffectModel a) => ((SO)a).Name, EffectComment, new List<string>(1) { "Eremite.Model" }, null, groupEnumsBy);
			CreateEnumTypesCSharpScript("ResolveEffectTypes", "SO.Settings.resolveEffects", SO.Settings.resolveEffects, (ResolveEffectModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("OrderTypes", "SO.Settings.orders", SO.Settings.orders, (OrderModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model.Orders" });
			CreateEnumTypesCSharpScript("BiomeTypes", "SO.Settings.biomes", SO.Settings.biomes, (BiomeModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.WorldMap" });
			CreateEnumTypesCSharpScript("DifficultyTypes", "SO.Settings.difficulties", SO.Settings.difficulties, (DifficultyModel a) => ((SO)a).Name, DifficultyComment, new List<string>(1) { "Eremite.Model" }, enumParser, null, includeNamespaceInType: false, (DifficultyModel a) => a.index);
			CreateEnumTypesCSharpScript("GoalTypes", "SO.Settings.goals", SO.Settings.goals, (GoalModel a) => ((SO)a).Name, NameAndDescription, new L