Decompiled source of Simple MMO Classes v1.0.7

SimpleMMOClasses.dll

Decompiled a year ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using SkillManager;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: Guid("C5D9D5A9-7FD1-479F-9B8B-CEA5FA2AF3E7")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyProduct("Simple MMO Classes")]
[assembly: AssemblyCompany("GGrNoob")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("SimpleMMOClasses MMO Classes")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyConfiguration("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<af9bd967-34a5-4325-8afd-29fa569b7e3d>Embedded]
	internal sealed class <af9bd967-34a5-4325-8afd-29fa569b7e3d>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[<af9bd967-34a5-4325-8afd-29fa569b7e3d>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <86b45fd5-044f-4370-bcca-22f6fd4cd358>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <86b45fd5-044f-4370-bcca-22f6fd4cd358>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <86b45fd5-044f-4370-bcca-22f6fd4cd358>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<af9bd967-34a5-4325-8afd-29fa569b7e3d>Embedded]
	internal sealed class <d13bfd6a-2b98-4893-b876-463b2beae858>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <d13bfd6a-2b98-4893-b876-463b2beae858>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
public class ChangeImage : MonoBehaviour
{
	public Button newButton;

	public Image buttonImage;

	public Sprite[] toggledSprites;

	private bool buttonToggled;

	public void ToggleButton()
	{
		buttonToggled = !buttonToggled;
		if (buttonToggled)
		{
			buttonImage.sprite = toggledSprites[1];
		}
		else
		{
			buttonImage.sprite = toggledSprites[0];
		}
	}

	public void newMethod()
	{
		((Selectable)newButton).interactable = false;
	}
}
public class DisableToggle : MonoBehaviour
{
	public Toggle newToggle1;

	public Toggle newToggle2;

	public Toggle newToggle3;

	public Toggle newToggle4;

	public Toggle newToggle5;

	public Toggle newToggle6;

	public Toggle newToggle7;

	public Toggle newToggle8;

	public void newMethod()
	{
		((Selectable)newToggle1).interactable = false;
		((Selectable)newToggle2).interactable = false;
		((Selectable)newToggle3).interactable = false;
		((Selectable)newToggle4).interactable = false;
		((Selectable)newToggle5).interactable = false;
		((Selectable)newToggle6).interactable = false;
		((Selectable)newToggle7).interactable = false;
		((Selectable)newToggle8).interactable = false;
	}
}
public class MenuManager : MonoBehaviour
{
	public GameObject ActivateSelectionPanel;

	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)9))
		{
			ActivateSelectionPanel.gameObject.SetActive(!ActivateSelectionPanel.gameObject.activeSelf);
		}
		if (Input.GetKeyDown((KeyCode)27))
		{
			ActivateSelectionPanel.gameObject.SetActive(false);
		}
	}
}
public class PanelHide : MonoBehaviour
{
	public GameObject Panel;

	public void OpenPanel()
	{
		if ((Object)(object)Panel != (Object)null)
		{
			bool activeSelf = Panel.activeSelf;
			Panel.SetActive(!activeSelf);
		}
	}
}
public class SaveMe : MonoBehaviour
{
	private void Start()
	{
		//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)
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		Scene scene = ((Component)this).gameObject.scene;
		Debug.Log((object)((Scene)(ref scene)).name);
	}
}
public class SaveSelectedButton : MonoBehaviour
{
	[SerializeField]
	private Toggle toggle1;

	[SerializeField]
	private Toggle toggle2;

	[SerializeField]
	private Toggle toggle3;

	[SerializeField]
	private Toggle toggle4;

	[SerializeField]
	private Toggle toggle5;

	[SerializeField]
	private Toggle toggle6;

	[SerializeField]
	private Toggle toggle7;

	[SerializeField]
	private Toggle toggle8;

	private string _savedSimpleClass = "Classless";

	private const string _simpleMMOClass = "SimpleMMOClass";

	private void Awake()
	{
		if (!Player.m_localPlayer.m_customData.ContainsKey("SimpleMMOClass"))
		{
			Player.m_localPlayer.m_customData.Add("SimpleMMOClass", _savedSimpleClass);
		}
		if (!Player.m_localPlayer.m_customData.ContainsKey("SimpleMMOClass"))
		{
			Debug.Log((object)"SimpleMMOClass Entry is not found");
		}
		else
		{
			Debug.Log((object)"SimpleMMOClass Entry Found!");
		}
		if (!Player.m_localPlayer.m_customData.ContainsValue(_savedSimpleClass))
		{
			Debug.Log((object)"Selected Class Entry is not found");
		}
		else
		{
			Debug.Log((object)"Selected Class Entry Found!");
		}
		if (Player.m_localPlayer.m_customData.ContainsValue("Warrior"))
		{
			((Selectable)toggle1).interactable = true;
			toggle1.isOn = true;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Warrior");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Paladin"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = true;
			toggle2.isOn = true;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Paladin");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Rogue"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = true;
			toggle3.isOn = true;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Rogue");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Hunter"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = true;
			toggle4.isOn = true;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Hunter");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Priest"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = true;
			toggle5.isOn = true;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Priest");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Druid"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = true;
			toggle6.isOn = true;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Druid");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Mage"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = true;
			toggle7.isOn = true;
			((Selectable)toggle8).interactable = false;
			toggle8.isOn = false;
			Debug.Log((object)"You are a Mage");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Warlock"))
		{
			((Selectable)toggle1).interactable = false;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = false;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = false;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = false;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = false;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = false;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = false;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = true;
			toggle8.isOn = true;
			Debug.Log((object)"You are a Warlock");
		}
		else if (Player.m_localPlayer.m_customData.ContainsValue("Classless"))
		{
			((Selectable)toggle1).interactable = true;
			toggle1.isOn = false;
			((Selectable)toggle2).interactable = true;
			toggle2.isOn = false;
			((Selectable)toggle3).interactable = true;
			toggle3.isOn = false;
			((Selectable)toggle4).interactable = true;
			toggle4.isOn = false;
			((Selectable)toggle5).interactable = true;
			toggle5.isOn = false;
			((Selectable)toggle6).interactable = true;
			toggle6.isOn = false;
			((Selectable)toggle7).interactable = true;
			toggle7.isOn = false;
			((Selectable)toggle8).interactable = true;
			toggle8.isOn = false;
			Debug.Log((object)"You have no class yet");
		}
	}

	public void Toggle1Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Warrior");
	}

	public void Toggle2Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Paladin");
	}

	public void Toggle3Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Rogue");
	}

	public void Toggle4Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Hunter");
	}

	public void Toggle5Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Priest");
	}

	public void Toggle6Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Druid");
	}

	public void Toggle7Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Mage");
	}

	public void Toggle8Selected()
	{
		Player.m_localPlayer.m_customData.Remove(_savedSimpleClass);
		Player.m_localPlayer.m_customData.Add(_savedSimpleClass, "Warlock");
	}
}
public class selectionManager : MonoBehaviour
{
	public GameObject simpleMMOClass;

	public void selectedMMOClass()
	{
		if (simpleMMOClass.activeInHierarchy)
		{
			simpleMMOClass.SetActive(false);
		}
		else
		{
			simpleMMOClass.SetActive(true);
		}
	}
}
[RequireComponent(typeof(Image))]
public class TabButton : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerClickHandler, IPointerExitHandler
{
	public TabGroup tabGroup;

	public Image background;

	public void OnPointerClick(PointerEventData eventData)
	{
		tabGroup.OnTabSelected(this);
	}

	public void OnPointerEnter(PointerEventData eventData)
	{
		tabGroup.OnTabEnter(this);
	}

	public void OnPointerExit(PointerEventData eventData)
	{
		tabGroup.OnTabExit(this);
	}

	private void Start()
	{
		background = ((Component)this).GetComponent<Image>();
		tabGroup.Subscribe(this);
	}

	private void Update()
	{
	}
}
public class TabGroup : MonoBehaviour
{
	public List<TabButton> tabButtons;

	public Sprite tabIdle;

	public Sprite tabHover;

	public Sprite tabActive;

	public TabButton selectedTab;

	public List<GameObject> objectsToSwap;

	public void Subscribe(TabButton button)
	{
		if (tabButtons == null)
		{
			tabButtons = new List<TabButton>();
		}
		tabButtons.Add(button);
	}

	public void OnTabEnter(TabButton button)
	{
		ResetTabs();
		if ((Object)(object)selectedTab == (Object)null || (Object)(object)button != (Object)(object)selectedTab)
		{
			button.background.sprite = tabHover;
		}
	}

	public void OnTabExit(TabButton button)
	{
		ResetTabs();
	}

	public void OnTabSelected(TabButton button)
	{
		selectedTab = button;
		ResetTabs();
		button.background.sprite = tabActive;
		int siblingIndex = ((Component)button).transform.GetSiblingIndex();
		for (int i = 0; i < objectsToSwap.Count; i++)
		{
			if (i == siblingIndex)
			{
				objectsToSwap[i].SetActive(true);
			}
			else
			{
				objectsToSwap[i].SetActive(false);
			}
		}
	}

	public void ResetTabs()
	{
		foreach (TabButton tabButton in tabButtons)
		{
			if (!((Object)(object)selectedTab != (Object)null) || !((Object)(object)tabButton == (Object)(object)selectedTab))
			{
				tabButton.background.sprite = tabIdle;
			}
		}
	}
}
namespace SkillManager
{
	[PublicAPI]
	public class Skill
	{
		public static class LocalizationCache
		{
			private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>();

			internal static void LocalizationPostfix(Localization __instance, string language)
			{
				string key = localizations.FirstOrDefault((KeyValuePair<string, Localization> l) => l.Value == __instance).Key;
				if (key != null)
				{
					localizations.Remove(key);
				}
				if (!localizations.ContainsKey(language))
				{
					localizations.Add(language, __instance);
				}
			}

			public static Localization ForLanguage([<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)] string language = null)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value))
				{
					return value;
				}
				value = new Localization();
				if (language != null)
				{
					value.SetupLanguage(language);
				}
				return value;
			}
		}

		[PublicAPI]
		public class LocalizeKey
		{
			private static readonly List<LocalizeKey> keys = new List<LocalizeKey>();

			public readonly string Key;

			public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>();

			public LocalizeKey(string key)
			{
				Key = key.Replace("$", "");
			}

			public void Alias(string alias)
			{
				Localizations.Clear();
				if (!alias.Contains("$"))
				{
					alias = "$" + alias;
				}
				Localizations["alias"] = alias;
				Localization.instance.AddWord(Key, Localization.instance.Localize(alias));
			}

			public LocalizeKey English(string key)
			{
				return addForLang("English", key);
			}

			public LocalizeKey Swedish(string key)
			{
				return addForLang("Swedish", key);
			}

			public LocalizeKey French(string key)
			{
				return addForLang("French", key);
			}

			public LocalizeKey Italian(string key)
			{
				return addForLang("Italian", key);
			}

			public LocalizeKey German(string key)
			{
				return addForLang("German", key);
			}

			public LocalizeKey Spanish(string key)
			{
				return addForLang("Spanish", key);
			}

			public LocalizeKey Russian(string key)
			{
				return addForLang("Russian", key);
			}

			public LocalizeKey Romanian(string key)
			{
				return addForLang("Romanian", key);
			}

			public LocalizeKey Bulgarian(string key)
			{
				return addForLang("Bulgarian", key);
			}

			public LocalizeKey Macedonian(string key)
			{
				return addForLang("Macedonian", key);
			}

			public LocalizeKey Finnish(string key)
			{
				return addForLang("Finnish", key);
			}

			public LocalizeKey Danish(string key)
			{
				return addForLang("Danish", key);
			}

			public LocalizeKey Norwegian(string key)
			{
				return addForLang("Norwegian", key);
			}

			public LocalizeKey Icelandic(string key)
			{
				return addForLang("Icelandic", key);
			}

			public LocalizeKey Turkish(string key)
			{
				return addForLang("Turkish", key);
			}

			public LocalizeKey Lithuanian(string key)
			{
				return addForLang("Lithuanian", key);
			}

			public LocalizeKey Czech(string key)
			{
				return addForLang("Czech", key);
			}

			public LocalizeKey Hungarian(string key)
			{
				return addForLang("Hungarian", key);
			}

			public LocalizeKey Slovak(string key)
			{
				return addForLang("Slovak", key);
			}

			public LocalizeKey Polish(string key)
			{
				return addForLang("Polish", key);
			}

			public LocalizeKey Dutch(string key)
			{
				return addForLang("Dutch", key);
			}

			public LocalizeKey Portuguese_European(string key)
			{
				return addForLang("Portuguese_European", key);
			}

			public LocalizeKey Portuguese_Brazilian(string key)
			{
				return addForLang("Portuguese_Brazilian", key);
			}

			public LocalizeKey Chinese(string key)
			{
				return addForLang("Chinese", key);
			}

			public LocalizeKey Japanese(string key)
			{
				return addForLang("Japanese", key);
			}

			public LocalizeKey Korean(string key)
			{
				return addForLang("Korean", key);
			}

			public LocalizeKey Hindi(string key)
			{
				return addForLang("Hindi", key);
			}

			public LocalizeKey Thai(string key)
			{
				return addForLang("Thai", key);
			}

			public LocalizeKey Abenaki(string key)
			{
				return addForLang("Abenaki", key);
			}

			public LocalizeKey Croatian(string key)
			{
				return addForLang("Croatian", key);
			}

			public LocalizeKey Georgian(string key)
			{
				return addForLang("Georgian", key);
			}

			public LocalizeKey Greek(string key)
			{
				return addForLang("Greek", key);
			}

			public LocalizeKey Serbian(string key)
			{
				return addForLang("Serbian", key);
			}

			public LocalizeKey Ukrainian(string key)
			{
				return addForLang("Ukrainian", key);
			}

			private LocalizeKey addForLang(string lang, string value)
			{
				Localizations[lang] = value;
				if (Localization.instance.GetSelectedLanguage() == lang)
				{
					Localization.instance.AddWord(Key, value);
				}
				else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key))
				{
					Localization.instance.AddWord(Key, value);
				}
				return this;
			}

			[HarmonyPriority(300)]
			internal static void AddLocalizedKeys(Localization __instance, string language)
			{
				foreach (LocalizeKey key in keys)
				{
					string value2;
					if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value))
					{
						__instance.AddWord(key.Key, value);
					}
					else if (key.Localizations.TryGetValue("alias", out value2))
					{
						Localization.instance.AddWord(key.Key, Localization.instance.Localize(value2));
					}
				}
			}
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
			public string Category;
		}

		[HarmonyPatch(typeof(Skills), "IsSkillValid")]
		private static class Patch_Skills_IsSkillValid
		{
			private static void Postfix(SkillType type, ref bool __result)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (!__result && skills.ContainsKey(type))
				{
					__result = true;
				}
			}
		}

		private static readonly Dictionary<SkillType, Skill> skills;

		internal static readonly Dictionary<string, Skill> skillByName;

		private readonly string skillName;

		private readonly string internalSkillName;

		private readonly SkillDef skillDef;

		public readonly LocalizeKey Name;

		public readonly LocalizeKey Description;

		private float skillEffectFactor = 1f;

		public bool Configurable = false;

		private static bool InitializedTerminal;

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		private static Localization _english;

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static bool hasConfigSync;

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		private static object _configSync;

		public float SkillGainFactor
		{
			get
			{
				return skillDef.m_increseStep;
			}
			set
			{
				skillDef.m_increseStep = value;
				this.SkillGainFactorChanged?.Invoke(value);
			}
		}

		public float SkillEffectFactor
		{
			get
			{
				return skillEffectFactor;
			}
			set
			{
				skillEffectFactor = value;
				this.SkillEffectFactorChanged?.Invoke(value);
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				object obj = _plugin;
				if (obj == null)
				{
					BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Assembly.GetExecutingAssembly().DefinedTypes.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
					_plugin = val;
					obj = (object)val;
				}
				return (BaseUnityPlugin)obj;
			}
		}

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		private static object configSync
		{
			[<d13bfd6a-2b98-4893-b876-463b2beae858>NullableContext(2)]
			get
			{
				if (_configSync == null && hasConfigSync)
				{
					Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
					if ((object)type != null)
					{
						_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager");
						type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
						type.GetProperty("IsLocked").SetValue(_configSync, true);
					}
					else
					{
						hasConfigSync = false;
					}
				}
				return _configSync;
			}
		}

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		[method: <d13bfd6a-2b98-4893-b876-463b2beae858>NullableContext(2)]
		[field: <86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		public event Action<float> SkillGainFactorChanged;

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		[method: <d13bfd6a-2b98-4893-b876-463b2beae858>NullableContext(2)]
		[field: <86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		public event Action<float> SkillEffectFactorChanged;

		public Skill(string englishName, string icon)
			: this(englishName, loadSprite(icon, 64, 64))
		{
		}

		public Skill(string englishName, Sprite icon)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0057: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			SkillType val = fromName(englishName);
			string text = new Regex("[^a-zA-Z]").Replace(englishName, "_");
			skills[val] = this;
			skillByName[englishName] = this;
			skillDef = new SkillDef
			{
				m_description = "$skilldesc_" + text,
				m_icon = icon,
				m_increseStep = 1f,
				m_skill = val
			};
			internalSkillName = text;
			skillName = englishName;
			Name = new LocalizeKey("skill_" + ((object)(SkillType)(ref val)).ToString()).English(englishName);
			Description = new LocalizeKey("skilldesc_" + text);
		}

		public static SkillType fromName(string englishName)
		{
			return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName));
		}

		static Skill()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01ad: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			skills = new Dictionary<SkillType, Skill>();
			skillByName = new Dictionary<string, Skill>();
			InitializedTerminal = false;
			hasConfigSync = true;
			Harmony val = new Harmony("org.bepinex.helpers.skillmanager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void Patch_FejdStartup()
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			foreach (Skill skill in skills.Values)
			{
				if (skill.Configurable)
				{
					string key = skill.Name.Key;
					string group = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim();
					string category = Localization.instance.Localize(key).Trim();
					ConfigEntry<float> skillGain = config(group, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.SkillGainFactor = skillGain.Value;
					skillGain.SettingChanged += delegate
					{
						skill.SkillGainFactor = skillGain.Value;
					};
					ConfigEntry<float> skillEffect = config(group, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.SkillEffectFactor = skillEffect.Value;
					skillEffect.SettingChanged += delegate
					{
						skill.SkillEffectFactor = skillEffect.Value;
					};
				}
			}
		}

		private static void Patch_Skills_GetSkillDef([<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)] ref SkillDef __result, List<SkillDef> ___m_skills, SkillType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (__result == null)
			{
				SkillDef val = GetSkillDef(type);
				if (val != null)
				{
					___m_skills.Add(val);
					__result = val;
				}
			}
		}

		private static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkillType key in skills.Keys)
			{
				SkillType current = key;
				Skill skill = skills[current];
				if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase))
				{
					Skill skill2 = __instance.GetSkill(current);
					skill2.m_level += value;
					skill2.m_level = Mathf.Clamp(skill2.m_level, 0f, 100f);
					((Character)___m_player).Message((MessageType)1, "Skill increased " + Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref current)).ToString()) + ": " + (int)skill2.m_level, 0, skill2.m_info.m_icon);
					Console.instance.Print("Skill " + skill.internalSkillName + " = " + skill2.m_level);
					return false;
				}
			}
			return true;
		}

		private static bool Patch_Skills_CheatResetSkill(Skills __instance, string name)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkillType key in skills.Keys)
			{
				Skill skill = skills[key];
				if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase))
				{
					__instance.ResetSkill(key);
					Console.instance.Print("Skill " + skill.internalSkillName + " reset");
					return false;
				}
			}
			return true;
		}

		private static void Patch_Terminal_InitTerminal_Prefix()
		{
			InitializedTerminal = Terminal.m_terminalInitialized;
		}

		private static void Patch_Terminal_InitTerminal()
		{
			if (!InitializedTerminal)
			{
				AddSkill(Terminal.commands["raiseskill"]);
				AddSkill(Terminal.commands["resetskill"]);
			}
			static void AddSkill(ConsoleCommand command)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected O, but got Unknown
				ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher;
				command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)delegate
				{
					List<string> list = fetcher.Invoke();
					list.AddRange(skills.Values.Select((Skill skill) => skill.internalSkillName));
					return list;
				};
			}
		}

		[<d13bfd6a-2b98-4893-b876-463b2beae858>NullableContext(2)]
		private static SkillDef GetSkillDef(SkillType skillType)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!skills.ContainsKey(skillType))
			{
				return null;
			}
			Skill skill = skills[skillType];
			return skill.skillDef;
		}

		private static byte[] ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static Texture2D loadTexture(string name)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name));
			return val;
		}

		private static Sprite loadSprite(string name, int width, int height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description);
			configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T))
				.Invoke(configSync, new object[1] { val });
			return val;
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[PublicAPI]
	public static class SkillExtensions
	{
		public static float GetSkillFactor(this Character character, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor;
		}

		public static float GetSkillFactor(this Skills skills, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor;
		}

		public static void RaiseSkill(this Character character, string name, float value = 1f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			character.RaiseSkill(Skill.fromName(name), value);
		}

		public static void RaiseSkill(this Skills skill, string name, float value = 1f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			skill.RaiseSkill(Skill.fromName(name), value);
		}
	}
}
namespace SimpleMMOClassSelection
{
	public class simpleMMOClassSelection : MonoBehaviour
	{
		public string simpleMMOClass;

		public static string simpleMMOClassSelected;

		private bool buttonToggled;

		public void SimpleMMOSelector()
		{
			buttonToggled = !buttonToggled;
			if (buttonToggled)
			{
				simpleMMOClassSelected = simpleMMOClass;
			}
			Debug.Log((object)simpleMMOClassSelected);
		}
	}
}
namespace SimpleMMOClasses
{
	[BepInPlugin("GGrNoob.SimpleMMOClasses", "SimpleMMOClasses", "1.0.0")]
	public class SimpleMMOClasses : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		[HarmonyPatch(typeof(Skill), "Raise")]
		private static class SkillCapping
		{
			private static bool Prefix(Skill __instance)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Warrior"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Sneak"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Crossbows"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Bows"))
					{
						return __instance.m_level < 20f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Paladin"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 25f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Unarmed"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Sneak"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Bows"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Crossbows"))
					{
						return __instance.m_level < 20f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Rogue"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Blocking"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Polearms"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Bows"))
					{
						return __instance.m_level < 50f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Crossbows"))
					{
						return __instance.m_level < 50f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Hunter"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Blocking"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Polearms"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Clubs"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Swords"))
					{
						return __instance.m_level < 30f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Priest"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Unarmed"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Axes"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Blocking"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Bows"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Swords"))
					{
						return __instance.m_level < 30f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Druid"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Knives"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Blocking"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Swords"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 20f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Mage"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Unarmed"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Axes"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Blocking"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Bows"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Crossbows"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Swords"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 0f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Warlock"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Axes"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Blocking"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Bows"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Crossbows"))
					{
						return __instance.m_level < 20f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "Swords"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
				}
				else if (Player.m_localPlayer.m_customData.ContainsValue("Classless"))
				{
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "ElementalMagic"))
					{
						return __instance.m_level < 0f;
					}
					if (string.Equals(((object)(SkillType)(ref __instance.m_info.m_skill)).ToString(), "BloodMagic"))
					{
						return __instance.m_level < 0f;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class WarriorLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Warrior") && ((int)skill == 11 || (int)skill == 3 || (int)skill == 6 || (int)skill == 1))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Warrior"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class PaladinLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Paladin") && ((int)skill == 5 || (int)skill == 3 || (int)skill == 4 || (int)skill == 1))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Paladin"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class RogueLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Rogue") && ((int)skill == 11 || (int)skill == 2 || (int)skill == 1 || (int)skill == 5))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Hunter"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class HunterLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Hunter") && ((int)skill == 8 || (int)skill == 2 || (int)skill == 5 || (int)skill == 14))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Hunter"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class PriestLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Priest") && ((int)skill == 10 || (int)skill == 3 || (int)skill == 5 || (int)skill == 4))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Priest"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class DruidLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Invalid comparison between Unknown and I4
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Druid") && ((int)skill == 9 || (int)skill == 5 || (int)skill == 11 || (int)skill == 4))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Druid"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class MageLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Mage") && ((int)skill == 9 || (int)skill == 3 || (int)skill == 5 || (int)skill == 4))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Mage"), 0.25f);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		private static class WarlockLeveling
		{
			[UsedImplicitly]
			private static void Prefix(Player __instance, SkillType skill, float value)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (Player.m_localPlayer.m_customData.ContainsValue("Warlock") && ((int)skill == 10 || (int)skill == 5 || (int)skill == 3 || (int)skill == 4))
				{
					((Character)__instance).RaiseSkill(Skill.fromName("Warlock"), 0.25f);
				}
			}
		}

		private class ConfigurationManagerAttributes
		{
			public bool? Browsable = false;
		}

		internal const string ModName = "SimpleMMOClasses";

		internal const string ModVersion = "1.0.0";

		internal const string Author = "GGrNoob";

		private const string ModGUID = "GGrNoob.SimpleMMOClasses";

		private static string ConfigFileName = "GGrNoob.SimpleMMOClasses.cfg";

		private static string ConfigFileFullPath;

		internal static string ConnectionError;

		public static GameObject SimpleMMOClassesPanel;

		public static readonly ManualLogSource SimpleMMOClassesLogger;

		private static ConfigEntry<KeyCode> _panelToggleKey;

		private static readonly ConfigSync ConfigSync;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		public static GameObject globalprefabVariable;

		public void Awake()
		{
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Expected O, but got Unknown
			_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
			Skill skill = new Skill("Warrior", "warrior-icon.png");
			skill.Description.English("The Warrior is a Tank, and can take a lot of damage.");
			skill.Name.German("Hartnäckigkeit");
			skill.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill.Configurable = true;
			Skill skill2 = new Skill("Paladin", "paladin-icon.png");
			skill2.Description.English("The Paladin is a Utility class, with some healing ability.");
			skill2.Name.German("Hartnäckigkeit");
			skill2.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill2.Configurable = true;
			Skill skill3 = new Skill("Rogue", "rogue-icon.png");
			skill3.Description.English("The Rogue is a high damage melee style class.");
			skill3.Name.German("Hartnäckigkeit");
			skill3.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill3.Configurable = true;
			Skill skill4 = new Skill("Hunter", "hunter-icon.png");
			skill4.Description.English("The Hunter is an expert marksman and light on their feet.");
			skill4.Name.German("Hartnäckigkeit");
			skill4.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill4.Configurable = true;
			Skill skill5 = new Skill("Priest", "priest-icon.png");
			skill5.Description.English("The Priest bring healing to the group.");
			skill5.Name.German("Hartnäckigkeit");
			skill5.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill5.Configurable = true;
			Skill skill6 = new Skill("Druid", "druid-icon.png");
			skill6.Description.English("The Druid is a Utility style class, with some healing abilites.");
			skill6.Name.German("Hartnäckigkeit");
			skill6.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill6.Configurable = true;
			Skill skill7 = new Skill("Mage", "mage-icon.png");
			skill7.Description.English("The Mage is a High Damage Magic using class.");
			skill7.Name.German("Hartnäckigkeit");
			skill7.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill7.Configurable = true;
			Skill skill8 = new Skill("Warlock", "warlock-icon.png");
			skill8.Description.English("The Warlock is a master of Minions and the Dark forces.");
			skill8.Name.German("Hartnäckigkeit");
			skill8.Description.German("Reduziert erlittenen Schaden um 0,2% pro Stufe.");
			skill8.Configurable = true;
			LoadAssets();
			_panelToggleKey = config<KeyCode>("1 - General", "Panel Toggle Key", (KeyCode)9, "Key used to toggle the panel on and off.");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			Harmony val = new Harmony("GGrNoob.SimpleMMOClasses");
			val.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private static AssetBundle GetAssetBundleFromResources(string filename)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename));
			using Stream stream = executingAssembly.GetManifestResourceStream(name);
			return AssetBundle.LoadFromStream(stream);
		}

		public static void LoadAssets()
		{
			AssetBundle assetBundleFromResources = GetAssetBundleFromResources("simplemmoclassespanel");
			globalprefabVariable = assetBundleFromResources.LoadAsset<GameObject>("SimpleMMOClassesPanel");
			if (assetBundleFromResources != null)
			{
				assetBundleFromResources.Unload(false);
			}
			if ((Object)(object)globalprefabVariable != (Object)null)
			{
				SimpleMMOClassesPanel = Object.Instantiate<GameObject>(globalprefabVariable);
				Object.DontDestroyOnLoad((Object)(object)SimpleMMOClassesPanel);
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				SimpleMMOClassesLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				SimpleMMOClassesLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				SimpleMMOClassesLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		static SimpleMMOClasses()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			SimpleMMOClassesLogger = Logger.CreateLogSource("SimpleMMOClasses");
			ConfigSync = new ConfigSync("GGrNoob.SimpleMMOClasses")
			{
				DisplayName = "SimpleMMOClasses",
				CurrentVersion = "1.0.0",
				MinimumRequiredVersion = "1.0.0"
			};
			_serverConfigLocked = null;
		}
	}
	public class ClassBonuses
	{
		[HarmonyPatch(typeof(Player), "SetMaxHealth")]
		public static class WarriorHealthBonus
		{
			private static void Prefix(Player __instance, ref float health)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Warrior"))
				{
					health += 50f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxHealth")]
		public static class PaladinHealthBonus
		{
			private static void Prefix(Player __instance, ref float health)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Paladin"))
				{
					health += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxHealth")]
		public static class RogueHealthBonus
		{
			private static void Prefix(Player __instance, ref float health)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Rogue"))
				{
					health += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxHealth")]
		public static class HunterHealthBonus
		{
			private static void Prefix(Player __instance, ref float health)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Hunter"))
				{
					health += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxHealth")]
		public static class DruidHealthBonus
		{
			private static void Prefix(Player __instance, ref float health)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Druid"))
				{
					health += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxStamina")]
		public static class WarriorStaminaBonus
		{
			private static void Prefix(Player __instance, ref float stamina)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Warrior"))
				{
					stamina += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxStamina")]
		public static class RogueStaminaBonus
		{
			private static void Prefix(Player __instance, ref float stamina)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Rogue"))
				{
					stamina += 50f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxStamina")]
		public static class HunterStaminaBonus
		{
			private static void Prefix(Player __instance, ref float stamina)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Hunter"))
				{
					stamina += 50f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxStamina")]
		public static class DruidStaminaBonus
		{
			private static void Prefix(Player __instance, ref float stamina)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Druid"))
				{
					stamina += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxStamina")]
		public static class MageStaminaBonus
		{
			private static void Prefix(Player __instance, ref float stamina)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Mage"))
				{
					stamina += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxStamina")]
		public static class WarlockStaminaBonus
		{
			private static void Prefix(Player __instance, ref float stamina)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Warlock"))
				{
					stamina += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		public static class PaladinEitrBonus
		{
			private static void Prefix(Player __instance, ref float eitr)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Paladin"))
				{
					eitr += 25f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		public static class PriestEitrBonus
		{
			private static void Prefix(Player __instance, ref float eitr)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Priest"))
				{
					eitr += 75f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		public static class DruidEitrBonus
		{
			private static void Prefix(Player __instance, ref float eitr)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Druid"))
				{
					eitr += 35f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		public static class MageEitrBonus
		{
			private static void Prefix(Player __instance, ref float eitr)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Mage"))
				{
					eitr += 50f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		public static class WarlockEitrBonus
		{
			private static void Prefix(Player __instance, ref float eitr)
			{
				if (Player.m_localPlayer.m_customData.ContainsValue("Warlock"))
				{
					eitr += 50f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			SimpleMMOClasses.SimpleMMOClassesLogger.LogDebug((object)"Registering version RPC handler");
			peer.m_rpc.Register<ZPackage>("SimpleMMOClasses_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_SkillManagerModTemplate_Version);
			SimpleMMOClasses.SimpleMMOClassesLogger.LogDebug((object)"Invoking version check");
			ZPackage val = new ZPackage();
			val.Write("1.0.0");
			peer.m_rpc.Invoke("SimpleMMOClasses_VersionCheck", new object[1] { val });
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			SimpleMMOClasses.SimpleMMOClassesLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "RequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				__instance.m_connectionFailedError.fontSizeMax = 25f;
				__instance.m_connectionFailedError.fontSizeMin = 15f;
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + SimpleMMOClasses.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				SimpleMMOClasses.SimpleMMOClassesLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_SkillManagerModTemplate_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			SimpleMMOClasses.SimpleMMOClassesLogger.LogInfo((object)("Version check, local: 1.0.0,  remote: " + text));
			if (text != "1.0.0")
			{
				SimpleMMOClasses.ConnectionError = "SimpleMMOClasses Installed: 1.0.0\n Needed: " + text;
				if (ZNet.instance.IsServer())
				{
					SimpleMMOClasses.SimpleMMOClassesLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting"));
					rpc.Invoke("Error", new object[1] { 3 });
				}
			}
			else if (!ZNet.instance.IsServer())
			{
				SimpleMMOClasses.SimpleMMOClassesLogger.LogInfo((object)"Received same version from server!");
			}
			else
			{
				SimpleMMOClasses.SimpleMMOClassesLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out var value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out var value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<[<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(1)] T>(string key, string placeholder, ConfigEntry<T> config, [<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(new byte[] { 2, 0, 0 })] Func<T, string> convertConfigValue = null)
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1];
				if (dictionary.ContainsKey(text))
				{
					Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
				}
				else
				{
					dictionary[text] = item;
				}
			}
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.ContainsKey(language))
				{
					text2 = File.ReadAllText(dictionary[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text2 = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text2 == null && dictionary.ContainsKey("English"))
			{
				text2 = File.ReadAllText(dictionary["English"]);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		[return: <86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(2)]
		private static byte[] LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		[<d13bfd6a-2b98-4893-b876-463b2beae858>NullableContext(2)]
		public static byte[] ReadEmbeddedFileBytes([<86b45fd5-044f-4370-bcca-22f6fd4cd358>Nullable(0)] string resourceFileName, Assembly containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[<67ebcbcf-3fa8-4bf7-b9b9-7c0d1aaf6abd>Embedded]
	[CompilerGenerated]
	internal sealed class <67ebcbcf-3fa8-4bf7-b9b9-7c0d1aaf6abd>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[<67ebcbcf-3fa8-4bf7-b9b9-7c0d1aaf6abd>Embedded]
	[CompilerGenerated]
	internal sealed class <178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<67ebcbcf-3fa8-4bf7-b9b9-7c0d1aaf6abd>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <a59b468f-6f30-4be1-8422-897482daea74>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <a59b468f-6f30-4be1-8422-897482daea74>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	[<67ebcbcf-3fa8-4bf7-b9b9-7c0d1aaf6abd>Embedded]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServerSync
{
	[PublicAPI]
	[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
	[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
	internal abstract class OwnConfigEntryBase
	{
		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		public object LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
	[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
	[PublicAPI]
	internal class SyncedConfigEntry<[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)] T> : OwnConfigEntryBase
	{
		public readonly ConfigEntry<T> SourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

		public T Value
		{
			get
			{
				return SourceConfig.Value;
			}
			set
			{
				SourceConfig.Value = value;
			}
		}

		public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
		{
			SourceConfig = sourceConfig;
		}

		public void AssignLocalValue(T value)
		{
			if (LocalBaseValue == null)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
	[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(2)]
	internal abstract class CustomSyncedValueBase
	{
		public object LocalBaseValue;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(1)]
		public readonly string Identifier;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(1)]
		public readonly Type Type;

		private object boxedValue;

		protected bool localIsOwner;

		public object BoxedValue
		{
			get
			{
				return boxedValue;
			}
			set
			{
				boxedValue = value;
				this.ValueChanged?.Invoke();
			}
		}

		public event Action ValueChanged;

		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
		protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type)
		{
			Identifier = identifier;
			Type = type;
			configSync.AddCustomValue(this);
			localIsOwner = configSync.IsSourceOfTruth;
			configSync.SourceOfTruthChanged += delegate(bool truth)
			{
				localIsOwner = truth;
			};
		}
	}
	[PublicAPI]
	[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
	[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
	internal sealed class CustomSyncedValue<[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)] T> : CustomSyncedValueBase
	{
		public T Value
		{
			get
			{
				return (T)base.BoxedValue;
			}
			set
			{
				base.BoxedValue = value;
			}
		}

		public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T))
			: base(configSync, identifier, typeof(T))
		{
			Value = value;
		}

		public void AssignLocalValue(T value)
		{
			if (localIsOwner)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ReadOnly = false;
	}
	[PublicAPI]
	[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
	[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
	internal class ConfigSync
	{
		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
		private static class SnatchCurrentlyHandlingRPC
		{
			[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
			public static ZRpc currentRpc;

			[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
			[HarmonyPrefix]
			private static void Prefix(ZRpc __instance)
			{
				currentRpc = __instance;
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		internal static class RegisterRPCPatch
		{
			[HarmonyPostfix]
			[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				foreach (ConfigSync configSync2 in configSyncs)
				{
					ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
					if (isServer)
					{
						configSync2.InitialSyncDone = true;
						Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
					}
				}
				if (isServer)
				{
					((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
				}
				[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
				static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
				{
					ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
					{
						new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = isAdmin
						}
					});
					ConfigSync configSync = configSyncs.First();
					if (configSync != null)
					{
						((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
					}
				}
				[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
				static IEnumerator WatchAdminListChanges()
				{
					SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					List<string> CurrentList = new List<string>(adminList.GetList());
					while (true)
					{
						yield return (object)new WaitForSeconds(30f);
						if (!adminList.GetList().SequenceEqual(CurrentList))
						{
							CurrentList = new List<string>(adminList.GetList());
							List<ZNetPeer> adminPeer = (from p in ZNet.instance.GetPeers()
								where adminList.Contains(p.m_rpc.GetSocket().GetHostName())
								select p).ToList();
							List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
							SendAdmin(nonAdminPeer, isAdmin: false);
							SendAdmin(adminPeer, isAdmin: true);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		private static class RegisterClientRPCPatch
		{
			[HarmonyPostfix]
			[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					return;
				}
				foreach (ConfigSync configSync in configSyncs)
				{
					peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
				}
			}
		}

		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		private class ParsedConfigs
		{
			[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(new byte[] { 1, 1, 2 })]
			public readonly Dictionary<OwnConfigEntryBase, object> configValues = new Dictionary<OwnConfigEntryBase, object>();

			[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(new byte[] { 1, 1, 2 })]
			public readonly Dictionary<CustomSyncedValueBase, object> customValues = new Dictionary<CustomSyncedValueBase, object>();
		}

		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ResetConfigsOnShutdown
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ProcessingServerUpdate = true;
				foreach (ConfigSync configSync in configSyncs)
				{
					configSync.resetConfigsFromServer();
					configSync.IsSourceOfTruth = true;
					configSync.InitialSyncDone = false;
				}
				ProcessingServerUpdate = false;
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
		private class SendConfigsAfterLogin
		{
			[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
			private class BufferingSocket : ISocket
			{
				public volatile bool finished = false;

				public volatile int versionMatchQueued = -1;

				public readonly List<ZPackage> Package = new List<ZPackage>();

				public readonly ISocket Original;

				public BufferingSocket(ISocket original)
				{
					Original = original;
				}

				public bool IsConnected()
				{
					return Original.IsConnected();
				}

				public ZPackage Recv()
				{
					return Original.Recv();
				}

				public int GetSendQueueSize()
				{
					return Original.GetSendQueueSize();
				}

				public int GetCurrentSendRate()
				{
					return Original.GetCurrentSendRate();
				}

				public bool IsHost()
				{
					return Original.IsHost();
				}

				public void Dispose()
				{
					Original.Dispose();
				}

				public bool GotNewData()
				{
					return Original.GotNewData();
				}

				public void Close()
				{
					Original.Close();
				}

				public string GetEndPointString()
				{
					return Original.GetEndPointString();
				}

				public void GetAndResetStats(out int totalSent, out int totalRecv)
				{
					Original.GetAndResetStats(ref totalSent, ref totalRecv);
				}

				public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
				{
					Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
				}

				public ISocket Accept()
				{
					return Original.Accept();
				}

				public int GetHostPort()
				{
					return Original.GetHostPort();
				}

				public bool Flush()
				{
					return Original.Flush();
				}

				public string GetHostName()
				{
					return Original.GetHostName();
				}

				public void VersionMatch()
				{
					if (finished)
					{
						Original.VersionMatch();
					}
					else
					{
						versionMatchQueued = Package.Count;
					}
				}

				public void Send(ZPackage pkg)
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Expected O, but got Unknown
					int pos = pkg.GetPos();
					pkg.SetPos(0);
					int num = pkg.ReadInt();
					if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
					{
						ZPackage val = new ZPackage(pkg.GetArray());
						val.SetPos(pos);
						Package.Add(val);
					}
					else
					{
						pkg.SetPos(pos);
						Original.Send(pkg);
					}
				}
			}

			[HarmonyPriority(800)]
			[HarmonyPrefix]
			private static void Prefix([<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(new byte[] { 2, 1, 1 })] ref Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Invalid comparison between Unknown and I4
				if (__instance.IsServer())
				{
					BufferingSocket value = new BufferingSocket(rpc.GetSocket());
					AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value);
					object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
					ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (val != null && (int)ZNet.m_onlineBackend > 0)
					{
						AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value);
					}
					if (__state == null)
					{
						__state = new Dictionary<Assembly, BufferingSocket>();
					}
					__state[Assembly.GetExecutingAssembly()] = value;
				}
			}

			[HarmonyPostfix]
			private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
			{
				ZNetPeer peer;
				if (__instance.IsServer())
				{
					object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
					peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (peer == null)
					{
						SendBufferedData();
					}
					else
					{
						((MonoBehaviour)__instance).StartCoroutine(sendAsync());
					}
				}
				void SendBufferedData()
				{
					if (rpc.GetSocket() is BufferingSocket bufferingSocket)
					{
						AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket.Original);
						object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
						ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
						if (val != null)
						{
							AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
						}
					}
					BufferingSocket bufferingSocket2 = __state[Assembly.GetExecutingAssembly()];
					bufferingSocket2.finished = true;
					for (int i = 0; i < bufferingSocket2.Package.Count; i++)
					{
						if (i == bufferingSocket2.versionMatchQueued)
						{
							bufferingSocket2.Original.VersionMatch();
						}
						bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
					}
					if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
					{
						bufferingSocket2.Original.VersionMatch();
					}
				}
				IEnumerator sendAsync()
				{
					foreach (ConfigSync configSync in configSyncs)
					{
						List<PackageEntry> entries = new List<PackageEntry>();
						if (configSync.CurrentVersion != null)
						{
							entries.Add(new PackageEntry
							{
								section = "Internal",
								key = "serverversion",
								type = typeof(string),
								value = configSync.CurrentVersion
							});
						}
						MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						entries.Add(new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2]
							{
								adminList,
								rpc.GetSocket().GetHostName()
							}))
						});
						ZPackage package = ConfigsToPackage(configSync.allConfigs.Select([<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)] (OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false);
						yield return ((MonoBehaviour)__instance).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package));
					}
					SendBufferedData();
				}
			}
		}

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
		private class PackageEntry
		{
			public string section = null;

			public string key = null;

			public Type type = null;

			[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
			public object value;
		}

		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
		private static class PreventSavingServerInfo
		{
			[HarmonyPrefix]
			[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
			private static bool Prefix(ConfigEntryBase __instance, ref string __result)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase))
				{
					return true;
				}
				__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
				return false;
			}
		}

		[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(0)]
		[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
		private static class PreventConfigRereadChangingValues
		{
			[<a59b468f-6f30-4be1-8422-897482daea74>NullableContext(1)]
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, string value)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null)
				{
					return true;
				}
				try
				{
					ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
				}
				return false;
			}
		}

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(0)]
		private class InvalidDeserializationTypeException : Exception
		{
			public string expected = null;

			public string received = null;

			public string field = "";
		}

		public static bool ProcessingServerUpdate;

		public readonly string Name;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		public string DisplayName;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		public string CurrentVersion;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		public string MinimumRequiredVersion;

		public bool ModRequired = false;

		private bool? forceConfigLocking;

		private bool isSourceOfTruth = true;

		private static readonly HashSet<ConfigSync> configSyncs;

		private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();

		private readonly HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();

		private static bool isServer;

		private static bool lockExempt;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		private OwnConfigEntryBase lockedConfig = null;

		private const byte PARTIAL_CONFIGS = 1;

		private const byte FRAGMENTED_CONFIG = 2;

		private const byte COMPRESSED_CONFIG = 4;

		private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(new byte[] { 1, 0, 1 })]
		private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();

		private static long packageCounter;

		public bool IsLocked
		{
			get
			{
				bool? flag = forceConfigLocking;
				bool num;
				if (!flag.HasValue)
				{
					if (lockedConfig == null)
					{
						goto IL_0052;
					}
					num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0;
				}
				else
				{
					num = flag.GetValueOrDefault();
				}
				if (!num)
				{
					goto IL_0052;
				}
				int result = ((!lockExempt) ? 1 : 0);
				goto IL_0053;
				IL_0053:
				return (byte)result != 0;
				IL_0052:
				result = 0;
				goto IL_0053;
			}
			set
			{
				forceConfigLocking = value;
			}
		}

		public bool IsAdmin => lockExempt || isSourceOfTruth;

		public bool IsSourceOfTruth
		{
			get
			{
				return isSourceOfTruth;
			}
			private set
			{
				if (value != isSourceOfTruth)
				{
					isSourceOfTruth = value;
					this.SourceOfTruthChanged?.Invoke(value);
				}
			}
		}

		public bool InitialSyncDone { get; private set; } = false;


		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		[method: <a59b468f-6f30-4be1-8422-897482daea74>NullableContext(2)]
		[field: <178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		public event Action<bool> SourceOfTruthChanged;

		[<178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		[method: <a59b468f-6f30-4be1-8422-897482daea74>NullableContext(2)]
		[field: <178e4b51-a1ad-4dc2-b6bb-5b28f65667b0>Nullable(2)]
		private event Action lockedConfigChanged;

		static ConfigSync()
		{
			ProcessingServerUpdate = false;
			configSyncs = new HashSet<ConfigSync>();
			lockExempt = f