Decompiled source of LethalCompanyProgressionPatchFix v2.0.0

LethalProgression.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using LethalProgression.Config;
using LethalProgression.GUI.HandSlot;
using LethalProgression.GUI.Skills;
using LethalProgression.GUI.XPBar;
using LethalProgression.LessShitConfig;
using LethalProgression.LessShitConfig.Attributes;
using LethalProgression.LessShitConfig.Internal;
using LethalProgression.LessShitConfig.Internal.ClassBuilders;
using LethalProgression.LessShitConfig.Sources;
using LethalProgression.Network;
using LethalProgression.Patches;
using LethalProgression.Properties;
using LethalProgression.Saving;
using LethalProgression.Skills;
using LethalProgression.Skills.Upgrades;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Steamworks;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("LethalProgression")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Leveling and skillpoints through a managed GUI! Patched and bugfixed until official copy updated.")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("LethalProgression")]
[assembly: AssemblyTitle("LethalProgression")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalProgression
{
	internal class LC_XP : NetworkBehaviour
	{
		public LethalNetworkVariable<int> teamLevel = new LethalNetworkVariable<int>("teamLevel")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamXP = new LethalNetworkVariable<int>("teamXP")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamTotalValue = new LethalNetworkVariable<int>("teamTotalValue")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamXPRequired = new LethalNetworkVariable<int>("teamXPRequired")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamLootLevel = new LethalNetworkVariable<int>("teamLootLevel")
		{
			Value = 0
		};

		public LethalClientEvent playerConnectClientEvent = new LethalClientEvent("playerConnectEvent", (Action)null, (Action<ulong>)null);

		public LethalServerEvent playerConnectServerEvent = new LethalServerEvent("playerConnectEvent", (Action<ulong>)null);

		public LethalClientEvent evaluateXPRequirementClientEvent = new LethalClientEvent("evaluateXPRequirementEvent", (Action)null, (Action<ulong>)null);

		public LethalServerEvent evaluateXPRequirementServerEvent = new LethalServerEvent("evaluateXPRequirementEvent", (Action<ulong>)null);

		public LethalClientEvent calculateAllPlayersHandSlotsClientEvent = new LethalClientEvent("calculateAllPlayersHandSlotsEvent", (Action)null, (Action<ulong>)null);

		public LethalServerEvent calculateAllPlayersHandSlotsServerEvent = new LethalServerEvent("calculateAllPlayersHandSlotsEvent", (Action<ulong>)null);

		public LethalServerMessage<string> sendConfigServerMessage = new LethalServerMessage<string>("sendConfigMessage", (Action<string, ulong>)null);

		public LethalClientMessage<string> sendConfigClientMessage = new LethalClientMessage<string>("sendConfigMessage", (Action<string>)null, (Action<string, ulong>)null);

		public LethalServerMessage<ulong> requestProfileDataServerMessage = new LethalServerMessage<ulong>("requestProfileDataMessage", (Action<ulong, ulong>)null);

		public LethalClientMessage<ulong> requestProfileDataClientMessage = new LethalClientMessage<ulong>("requestProfileDataMessage", (Action<ulong>)null, (Action<ulong, ulong>)null);

		public LethalServerMessage<string> sendProfileDataServerMessage = new LethalServerMessage<string>("sendProfileDataMessage", (Action<string, ulong>)null);

		public LethalClientMessage<string> receiveProfileDataClientMessage = new LethalClientMessage<string>("sendProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null);

		public LethalServerMessage<string> saveProfileDataServerMessage = new LethalServerMessage<string>("saveProfileDataMessage", (Action<string, ulong>)null);

		public LethalClientMessage<string> saveProfileDataClientMessage = new LethalClientMessage<string>("saveProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null);

		public LethalServerMessage<int> updateTeamLootLevelServerMessage = new LethalServerMessage<int>("updateTeamLootLevelMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updateTeamLootLevelClientMessage = new LethalClientMessage<int>("updateTeamLootLevelMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<int> updateTeamXPServerMessage = new LethalServerMessage<int>("updateTeamXPMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updateTeamXPClientMessage = new LethalClientMessage<int>("updateTeamXPMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<int> updatePlayerSkillpointsServerMessage = new LethalServerMessage<int>("updatePlayerSkillPointsMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updatePlayerSkillpointsClientMessage = new LethalClientMessage<int>("updatePlayerSkillPointsMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<int> updateSPHandSlotsServerMessage = new LethalServerMessage<int>("updateSPHandSlotsMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updateSPHandSlotsClientMessage = new LethalClientMessage<int>("updateSPHandSlotsMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<PlayerHandSlotData> updatePlayerHandSlotsServerMessage = new LethalServerMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData, ulong>)null);

		public LethalClientMessage<PlayerHandSlotData> updatePlayerHandSlotsClientMessage = new LethalClientMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData>)null, (Action<PlayerHandSlotData, ulong>)null);

		public int skillPoints;

		public SkillList skillList = new SkillList();

		public bool Initialized = false;

		public bool loadedSave = false;

		public void Start()
		{
			LethalPlugin.Log.LogInfo((object)"XP Network Behavior Made!");
			teamLevel.OnValueChanged += OnTeamLevelChange;
			playerConnectServerEvent.OnReceived += PlayerConnect_C2SEvent;
			evaluateXPRequirementServerEvent.OnReceived += EvaluateXPRequirements_C2SEvent;
			calculateAllPlayersHandSlotsServerEvent.OnReceived += RefreshAllPlayerHandSlots_C2SEvent;
			sendConfigClientMessage.OnReceived += SendHostConfig_S2CMessage;
			receiveProfileDataClientMessage.OnReceived += LoadProfileData_S2CMessage;
			updatePlayerSkillpointsClientMessage.OnReceived += UpdateSkillPoints_S2CMessage;
			updatePlayerHandSlotsClientMessage.OnReceived += UpdatePlayerHandSlots_S2CMessage;
			requestProfileDataServerMessage.OnReceived += RequestSavedData_C2SMessage;
			saveProfileDataServerMessage.OnReceived += SaveProfileData_C2SMessage;
			updateTeamLootLevelServerMessage.OnReceived += UpdateTeamLootLevel_C2SMessage;
			updateTeamXPServerMessage.OnReceived += UpdateTeamXP_C2SMessage;
			updateSPHandSlotsServerMessage.OnReceived += UpdateSPHandSlots_C2SMessage;
			playerConnectClientEvent.InvokeServer();
		}

		public override void OnDestroy()
		{
			teamLevel.OnValueChanged -= OnTeamLevelChange;
			teamLootLevel.OnValueChanged -= LethalPlugin.SkillsGUI.TeamLootHudUpdate;
			playerConnectServerEvent.OnReceived -= PlayerConnect_C2SEvent;
			evaluateXPRequirementServerEvent.OnReceived -= EvaluateXPRequirements_C2SEvent;
			calculateAllPlayersHandSlotsServerEvent.OnReceived -= RefreshAllPlayerHandSlots_C2SEvent;
			sendConfigClientMessage.OnReceived -= SendHostConfig_S2CMessage;
			receiveProfileDataClientMessage.OnReceived -= LoadProfileData_S2CMessage;
			updatePlayerSkillpointsClientMessage.OnReceived -= UpdateSkillPoints_S2CMessage;
			updatePlayerHandSlotsClientMessage.OnReceived -= UpdatePlayerHandSlots_S2CMessage;
			requestProfileDataServerMessage.OnReceived -= RequestSavedData_C2SMessage;
			saveProfileDataServerMessage.OnReceived -= SaveProfileData_C2SMessage;
			updateTeamLootLevelServerMessage.OnReceived -= UpdateTeamLootLevel_C2SMessage;
			updateTeamXPServerMessage.OnReceived -= UpdateTeamXP_C2SMessage;
			updateSPHandSlotsServerMessage.OnReceived -= UpdateSPHandSlots_C2SMessage;
			((NetworkBehaviour)this).OnDestroy();
		}

		private void OnTeamLevelChange(int newLevel)
		{
			((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowLevelUp));
		}

		private void OnTeamXPChange(int newXP)
		{
			((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowXPUpdate));
		}

		public IEnumerator WaitUntilInitialisedThenAction(Action callback)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => Initialized));
			callback();
		}

		public void PlayerConnect_C2SEvent(ulong clientId)
		{
			LethalPlugin.Log.LogInfo((object)$"Received PlayerConnect message from {clientId}");
			LessShitConfigSystem.ClearHostConfigs();
			string text = LessShitConfigSystem.SerializeLocalConfigs();
			LethalPlugin.Log.LogInfo((object)("Sending config -> " + text));
			sendConfigServerMessage.SendClient(text, clientId);
		}

		public void LoadSharedData()
		{
			SaveSharedData? saveSharedData = SaveManager.LoadSharedFile();
			if (!saveSharedData.HasValue)
			{
				LethalPlugin.Log.LogInfo((object)"Shared data is null!");
				return;
			}
			SaveSharedData value = saveSharedData.Value;
			LethalPlugin.Log.LogInfo((object)"Loading Lobby shared data.");
			teamXP.Value = value.xp;
			teamLevel.Value = value.level;
			teamTotalValue.Value = value.quota;
			teamXPRequired.Value = CalculateXPRequirement();
			LethalPlugin.Log.LogInfo((object)$"{value.level} current lvl, {value.xp} XP, {value.quota} Profit, {teamXPRequired.Value} teamXPRequired");
		}

		public IEnumerator LoadProfileData(string data)
		{
			LethalPlugin.Log.LogInfo((object)("Received player data from host -> " + data));
			yield return (object)new WaitUntil((Func<bool>)(() => Initialized));
			if (loadedSave)
			{
				LethalPlugin.Log.LogWarning((object)"Already loaded player data from host.");
				yield return null;
			}
			loadedSave = true;
			SaveData saveData = JsonConvert.DeserializeObject<SaveData>(data);
			skillPoints = saveData.skillPoints;
			LethalPlugin.Log.LogDebug((object)$"skillPoints -> {skillPoints}");
			int skillCheck = 0;
			foreach (KeyValuePair<UpgradeType, int> skill in saveData.skillAllocation)
			{
				LethalPlugin.Log.LogDebug((object)$"{skill.Key} -> {skill.Value}");
				skillList.skills[skill.Key].SetLevel(skill.Value, triggerHostProfileSave: false);
				skillCheck += skill.Value;
				LethalPlugin.Log.LogDebug((object)$"skillCheck -> {skillCheck}");
			}
			if (skillCheck + skillPoints < teamLevel.Value + 5)
			{
				LethalPlugin.Log.LogInfo((object)$"Skill check is less than current level, adding {teamLevel.Value + 5 - (skillCheck + skillPoints)} skill points.");
				skillPoints += teamLevel.Value + 5 - (skillCheck + skillPoints);
			}
			LethalPlugin.SkillsGUI.UpdateAllStats();
		}

		public int CalculateXPRequirement()
		{
			int connectedPlayersAmount = StartOfRound.Instance.connectedPlayersAmount;
			int timesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota;
			IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
			int num = connectedPlayersAmount * active.personMultiplier;
			int num2 = active.minXP + num;
			int num3 = timesFulfilledQuota * active.quotaMultiplier;
			num2 += (int)((float)num2 * ((float)num3 / 100f));
			if (num2 > active.maxXP)
			{
				num2 = active.maxXP;
			}
			LethalPlugin.Log.LogInfo((object)$"{connectedPlayersAmount} players, {timesFulfilledQuota} quotas, {active.minXP} initial cost, {num} person value, {num3} quota value, {num2} total cost.");
			return num2;
		}

		public int GetXP()
		{
			return teamXP.Value;
		}

		public int GetLevel()
		{
			return teamLevel.Value;
		}

		public int GetProfit()
		{
			return teamTotalValue.Value;
		}

		public int GetSkillPoints()
		{
			return skillPoints;
		}

		public void SetSkillPoints(int num)
		{
			skillPoints = num;
		}

		public void EvaluateXPRequirements_C2SEvent(ulong clientId)
		{
			((MonoBehaviour)this).StartCoroutine(XPRequirementCoroutine());
		}

		public IEnumerator XPRequirementCoroutine()
		{
			yield return (object)new WaitForSeconds(0.5f);
			teamXPRequired.Value = CalculateXPRequirement();
		}

		public void UpdateTeamXP_C2SMessage(int xpToAdd, ulong clientId)
		{
			LethalNetworkVariable<int> obj = teamXP;
			obj.Value += xpToAdd;
			LethalNetworkVariable<int> obj2 = teamTotalValue;
			obj2.Value += xpToAdd;
			int num = GetXP();
			if (num >= teamXPRequired.Value)
			{
				int num2 = 0;
				while (num >= teamXPRequired.Value)
				{
					num2++;
					num -= teamXPRequired.Value;
				}
				teamXP.Value = num;
				LethalNetworkVariable<int> obj3 = teamLevel;
				obj3.Value += num2;
				updatePlayerSkillpointsServerMessage.SendAllClients(num2, true);
			}
		}

		public void UpdateSkillPoints_S2CMessage(int pointsToAdd)
		{
			skillPoints += pointsToAdd;
		}

		public void UpdateTeamLootLevel_C2SMessage(int change, ulong clientId)
		{
			int value = teamLootLevel.Value;
			if (value + change < 0)
			{
				teamLootLevel.Value = 0;
			}
			else
			{
				LethalNetworkVariable<int> obj = teamLootLevel;
				obj.Value += change;
			}
			LethalPlugin.Log.LogInfo((object)$"Changed team loot value by {change} turning into {teamLootLevel.Value}.");
		}

		public void UpdateSPHandSlots_C2SMessage(int slotChange, ulong clientId)
		{
			if (!LethalPlugin.ReservedSlots)
			{
				LethalPlugin.Log.LogInfo((object)$"C2S Received update for Player {clientId} to add {slotChange} slots");
				updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(clientId, slotChange), true);
			}
		}

		public void UpdatePlayerHandSlots_S2CMessage(PlayerHandSlotData data)
		{
			LethalPlugin.Log.LogInfo((object)$"S2C Received update for Player {data.clientId} to add {data.additionalSlots} slots");
			SetHandSlot(data.clientId, data.additionalSlots);
		}

		public void SetHandSlot(ulong playerID, int additionalSlots)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.playerClientId != playerID)
				{
					continue;
				}
				int num = 4 + additionalSlots;
				List<GrabbableObject> list = val.ItemSlots.ToList();
				if (val.currentItemSlot > num - 1)
				{
					HandSlots.SwitchItemSlots(val, num - 1);
				}
				for (int j = 0; j < list.Count; j++)
				{
					if (j > num - 1 && (Object)(object)list[j] != (Object)null)
					{
						HandSlots.SwitchItemSlots(val, j);
						val.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
					}
				}
				val.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[num];
				for (int k = 0; k < list.Count; k++)
				{
					if (!((Object)(object)list[k] == (Object)null))
					{
						val.ItemSlots[k] = list[k];
					}
				}
				LethalPlugin.Log.LogDebug((object)$"Player {playerID} has {val.ItemSlots.Length} slots after setting.");
				if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					LethalPlugin.Log.LogDebug((object)"Updating HUD slots.");
					HandSlots.UpdateHudSlots();
				}
				break;
			}
		}

		public void RefreshAllPlayerHandSlots_C2SEvent(ulong clientId)
		{
			if (LethalPlugin.ReservedSlots || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot))
			{
				return;
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (((Component)val).gameObject.activeSelf)
				{
					ulong playerClientId = val.playerClientId;
					int additionalSlots = val.ItemSlots.Length - 4;
					updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(playerClientId, additionalSlots), true);
				}
			}
		}

		public void SendHostConfig_S2CMessage(string serializedConfig)
		{
			LessShitConfigSystem.ApplyHostConfigs(serializedConfig);
			if (!Initialized)
			{
				Initialized = true;
				LP_NetworkManager.xpInstance = this;
				skillList.InitializeSkills();
				if (GameNetworkManager.Instance.isHostingGame)
				{
					LoadSharedData();
				}
				teamLootLevel.OnValueChanged += LethalPlugin.SkillsGUI.TeamLootHudUpdate;
				skillPoints = teamLevel.Value + 5;
				calculateAllPlayersHandSlotsClientEvent.InvokeServer();
				evaluateXPRequirementClientEvent.InvokeServer();
			}
		}

		public void RequestSavedData_C2SMessage(ulong steamID, ulong clientId)
		{
			string text = SaveManager.LoadPlayerFile(steamID);
			PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId);
			sendProfileDataServerMessage.SendClient(text, playerController.actualClientId);
		}

		public void LoadProfileData_S2CMessage(string saveData)
		{
			LethalPlugin.Log.LogInfo((object)("Received LoadProfileData_S2CMessage -> " + saveData));
			if (saveData != null)
			{
				((MonoBehaviour)this).StartCoroutine(LoadProfileData(saveData));
			}
		}

		public void SaveProfileData_C2SMessage(string data, ulong clientId)
		{
			SaveProfileData saveProfileData = JsonConvert.DeserializeObject<SaveProfileData>(data);
			LethalPlugin.Log.LogInfo((object)$"Received SaveData request for {saveProfileData.steamId} with data -> {JsonConvert.SerializeObject((object)saveProfileData.saveData)}");
			SaveManager.Save(saveProfileData.steamId, saveProfileData.saveData);
			SaveManager.SaveShared(teamXP.Value, teamLevel.Value, teamTotalValue.Value);
		}
	}
	[HarmonyPatch]
	internal class LP_NetworkManager
	{
		public static LC_XP xpInstance;

		public static GameObject xpNetworkObject;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void Init()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (!((Object)(object)xpNetworkObject != (Object)null))
			{
				xpNetworkObject = (GameObject)LethalPlugin.skillBundle.LoadAsset("LP_XPHandler");
				xpNetworkObject.AddComponent<LC_XP>();
				NetworkManager.Singleton.AddNetworkPrefab(xpNetworkObject);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				GameObject val = Object.Instantiate<GameObject>(xpNetworkObject, Vector3.zero, Quaternion.identity);
				val.GetComponent<NetworkObject>().Spawn(false);
				xpInstance = val.GetComponent<LC_XP>();
				LethalPlugin.Log.LogInfo((object)"XPHandler Initialized.");
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("TisRyno.LethalProgression", "Lethal Progression", "2.0.0")]
	internal class LethalPlugin : BaseUnityPlugin
	{
		private const string modGUID = "TisRyno.LethalProgression";

		private const string modName = "Lethal Progression";

		private const string modVersion = "2.0.0";

		public static AssetBundle skillBundle;

		internal static ManualLogSource Log;

		internal static bool ReservedSlots;

		public static LethalPlugin Instance { get; private set; }

		public static XPBarGUI XPBarGUI { get; private set; }

		public static SkillsGUI SkillsGUI { get; private set; }

		public static SlotTemplate SlotTemplate { get; private set; }

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Instance = this;
			XPBarGUI = new XPBarGUI();
			SkillsGUI = new SkillsGUI();
			SlotTemplate = new SlotTemplate();
			Harmony val = new Harmony("TisRyno.LethalProgression");
			val.PatchAll();
			skillBundle = AssetBundle.LoadFromMemory(Resources.skillmenu);
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Lethal Progression initialised.");
			LessShitConfigSystem.RegisterSection<IGeneralConfig>();
			LessShitConfigSystem.RegisterSection<IBatteryLifeConfig>();
			LessShitConfigSystem.RegisterSection<IHandSlotsConfig>();
			LessShitConfigSystem.RegisterSection<IHealthRegenConfig>();
			LessShitConfigSystem.RegisterSection<IJumpHeightConfig>();
			LessShitConfigSystem.RegisterSection<ILootValueConfig>();
			LessShitConfigSystem.RegisterSection<ISprintSpeedConfig>();
			LessShitConfigSystem.RegisterSection<IStaminaConfig>();
			LessShitConfigSystem.RegisterSection<IStrengthConfig>();
			LessShitConfigSystem.Bake(((BaseUnityPlugin)this).Config);
			LessShitConfigSystem.SerializeLocalConfigs();
			Log.LogInfo((object)"Lethal Progression Config loaded.");
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				string gUID = pluginInfo.Value.Metadata.GUID;
				if (gUID.Contains("ReservedItem"))
				{
					ReservedSlots = true;
					break;
				}
				if (gUID.Contains("mikestweaks") && (from entry in pluginInfo.Value.Instance.Config.GetConfigEntries()
					where entry.Definition.Key == "ExtraItemSlots"
					where int.TryParse(entry.GetSerializedValue(), out var result) && result > 0
					select entry).Any())
				{
					ReservedSlots = true;
					break;
				}
			}
		}

		public IDictionary<string, object> GetAllConfigEntries()
		{
			return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)((BaseUnityPlugin)this).Config).ToDictionary((KeyValuePair<ConfigDefinition, ConfigEntryBase> entry) => entry.Value.Definition.Key, (KeyValuePair<ConfigDefinition, ConfigEntryBase> entry) => entry.Value.BoxedValue);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalProgression";

		public const string PLUGIN_NAME = "LethalProgression";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalProgression.Skills
{
	internal class Skill
	{
		private readonly string _shortName;

		private readonly string _name;

		private readonly string _attribute;

		private readonly string _description;

		private readonly UpgradeType _upgradeType;

		private readonly int _cost;

		private readonly int _maxLevel;

		private readonly float _multiplier;

		private readonly Action<int> _callback;

		public bool _teamShared;

		private int _level;

		public Skill(string name, string description, string shortname, string attribute, UpgradeType upgradeType, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false)
		{
			_name = name;
			_shortName = shortname;
			_attribute = attribute;
			_description = description;
			_upgradeType = upgradeType;
			_cost = cost;
			_maxLevel = maxLevel;
			_multiplier = multiplier;
			_level = 0;
			_callback = callback;
			_teamShared = teamShared;
		}

		public string GetName()
		{
			return _name;
		}

		public string GetShortName()
		{
			return _shortName;
		}

		public string GetAttribute()
		{
			return _attribute;
		}

		public string GetDescription()
		{
			return _description;
		}

		public UpgradeType GetUpgradeType()
		{
			return _upgradeType;
		}

		public int GetCost()
		{
			return _cost;
		}

		public int GetMaxLevel()
		{
			return _maxLevel;
		}

		public int GetLevel()
		{
			return _level;
		}

		public float GetMultiplier()
		{
			return _multiplier;
		}

		public float GetTrueValue()
		{
			return _multiplier * (float)_level;
		}

		public void SetLevel(int newLevel, bool triggerHostProfileSave = true)
		{
			int level = _level;
			_level = newLevel;
			_callback?.Invoke(newLevel - level);
			if (triggerHostProfileSave)
			{
				SaveManager.TriggerHostProfileSave();
			}
		}

		public void AddLevel(int change)
		{
			_level += change;
			_callback?.Invoke(change);
			SaveManager.TriggerHostProfileSave();
		}
	}
	internal class SkillList
	{
		public Dictionary<UpgradeType, Skill> skills = new Dictionary<UpgradeType, Skill>();

		public void CreateSkill(UpgradeType upgrade, string name, string description, string shortname, string attribute, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false)
		{
			Skill value = new Skill(name, description, shortname, attribute, upgrade, cost, maxLevel, multiplier, callback, teamShared);
			skills.Add(upgrade, value);
		}

		public bool IsSkillValid(UpgradeType upgrade)
		{
			return skills.ContainsKey(upgrade) && skills[upgrade].GetLevel() > 0;
		}

		public Skill GetSkill(UpgradeType upgrade)
		{
			if (!IsSkillValid(upgrade))
			{
				return null;
			}
			return skills[upgrade];
		}

		public Dictionary<UpgradeType, Skill> GetSkills()
		{
			return skills;
		}

		public void InitializeSkills()
		{
			IHealthRegenConfig active = LessShitConfigSystem.GetActive<IHealthRegenConfig>();
			IStaminaConfig active2 = LessShitConfigSystem.GetActive<IStaminaConfig>();
			IBatteryLifeConfig active3 = LessShitConfigSystem.GetActive<IBatteryLifeConfig>();
			IHandSlotsConfig active4 = LessShitConfigSystem.GetActive<IHandSlotsConfig>();
			ILootValueConfig active5 = LessShitConfigSystem.GetActive<ILootValueConfig>();
			IStrengthConfig active6 = LessShitConfigSystem.GetActive<IStrengthConfig>();
			IJumpHeightConfig active7 = LessShitConfigSystem.GetActive<IJumpHeightConfig>();
			ISprintSpeedConfig active8 = LessShitConfigSystem.GetActive<ISprintSpeedConfig>();
			if (active.isEnabled)
			{
				CreateSkill(UpgradeType.HPRegen, "Health Regen", "The company installs a basic healer into your suit, letting you regenerate health slowly. Only regenerate up to 100 HP.", "HPR", "Health Regeneration", 1, active.maxLevel, active.multiplier);
			}
			if (active2.isEnabled)
			{
				CreateSkill(UpgradeType.Stamina, "Stamina", "Hours on that company gym finally coming into play. Allows you to run for longer, but has to regenerate it slower.", "STM", "Stamina", 1, active2.maxLevel, active2.multiplier);
			}
			if (active3.isEnabled)
			{
				CreateSkill(UpgradeType.Battery, "Battery Life", "The company provides you with better batteries. Replace your batteries AT THE SHIP'S CHARGER to see an effect.", "BAT", "Battery Life", 1, active3.maxLevel, active3.multiplier);
			}
			if (active4.isEnabled && !LethalPlugin.ReservedSlots)
			{
				CreateSkill(UpgradeType.HandSlot, "Hand Slot", "The company finally gives you a better belt! Fit more stuff! (One slot every 100%.)", "HND", "Hand Slots", 1, active4.maxLevel, active4.multiplier, HandSlots.HandSlotsUpdate);
			}
			if (active5.isEnabled)
			{
				CreateSkill(UpgradeType.Value, "Loot Value", "The company gives you a better pair of eyes, allowing you to see the value in things.", "VAL", "Loot Value", 1, active5.maxLevel, active5.multiplier, LootValue.LootValueUpdate, teamShared: true);
			}
			if (active6.isEnabled)
			{
				CreateSkill(UpgradeType.Strength, "Strength", "More work at the Company's gym gives you pure muscles! You can carry better. (Reduces weight by a percentage.)", "STR", "Weight Reduction", 1, active6.maxLevel, active6.multiplier, Strength.StrengthUpdate);
			}
			if (active7.isEnabled)
			{
				CreateSkill(UpgradeType.JumpHeight, "Jump Height", "The company installs you with jumping boots! (The company is not responsible for any broken knees.)", "JMP", "Jump Height", 1, active7.maxLevel, active7.multiplier);
			}
			if (active8.isEnabled)
			{
				CreateSkill(UpgradeType.SprintSpeed, "Sprint Speed", "The company empowers you with pure steroids, run, spaceman.", "SPD", "Sprint Speed", 1, active8.maxLevel, active8.multiplier);
			}
		}
	}
	public enum UpgradeType
	{
		HPRegen,
		Stamina,
		Battery,
		HandSlot,
		Value,
		JumpHeight,
		SprintSpeed,
		Strength
	}
}
namespace LethalProgression.Skills.Upgrades
{
	internal class BatteryLife
	{
		public static float GetUseItemBatteryUsage(float defaultBatteryUsage)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery))
			{
				return defaultBatteryUsage;
			}
			float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue() / 100f;
			float num2 = 1f / num;
			return defaultBatteryUsage * num2;
		}

		public static List<CodeInstruction> UseItemBatteriesOpCode(List<CodeInstruction> codes)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			FieldInfo field = typeof(Item).GetField("batteryUsage");
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(BatteryLife).GetMethod("GetUseItemBatteryUsage")));
				}
			}
			return codes;
		}

		public static float GetUpdateBatteryUsage(float defaultBatteryUsage)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery))
			{
				return defaultBatteryUsage;
			}
			float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue() / 100f;
			return defaultBatteryUsage * num;
		}

		public static List<CodeInstruction> BatteryDegradeUpdateOpCode(List<CodeInstruction> codes)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			FieldInfo field = typeof(Item).GetField("batteryUsage");
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(BatteryLife).GetMethod("GetUpdateBatteryUsage")));
				}
			}
			return codes;
		}
	}
	internal class HandSlots
	{
		public static int currentSlotCount = 4;

		public static void HandSlotsUpdate(int updateValue)
		{
			if (!LethalPlugin.ReservedSlots && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot))
			{
				LC_XP xpInstance = LP_NetworkManager.xpInstance;
				int num = (int)xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue();
				int num2 = (int)Math.Floor((double)(num / 100));
				ulong playerClientId = GameNetworkManager.Instance.localPlayerController.playerClientId;
				LethalPlugin.Log.LogInfo((object)$"Updating Player HandSlot {playerClientId}");
				xpInstance.updateSPHandSlotsClientMessage.SendServer(num2);
			}
		}

		public static void UpdateHudSlots()
		{
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			LC_XP xpInstance = LP_NetworkManager.xpInstance;
			float num = xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue() / 100f;
			int num2 = 4 + (int)Math.Floor(num);
			int num3 = num2 - currentSlotCount;
			GameObject val = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory");
			List<string> list = new List<string> { "Slot0", "Slot1", "Slot2", "Slot3" };
			for (int i = 0; i < val.transform.childCount; i++)
			{
				Transform child = val.transform.GetChild(i);
				if (!list.Contains(((Object)((Component)child).gameObject).name))
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
				}
			}
			int num4 = (int)xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue();
			int num5 = (int)Math.Floor((double)(num4 / 100));
			Image[] array = (Image[])(object)new Image[num2];
			array[0] = HUDManager.Instance.itemSlotIconFrames[0];
			array[1] = HUDManager.Instance.itemSlotIconFrames[1];
			array[2] = HUDManager.Instance.itemSlotIconFrames[2];
			array[3] = HUDManager.Instance.itemSlotIconFrames[3];
			Image[] array2 = (Image[])(object)new Image[num2];
			array2[0] = HUDManager.Instance.itemSlotIcons[0];
			array2[1] = HUDManager.Instance.itemSlotIcons[1];
			array2[2] = HUDManager.Instance.itemSlotIcons[2];
			array2[3] = HUDManager.Instance.itemSlotIcons[3];
			GameObject val2 = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory/Slot3");
			GameObject templateSlot = LethalPlugin.SlotTemplate.GetTemplateSlot();
			GameObject val3 = val2;
			currentSlotCount = num2;
			for (int j = 0; j < (int)num; j++)
			{
				GameObject val4 = Object.Instantiate<GameObject>(templateSlot);
				((Object)val4).name = $"Slot{3 + (j + 1)}";
				val4.transform.SetParent(val.transform);
				Vector3 localPosition = val3.transform.localPosition;
				val4.transform.SetLocalPositionAndRotation(new Vector3(localPosition.x + 50f, localPosition.y, localPosition.z), val3.transform.localRotation);
				val3 = val4;
				array[3 + (j + 1)] = val4.GetComponent<Image>();
				array2[3 + (j + 1)] = ((Component)val4.transform.GetChild(0)).GetComponent<Image>();
				val4.SetActive(true);
			}
			for (int k = 0; k < array.Length; k++)
			{
				Vector3 localPosition2 = ((Component)array[k]).transform.localPosition;
				((Component)array[k]).transform.SetLocalPositionAndRotation(new Vector3(localPosition2.x - (float)(num3 * 25), localPosition2.y, localPosition2.z), ((Component)array[k]).transform.localRotation);
			}
			HUDManager.Instance.itemSlotIconFrames = array;
			HUDManager.Instance.itemSlotIcons = array2;
		}

		public static bool IsItemSwitchPossible(PlayerControllerB player)
		{
			return (double)player.timeSinceSwitchingSlots >= 0.01 && !player.inTerminalMenu && !player.isGrabbingObjectAnimation && !player.inSpecialInteractAnimation && !player.throwingObject && !player.isTypingChat && !player.twoHanded && !player.activatingItem && !player.jetpackControls && !player.disablingJetpackControls;
		}

		public static bool SwitchItemSlots(PlayerControllerB player, int requestedSlot)
		{
			if (!IsItemSwitchPossible(player) || player.currentItemSlot == requestedSlot)
			{
				return false;
			}
			LethalPlugin.Log.LogDebug((object)$"Trying to switch to slot {requestedSlot}");
			int num = player.currentItemSlot - requestedSlot;
			bool flag = num > 0;
			if (Math.Abs(num) == player.ItemSlots.Length - 1)
			{
				player.SwitchItemSlotsServerRpc(flag);
			}
			else
			{
				do
				{
					player.SwitchItemSlotsServerRpc(flag);
					num += ((!flag) ? 1 : (-1));
				}
				while (num != 0);
			}
			ShipBuildModeManager.Instance.CancelBuildMode(true);
			player.playerBodyAnimator.SetBool("GrabValidated", false);
			LethalPlugin.Log.LogDebug((object)$"Switched to slot {requestedSlot}");
			player.SwitchToItemSlot(requestedSlot, (GrabbableObject)null);
			if ((Object)(object)player.currentlyHeldObjectServer != (Object)null)
			{
				((Component)player.currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>().PlayOneShot(player.currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f);
			}
			return true;
		}
	}
	internal class HPRegen
	{
		public static List<CodeInstruction> DisableBaseGameHPRegen(List<CodeInstruction> codes)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)LP_NetworkManager.xpInstance) || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen))
			{
				return codes;
			}
			FieldInfo field = typeof(PlayerControllerB).GetField("health");
			for (int i = 0; i < codes.Count; i++)
			{
				if (!(codes[i].opcode != OpCodes.Ldfld) && !((FieldInfo)codes[i].operand != field) && !(codes[i + 1].opcode != OpCodes.Ldc_I4) && (int)codes[i + 1].operand == 20 && !(codes[i + 2].opcode != OpCodes.Bge_S))
				{
					codes.Insert(i + 2, new CodeInstruction(OpCodes.Pop, (object)null));
					codes.Insert(i + 3, new CodeInstruction(OpCodes.Dup, (object)null));
				}
			}
			return codes;
		}
	}
	internal class JumpHeight
	{
		public static float GetJumpForce(float defaultJumpForce)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.JumpHeight))
			{
				return defaultJumpForce;
			}
			float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.JumpHeight].GetTrueValue() / 100f;
			return defaultJumpForce * num;
		}

		public static List<CodeInstruction> PlayerJumpOpCode(List<CodeInstruction> codes)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			FieldInfo field = typeof(PlayerControllerB).GetField("jumpForce");
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(JumpHeight).GetMethod("GetJumpForce")));
				}
			}
			return codes;
		}
	}
	internal class LootValue
	{
		public static float GetScrapValueMultiplier(float defaultScrapValueMultiplier)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value))
			{
				return defaultScrapValueMultiplier;
			}
			float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier();
			float num = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier;
			float num2 = 1f + num / 100f;
			return defaultScrapValueMultiplier * num2;
		}

		public static List<CodeInstruction> ScrapValueMultiplierOpCode(List<CodeInstruction> codes)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			FieldInfo field = typeof(RoundManager).GetField("scrapValueMultiplier");
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(LootValue).GetMethod("GetScrapValueMultiplier")));
				}
			}
			return codes;
		}

		public static void LootValueUpdate(int change)
		{
			if (LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value))
			{
				LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(change);
			}
		}
	}
	public static class SprintSpeed
	{
		public static float GetSprintSpeed(float defaultSprintSpeed)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.SprintSpeed))
			{
				return defaultSprintSpeed;
			}
			float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.SprintSpeed].GetTrueValue() / 100f;
			return defaultSprintSpeed * num;
		}

		public static List<CodeInstruction> PlayerSprintSpeedOpCode(List<CodeInstruction> codes)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].operand.Equals(2.25f))
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(SprintSpeed).GetMethod("GetSprintSpeed")));
				}
			}
			return codes;
		}
	}
	internal class Stamina
	{
		public static float GetJumpStaminaUsage(float defaultJumpStaminaUsage)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina))
			{
				return defaultJumpStaminaUsage;
			}
			float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina].GetTrueValue() / 100f;
			float num2 = 1f / num;
			return defaultJumpStaminaUsage * num2;
		}

		public static List<CodeInstruction> PlayerJumpStaminaOpCode(List<CodeInstruction> codes)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].operand.Equals(0.08f))
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(Stamina).GetMethod("GetJumpStaminaUsage")));
				}
			}
			return codes;
		}

		public static float GetSprintTime(float defaultStaminaTime)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina))
			{
				return defaultStaminaTime;
			}
			float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina].GetTrueValue() / 100f;
			return defaultStaminaTime * num;
		}

		public static List<CodeInstruction> PlayerSprintTimeOpCode(List<CodeInstruction> codes)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			FieldInfo field = typeof(PlayerControllerB).GetField("sprintTime");
			for (int i = 0; i < codes.Count; i++)
			{
				if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
				{
					codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(Stamina).GetMethod("GetSprintTime")));
				}
			}
			return codes;
		}
	}
	[HarmonyPatch]
	internal class Strength
	{
		public static void StrengthUpdate(int change = 0)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Strength) || LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Strength].GetLevel() == 0)
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			List<GrabbableObject> list = localPlayerController.ItemSlots.ToList();
			LethalPlugin.Log.LogDebug((object)$"Carry weight was {localPlayerController.carryWeight}");
			float trueValue = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Strength].GetTrueValue();
			float num = trueValue / 100f;
			float num2 = 0f;
			foreach (GrabbableObject item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					float num3 = item.itemProperties.weight - 1f;
					num3 *= 1f - num;
					num2 += num3;
					LethalPlugin.Log.LogDebug((object)$"Item weight was {item.itemProperties.weight - 1f} and is now {num3}");
					LethalPlugin.Log.LogDebug((object)$"Adding carryweight.. now up to {num2}");
				}
			}
			localPlayerController.carryWeight = Math.Clamp(1f + num2, 0f, 10f);
			LethalPlugin.Log.LogDebug((object)$"Player carry weight is now {localPlayerController.carryWeight}");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		private static void UpdateObjects()
		{
			StrengthUpdate();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GrabbableObject), "DiscardItem")]
		private static void UpdateByDiscard(GrabbableObject __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				StrengthUpdate();
			}
		}
	}
}
namespace LethalProgression.Saving
{
	internal struct SaveData
	{
		public ulong steamId;

		public int skillPoints;

		public Dictionary<UpgradeType, int> skillAllocation;

		public SaveData(ulong steamId, int skillPoints)
		{
			skillAllocation = new Dictionary<UpgradeType, int>();
			this.steamId = steamId;
			this.skillPoints = skillPoints;
		}
	}
	internal static class SaveManager
	{
		public static int saveFileSlot;

		public static void TriggerHostProfileSave()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ulong num = SteamId.op_Implicit(SteamClient.SteamId);
			SaveData saveData = default(SaveData);
			saveData.steamId = num;
			saveData.skillPoints = LP_NetworkManager.xpInstance.skillPoints;
			saveData.skillAllocation = new Dictionary<UpgradeType, int>();
			SaveData saveData2 = saveData;
			foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills)
			{
				LethalPlugin.Log.LogInfo((object)$"Skill is {skill.Key} and value is {skill.Value.GetLevel()}");
				saveData2.skillAllocation.Add(skill.Key, skill.Value.GetLevel());
			}
			LethalPlugin.Log.LogInfo((object)$"Invoke saveProfileDataClientMessage({num}, {JsonConvert.SerializeObject((object)saveData2)})");
			LP_NetworkManager.xpInstance.saveProfileDataClientMessage.SendServer(JsonConvert.SerializeObject((object)new SaveProfileData(num, saveData2)));
		}

		public static void Save(ulong steamid, SaveData data)
		{
			saveFileSlot = GameNetworkManager.Instance.saveFileNum;
			LethalPlugin.Log.LogInfo((object)$"Saving to slot {saveFileSlot + 1} in {GetSavePath()}");
			if (!Directory.Exists(GetSavePath()))
			{
				Directory.CreateDirectory(GetSavePath());
			}
			File.WriteAllText(GetSavePath() + steamid + ".json", JsonConvert.SerializeObject((object)data));
		}

		public static void SaveShared(int xp, int level, int quota)
		{
			saveFileSlot = GameNetworkManager.Instance.saveFileNum;
			LethalPlugin.Log.LogInfo((object)("Saving to slot " + saveFileSlot + 1));
			if (!Directory.Exists(GetSavePath()))
			{
				Directory.CreateDirectory(GetSavePath());
			}
			File.WriteAllText(GetSavePath() + "shared.json", JsonConvert.SerializeObject((object)new SaveSharedData(xp, level, quota)));
		}

		public static void DeleteSave(int _saveFileSlot)
		{
			saveFileSlot = _saveFileSlot;
			if (Directory.Exists(GetSavePath()))
			{
				Directory.Delete(Application.persistentDataPath + "/lethalprogression/save" + (saveFileSlot + 1), recursive: true);
			}
		}

		public static string GetSavePath()
		{
			return Application.persistentDataPath + "/lethalprogression/save" + (saveFileSlot + 1) + "/";
		}

		public static string LoadPlayerFile(ulong steamId)
		{
			saveFileSlot = GameNetworkManager.Instance.saveFileNum;
			if (!File.Exists(GetSavePath() + steamId + ".json"))
			{
				LethalPlugin.Log.LogInfo((object)$"Player file for {steamId} doesn't exist");
				return null;
			}
			LethalPlugin.Log.LogInfo((object)$"Player file for {steamId} found");
			return File.ReadAllText(GetSavePath() + steamId + ".json");
		}

		public static SaveSharedData? LoadSharedFile()
		{
			saveFileSlot = GameNetworkManager.Instance.saveFileNum;
			if (!File.Exists(GetSavePath() + "shared.json"))
			{
				LethalPlugin.Log.LogInfo((object)"Shared file doesn't exist");
				return null;
			}
			LethalPlugin.Log.LogInfo((object)"Shared file exists");
			string text = File.ReadAllText(GetSavePath() + "shared.json");
			return JsonConvert.DeserializeObject<SaveSharedData>(text);
		}
	}
	internal struct SaveSharedData
	{
		public int xp;

		public int level;

		public int quota;

		public SaveSharedData(int xp, int level, int quota)
		{
			this.xp = xp;
			this.level = level;
			this.quota = quota;
		}
	}
}
namespace LethalProgression.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("LethalProgression.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] skillmenu
		{
			get
			{
				object @object = ResourceManager.GetObject("skillmenu", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace LethalProgression.Patches
{
	[HarmonyPatch]
	internal class SavePatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(DeleteFileButton), "DeleteFile")]
		private static void DeleteSaveFile(DeleteFileButton __instance)
		{
			SaveManager.DeleteSave(__instance.fileToDelete);
		}
	}
	[HarmonyPatch]
	internal class EnemyAIPatch
	{
		private static Dictionary<string, int> _enemyReward = new Dictionary<string, int>
		{
			{ "HoarderBug (EnemyType)", 30 },
			{ "BaboonBird (EnemyType)", 15 },
			{ "MouthDog (EnemyType)", 200 },
			{ "Centipede (EnemyType)", 30 },
			{ "Flowerman (EnemyType)", 200 },
			{ "SandSpider (EnemyType)", 50 },
			{ "Crawler (EnemyType)", 50 },
			{ "Puffer (EnemyType)", 15 }
		};

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
		private static void CalculateXPForEnemyDeath(EnemyAI __instance)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				string text = ((object)__instance.enemyType).ToString();
				LethalPlugin.Log.LogInfo((object)("Enemy type: " + text));
				int num = 30;
				if (_enemyReward.ContainsKey(text))
				{
					num = _enemyReward[text];
				}
				LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(num);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyAI), "HitEnemyServerRpc")]
		private static void HitEnemyTrigger(EnemyAI __instance, int force, int playerWhoHit)
		{
			LethalPlugin.Log.LogInfo((object)$"Player {playerWhoHit} hit enemy {((object)__instance).GetType()} with force {force}");
		}
	}
	[HarmonyPatch]
	internal class GameNetworkManagerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		private static void DisconnectXPHandler()
		{
			if (LP_NetworkManager.xpInstance.skillList.GetSkill(UpgradeType.Value).GetLevel() != 0)
			{
				int level = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetLevel();
				LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(-level);
			}
			HandSlots.currentSlotCount = 4;
			LethalPlugin.SkillsGUI.CleanupGUI();
			LethalPlugin.SkillsGUI.CloseSkillMenu();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameNetworkManager), "SaveGame")]
		[HarmonyPriority(800)]
		private static void SaveGamePrefix()
		{
			LethalPlugin.Log.LogDebug((object)"Invoked DoSave via SaveGame");
			SaveManager.TriggerHostProfileSave();
		}
	}
	[HarmonyPatch]
	internal class GrabbableObjectPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GrabbableObject), "UseItemBatteries")]
		private static IEnumerable<CodeInstruction> UseItemBatteriesTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			return BatteryLife.UseItemBatteriesOpCode(codes);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GrabbableObject), "Update")]
		private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			return BatteryLife.BatteryDegradeUpdateOpCode(codes);
		}
	}
	[HarmonyPatch]
	internal class HUDManagerPatch
	{
		private static GameObject _tempBar;

		private static GameObject _bottomMiddle;

		private static TextMeshProUGUI _tempText;

		private static float _tempBarTime;

		private static GameObject levelText;

		private static float levelTextTime;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HUDManager), "AddNewScrapFoundToDisplay")]
		private static void GiveXPForScrap(GrabbableObject GObject)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				int scrapValue = GObject.scrapValue;
				float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier();
				float num = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier;
				float num2 = 1f + num / 100f;
				int num3 = (int)Math.Floor((float)scrapValue / num2);
				LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(num3);
			}
		}

		public static void ShowXPUpdate()
		{
			if (!Object.op_Implicit((Object)(object)_tempBar))
			{
				MakeBar();
			}
			LC_XP xpInstance = LP_NetworkManager.xpInstance;
			GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPBarProgress");
			val.GetComponent<Image>().fillAmount = (float)xpInstance.teamXP.Value / (float)xpInstance.CalculateXPRequirement();
			((TMP_Text)_tempText).text = xpInstance.teamXP.Value + " / " + (float)xpInstance.CalculateXPRequirement();
			_tempBarTime = 2f;
			if (!_tempBar.activeSelf)
			{
				((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(XPBarCoroutine());
			}
		}

		private static IEnumerator XPBarCoroutine()
		{
			_tempBar.SetActive(true);
			while (_tempBarTime > 0f)
			{
				float time = _tempBarTime;
				_tempBarTime = 0f;
				yield return (object)new WaitForSeconds(time);
			}
			_tempBar.SetActive(false);
		}

		public static void ShowLevelUp()
		{
			if (!Object.op_Implicit((Object)(object)levelText))
			{
				MakeLevelUp();
			}
			levelTextTime = 5f;
			if (!levelText.gameObject.activeSelf)
			{
				((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(LevelUpCoroutine());
			}
		}

		public static void MakeLevelUp()
		{
			levelText = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("LevelUp"));
			((TMP_Text)((Component)levelText.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "Level Up! Spend your skill points.";
			levelText.gameObject.SetActive(false);
		}

		private static IEnumerator LevelUpCoroutine()
		{
			levelText.gameObject.SetActive(true);
			while (levelTextTime > 0f)
			{
				float time = levelTextTime;
				levelTextTime = 0f;
				yield return (object)new WaitForSeconds(time);
			}
			levelText.gameObject.SetActive(false);
		}

		private static void MakeBar()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			LethalPlugin.XPBarGUI.CreateAllObjectsIfRequired();
			GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD");
			GameObject val2 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle");
			_bottomMiddle = Object.Instantiate<GameObject>(val2);
			_bottomMiddle.transform.SetParent(val.transform, false);
			((Object)_bottomMiddle).name = "BottomMiddleXPStatus";
			foreach (Transform item in _bottomMiddle.transform)
			{
				Transform val3 = item;
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
			GameObject val4 = GameObject.Find("/Systems/UI/Canvas/QuickMenu/XpInfoContainer/XPBar");
			_tempBar = Object.Instantiate<GameObject>(val4);
			((Object)_tempBar).name = "XPUpdate";
			_tempBar.SetActive(false);
			_tempText = _tempBar.GetComponentInChildren<TextMeshProUGUI>();
			_tempBar.transform.SetParent(_bottomMiddle.transform, false);
			_tempBar.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
			GameObject val5 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPLevel");
			Object.Destroy((Object)(object)val5);
			GameObject val6 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPProfit");
			Object.Destroy((Object)(object)val6);
			Vector3 localPosition = _bottomMiddle.transform.localPosition;
			float x = _bottomMiddle.GetComponent<RectTransform>().sizeDelta.x;
			float x2 = _tempBar.GetComponent<RectTransform>().sizeDelta.x;
			LethalPlugin.Log.LogInfo((object)$"Move Bar {x} {x2}");
			_tempBar.transform.Translate(0f, 0f, 0f);
			_tempBar.transform.localPosition = new Vector3(x + 50f, localPosition.y - 30f, localPosition.z);
		}
	}
	[HarmonyPatch]
	internal class PlayerControllerBPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		private static void ConnectClientToPlayerObjectHandler()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ulong num = SteamId.op_Implicit(SteamClient.SteamId);
			LethalPlugin.Log.LogInfo((object)$"Player {num} has joined the game.");
			LP_NetworkManager.xpInstance.requestProfileDataClientMessage.SendServer(num);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static IEnumerable<CodeInstruction> PlayerJumpTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			return JumpHeight.PlayerJumpOpCode(codes);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")]
		private static IEnumerable<CodeInstruction> Jump_performedTransplier(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			return Stamina.PlayerJumpStaminaOpCode(codes);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			codes = JumpHeight.PlayerJumpOpCode(codes);
			return SprintSpeed.PlayerSprintSpeedOpCode(codes);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		private static IEnumerable<CodeInstruction> LateUpdateTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			codes = HPRegen.DisableBaseGameHPRegen(codes);
			return Stamina.PlayerSprintTimeOpCode(codes);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		private static void HPRegenUpdate(PlayerControllerB __instance)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen))
			{
				return;
			}
			if (__instance.healthRegenerateTimer > 0f)
			{
				__instance.healthRegenerateTimer -= Time.deltaTime;
				return;
			}
			Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.HPRegen];
			__instance.healthRegenerateTimer = 1f / skill.GetTrueValue();
			__instance.health++;
			if (__instance.health >= 20)
			{
				__instance.MakeCriticallyInjured(false);
			}
			if (((NetworkBehaviour)__instance).IsOwner && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject) && __instance.isPlayerControlled && __instance.health < 100 && !__instance.isPlayerDead)
			{
				HUDManager.Instance.UpdateHealthUI(__instance.health, false);
			}
		}
	}
	[HarmonyPatch]
	internal class QuickMenuManagerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")]
		private static void OpenQuickMenu_Postfix(QuickMenuManager __instance)
		{
			if (__instance.isMenuOpen)
			{
				LethalPlugin.XPBarGUI.Show();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "Update")]
		private static void QuickMenuManager_Postfix(QuickMenuManager __instance)
		{
			LethalPlugin.XPBarGUI.Update(__instance.mainButtonsPanel.activeSelf);
			if (!LethalPlugin.SkillsGUI.isMenuOpen)
			{
				LethalPlugin.SkillsGUI.CloseSkillMenu();
				return;
			}
			IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
			if (active.enableUnspecInShip && !active.disableUnspec)
			{
				if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)
				{
					LethalPlugin.SkillsGUI.SetUnspec(show: true);
				}
				else
				{
					LethalPlugin.SkillsGUI.SetUnspec(show: false);
				}
			}
			if (active.enableUnspecInOrbit)
			{
				if (StartOfRound.Instance.inShipPhase)
				{
					LethalPlugin.SkillsGUI.SetUnspec(show: true);
				}
				else
				{
					LethalPlugin.SkillsGUI.SetUnspec(show: false);
				}
			}
			if (active.disableUnspec)
			{
				LethalPlugin.SkillsGUI.SetUnspec(show: false);
			}
			LethalPlugin.SkillsGUI.OpenSkillMenu();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
		private static void SkillMenuClose()
		{
			LethalPlugin.SkillsGUI.CloseSkillMenu();
		}
	}
	[HarmonyPatch]
	internal class RoundManagerPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
		private static IEnumerable<CodeInstruction> SpawnScrapInLevelTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
			return LootValue.ScrapValueMultiplierOpCode(codes);
		}
	}
	[HarmonyPatch]
	internal class StartOfRoundPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")]
		private static void ResetXPValues(StartOfRound __instance)
		{
			IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
			if (active.keepProgress)
			{
				return;
			}
			LC_XP xpInstance = LP_NetworkManager.xpInstance;
			int saveFileSlot = GameNetworkManager.Instance.saveFileNum + 1;
			SaveManager.DeleteSave(saveFileSlot);
			xpInstance.teamXPRequired.Value = xpInstance.CalculateXPRequirement();
			foreach (Skill value in xpInstance.skillList.skills.Values)
			{
				value.SetLevel(0);
			}
			xpInstance.SetSkillPoints(5);
			xpInstance.teamXP.Value = 0;
			xpInstance.teamTotalValue.Value = 0;
			xpInstance.teamLevel.Value = 0;
			xpInstance.teamLootLevel.Value = 0;
		}
	}
	[HarmonyPatch]
	internal class TimeOfDayPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")]
		private static void ProfitQuotaUpdate(TimeOfDay __instance)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				LP_NetworkManager.xpInstance.teamXPRequired.Value = LP_NetworkManager.xpInstance.CalculateXPRequirement();
			}
		}
	}
}
namespace LethalProgression.LessShitConfig
{
	public static class LessShitConfigSystem
	{
		private static readonly IDictionary<ConfigDefinition, ConfigEntryData> entries = new Dictionary<ConfigDefinition, ConfigEntryData>();

		private static readonly IDictionary<Type, ConfigSectionData> sections = new Dictionary<Type, ConfigSectionData>();

		private static readonly IDictionary<Type, LocalConfigBase> localSections = new Dictionary<Type, LocalConfigBase>();

		private static readonly IDictionary<Type, DictionaryOverlayConfigBase> activeSections = new Dictionary<Type, DictionaryOverlayConfigBase>();

		private static readonly IDictionary<ConfigDefinition, object> hostConfigOverlay = new Dictionary<ConfigDefinition, object>();

		public static object ActiveConfig { get; internal set; }

		public static void RegisterSection<T>()
		{
			Type typeFromHandle = typeof(T);
			LethalPlugin.Log.LogInfo((object)("RegisterSection: " + typeFromHandle.FullName));
			if (sections.ContainsKey(typeFromHandle))
			{
				throw new ConfigRegistrationException("The config section defintion has already been registered: " + typeFromHandle.FullName);
			}
			ConfigSectionData configSectionData = new ConfigSectionData(typeFromHandle);
			sections[typeFromHandle] = configSectionData;
			foreach (ConfigEntryData entry in configSectionData.Entries)
			{
				entries[entry.Definition] = entry;
			}
		}

		public static void Bake(ConfigFile configFile)
		{
			if (configFile == null)
			{
				throw new ArgumentNullException("config");
			}
			if (localSections.Count > 0)
			{
				throw new InvalidOperationException("Calling Bind multiple times is not allowed.");
			}
			foreach (ConfigEntryData value in entries.Values)
			{
				value.Bind(configFile);
			}
			foreach (KeyValuePair<Type, ConfigSectionData> section in sections)
			{
				LocalConfigSectionClassBuilder localConfigSectionClassBuilder = new LocalConfigSectionClassBuilder(section.Value, configFile);
				foreach (ConfigEntryData entry in section.Value.Entries)
				{
					localConfigSectionClassBuilder.AddEntry(entry);
				}
				LocalConfigBase localConfigBase = localConfigSectionClassBuilder.Build();
				localSections[section.Key] = localConfigBase;
				DictionaryOverlayConfigSectionClassBuilder dictionaryOverlayConfigSectionClassBuilder = new DictionaryOverlayConfigSectionClassBuilder(section.Value, localConfigBase, hostConfigOverlay);
				foreach (ConfigEntryData entry2 in section.Value.Entries)
				{
					dictionaryOverlayConfigSectionClassBuilder.AddEntry(entry2);
				}
				activeSections[section.Key] = dictionaryOverlayConfigSectionClassBuilder.Build();
			}
		}

		internal static T GetActive<T>()
		{
			return (T)(object)activeSections[typeof(T)];
		}

		internal static string SerializeLocalConfigs()
		{
			IDictionary<string, IDictionary<string, string>> dictionary = new Dictionary<string, IDictionary<string, string>>();
			foreach (ConfigEntryData value2 in entries.Values)
			{
				string section = value2.Definition.Section;
				string key = value2.Definition.Key;
				if (!dictionary.ContainsKey(section))
				{
					dictionary[section] = new Dictionary<string, string>();
				}
				object value = localSections[value2.Section.InterfaceType].GetValue(value2.Definition);
				dictionary[section][key] = TomlTypeConverter.ConvertToString(value, value2.Property.PropertyType);
			}
			return JsonConvert.SerializeObject((object)dictionary);
		}

		internal static void ApplyHostConfigs(string configString)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			IDictionary<string, IDictionary<string, string>> dictionary = JsonConvert.DeserializeObject<IDictionary<string, IDictionary<string, string>>>(configString);
			foreach (KeyValuePair<string, IDictionary<string, string>> item in dictionary)
			{
				foreach (KeyValuePair<string, string> item2 in item.Value)
				{
					ConfigDefinition val = new ConfigDefinition(item.Key, item2.Key);
					Type propertyType = entries[val].Property.PropertyType;
					hostConfigOverlay[val] = TomlTypeConverter.ConvertToValue(item2.Value, propertyType);
					LethalPlugin.Log.LogInfo((object)$"Applied host config override: {val} = {item2.Value}");
				}
			}
		}

		internal static void ClearHostConfigs()
		{
			hostConfigOverlay.Clear();
			LethalPlugin.Log.LogInfo((object)"Cleared host config overrides");
		}
	}
}
namespace LethalProgression.LessShitConfig.Internal
{
	public class ConfigEntryData
	{
		public readonly ConfigSectionData Section;

		public readonly PropertyInfo Property;

		public readonly ConfigDefinition Definition;

		public readonly ConfigDescription Description;

		public readonly object DefaultValue;

		public ConfigEntryData(ConfigSectionData section, PropertyInfo property)
		{
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			if (!TomlTypeConverter.CanConvert(property.PropertyType))
			{
				throw new ConfigRegistrationException("There is no TOML converter registered for " + property.PropertyType.FullName + " entries: " + section.InterfaceType.FullName);
			}
			if (property.CanWrite)
			{
				throw new ConfigRegistrationException("Config section entries must not have property setter: (" + property.Name + " in " + section.InterfaceType.FullName + ")");
			}
			if (!property.CanRead)
			{
				throw new ConfigRegistrationException("Config section entries must have property getter: (" + property.Name + " in " + section.InterfaceType.FullName + ")");
			}
			ConfigNameAttribute customAttribute = property.GetCustomAttribute<ConfigNameAttribute>();
			if (customAttribute == null)
			{
				throw new ConfigRegistrationException("Config section must have a named defined with Configname (" + property.Name + " in " + section.InterfaceType.FullName + ")");
			}
			ConfigDescriptionAttribute customAttribute2 = property.GetCustomAttribute<ConfigDescriptionAttribute>();
			ConfigDefaultAttribute customAttribute3 = property.GetCustomAttribute<ConfigDefaultAttribute>(inherit: true);
			LethalPlugin.Log.LogInfo((object)("Register Property: " + section.Name + " " + customAttribute.name));
			Section = section;
			Property = property;
			Definition = new ConfigDefinition(section.Name, customAttribute.name);
			Description = customAttribute2?.Description;
			DefaultValue = ResolveDefaultValue(customAttribute3);
		}

		private object ResolveDefaultValue(ConfigDefaultAttribute defaultValue)
		{
			if (defaultValue != null)
			{
				return defaultValue.Value;
			}
			return Property.PropertyType.IsValueType ? Activator.CreateInstance(Property.PropertyType) : null;
		}

		public void Bind(ConfigFile file)
		{
			MethodInfo methodInfo = typeof(ConfigFile).GetMethod("Bind", new Type[3]
			{
				typeof(ConfigDefinition),
				Type.MakeGenericMethodParameter(0),
				typeof(ConfigDescription)
			}).MakeGenericMethod(Property.PropertyType);
			methodInfo.Invoke(file, new List<object> { Definition, DefaultValue, Description }.ToArray());
		}
	}
	public class ConfigRegistrationException : Exception
	{
		public ConfigRegistrationException(string message)
			: base(message)
		{
		}
	}
	public class ConfigSectionData
	{
		public readonly Type InterfaceType;

		public readonly ICollection<ConfigEntryData> Entries;

		public readonly string Name;

		public ConfigDescription Description { get; private set; }

		public ConfigSectionData(Type type)
		{
			if (!type.IsInterface)
			{
				throw new ConfigRegistrationException("Config section definitions must be interfaces: " + type.FullName);
			}
			ConfigSectionAttribute customAttribute = type.GetCustomAttribute<ConfigSectionAttribute>();
			if (customAttribute == null)
			{
				throw new ConfigRegistrationException("Cannot register a config section without a ConfigSection attribute: " + type.FullName);
			}
			Name = customAttribute.section;
			InterfaceType = type;
			Entries = new List<ConfigEntryData>();
			MemberInfo[] members = type.GetMembers();
			foreach (MemberInfo memberInfo in members)
			{
				if (memberInfo.MemberType != MemberTypes.Property)
				{
					if (memberInfo.MemberType != MemberTypes.Method || !((MethodInfo)memberInfo).Name.StartsWith("get_"))
					{
						throw new ConfigRegistrationException($"Non-property members are not allowed in config section definitions: ({memberInfo.Name} is {memberInfo.MemberType})");
					}
				}
				else
				{
					LethalPlugin.Log.LogInfo((object)("Register: " + type.Name + " = " + memberInfo.Name));
					ConfigEntryData item = new ConfigEntryData(this, (PropertyInfo)memberInfo);
					Entries.Add(item);
				}
			}
		}
	}
}
namespace LethalProgression.LessShitConfig.Internal.ClassBuilders
{
	public abstract class ConfigSectionClassBuilder
	{
		protected static readonly MethodAttributes propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName;

		protected static readonly MethodInfo AbstractConfigBase_GetDefinitionMethod = typeof(AbstractConfigBase).GetMethod("GetDefinition", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);

		protected readonly TypeBuilder typeBuilder;

		protected readonly ILGenerator constructorGenerator;

		protected readonly ConfigSectionData sectionData;

		protected abstract Type ConfigBaseType { get; }

		protected abstract ConstructorInfo BaseConstructor { get; }

		public ConfigSectionClassBuilder(ConfigSectionData section)
		{
			sectionData = section;
			string text = "DynamicConfigClass_" + ConfigBaseType.Name + "_" + section.Name;
			AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(text), AssemblyBuilderAccess.Run);
			ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(text);
			typeBuilder = moduleBuilder.DefineType(ConfigBaseType.Name + "_" + section.Name, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.BeforeFieldInit, ConfigBaseType, new Type[1] { section.InterfaceType });
			Type[] parameterTypes = (from param in BaseConstructor.GetParameters()
				select param.ParameterType).ToArray();
			ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, parameterTypes);
			constructorGenerator = constructorBuilder.GetILGenerator();
			AppendBaseConstructorOpcodes();
		}

		protected abstract void AppendBaseConstructorOpcodes();

		public void AddEntry(ConfigEntryData entry)
		{
			PropertyInfo property = entry.Property;
			Type propertyType = property.PropertyType;
			string fieldName = "Definition_" + property.Name;
			FieldBuilder field = typeBuilder.DefineField(fieldName, typeof(ConfigDefinition), FieldAttributes.Private);
			MethodInfo methodInfo = ConfigBaseType.GetMethods().First((MethodInfo m) => m.Name == "GetValue" && m.IsGenericMethod);
			constructorGenerator.Emit(OpCodes.Ldarg_0);
			constructorGenerator.Emit(OpCodes.Ldarg_0);
			constructorGenerator.Emit(OpCodes.Ldstr, entry.Definition.Key);
			constructorGenerator.Emit(OpCodes.Callvirt, AbstractConfigBase_GetDefinitionMethod);
			constructorGenerator.Emit(OpCodes.Stfld, field);
			string name = "get_" + property.Name;
			MethodBuilder methodBuilder = typeBuilder.DefineMethod(name, propertyMethodAttributes, propertyType, Type.EmptyTypes);
			ILGenerator iLGenerator = methodBuilder.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldfld, field);
			iLGenerator.Emit(OpCodes.Callvirt, methodInfo.MakeGenericMethod(propertyType));
			iLGenerator.Emit(OpCodes.Ret);
			PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(property.Name, PropertyAttributes.None, propertyType, Type.EmptyTypes);
			propertyBuilder.SetGetMethod(methodBuilder);
		}

		public AbstractConfigBase Build()
		{
			constructorGenerator.Emit(OpCodes.Ret);
			Type type = typeBuilder.CreateType();
			return ConstructGeneratedType(type);
		}

		protected abstract AbstractConfigBase ConstructGeneratedType(Type type);
	}
	public class DictionaryOverlayConfigSectionClassBuilder : ConfigSectionClassBuilder
	{
		private readonly AbstractConfigBase baseConfig;

		private readonly IDictionary<ConfigDefinition, object> overlay;

		protected override Type ConfigBaseType => typeof(DictionaryOverlayConfigBase);

		protected override ConstructorInfo BaseConstructor => ConfigBaseType.GetConstructor(new Type[3]
		{
			typeof(string),
			typeof(AbstractConfigBase),
			typeof(Dictionary<ConfigDefinition, object>)
		});

		public DictionaryOverlayConfigSectionClassBuilder(ConfigSectionData section, AbstractConfigBase baseConfig, IDictionary<ConfigDefinition, object> overlay)
			: base(section)
		{
			this.baseConfig = baseConfig;
			this.overlay = overlay;
		}

		protected override void AppendBaseConstructorOpcodes()
		{
			constructorGenerator.Emit(OpCodes.Ldarg_0);
			constructorGenerator.Emit(OpCodes.Ldarg_1);
			constructorGenerator.Emit(OpCodes.Ldarg_2);
			constructorGenerator.Emit(OpCodes.Ldarg_3);
			constructorGenerator.Emit(OpCodes.Call, BaseConstructor);
		}

		protected override AbstractConfigBase ConstructGeneratedType(Type type)
		{
			return (AbstractConfigBase)Activator.CreateInstance(type, sectionData.Name, baseConfig, overlay);
		}

		public new DictionaryOverlayConfigBase Build()
		{
			return (DictionaryOverlayConfigBase)base.Build();
		}
	}
	public class LocalConfigSectionClassBuilder : ConfigSectionClassBuilder
	{
		private readonly ConfigFile configFile;

		protected override Type ConfigBaseType => typeof(LocalConfigBase);

		protected override ConstructorInfo BaseConstructor => ConfigBaseType.GetConstructor(new Type[2]
		{
			typeof(string),
			typeof(ConfigFile)
		});

		public LocalConfigSectionClassBuilder(ConfigSectionData section, ConfigFile config)
			: base(section)
		{
			configFile = config;
		}

		protected override void AppendBaseConstructorOpcodes()
		{
			constructorGenerator.Emit(OpCodes.Ldarg_0);
			constructorGenerator.Emit(OpCodes.Ldarg_1);
			constructorGenerator.Emit(OpCodes.Ldarg_2);
			constructorGenerator.Emit(OpCodes.Call, BaseConstructor);
		}

		protected override AbstractConfigBase ConstructGeneratedType(Type type)
		{
			return (AbstractConfigBase)Activator.CreateInstance(type, sectionData.Name, configFile);
		}

		public new LocalConfigBase Build()
		{
			return (LocalConfigBase)base.Build();
		}
	}
}
namespace LethalProgression.LessShitConfig.Sources
{
	public abstract class AbstractConfigBase
	{
		private string sectionName;

		protected AbstractConfigBase(string sectionName)
		{
			this.sectionName = sectionName;
		}

		protected ConfigDefinition GetDefinition(string key)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new ConfigDefinition(sectionName, key);
		}

		public abstract object GetValue(ConfigDefinition definition);

		public abstract T GetValue<T>(ConfigDefinition definition);
	}
	public abstract class DictionaryOverlayConfigBase : AbstractConfigBase
	{
		private readonly AbstractConfigBase baseConfig;

		private readonly IDictionary<ConfigDefinition, object> overlay;

		public DictionaryOverlayConfigBase(string sectionName, AbstractConfigBase baseConfig, IDictionary<ConfigDefinition, object> overlay)
			: base(sectionName)
		{
			this.baseConfig = baseConfig;
			this.overlay = overlay;
		}

		public override object GetValue(ConfigDefinition definition)
		{
			if (overlay.TryGetValue(definition, out var value))
			{
				return value;
			}
			return baseConfig.GetValue(definition);
		}

		public override T GetValue<T>(ConfigDefinition definition)
		{
			if (overlay.TryGetValue(definition, out var value))
			{
				return (T)value;
			}
			return baseConfig.GetValue<T>(definition);
		}
	}
	public abstract class LocalConfigBase : AbstractConfigBase
	{
		private readonly ConfigFile configFile;

		public LocalConfigBase(string sectionName, ConfigFile config)
			: base(sectionName)
		{
			configFile = config;
		}

		public override object GetValue(ConfigDefinition definition)
		{
			IDictionary<ConfigDefinition, ConfigEntryBase> dictionary = (IDictionary<ConfigDefinition, ConfigEntryBase>)configFile;
			if (dictionary.TryGetValue(definition, out var value))
			{
				return value.BoxedValue;
			}
			throw new ArgumentException($"The config entry {definition} is not registered.", "definition");
		}

		public override T GetValue<T>(ConfigDefinition definition)
		{
			ConfigEntry<T> val = default(ConfigEntry<T>);
			if (configFile.TryGetEntry<T>(definition, ref val))
			{
				return val.Value;
			}
			throw new ArgumentException($"The config entry {definition} is not registered.", "definition");
		}
	}
}
namespace LethalProgression.LessShitConfig.Attributes
{
	[AttributeUsage(AttributeTargets.Property)]
	public class ConfigDefaultAttribute : Attribute
	{
		public object Value;

		public ConfigDefaultAttribute(object value)
		{
			Value = value;
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigDescriptionAttribute : Attribute
	{
		public readonly ConfigDescription Description;

		public ConfigDescriptionAttribute(string description)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Description = new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>());
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigNameAttribute : Attribute
	{
		public readonly string name;

		public ConfigNameAttribute(string name)
		{
			this.name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Interface)]
	internal class ConfigSectionAttribute : Attribute
	{
		public readonly string section;

		public ConfigSectionAttribute(string section)
		{
			this.section = section;
		}
	}
}
namespace LethalProgression.GUI.XPBar
{
	internal class XPBarGUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OpenSkillTree;
		}

		private GameObject xpBar;

		private GameObject xpInfoContainer;

		private GameObject xpBarProgress;

		private GameObject skillTreeButton;

		private TextMeshProUGUI xpText;

		private TextMeshProUGUI xpLevel;

		private TextMeshProUGUI profit;

		public void Show()
		{
			CreateAllObjectsIfRequired();
			xpBar.SetActive(true);
			xpBarProgress.SetActive(true);
		}

		public void Update(bool active)
		{
			CreateAllObjectsIfRequired();
			LC_XP xpInstance = LP_NetworkManager.xpInstance;
			xpInfoContainer.SetActive(active);
			((TMP_Text)xpText).text = $"{xpInstance.GetXP()} / {xpInstance.teamXPRequired.Value}";
			((TMP_Text)xpLevel).text = $"Level: {xpInstance.GetLevel()}";
			((TMP_Text)profit).text = $"You've made.. {xpInstance.GetProfit()}$";
			xpBarProgress.GetComponent<Image>().fillAmount = (float)xpInstance.GetXP() / (float)xpInstance.teamXPRequired.Value;
		}

		private void CreateContainer()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)xpInfoContainer))
			{
				GameObject val = GameObject.Find("/Systems/UI/Canvas/QuickMenu");
				xpInfoContainer = new GameObject("XpInfoContainer");
				xpInfoContainer.transform.SetParent(val.transform, false);
				xpInfoContainer.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f);
				xpInfoContainer.transform.Translate(-1.7f, 0.9f, 0f);
			}
		}

		private void CreateXPBar()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)xpBar))
			{
				GameObject val = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpBox");
				GameObject val2 = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/Total");
				xpBar = Object.Instantiate<GameObject>(val);
				((Object)xpBar).name = "XPBar";
				xpBar.transform.SetParent(xpInfoContainer.transform, false);
				xpText = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>();
				((Object)xpText).name = "XPText";
				((TMP_Text)xpText).SetText("0/1000", true);
				((TMP_Text)xpText).alignment = (TextAlignmentOptions)514;
				((Graphic)xpText).color = new Color(1f, 0.6f, 0f, 1f);
				((TMP_Text)xpText).transform.SetParent(xpBar.transform, false);
				((TMP_Text)xpText).transform.Translate(-0.75f, 0.21f, 0f);
				xpLevel = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>();
				((Object)xpLevel).name = "XPLevel";
				((TMP_Text)xpLevel).SetText("Level: 0", true);
				((TMP_Text)xpLevel).alignment = (TextAlignmentOptions)514;
				((Graphic)xpLevel).color = new Color(1f, 0.6f, 0f, 1f);
				((TMP_Text)xpLevel).transform.SetParent(xpInfoContainer.transform, false);
				((TMP_Text)xpLevel).transform.position = new Vector3(xpBar.transform.position.x, xpBar.transform.position.y, xpBar.transform.position.z);
				((TMP_Text)xpLevel).transform.Translate(-0.3f, 0.2f, 0f);
				profit = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>();
				((Object)profit).name = "XPProfit";
				((TMP_Text)profit).SetText("You've made.. 0$.", true);
				((Graphic)profit).color = new Color(1f, 0.6f, 0f, 1f);
				((TMP_Text)profit).alignment = (TextAlignmentOptions)514;
				((TMP_Text)profit).transform.SetParent(xpInfoContainer.transform, false);
				((TMP_Text)profit).transform.position = new Vector3(xpBar.transform.position.x, xpBar.transform.position.y, xpBar.transform.position.z);
				((TMP_Text)profit).transform.Translate(-0.1f, -0.2f, 0f);
			}
		}

		private void CreateXPBarProgress()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)xpBarProgress))
			{
				GameObject val = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpMeter");
				xpBarProgress = Object.Instantiate<GameObject>(val);
				((Object)xpBarProgress).name = "XPBarProgress";
				xpBarProgress.GetComponent<Image>().fillAmount = 0f;
				xpBarProgress.transform.SetParent(xpBar.transform, false);
				xpBarProgress.transform.SetAsFirstSibling();
				xpBarProgress.transform.localScale = new Vector3(0.597f, 5.21f, 1f);
				xpBarProgress.transform.Translate(-0.8f, 0.2f, 0f);
				xpBarProgress.transform.localPosition = new Vector3(0f, 0f, 0f);
			}
		}

		private void CreateSkillTreeButton()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons/Resume");
			GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons");
			skillTreeButton = Object.Instantiate<GameObject>(val);
			((Object)skillTreeButton).name = "Skills";
			((TMP_Text)skillTreeButton.GetComponentInChildren<TextMeshProUGUI>()).text = "> Skills";
			skillTreeButton.transform.SetParent(val2.transform, false);
			skillTreeButton.transform.position = new Vector3(0.55f + xpBar.transform.position.x, 1.09f + xpBar.transform.position.y, xpBar.transform.position.z);
			Transform transform = ((TMP_Text)xpText).transform;
			skillTreeButton.transform.localPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z);
			Transform transform2 = skillTreeButton.transform;
			transform2.position += new Vector3(-0.15f, 1.056f);
			ButtonClickedEvent val3 = new ButtonClickedEvent();
			object obj = <>O.<0>__OpenSkillTree;
			if (obj == null)
			{
				UnityAction val4 = OpenSkillTree;
				<>O.<0>__OpenSkillTree = val4;
				obj = (object)val4;
			}
			((UnityEvent)val3).AddListener((UnityAction)obj);
			skillTreeButton.GetComponent<Button>().onClick = val3;
			Button component = xpBar.GetComponent<Button>();
			if (component == null)
			{
				component = xpBar.AddComponent<Button>();
				component.onClick = val3;
			}
			component = xpBarProgress.GetComponent<Button>();
			if (component == null)
			{
				component = xpBarProgress.AddComponent<Button>();
				component.onClick = val3;
			}
		}

		public void CreateAllObjectsIfRequired()
		{
			if (!Object.op_Implicit((Object)(object)xpInfoContainer))
			{
				CreateContainer();
			}
			if (!Object.op_Implicit((Object)(object)xpBar))
			{
				CreateXPBar();
			}
			if (!Object.op_Implicit((Object)(object)xpBarProgress))
			{
				CreateXPBarProgress();
			}
			if (!Object.op_Implicit((Object)(object)skillTreeButton))
			{
				CreateSkillTreeButton();
			}
		}

		private static void OpenSkillTree()
		{
			LethalPlugin.SkillsGUI.OpenSkillMenu();
		}
	}
}
namespace LethalProgression.GUI.Skills
{
	internal class SkillsGUI
	{
		private GameObject mainPanel;

		private GameObject infoPanel;

		private List<GameObject> skillButtonsList = new List<GameObject>();

		public bool isMenuOpen = false;

		public void OpenSkillMenu()
		{
			CreateAllObjectsIfRequired();
			isMenuOpen = true;
			mainPanel.SetActive(true);
			GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons");
			val.SetActive(false);
			GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList");
			val2.SetActive(false);
			RealTimeUpdateInfo();
		}

		public void CloseSkillMenu()
		{
			isMenuOpen = false;
			GameObject obj = mainPanel;
			if (obj != null)
			{
				obj.SetActive(false);
			}
		}

		public void CleanupGUI()
		{
			isMenuOpen = false;
			skillButtonsList = new List<GameObject>();
		}

		private void CreateAllObjectsIfRequired()
		{
			if (!Object.op_Implicit((Object)(object)mainPanel))
			{
				CreateMainSkillMenu();
			}
			if (!Object.op_Implicit((Object)(object)infoPanel))
			{
				CreateInfoPanel();
			}
		}

		private void CreateMainSkillMenu()
		{
			if (!Object.op_Implicit((Object)(object)mainPanel))
			{
				mainPanel = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("SkillMenu"));
				((Object)mainPanel).name = "SkillMenu";
				mainPanel.SetActive(false);
			}
		}

		private void CreateInfoPanel()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			infoPanel = ((Component)mainPanel.transform.GetChild(1)).gameObject;
			infoPanel.SetActive(false);
			GameObject gameObject = ((Component)mainPanel.transform.GetChild(4)).gameObject;
			gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(BackButton));
			if (LP_NetworkManager.xpInstance.skillList.skills == null)
			{
				return;
			}
			foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills)
			{
				LethalPlugin.Log.LogInfo((object)("Creating button for " + skill.Value.GetShortName()));
				GameObject val = SetupUpgradeButton(skill.Value);
				LethalPlugin.Log.LogInfo((object)"Setup passed!");
				skillButtonsList.Add(val);
				LethalPlugin.Log.LogInfo((object)"Added to skill list..");
				LoadSkillData(skill.Value, val);
			}
			TeamLootHudUpdate(0);
		}

		public void BackButton()
		{
			CreateAllObjectsIfRequired();
			isMenuOpen = false;
			GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons");
			val.SetActive(true);
			GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList");
			val2.SetActive(true);
		}

		public void SetUnspec(bool show)
		{
			CreateAllObjectsIfRequired();
			GameObject gameObject = ((Component)infoPanel.transform.GetChild(6)).gameObject;
			GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(7)).gameObject;
			GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(8)).gameObject;
			gameObject.SetActive(show);
			gameObject2.SetActive(show);
			gameObject3.SetActive(show);
			IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
			if (!active.disableUnspec)
			{
				GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(9)).gameObject;
				gameObject4.SetActive(!show);
			}
			if (active.enableUnspecInOrbit)
			{
				GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(9)).gameObject;
				((TMP_Text)((Component)gameObject5.transform).GetComponent<TextMeshProUGUI>()).SetText("Return to orbit to unspec.", true);
			}
		}

		public GameObject SetupUpgradeButton(Skill skill)
		{
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			CreateAllObjectsIfRequired();
			GameObject gameObject = ((Component)mainPanel.transform.GetChild(0)).gameObject;
			GameObject val = Object.Instantiate<GameObject>(gameObject);
			if (!Object.op_Implicit((Object)(object)gameObject))
			{
				LethalPlugin.Log.LogError((object)"Couldn't find template button!");
				return null;
			}
			((Object)val).name = skill.GetShortName();
			GameObject gameObject2 = ((Component)mainPanel.transform.GetChild(3)).gameObject;
			GameObject gameObject3 = ((Component)gameObject2.transform.GetChild(1)).gameObject;
			val.transform.SetParent(gameObject3.transform, false);
			GameObject gameObject4 = ((Component)val.transform.GetChild(0)).gameObject;
			((TMP_Text)gameObject4.GetComponent<TextMeshProUGUI>()).SetText(skill.GetShortName(), true);
			GameObject gameObject5 = ((Component)val.transform.GetChild(1)).gameObject;
			((TMP_Text)gameObject5.GetComponent<TextMeshProUGUI>()).SetText(skill.GetLevel().ToString(), true);
			GameObject gameObject6 = ((Component)val.transform.GetChild(2)).gameObject;
			((TMP_Text)gameObject6.GetComponent<TextMeshProUGUI>()).SetText("(" + skill.GetLevel() + " " + skill.GetAttribute() + ")", true);
			((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true);
			val.SetActive(true);
			val.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				UpdateStatInfo(skill);
			});
			return val;
		}

		public void LoadSkillData(Skill skill, GameObject skillButton)
		{
			CreateAllObjectsIfRequired();
			if (!skill._teamShared)
			{
				GameObject gameObject = ((Component)skillButton.transform.GetChild(1)).gameObject;
				((TMP_Text)gameObject.GetComponent<TextMeshProUGUI>()).SetText(skill.GetLevel().ToString(), true);
				GameObject gameObject2 = ((Component)skillButton.transform.GetChild(2)).gameObject;
				((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText($"(+{(float)skill.GetLevel() * skill.GetMultiplier()}% {skill.GetAttribute()})", true);
				((TMP_Text)skillButton.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true);
			}
		}

		public void UpdateAllStats()
		{
			CreateAllObjectsIfRequired();
			foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills)
			{
				if (!skill.Value._teamShared)
				{
					GameObject skillButton = skillButtonsList.Find((GameObject x) => ((Object)x).name == skill.Value.GetShortName());
					LoadSkillData(skill.Value, skillButton);
				}
			}
		}

		public void UpdateStatInfo(Skill skill)
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Expected O, but got Unknown
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Expected O, but got Unknown
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Expected O, but got Unknown
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Expected O, but got Unknown
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Expected O, but got Unknown
			CreateAllObjectsIfRequired();
			if (!infoPanel.activeSelf)
			{
				infoPanel.SetActive(true);
			}
			TextMeshProUGUI component = ((Component)infoPanel.transform.GetChild(0)).gameObject.GetComponent<TextMeshProUGUI>();
			TextMeshProUGUI component2 = ((Component)infoPanel.transform.GetChild(1)).gameObject.GetComponent<TextMeshProUGUI>();
			TextMeshProUGUI component3 = ((Component)infoPanel.transform.GetChild(2)).gameObject.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).SetText(skill.GetName(), true);
			if (skill.GetMaxLevel() == 99999)
			{
				((TMP_Text)component2).SetText($"{skill.GetLevel()}", true);
			}
			else
			{
				((TMP_Text)component2).SetText($"{skill.GetLevel()} / {skill.GetMaxLevel()}", true);
			}
			((TMP_Text)component3).SetText(skill.GetDescription(), true);
			GameObject gameObject = ((Component)infoPanel.transform.GetChild(3)).gameObject;
			GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(4)).gameObject;
			GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(5)).gameObject;
			gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ModifySkillPoints(skill, 5);
			});
			gameObject2.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ModifySkillPoints(skill, 2);
			});
			gameObject3.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject3.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ModifySkillPoints(skill, 1);
			});
			GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(6)).gameObject;
			GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(7)).gameObject;
			GameObject gameObject6 = ((Component)infoPanel.transform.GetChild(8)).gameObject;
			gameObject4.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject4.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ModifySkillPoints(skill, -5);
			});
			gameObject5.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject5.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ModifySkillPoints(skill, -2);
			});
			gameObject6.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject6.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ModifySkillPoints(skill, -1);
			});
		}

		public void ModifyS