API.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using ATS_API;
using ATS_API.Ascension;
using ATS_API.Biomes;
using ATS_API.Buildings;
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.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.Generator;
using Eremite.MapObjects;
using Eremite.MapTools;
using Eremite.Model;
using Eremite.Model.Configs;
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 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("2.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0+be14708c85606c6fab6ab841267cc008bdd50823")]
[assembly: AssemblyProduct("API")]
[assembly: AssemblyTitle("API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.3.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<LocalizationText>("Text", errorIfNotFound: true));
		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;
			SimpleTooltipTrigger orAdd = val10.GetOrAdd<SimpleTooltipTrigger>();
			orAdd.target = val10.GetComponent<RectTransform>();
			orAdd.descKey = "<align=\"left\">" + text + "<b>GUID:</b> " + item.Metadata.GUID + "\n\n<b>Dependencies:</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<TMP_Text>("Text", errorIfNotFound: true).text = "Mods";
		}
	}

	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 text = "";
		if (dictionary.Count > 0)
		{
			return string.Join("\n", dictionary.Select(delegate(KeyValuePair<string, Version> pair)
			{
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: 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_00e3: 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 += " (Wrong Version)";
					}
				}
				else
				{
					text2 += " (Missing)";
				}
				Color val = (flag ? Color.green : Color.red);
				string text3 = ColorUtility.ToHtmlStringRGB(val);
				return "<color=#" + text3 + ">" + text2 + "</color>";
			}));
		}
		return "None";
	}

	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;
		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);

	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 Sprite EffectIcon => EffectIconCache;

	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 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 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", "2.3.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;

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

		public static bool CoreGameLoaded { get; internal set; }

		public static event Action PostTick;

		private void Awake()
		{
			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;
			AssetBundleHelper.TryLoadAssetBundleFromFile("ats_api", out ATS_API_Bundle);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin API is loaded!");
		}

		private void LateUpdate()
		{
			if (CoreGameLoaded)
			{
				Hotkeys.Update();
				DifficultyManager.Tick();
				GoodsManager.Tick();
				EffectManager.Tick();
				TraderManager.Tick();
				OrdersManager.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();
			DifficultyManager.Instantiate();
			RecipeManager.Instantiate();
			GoodsManager.Instantiate();
			EffectManager.Instantiate();
			TraderManager.Instantiate();
			OrdersManager.Instantiate();
			BiomeManager.Instantiate();
			TextMeshProManager.Instantiate();
			BuildingManager.Instantiate();
			RaceManager.Instantiate();
			RaceNeedManager.Instantiate();
			MetaRewardManager.Instantiate();
		}

		[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 flag = MB.GameSaveService.IsNewGame();
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Entered a game. Is this a new game: {flag}.");
		}

		[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>();
		}

		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, string> comment, List<string> extraUsings = null, Func<string, string> enumParser = null, Func<T, string> groupEnumsBy = 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 item4 in hashSet)
				{
					string key = groupEnumsBy(item4);
					if (!dictionary.ContainsKey(key))
					{
						dictionary[key] = new List<T>();
					}
					dictionary[key].Add(item4);
				}
			}
			else
			{
				dictionary["__default"] = hashSet.ToList();
			}
			Dictionary<string, List<(string, string, string)>> dictionary2 = new Dictionary<string, List<(string, string, string)>>();
			foreach (KeyValuePair<string, List<T>> item5 in dictionary)
			{
				List<(string, string, string)> value = (from a in item5.Value.Select(delegate(T a)
					{
						string text6 = nameGetter(a);
						string item2 = null;
						if (comment != null)
						{
							try
							{
								string text7 = comment(a);
								if (!string.IsNullOrEmpty(text7) && text7 != ">Missing key<")
								{
									item2 = text7.Replace("\n", "");
								}
							}
							catch (Exception)
							{
							}
						}
						string item3 = ((enumParser != null) ? enumParser(text6) : text6.ToEnumString());
						return (text6, item3, item2);
					})
					orderby a.enu
					select a).ToList();
				dictionary2[item5.Key] = value;
			}
			List<string> list2 = dictionary.Keys.OrderBy((string a) => a).ToList();
			string name = typeof(T).Name;
			string version = Application.version;
			string newValue = "// Generated using Version " + version;
			string item = dictionary2[list2[0]][0].Item2;
			string newValue2 = "";
			if (extraUsings != null && extraUsings.Count > 0)
			{
				newValue2 = string.Join("\n", extraUsings.Select((string a) => "using " + a + ";")) + "\n";
			}
			int EnumCharacterCount = dictionary2.Max<KeyValuePair<string, List<(string, string, string)>>>((KeyValuePair<string, List<(string name, string enu, string locale)>> a) => a.Value.Max(((string name, string enu, string locale) b) => b.enu.Length));
			int DictionaryCharacterCount = dictionary2.Max<KeyValuePair<string, List<(string, string, string)>>>((KeyValuePair<string, List<(string name, string enu, string locale)>> a) => a.Value.Max(((string name, string enu, string locale) b) => b.enu.Length + b.name.Length));
			string text = "";
			string text2 = "";
			foreach (string item6 in list2)
			{
				List<(string, string, string)> source = dictionary2[item6];
				if (item6 != "__default")
				{
					text = text + "\n\t// " + item6 + "\n";
					text2 = text2 + "\n\t\t// " + item6 + "\n";
				}
				text = text + string.Join("\n", source.Select(GetEnumLine)) + "\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("{MODELNAME}", name)
				.Replace("{COLLECTION}", modelGetter)
				.Replace("{ENUM_TO_NAME}", text2);
			File.WriteAllText(Path.Combine(exportCSScriptsPath, EnumName + ".cs"), contents);
			string GetEnumLine((string name, string enu, string locale) a)
			{
				int count2 = EnumCharacterCount - a.enu.Length;
				string text5 = "\t" + a.enu + ", ";
				if (!string.IsNullOrEmpty(a.locale))
				{
					text5 = text5 + new string(' ', count2) + "// " + a.locale;
				}
				return text5;
			}
			string ToDictionaryRow((string name, string enu, string locale) a)
			{
				int count = DictionaryCharacterCount - (a.enu.Length + a.name.Length);
				string text4 = "\t\t{ " + EnumName + "." + a.enu + ", \"" + a.name + "\" }, ";
				if (!string.IsNullOrEmpty(a.locale))
				{
					text4 = text4 + new string(' ', count) + "// " + a.locale;
				}
				return text4;
			}
		}

		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("NeedTypes", "SO.Settings.Needs", SO.Settings.Needs, (NeedModel a) => ((SO)a).Name, (NeedModel a) => a.DisplayName, 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" });
			Func<EffectModel, string> groupEnumsBy = EffectGroup;
			CreateEnumTypesCSharpScript("EffectTypes", "SO.Settings.effects", SO.Settings.effects, (EffectModel a) => ((SO)a).Name, NameAndDescription, 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" });
			Func<DifficultyModel, string> comment = DifficultyComment;
			CreateEnumTypesCSharpScript("DifficultyTypes", "SO.Settings.difficulties", SO.Settings.difficulties, (DifficultyModel a) => ((SO)a).Name, comment, new List<string>(1) { "Eremite.Model" }, enumParser);
			CreateEnumTypesCSharpScript("GoalTypes", "SO.Settings.goals", SO.Settings.goals, (GoalModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model.Goals" });
			CreateEnumTypesCSharpScript("RelicTypes", "SO.Settings.Relics", SO.Settings.Relics, (RelicModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Buildings" });
			CreateEnumTypesCSharpScript("MetaRewardTypes", "SO.Settings.metaRewards", SO.Settings.metaRewards, (MetaRewardModel a) => ((SO)a).Name, (MetaRewardModel a) => ((object)a).GetType().Name + "-" + a.DisplayName, new List<string>(1) { "Eremite.Model.Meta" });
			CreateEnumTypesCSharpScript("OreTypes", "SO.Settings.Ore", SO.Settings.Ore, (OreModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("VillagerPerkTypes", "SO.Settings.villagersPerks", SO.Settings.villagersPerks, (VillagerPerkModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Characters.Villagers" });
			CreateEnumTypesCSharpScript("BuildingPerkTypes", "SO.Settings.buildingsPerks", SO.Settings.buildingsPerks, (BuildingPerkModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("MetaCurrencyTypes", "SO.Settings.metaCurrencies", SO.Settings.metaCurrencies, (MetaCurrencyModel a) => ((SO)a).Name, NameAndDescription, new List<string>(1) { "Eremite.Model" });
			CreateEnumTypesCSharpScript("AscensionModifierTypes", "SO.Settings.ascensionModifiers", SO.Settings.ascensionModifiers, (AscensionModifierModel a) => ((SO)a).Name, (AscensionModifierModel a) => NameAndDescription(a.effect), new List<string>(1) { "Eremite.Model" });
		}

		private static string EffectGroup(EffectModel arg)
		{
			return ((object)arg).GetType().Name;
		}

		private static string NameAndDescription(object a)
		{
			string text = GetFieldResults(a, new string[1] { "DisplayName" }, new string[1] { "displayName" });
			if (text == ">Missing key<")
			{
				Log(a, "DisplayName is missing key");
				text = "";
			}
			string text2 = GetFieldResults(a, new string[2] { "FormatedDescription", "Description" }, new string[1] { "description" });
			if (text2 == ">Missing key<")
			{
				Log(a, "Description is missing key");
				text2 = "";
			}
			string text3 = "";
			text3 = ((!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2)) ? (text + " - " + text2) : ((string.IsNullOrEmpty(text) && string.IsNullOrEmpty(text2)) ? "" : ((!string.IsNullOrEmpty(text)) ? text : text2)));
			Log(a, "Result: " + text3 + " from " + text + " - " + text2);
			return text3;
			static string GetFieldResults(object instance, string[] properties, string[] fields)
			{
				Type type = instance.GetType();
				Log(instance, "Properties: " + string.Join(", ", properties));
				object obj = null;
				List<PropertyInfo> source = Util.AllProperties(type, properties);
				foreach (string name2 in properties)
				{
					Log(instance, "Checking property " + name2);
					PropertyInfo propertyInfo = source.FirstOrDefault((PropertyInfo a) => a.Name == name2);
					if (propertyInfo != null)
					{
						MethodInfo getMethod = propertyInfo.GetMethod;
						if (getMethod != null)
						{
							Log(instance, "Property " + name2 + " has get method");
							Log(instance, "... Test");
							try
							{
								obj = propertyInfo.GetValue(instance);
								if (obj != null)
								{
									Log(instance, "Property Result is not null!");
									break;
								}
							}
							catch (Exception)
							{
								Log(instance, "Property " + name2 + " failed to get value");
							}
							Log(instance, "Property Result IS null...");
						}
						else
						{
							Log(instance, "Property " + name2 + " has no get method");
						}
					}
					else
					{
						Log(instance, "Property " + name2 + " not found");
					}
				}
				if (obj == null)
				{
					List<FieldInfo> source2 = Util.AllFields(type, fields);
					foreach (string name in fields)
					{
						FieldInfo fieldInfo = source2.FirstOrDefault((FieldInfo a) => a.Name == name);
						if (fieldInfo != null)
						{
							Log(instance, "Field " + name + " found");
							try
							{
								obj = fieldInfo.GetValue(instance);
								if (obj != null)
								{
									break;
								}
							}
							catch (Exception)
							{
								Log(instance, "Field " + name + " failed to get value");
							}
						}
						else
						{
							Log(instance, "Field " + name + " not found for type " + type.FullName);
						}
					}
				}
				if (obj != null)
				{
					LocaText val = (LocaText)((obj is LocaText) ? obj : null);
					if (val != null)
					{
						Log(instance, "Found " + val.GetText());
						return val.GetText();
					}
					if (obj is string text4)
					{
						Log(instance, "Found " + text4);
						return text4;
					}
					Log(instance, "Something was found but unknown " + obj.GetType().FullName);
				}
				else
				{
					Log(instance, "Nothing found");
				}
				return null;
			}
			static void Log(object o, string s)
			{
			}
		}

		private static string DifficultyComment(DifficultyModel a)
		{
			string text = (a.isAscension ? (a.ascensionIndex + 1 + " ") : "");
			return a.displayName.GetText() + " " + text + "- " + ((a.modifiers.Length == 0) ? ((SO)a).GetText("WorldUI_FieldPanel_Difficulty_NoModifiers") : a.modifiers.Last().shortDesc.Text);
		}

		public static void ExportCSVs()
		{
			Plugin.Log.LogInfo((object)"Exporting CSVs...");
			ExportRelicsAsCSV();
			ExportOrdersAsCSV();
			Plugin.Log.LogInfo((object)"Exporting CSVs... Done!");
		}

		private static void ExportOrdersAsCSV()
		{
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			CSVBuilder cSVBuilder = new CSVBuilder();
			IOrderedEnumerable<OrderModel> orderedEnumerable = from o in MB.Settings.orders
				where o.tiers.Length != 0
				select o into a
				orderby ((Object)a).name
				select a;
			int num = orderedEnumerable.Max((OrderModel a) => a.logicsSets.Length);
			foreach (OrderModel item in orderedEnumerable)
			{
				cSVBuilder.AddValue("ID", ((Object)item).name, 1);
				cSVBuilder.AddValue("Name", item.displayName.GetText(), 2);
				cSVBuilder.AddValue("Tiers", string.Join("-", item.tiers.Select((OrderTierModel a) => ((Object)a).name)).ToString(), 3);
				cSVBuilder.AddValue("FailTime", (item.timeToFail > 0f) ? item.timeToFail.ToString("F2") : "", 3);
				cSVBuilder.AddValue("Reputation", ((ReputationEffectModel)item.reputationReward).amount.ToString(), 4);
				for (int i = 0; i < item.rewards.Length; i++)
				{
					cSVBuilder.AddValue("Reward_" + (i + 1), ((Object)item.rewards[i]).name, 5 + i);
				}
				cSVBuilder.NextRow();
			}
			cSVBuilder.SaveAsCSV(Path.Combine(Plugin.ExportPath, "CSV", "Orders.csv"));
		}

		private static void ExportRelicsAsCSV()
		{
			CSVBuilder cSVBuilder = new CSVBuilder();
			HashSet<Type> hashSet = new HashSet<Type>();
			IEnumerable<RelicModel> enumerable = MB.Settings.Relics.OrderBy((RelicModel a) => ((Object)a).name).Distinct();
			foreach (RelicModel item in enumerable)
			{
				cSVBuilder.AddValue("ID", ((Object)item).name, 1);
				cSVBuilder.AddValue("Name", ((BuildingModel)item).displayName.GetText(), 2);
				cSVBuilder.AddValue("Description", ((BuildingModel)item).description.GetText(), 3);
				cSVBuilder.AddValue("DangerLevel", ((object)(DangerLevel)(ref item.dangerLevel)).ToString(), 4);
				cSVBuilder.AddValue("Category", ((Object)((BuildingModel)item).category).name, 5);
				cSVBuilder.AddValue("Profession", ((Object)item.profession).name, 6);
				for (int i = 0; i < item.difficulties.Length; i++)
				{
					RelicDifficulty val = item.difficulties[i];
					for (int j = 0; j < val.decisions.Length; j++)
					{
						RelicDecision val2 = val.decisions[j];
						string text = $"Difficulty_{val.difficulty + 1}_decision_{j + 1}";
						cSVBuilder.AddValue(text + "_workingTime", val2.workingTime.ToString("F"), 7);
						string header = text + "_decisionType";
						DecisionTag decisionTag = val2.decisionTag;
						cSVBuilder.AddValue(header, (decisionTag != null) ? ((Object)decisionTag).name : null, 8);
						List<string> list = new List<string>();
						for (int k = 0; k < val2.requriedGoods.sets.Length; k++)
						{
							GoodsSet val3 = val2.requriedGoods.sets[k];
							for (int l = 0; l < val3.goods.Length; l++)
							{
								GoodRef val4 = val3.goods[l];
								list.Add(val4.amount + ":" + ((Object)val4.good).name);
							}
						}
						cSVBuilder.AddValue(text + "_requiredGoods", (list.Count > 0) ? string.Join(", ", list) : "", 9);
						string value = string.Join(":", val2.workingEffects.Select((EffectModel a) => ((Object)a).name));
						cSVBuilder.AddValue(text + "_workingEffects", value, 10);
					}
				}
				for (int m = 0; m < item.effectsTiers.Length; m++)
				{
					EffectStep val5 = item.effectsTiers[m];
					string text2 = "EffectTier_" + (m + 1);
					cSVBuilder.AddValue(text2 + "_TTS", ((int)val5.timeToStart).ToString(), 11);
					for (int n = 0; n < val5.effect.Length; n++)
					{
						EffectModel val6 = val5.effect[n];
						cSVBuilder.AddValue(text2 + "_Effect_" + (n + 1), ((Object)val6).name, 12);
					}
				}
				for (int num = 0; num < item.activeEffects.Length; num++)
				{
					EffectModel val7 = item.activeEffects[num];
					cSVBuilder.AddValue("ActiveEffect_" + (num + 1), ((Object)((BuildingModel)item).category).name + ":" + ((object)val7).GetType().Name, 13);
				}
				int num2 = 0;
				EffectsTable[] decisionsRewards = item.decisionsRewards;
				foreach (EffectsTable val8 in decisionsRewards)
				{
					EffectsTableEntity[] effects = val8.effects;
					foreach (EffectsTableEntity val9 in effects)
					{
						EffectModel effect = val9.effect;
						cSVBuilder.AddValue("Reward_" + (num2 + 1), ((Object)effect).name + ":" + val9.chance + ":" + ((object)effect).GetType().Name, 14);
						hashSet.Add(((object)effect).GetType());
						num2++;
					}
				}
				cSVBuilder.NextRow();
			}
			cSVBuilder.SaveAsCSV(Path.Combine(Plugin.ExportPath, "CSV", "Relics.csv"));
		}

		public static void DumpGoodsToJSON(GoodModel[] effectModels, string key)
		{
			Plugin.Log.LogInfo((object)$"Exporting {effectModels.Length} goods to JSON.");
			foreach (GoodModel model in effectModels)
			{
				try
				{
					GoodsExport goodsExport = new GoodsExport();
					goodsExport.Good = model;
					TraderModel[] traders = SO.Settings.traders;
					foreach (TraderModel val in traders)
					{
						GoodRefWeight val2 = ((IEnumerable<GoodRefWeight>)val.offeredGoods).FirstOrDefault((Func<GoodRefWeight, bool>)((GoodRefWeight a) => ((Object)a.good).name == ((Object)model).name));
						if (val2 != null)
						{
							goodsExport.TradersAvailable.Add(new GoodsExport.TraderDetails
							{
								Name = val.displayName.GetText(),
								Amount = val2.amount,
								Weight = val2.weight
							});
						}
						GoodRef val3 = ((IEnumerable<GoodRef>)val.guaranteedOfferedGoods).FirstOrDefault((Func<GoodRef, bool>)((GoodRef a) => ((Object)a.good).name == ((Object)model).name));
						if (val3 != null)
						{
							goodsExport.TradersAvailable.Add(new GoodsExport.TraderDetails
							{
								Name = val.displayName.GetText(),
								Amount = val2.amount,
								Weight = 100
							});
						}
					}
					JSONSerializer.Result result = JSONSerializer.ToJson(goodsExport);
					string path = Path.Combine(Plugin.PluginDirectory, "Exports", key, ((SO)model).Name) + ".json";
					string directoryName = Path.GetDirectoryName(path);
					if (!Directory.Exists(directoryName))
					{
						Directory.CreateDirectory(directoryName);
					}
					File.WriteAllText(path, result.JSON);
					Plugin.Log.LogInfo((object)$"Exported {((SO)model).Name}'s SubObjects {result.SubObjects.Count} to JSON.");
					foreach (JSONSerializer.UnityObjectConverter.SubObjects subObject in result.SubObjects)
					{
						string text = Path.Combine(Plugin.PluginDirectory, "Exports", "Assets", ((Object)model).name + "_" + subObject.Path);
						Plugin.Log.LogInfo((object)("- " + text));
						string directoryName2 = Path.GetDirectoryName(text);
						if (!Directory.Exists(directoryName2))
						{
							Directory.CreateDirectory(directoryName2);
						}
						if (!File.Exists(text))
						{
							File.WriteAllBytes(text, subObject.Bytes);
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Failed to dump good to JSON: " + ((SO)model).Name));
					Plugin.Log.LogError((object)ex);
				}
			}
		}

		public static void DumpEffectsJSON<T>(T[] effectModels, string key, Func<T, string> nameGetter) where T : Object
		{
			Plugin.Log.LogInfo((object)$"Exporting {effectModels.Length} goods to JSON.");
			foreach (T val in effectModels)
			{
				string text = nameGetter(val);
				try
				{
					JSONSerializer.Result result = JSONSerializer.ToJson(val);
					string path = Path.Combine(Plugin.PluginDirectory, "Exports", key, text) + ".json";
					string directoryName = Path.GetDirectoryName(path);
					if (!Directory.Exists(directoryName))
					{
						Directory.CreateDirectory(directoryName);
					}
					File.WriteAllText(path, result.JSON);
					Plugin.Log.LogInfo((object)$"Exported {text}'s SubObjects {result.SubObjects.Count} to JSON.");
					foreach (JSONSerializer.UnityObjectConverter.SubObjects subObject in result.SubObjects)
					{
						string text2 = Path.Combine(Plugin.PluginDirectory, "Exports", "Assets", text + "_" + subObject.Path);
						Plugin.Log.LogInfo((object)("- " + text2));
						string directoryName2 = Path.GetDirectoryName(text2);
						if (!Directory.Exists(directoryName2))
						{
							Directory.CreateDirectory(directoryName2);
						}
						if (!File.Exists(text2))
						{
							File.WriteAllBytes(text2, subObject.Bytes);
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Failed to dump good to JSON: " + ((Object)val).name + " " + text));
					Plugin.Log.LogError((object)ex);
				}
			}
		}

		public static void DumpEffectsJSON()
		{
			WIKI.DumpEffectsJSON<EffectModel>(MB.Settings.effects, "Effects", (Func<EffectModel, string>)((EffectModel a) => a.DisplayName));
			WIKI.DumpEffectsJSON<ResolveEffectModel>(MB.Settings.resolveEffects, "Effects", (Func<ResolveEffectModel, string>)((ResolveEffectModel a) => a.displayName.GetText()));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "API";

		public const string PLUGIN_NAME = "API";

		public const string PLUGIN_VERSION = "2.3.0";
	}
}
namespace ATS_API.Traders
{
	public class CustomTrader : ASyncable<TraderModel>
	{
		public TraderTypes id;

		public TraderModel TraderModel;

		public List<string> DesiredGoods = new List<string>();

		public List<NameToAmount> GuaranteedOfferedGoods = new List<NameToAmount>();

		public List<NameToAmount> OfferedGoods = new List<NameToAmount>();

		public List<NameToAmount> Merchandise = new List<NameToAmount>();

		public Availability Availability = new Availability();

		public override bool Sync()
		{