Decompiled source of SkillLimitExtender v1.2.0

plugins/skill_Limit_Extender.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("skill_Limit_Extender")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cea2b9e20772a06bbb13306900b8227aabb27c88")]
[assembly: AssemblyProduct("skill_Limit_Extender")]
[assembly: AssemblyTitle("skill_Limit_Extender")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SkillLimitExtender
{
	[HarmonyPatch(typeof(Skills), "CheatRaiseSkill")]
	[HarmonyPatch(new Type[]
	{
		typeof(string),
		typeof(float),
		typeof(bool)
	})]
	internal static class SLE_CheatRaiseSkill_Transpiler
	{
		[HarmonyTranspiler]
		[HarmonyPriority(-9000)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(SkillConfigManager), "GetCap", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(SkillConfigManager), "GetCapByName", (Type[])null, (Type[])null);
			FieldInfo fieldInfo = AccessTools.Field(typeof(Skill), "m_info");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(SkillDef), "m_skill");
			if (methodInfo == null || fieldInfo == null || fieldInfo2 == null)
			{
				return list;
			}
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (!(val.opcode == OpCodes.Ldc_R4) || !(val.operand is float num) || !(Math.Abs(num - 100f) < 0.0001f))
				{
					continue;
				}
				bool flag = false;
				for (int j = Math.Max(0, i - 5); j < Math.Min(list.Count, i + 5); j++)
				{
					if (list[j].opcode == OpCodes.Call)
					{
						object operand = list[j].operand;
						if (operand != null && (operand.ToString()?.Contains("Clamp")).GetValueOrDefault())
						{
							flag = true;
							break;
						}
					}
				}
				if (!flag || !(methodInfo2 != null))
				{
					continue;
				}
				List<CodeInstruction> list2 = new List<CodeInstruction>
				{
					new CodeInstruction(OpCodes.Ldarg_1, (object)null),
					new CodeInstruction(OpCodes.Call, (object)methodInfo2),
					new CodeInstruction(OpCodes.Conv_R4, (object)null)
				};
				list[i] = list2[0];
				list.InsertRange(i + 1, list2.GetRange(1, list2.Count - 1));
				ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)"[SLE] CheatRaiseSkill: Replaced 100f with GetCapByName(name)");
					}
				}
				break;
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(SkillsDialog), "Setup")]
	internal static class SLE_Hook_SkillsDialog_LevelBars
	{
		[HarmonyPrefix]
		private static bool Prefix(SkillsDialog __instance, ref Player player)
		{
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Invalid comparison between Unknown and I4
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Invalid comparison between Unknown and I4
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected I4, but got Unknown
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Expected I4, but got Unknown
			try
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					Player obj = player;
					logger.LogInfo((object)("[SLE] SkillsDialog.Setup - Player: " + (((obj != null) ? obj.GetPlayerName() : null) ?? "null")));
				}
				if ((Object)(object)__instance == (Object)null)
				{
					ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogError((object)"[SLE] SkillsDialog instance is null - cannot proceed");
					}
					return false;
				}
				if ((Object)(object)player == (Object)null)
				{
					ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)"[SLE] SkillsDialog.Setup called with null player - attempting to get local player");
					}
					Player safeLocalPlayer = SLE_SkillHelpers.GetSafeLocalPlayer();
					if (!((Object)(object)safeLocalPlayer != (Object)null))
					{
						ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
						if (logger4 != null)
						{
							logger4.LogError((object)"[SLE] Cannot get local player - skipping SkillsDialog.Setup");
						}
						return false;
					}
					ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
					if (logger5 != null)
					{
						logger5.LogInfo((object)"[SLE] Successfully recovered local player for SkillsDialog.Setup");
					}
					player = safeLocalPlayer;
				}
				Skills skills = ((Character)player).GetSkills();
				if ((Object)(object)skills == (Object)null)
				{
					ManualLogSource logger6 = SkillLimitExtenderPlugin.Logger;
					if (logger6 != null)
					{
						logger6.LogWarning((object)"[SLE] Player skills are null - skipping SkillsDialog.Setup");
					}
					return false;
				}
				try
				{
					int cap = SkillConfigManager.GetCap((SkillType)1);
					ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
					if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
					{
						ManualLogSource logger7 = SkillLimitExtenderPlugin.Logger;
						if (logger7 != null)
						{
							logger7.LogDebug((object)$"[SLE] SkillConfigManager test - Swords cap: {cap}");
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource logger8 = SkillLimitExtenderPlugin.Logger;
					if (logger8 != null)
					{
						logger8.LogError((object)("[SLE] SkillConfigManager is in invalid state: " + ex.Message));
					}
					return false;
				}
				try
				{
					Dictionary<SkillType, Skill> value = Traverse.Create((object)skills).Field("m_skillData").GetValue<Dictionary<SkillType, Skill>>();
					if (value != null)
					{
						int num = 0;
						int num2 = 0;
						foreach (KeyValuePair<SkillType, Skill> item in value)
						{
							SkillType key = item.Key;
							Skill value2 = item.Value;
							if ((int)key <= 999)
							{
								continue;
							}
							num++;
							if (value2 == null)
							{
								ManualLogSource logger9 = SkillLimitExtenderPlugin.Logger;
								if (logger9 != null)
								{
									logger9.LogWarning((object)$"[SLE] MOD skill {key} ({(int)key}) is null in m_skillData");
								}
								continue;
							}
							SkillDef value3 = Traverse.Create((object)value2).Field("m_info").GetValue<SkillDef>();
							if (value3 != null)
							{
								continue;
							}
							num2++;
							if ((int)key == 1337)
							{
								ManualLogSource logger10 = SkillLimitExtenderPlugin.Logger;
								if (logger10 != null)
								{
									logger10.LogWarning((object)$"[SLE] MOD skill 1337 has null m_info (level={value2.m_level})");
								}
								continue;
							}
							ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
							if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
							{
								ManualLogSource logger11 = SkillLimitExtenderPlugin.Logger;
								if (logger11 != null)
								{
									logger11.LogDebug((object)$"[SLE] MOD skill {key} ({(int)key}) has null m_info (level={value2.m_level})");
								}
							}
						}
						ManualLogSource logger12 = SkillLimitExtenderPlugin.Logger;
						if (logger12 != null)
						{
							logger12.LogInfo((object)$"[SLE] Found {num} MOD skills ({num2} with null m_info)");
						}
					}
				}
				catch (Exception ex2)
				{
					ManualLogSource logger13 = SkillLimitExtenderPlugin.Logger;
					if (logger13 != null)
					{
						logger13.LogWarning((object)("[SLE] Could not check MOD skills: " + ex2.Message));
					}
				}
				ConfigEntry<bool> enableGrowthCurveDebug3 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug3 != null && enableGrowthCurveDebug3.Value)
				{
					ManualLogSource logger14 = SkillLimitExtenderPlugin.Logger;
					if (logger14 != null)
					{
						logger14.LogDebug((object)("[SLE] SkillsDialog.Setup proceeding with player: " + player.GetPlayerName()));
					}
				}
				return true;
			}
			catch (Exception arg)
			{
				ManualLogSource logger15 = SkillLimitExtenderPlugin.Logger;
				if (logger15 != null)
				{
					logger15.LogError((object)$"[SLE] SkillsDialog.Setup Prefix failed: {arg}");
				}
				return false;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPriority(-9000)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			try
			{
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(SkillConfigManager), "GetUiDenominator", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"[SLE] SkillsDialog: GetUiDenominator method missing; keeping original code");
					}
					return list;
				}
				try
				{
					float uiDenominator = SkillConfigManager.GetUiDenominator();
					if (uiDenominator <= 0f)
					{
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogWarning((object)$"[SLE] SkillsDialog: GetUiDenominator returned invalid value {uiDenominator}; keeping original code");
						}
						return list;
					}
				}
				catch (Exception ex)
				{
					ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogError((object)("[SLE] SkillsDialog: GetUiDenominator test failed: " + ex.Message + "; keeping original code"));
					}
					return list;
				}
				int num = 0;
				for (int i = 0; i < list.Count - 1; i++)
				{
					CodeInstruction val = list[i];
					CodeInstruction val2 = list[i + 1];
					if (!(val.opcode == OpCodes.Ldc_R4) || !(val.operand is float num2) || !(Math.Abs(num2 - 100f) < 0.0001f) || !(val2.opcode == OpCodes.Div))
					{
						continue;
					}
					bool flag = false;
					for (int j = i + 1; j < Math.Min(list.Count, i + 12); j++)
					{
						if (list[j].opcode == OpCodes.Callvirt)
						{
							object operand = list[j].operand;
							if (operand != null && (operand.ToString()?.Contains("SetValue")).GetValueOrDefault())
							{
								flag = true;
								break;
							}
						}
					}
					if (flag)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						list.Insert(i + 1, new CodeInstruction(OpCodes.Conv_R4, (object)null));
						i++;
						num++;
					}
				}
				ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogInfo((object)$"[SLE] SkillsDialog: Replaced {num} instances of 100f with global UI denominator");
				}
				return list;
			}
			catch (Exception arg)
			{
				ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)$"[SLE] SkillsDialog Transpiler failed: {arg}");
				}
				return instructions;
			}
		}
	}
	[HarmonyPatch(typeof(Skills), "GetSkillFactor")]
	internal static class SLE_Hook_Skills_GetSkillFactor
	{
		[HarmonyPrefix]
		private static bool Prefix(Skills __instance, SkillType skillType, ref float __result)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float num = __instance.GetSkillSafe(skillType)?.m_level ?? 0f;
				int num2 = Math.Max(1, SkillConfigManager.GetBonusCap(skillType));
				float num3 = (float)num2 / 100f;
				float num6;
				if (SkillConfigManager.IsRelative(skillType))
				{
					int cap = SkillConfigManager.GetCap(skillType);
					float num4 = ((cap > 0) ? ((float)cap) : 100f);
					float num5 = ((num4 > 0f) ? (num / num4) : 0f);
					num6 = num5 * num3;
				}
				else
				{
					float factorDenominator = SkillConfigManager.GetFactorDenominator(skillType);
					num6 = num / factorDenominator;
				}
				if (num6 < 0f)
				{
					num6 = 0f;
				}
				if (num6 > num3)
				{
					num6 = num3;
				}
				__result = num6;
				return false;
			}
			catch
			{
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(Skills), "Save")]
	internal static class SLE_Hook_Skills_Save_Cleanup
	{
		[HarmonyPrefix]
		private static bool Prefix(Skills __instance, ZPackage pkg)
		{
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected I4, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected I4, but got Unknown
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Expected I4, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Invalid comparison between Unknown and I4
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!(AccessTools.Field(typeof(Skills), "m_skillData")?.GetValue(__instance) is IDictionary<SkillType, Skill> dictionary))
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogError((object)"[SLE] Skills.Save: m_skillData is null!");
					}
					pkg.Write(2);
					pkg.Write(0);
					return false;
				}
				List<KeyValuePair<SkillType, Skill>> list = new List<KeyValuePair<SkillType, Skill>>();
				int num = 0;
				foreach (KeyValuePair<SkillType, Skill> item in dictionary)
				{
					SkillType key = item.Key;
					Skill value = item.Value;
					if (value == null)
					{
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogWarning((object)$"[SLE] Skills.Save: Skipping null skill {key}");
						}
						num++;
						continue;
					}
					try
					{
						SkillDef value2 = Traverse.Create((object)value).Field("m_info").GetValue<SkillDef>();
						if (value2 == null)
						{
							int num2 = (int)key;
							string skillKey = ((object)(SkillType)(ref key)).ToString();
							if (num2 > 999 || IsSkillDefinedInYaml(skillKey))
							{
								ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
								if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
								{
									ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
									if (logger3 != null)
									{
										logger3.LogDebug((object)$"[SLE] Skills.Save: Including custom skill {key} (ID: {num2}) with null m_info");
									}
								}
								list.Add(item);
							}
							else if ((int)key > 0)
							{
								ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
								if (logger4 != null)
								{
									logger4.LogWarning((object)$"[SLE] Skills.Save: Skipping vanilla skill {key} with null m_info");
								}
								num++;
							}
							continue;
						}
						SkillType value3 = Traverse.Create((object)value2).Field("m_skill").GetValue<SkillType>();
						int num3 = (int)key;
						if (num3 > 999)
						{
							if (!Enum.IsDefined(typeof(SkillType), value3))
							{
								ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
								if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
								{
									ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
									if (logger5 != null)
									{
										logger5.LogDebug((object)$"[SLE] Skills.Save: Including MOD skill {key} (ID: {num3}) with undefined m_info.m_skill value {value3}");
									}
								}
							}
							else
							{
								ConfigEntry<bool> enableGrowthCurveDebug3 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
								if (enableGrowthCurveDebug3 != null && enableGrowthCurveDebug3.Value)
								{
									ManualLogSource logger6 = SkillLimitExtenderPlugin.Logger;
									if (logger6 != null)
									{
										logger6.LogDebug((object)$"[SLE] Skills.Save: Including MOD skill {key} (ID: {num3})");
									}
								}
							}
							list.Add(item);
						}
						else if (!Enum.IsDefined(typeof(SkillType), value3))
						{
							ManualLogSource logger7 = SkillLimitExtenderPlugin.Logger;
							if (logger7 != null)
							{
								logger7.LogWarning((object)$"[SLE] Skills.Save: Skipping vanilla skill '{key}' (ID: {num3}) with invalid m_info.m_skill value {value3}");
							}
							num++;
						}
						else if (num3 <= 999 && value3 != key)
						{
							ManualLogSource logger8 = SkillLimitExtenderPlugin.Logger;
							if (logger8 != null)
							{
								logger8.LogWarning((object)$"[SLE] Skills.Save: Skipping skill '{key}' (ID: {num3}) with mismatched m_info.m_skill value {value3}");
							}
							num++;
						}
						else
						{
							list.Add(item);
						}
					}
					catch (Exception ex)
					{
						ManualLogSource logger9 = SkillLimitExtenderPlugin.Logger;
						if (logger9 != null)
						{
							logger9.LogWarning((object)$"[SLE] Skills.Save: Skipping skill {key} due to error: {ex.Message}");
						}
						num++;
					}
				}
				pkg.Write(2);
				pkg.Write(list.Count);
				foreach (KeyValuePair<SkillType, Skill> item2 in list)
				{
					try
					{
						Skill value4 = item2.Value;
						SkillType key2 = item2.Key;
						SkillDef value5 = Traverse.Create((object)value4).Field("m_info").GetValue<SkillDef>();
						SkillType val = ((value5 == null) ? key2 : Traverse.Create((object)value5).Field("m_skill").GetValue<SkillType>());
						pkg.Write((int)val);
						pkg.Write(value4.m_level);
						pkg.Write(value4.m_accumulator);
					}
					catch (Exception ex2)
					{
						ManualLogSource logger10 = SkillLimitExtenderPlugin.Logger;
						if (logger10 != null)
						{
							logger10.LogError((object)$"[SLE] Skills.Save: Failed to write skill {item2.Key}: {ex2.Message}");
						}
					}
				}
				if (num > 0)
				{
					ManualLogSource logger11 = SkillLimitExtenderPlugin.Logger;
					if (logger11 != null)
					{
						logger11.LogWarning((object)$"[SLE] Skills.Save: Saved {list.Count} valid skills, skipped {num} invalid skills");
					}
				}
				else
				{
					ConfigEntry<bool> enableGrowthCurveDebug4 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
					if (enableGrowthCurveDebug4 != null && enableGrowthCurveDebug4.Value)
					{
						ManualLogSource logger12 = SkillLimitExtenderPlugin.Logger;
						if (logger12 != null)
						{
							logger12.LogDebug((object)$"[SLE] Skills.Save: Successfully saved {list.Count} skills");
						}
					}
				}
				return false;
			}
			catch (Exception arg)
			{
				ManualLogSource logger13 = SkillLimitExtenderPlugin.Logger;
				if (logger13 != null)
				{
					logger13.LogError((object)$"[SLE] Skills.Save replacement failed: {arg}");
				}
				return true;
			}
		}

		private static bool IsSkillDefinedInYaml(string skillKey)
		{
			try
			{
				if (typeof(SkillConfigManager).GetField("_entriesByName", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) is Dictionary<string, YamlExporter.SkillYamlEntry> dictionary)
				{
					return dictionary.ContainsKey(skillKey);
				}
				return false;
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class SLE_SkillsExtensions
	{
		private static readonly MethodInfo _miGetSkill = AccessTools.Method(typeof(Skills), "GetSkill", new Type[1] { typeof(SkillType) }, (Type[])null);

		private static readonly FieldInfo _fiSkillData = AccessTools.Field(typeof(Skills), "m_skillData");

		internal static Skill? GetSkillSafe(this Skills skills, SkillType st)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)skills == (Object)null)
			{
				return null;
			}
			if (_miGetSkill != null)
			{
				try
				{
					return (Skill)_miGetSkill.Invoke(skills, new object[1] { st });
				}
				catch
				{
				}
			}
			if (_fiSkillData != null)
			{
				try
				{
					if (_fiSkillData.GetValue(skills) is IDictionary<SkillType, Skill> dictionary && dictionary.TryGetValue(st, out var value))
					{
						return value;
					}
				}
				catch
				{
				}
			}
			return null;
		}
	}
	internal static class SLE_SkillHelpers
	{
		internal static Player? GetSafeLocalPlayer()
		{
			try
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					return Player.m_localPlayer;
				}
				Game instance = Game.instance;
				if (instance != null)
				{
					PlayerProfile playerProfile = instance.GetPlayerProfile();
					if (((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : null) == 0)
					{
						goto IL_00d9;
					}
				}
				List<Player> allPlayers = Player.GetAllPlayers();
				if (allPlayers != null && allPlayers.Count > 0)
				{
					foreach (Player item in allPlayers)
					{
						if ((Object)(object)item != (Object)null && ((Character)item).IsOwner())
						{
							return item;
						}
					}
				}
				goto IL_00d9;
				IL_00d9:
				return null;
			}
			catch
			{
				return null;
			}
		}
	}
	[HarmonyPatch(typeof(Skill), "Raise")]
	internal static class SLE_Skill_Raise_Transpiler
	{
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo fieldInfo = AccessTools.Field(typeof(Skill), "m_info");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(SkillDef), "m_skill");
			MethodInfo methodInfo = AccessTools.Method(typeof(SkillConfigManager), "GetCap", (Type[])null, (Type[])null);
			if (fieldInfo == null || fieldInfo2 == null || methodInfo == null)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)"[SLE] Transpiler failed: Cannot find required fields/methods");
				}
				return list;
			}
			bool flag = false;
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (val.opcode == OpCodes.Ldc_R4 && val.operand is float num2 && Math.Abs(num2 - 100f) < 0.0001f)
				{
					List<CodeInstruction> list2 = new List<CodeInstruction>();
					list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list2.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(SLE_Skill_Raise_Transpiler), "GetSkillTypeFromInstance", (Type[])null, (Type[])null)));
					list2.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo));
					list2.Add(new CodeInstruction(OpCodes.Conv_R4, (object)null));
					List<CodeInstruction> list3 = list2;
					list[i] = list3[0];
					list.InsertRange(i + 1, list3.GetRange(1, list3.Count - 1));
					i += list3.Count - 1;
					num++;
					ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogInfo((object)$"[SLE] Skill.Raise: Replaced 100f #{num} with GetCap(GetSkillTypeFromInstance()) at position {i}");
					}
					flag = true;
				}
			}
			if (!flag)
			{
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogWarning((object)"[SLE] Transpiler: No 100f constant found to replace in Skills.Skill.Raise");
				}
			}
			return list;
		}

		internal static SkillType GetSkillTypeFromInstance(Skill skillInstance)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SkillDef value = Traverse.Create((object)skillInstance).Field("m_info").GetValue<SkillDef>();
				if (value != null)
				{
					SkillType value2 = Traverse.Create((object)value).Field("m_skill").GetValue<SkillType>();
					if (int.TryParse(((object)(SkillType)(ref value2)).ToString(), out var result) && result == 1337)
					{
						ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
						{
							ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
							if (logger != null)
							{
								logger.LogInfo((object)$"[SLE DEBUG Transpiler] Skill 1337 found via m_info path, returning: {value2}");
							}
						}
					}
					return value2;
				}
				Player safeLocalPlayer = SLE_SkillHelpers.GetSafeLocalPlayer();
				Skills val = ((safeLocalPlayer != null) ? ((Character)safeLocalPlayer).GetSkills() : null);
				if ((Object)(object)val != (Object)null)
				{
					Dictionary<SkillType, Skill> value3 = Traverse.Create((object)val).Field("m_skillData").GetValue<Dictionary<SkillType, Skill>>();
					if (value3 != null)
					{
						foreach (KeyValuePair<SkillType, Skill> item in value3)
						{
							if (item.Value != skillInstance)
							{
								continue;
							}
							SkillType key = item.Key;
							if (int.TryParse(((object)(SkillType)(ref key)).ToString(), out var result2) && result2 == 1337)
							{
								ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
								if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
								{
									ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
									if (logger2 != null)
									{
										logger2.LogInfo((object)$"[SLE DEBUG Transpiler] Skill 1337 found via skillData search, returning: {item.Key}");
									}
								}
							}
							return item.Key;
						}
					}
				}
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogWarning((object)"[SLE DEBUG Transpiler] Could not find skill type for instance, returning None");
				}
				return (SkillType)0;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("[SLE DEBUG Transpiler] Exception in GetSkillTypeFromInstance: " + ex.Message));
				}
				return (SkillType)0;
			}
		}
	}
	[HarmonyPatch(typeof(Skill), "Raise")]
	internal static class SLE_Skill_Raise_Debug
	{
		[HarmonyPatch(typeof(Skill), "GetLevelPercentage")]
		internal static class SLE_Skill_GetLevelPercentage_Patch
		{
			[HarmonyPrefix]
			private static bool Prefix(Skill __instance, ref float __result)
			{
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					SkillDef value = Traverse.Create((object)__instance).Field("m_info").GetValue<SkillDef>();
					SkillType val2;
					if (value == null)
					{
						Player safeLocalPlayer = SLE_SkillHelpers.GetSafeLocalPlayer();
						Skills val = ((safeLocalPlayer != null) ? ((Character)safeLocalPlayer).GetSkills() : null);
						if ((Object)(object)val != (Object)null)
						{
							Dictionary<SkillType, Skill> value2 = Traverse.Create((object)val).Field("m_skillData").GetValue<Dictionary<SkillType, Skill>>();
							if (value2 != null)
							{
								foreach (KeyValuePair<SkillType, Skill> item in value2)
								{
									if (item.Value != __instance)
									{
										continue;
									}
									val2 = item.Key;
									ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
									if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
									{
										ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
										if (logger != null)
										{
											logger.LogDebug((object)$"[SLE] Found MOD skill type {val2} for skill with null m_info");
										}
									}
									goto IL_011e;
								}
							}
						}
						return true;
					}
					val2 = Traverse.Create((object)value).Field("m_skill").GetValue<SkillType>();
					goto IL_011e;
					IL_011e:
					int cap = SkillConfigManager.GetCap(val2);
					if (__instance.m_level >= (float)cap)
					{
						__result = 0f;
						return false;
					}
					float num = CalculateNextLevelRequirement(__instance, val2);
					__result = Mathf.Clamp01(__instance.m_accumulator / num);
					return false;
				}
				catch (Exception ex)
				{
					if (SkillLimitExtenderPlugin.EnableGrowthCurveDebug.Value)
					{
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogError((object)("[SLE Growth Curve] Error in GetLevelPercentage patch: " + ex.Message));
						}
					}
					return true;
				}
			}

			private static float CalculateNextLevelRequirement(Skill skill, SkillType skillType)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					bool flag = SkillConfigManager.UseCustomGrowthCurve(skillType);
					float level = skill.m_level;
					float num;
					if (!flag)
					{
						num = Mathf.Pow(Mathf.Floor(level + 1f), 1.5f) * 0.5f + 0.5f;
						if (SkillLimitExtenderPlugin.EnableGrowthCurveDebug.Value)
						{
							string skillDisplayName = SkillConfigManager.GetSkillDisplayName(skillType);
							ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
							if (logger != null)
							{
								logger.LogInfo((object)($"[SLE Growth Curve] Skill: {skillDisplayName}, Level: {level:F1}, " + $"Mode: Vanilla, Result: {num:F2}"));
							}
						}
					}
					else
					{
						float growthExponent = SkillConfigManager.GetGrowthExponent(skillType);
						float growthMultiplier = SkillConfigManager.GetGrowthMultiplier(skillType);
						float growthConstant = SkillConfigManager.GetGrowthConstant(skillType);
						num = growthMultiplier * Mathf.Pow(level + growthConstant, growthExponent);
						if (SkillLimitExtenderPlugin.EnableGrowthCurveDebug.Value)
						{
							string skillDisplayName2 = SkillConfigManager.GetSkillDisplayName(skillType);
							float num2 = Mathf.Pow(Mathf.Floor(level + 1f), 1.5f) * 0.5f + 0.5f;
							ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
							if (logger2 != null)
							{
								logger2.LogInfo((object)($"[SLE Growth Curve] Skill: {skillDisplayName2}, Level: {level:F1}, " + $"Mode: Custom, Params: exp={growthExponent:F2}, mult={growthMultiplier:F2}, const={growthConstant:F2}, " + $"Vanilla: {num2:F2}, Custom: {num:F2}"));
							}
						}
					}
					return num;
				}
				catch (Exception ex)
				{
					if (SkillLimitExtenderPlugin.EnableGrowthCurveDebug.Value)
					{
						ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogError((object)("[SLE Growth Curve] Error in CalculateNextLevelRequirement: " + ex.Message));
						}
					}
					float level2 = skill.m_level;
					return Mathf.Pow(Mathf.Floor(level2 + 1f), 1.5f) * 0.5f + 0.5f;
				}
			}
		}

		[HarmonyPrefix]
		private static void Prefix(Skill __instance, float factor, out float __state)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			__state = __instance.m_level;
			SkillType skillTypeFromInstance = SLE_Skill_Raise_Transpiler.GetSkillTypeFromInstance(__instance);
			if (!int.TryParse(((object)(SkillType)(ref skillTypeFromInstance)).ToString(), out var result) || result != 1337)
			{
				return;
			}
			ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
			if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"[SLE DEBUG Raise] BEFORE - Skill 1337: Level={__instance.m_level:F2}, Accumulator={__instance.m_accumulator:F2}, Factor={factor:F4}");
				}
			}
		}

		[HarmonyPostfix]
		private static void Postfix(Skill __instance, float factor, float __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SkillType skillTypeFromInstance = SLE_Skill_Raise_Transpiler.GetSkillTypeFromInstance(__instance);
			if (!int.TryParse(((object)(SkillType)(ref skillTypeFromInstance)).ToString(), out var result) || result != 1337)
			{
				return;
			}
			float num = __instance.m_level - __state;
			ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
			if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"[SLE DEBUG Raise] AFTER - Skill 1337: Level={__instance.m_level:F2} (change: {num:F2}), Accumulator={__instance.m_accumulator:F2}");
				}
			}
			if (num > 0f)
			{
				ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
				{
					ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogInfo((object)$"[SLE DEBUG Raise] *** LEVEL UP DETECTED *** Skill 1337 leveled up by {num:F2}!");
					}
				}
			}
			if (__instance.m_level >= 100f)
			{
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogInfo((object)$"[SLE] Skill 1337 reached level {__instance.m_level:F2} (cap: 250)");
				}
			}
		}
	}
	internal static class SLE_TerminalCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleEvent <>9__0_1;

			internal void <Register>b__0_0(ConsoleEventArgs args)
			{
				ZNet instance = ZNet.instance;
				if (instance != null && instance.IsServer())
				{
					SkillConfigManager.ReloadFromYaml();
					SkillConfigManager.SendConfigToClientsIfChanged();
					args.Context.AddString("SLE: reloaded YAML; broadcasted only if changed.");
				}
				else
				{
					SkillConfigManager.ReloadFromYaml();
					args.Context.AddString("SLE: reloaded local YAML.");
				}
			}

			internal void <Register>b__0_1(ConsoleEventArgs args)
			{
				args.Context.AddString("SLE YAML path: " + YamlExporter.GetYamlPath());
			}
		}

		public static void Register()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			try
			{
				object obj = <>c.<>9__0_0;
				if (obj == null)
				{
					ConsoleEvent val = delegate(ConsoleEventArgs args)
					{
						ZNet instance = ZNet.instance;
						if (instance != null && instance.IsServer())
						{
							SkillConfigManager.ReloadFromYaml();
							SkillConfigManager.SendConfigToClientsIfChanged();
							args.Context.AddString("SLE: reloaded YAML; broadcasted only if changed.");
						}
						else
						{
							SkillConfigManager.ReloadFromYaml();
							args.Context.AddString("SLE: reloaded local YAML.");
						}
					};
					<>c.<>9__0_0 = val;
					obj = (object)val;
				}
				new ConsoleCommand("sle_yaml_reload", "Reload SLE YAML", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj2 = <>c.<>9__0_1;
				if (obj2 == null)
				{
					ConsoleEvent val2 = delegate(ConsoleEventArgs args)
					{
						args.Context.AddString("SLE YAML path: " + YamlExporter.GetYamlPath());
					};
					<>c.<>9__0_1 = val2;
					obj2 = (object)val2;
				}
				new ConsoleCommand("sle_yaml_path", "Show current SLE YAML path", (ConsoleEvent)obj2, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			}
			catch (Exception arg)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)$"[SLE] Failed to register console command: {arg}");
				}
			}
		}
	}
	internal static class SLE_VersionHandshake
	{
		internal static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		internal static void RPC_SLE_Version(ZRpc rpc, ZPackage pkg)
		{
			try
			{
				string text = pkg.ReadString();
				ZNet instance = ZNet.instance;
				bool flag = instance != null && instance.IsServer();
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)("[SLE] Version check: remote=" + text + ", local=1.2.0"));
				}
				if (text != "1.2.0")
				{
					if (flag)
					{
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogWarning((object)"[SLE] Incompatible client version; disconnecting");
						}
						rpc.Invoke("Error", new object[1] { 3 });
					}
					else
					{
						ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogWarning((object)"[SLE] Server version differs; features may be limited");
						}
					}
				}
				else if (flag)
				{
					ValidatedPeers.Add(rpc);
				}
				else
				{
					ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogInfo((object)"[SLE] Server and client versions match");
					}
				}
			}
			catch (EndOfStreamException ex)
			{
				ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)("[SLE] Version handshake failed - incompatible data format: " + ex.Message));
				}
				rpc.Invoke("Error", new object[1] { 3 });
			}
			catch (Exception arg)
			{
				ManualLogSource logger6 = SkillLimitExtenderPlugin.Logger;
				if (logger6 != null)
				{
					logger6.LogError((object)$"[SLE] Version handshake error: {arg}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	internal static class SLE_VersionHandshake_OnNewConnection
	{
		[HarmonyPrefix]
		private static void Prefix(ZNetPeer peer, ZNet __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			peer.m_rpc.Register<ZPackage>("SLE_Version", (Action<ZRpc, ZPackage>)SLE_VersionHandshake.RPC_SLE_Version);
			ZPackage val = new ZPackage();
			val.Write("1.2.0");
			peer.m_rpc.Invoke("SLE_Version", new object[1] { val });
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	internal static class SLE_VersionHandshake_VerifyClient
	{
		[HarmonyPrefix]
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ZNet __instance)
		{
			if (__instance.IsServer() && !SLE_VersionHandshake.ValidatedPeers.Contains(rpc))
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"[SLE] Peer never sent version; disconnecting");
				}
				rpc.Invoke("Error", new object[1] { 3 });
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	internal static class SLE_VersionHandshake_RemovePeerOnDisconnect
	{
		[HarmonyPrefix]
		private static void Prefix(ZNetPeer peer, ZNet __instance)
		{
			if (__instance.IsServer())
			{
				ZRpc val = peer?.m_rpc;
				if (val != null)
				{
					SLE_VersionHandshake.ValidatedPeers.Remove(val);
				}
			}
		}
	}
	internal static class SkillConfigManager
	{
		internal static ConfigEntry<bool> ServerConfigLocked = null;

		internal static ConfigEntry<bool> EnableYamlOverride = null;

		private static Dictionary<string, YamlExporter.SkillYamlEntry> _entriesByName = new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);

		private static bool _initialized;

		private static bool _isServerConfig;

		private static string _lastYamlHash = string.Empty;

		private static HashSet<int> _warnedSkillIds = new HashSet<int>();

		private static readonly Dictionary<int, string> _skillKeyCache = new Dictionary<int, string>();

		private static DateTime _lastSkillKeyCacheUpdate = DateTime.MinValue;

		private static readonly TimeSpan SkillKeyCacheExpiry = TimeSpan.FromMinutes(5.0);

		internal const int DefaultCapFallback = 250;

		internal const int DefaultBonusCapFallback = 100;

		internal static void Initialize(ConfigFile config)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			if (!_initialized)
			{
				ServerConfigLocked = config.Bind<bool>("Server", "LockConfiguration", false, new ConfigDescription("If true, server forces its configuration to all clients. (Admin Only)", (AcceptableValueBase)null, new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Category = "Server",
						Order = -1000,
						IsAdminOnly = true
					}
				}));
				EnableYamlOverride = config.Bind<bool>("General", "EnableYamlOverride", true, new ConfigDescription("Allow YAML file to override individual skill caps/bonus/relative", (AcceptableValueBase)null, new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Category = "Skill Level",
						Order = -85
					}
				}));
				ReloadFromYaml();
				_initialized = true;
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"[SLE] Configuration loaded");
				}
			}
		}

		internal static void OnYamlReceivedStatic(long sender, string yamlContent, int protocolVersion)
		{
			OnYamlReceived(sender, yamlContent, protocolVersion);
		}

		internal static void ReloadFromYaml()
		{
			if (_isServerConfig || (EnableYamlOverride != null && !EnableYamlOverride.Value))
			{
				if (!_isServerConfig)
				{
					return;
				}
				ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)"[SLE] Using server configuration (YAML disabled locally)");
					}
				}
				return;
			}
			try
			{
				Dictionary<string, YamlExporter.SkillYamlEntry> dictionary = YamlExporter.LoadYamlEntries();
				if (dictionary != null)
				{
					_entriesByName = dictionary;
					_skillKeyCache.Clear();
					ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
					if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
					{
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogInfo((object)$"[SLE] YAML reloaded successfully ({_entriesByName.Count} entries)");
						}
					}
					return;
				}
				ConfigEntry<bool> enableGrowthCurveDebug3 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug3 != null && enableGrowthCurveDebug3.Value)
				{
					ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)"[SLE] YAML reload returned null, keeping existing configuration");
					}
				}
				_entriesByName = _entriesByName ?? new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("[SLE] YAML reload failed: " + ex.Message));
				}
				_entriesByName = _entriesByName ?? new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
			}
		}

		private static string GetSkillKeyForLookup(SkillType st)
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			string text = ((object)(SkillType)(ref st)).ToString();
			string text2;
			if (int.TryParse(text, out var result) && result > 999)
			{
				if (DateTime.Now - _lastSkillKeyCacheUpdate > SkillKeyCacheExpiry)
				{
					_skillKeyCache.Clear();
					_lastSkillKeyCacheUpdate = DateTime.Now;
				}
				if (_skillKeyCache.TryGetValue(result, out string value))
				{
					return value;
				}
				text2 = text;
				if (_entriesByName != null)
				{
					if (_entriesByName.ContainsKey(text))
					{
						ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
						{
							ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
							if (logger != null)
							{
								logger.LogDebug((object)("[SLE] Using numeric key '" + text + "' for MOD skill"));
							}
						}
						_skillKeyCache[result] = text;
						return text;
					}
					string actualModSkillName = GetActualModSkillName(st);
					if (!string.IsNullOrEmpty(actualModSkillName) && !string.Equals(actualModSkillName, text, StringComparison.Ordinal))
					{
						if (_entriesByName.ContainsKey(actualModSkillName))
						{
							ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
							if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
							{
								ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
								if (logger2 != null)
								{
									logger2.LogDebug((object)$"[SLE] Mapping MOD skill ID {result} to actual name '{actualModSkillName}'");
								}
							}
							text2 = actualModSkillName;
							_skillKeyCache[result] = text2;
							return text2;
						}
						string[] array = GenerateSkillNameVariations(actualModSkillName);
						string[] array2 = array;
						foreach (string text3 in array2)
						{
							if (!_entriesByName.ContainsKey(text3))
							{
								continue;
							}
							ConfigEntry<bool> enableGrowthCurveDebug3 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
							if (enableGrowthCurveDebug3 != null && enableGrowthCurveDebug3.Value)
							{
								ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
								if (logger3 != null)
								{
									logger3.LogDebug((object)$"[SLE] Mapping MOD skill ID {result} to variation '{text3}' (from '{actualModSkillName}')");
								}
							}
							text2 = text3;
							_skillKeyCache[result] = text2;
							return text2;
						}
					}
					string[] array3 = GenerateCommonModSkillNames(result);
					string[] array4 = array3;
					foreach (string text4 in array4)
					{
						if (!_entriesByName.ContainsKey(text4))
						{
							continue;
						}
						ConfigEntry<bool> enableGrowthCurveDebug4 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug4 != null && enableGrowthCurveDebug4.Value)
						{
							ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
							if (logger4 != null)
							{
								logger4.LogDebug((object)$"[SLE] Mapping MOD skill ID {result} to common name '{text4}'");
							}
						}
						text2 = text4;
						_skillKeyCache[result] = text2;
						return text2;
					}
					if (!_warnedSkillIds.Contains(result))
					{
						ConfigEntry<bool> enableGrowthCurveDebug5 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug5 != null && enableGrowthCurveDebug5.Value)
						{
							_warnedSkillIds.Add(result);
							string text5 = string.Join(", ", _entriesByName.Keys.Take(10));
							string text6 = ((!string.IsNullOrEmpty(actualModSkillName) && !actualModSkillName.StartsWith("$")) ? actualModSkillName : text);
							ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
							if (logger5 != null)
							{
								logger5.LogWarning((object)string.Format("[SLE] MOD skill ID {0} (name: '{1}') not found in YAML. Available keys: {2}... Please add '{3}' to your YAML file.", result, actualModSkillName ?? "Unknown", text5, text6));
							}
							goto IL_0392;
						}
					}
					if (!_warnedSkillIds.Contains(result))
					{
						_warnedSkillIds.Add(result);
					}
				}
				goto IL_0392;
			}
			return text;
			IL_0392:
			_skillKeyCache[result] = text2;
			return text2;
		}

		private static string[] GenerateSkillNameVariations(string skillName)
		{
			if (string.IsNullOrEmpty(skillName))
			{
				return new string[0];
			}
			List<string> list = new List<string>();
			list.Add(skillName);
			if (skillName.StartsWith("$"))
			{
				string text = skillName.Substring(1);
				list.Add(text);
				if (text.StartsWith("skilldesc_"))
				{
					list.Add(text.Substring(10));
				}
				if (text.EndsWith("Skill"))
				{
					list.Add(text.Substring(0, text.Length - 5));
				}
			}
			string item = CleanSkillNameForYaml(skillName);
			if (!list.Contains(item))
			{
				list.Add(item);
			}
			return list.ToArray();
		}

		private static string[] GenerateCommonModSkillNames(int skillId)
		{
			List<string> list = new List<string>();
			list.Add(skillId.ToString());
			switch (skillId)
			{
			case 1337:
				list.AddRange(new string[3] { "Cartography", "CartographySkill", "Cartographer" });
				break;
			case 410134081:
				list.AddRange(new string[3] { "Agility", "AgilitySkill", "Agile" });
				break;
			}
			return list.ToArray();
		}

		private static string? TryGetLocalizedName(string descriptionKey)
		{
			if (string.IsNullOrEmpty(descriptionKey) || !descriptionKey.StartsWith("$"))
			{
				return null;
			}
			try
			{
				Type type = AccessTools.TypeByName("Localization");
				if (type != null)
				{
					object obj = null;
					try
					{
						obj = Traverse.Create(type).Property("instance", (object[])null).GetValue<object>();
						if (obj == null)
						{
							obj = Traverse.Create(type).Field("instance").GetValue<object>();
						}
					}
					catch
					{
					}
					MethodInfo methodInfo = AccessTools.Method(type, "Localize", new Type[1] { typeof(string) }, (Type[])null);
					if (obj != null && methodInfo != null)
					{
						string text = methodInfo.Invoke(obj, new object[1] { descriptionKey }) as string;
						if (!string.IsNullOrEmpty(text) && text != descriptionKey)
						{
							return text;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		internal static string GetActualModSkillName(SkillType skillType)
		{
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			try
			{
				Player safeLocalPlayer = SLE_SkillHelpers.GetSafeLocalPlayer();
				Skills val = ((safeLocalPlayer != null) ? ((Character)safeLocalPlayer).GetSkills() : null);
				if ((Object)(object)val != (Object)null)
				{
					Dictionary<SkillType, Skill> value = Traverse.Create((object)val).Field("m_skillData").GetValue<Dictionary<SkillType, Skill>>();
					if (value != null && value.TryGetValue(skillType, out var value2))
					{
						SkillDef value3 = Traverse.Create((object)value2).Field("m_info").GetValue<SkillDef>();
						if (value3 != null)
						{
							SkillType value4 = Traverse.Create((object)value3).Field("m_skill").GetValue<SkillType>();
							if ((int)value4 > 0)
							{
								string text = ((object)(SkillType)(ref value4)).ToString();
								if (!int.TryParse(text, out var _))
								{
									return text;
								}
							}
							try
							{
								string value5 = Traverse.Create((object)value3).Field("m_name").GetValue<string>();
								if (!string.IsNullOrEmpty(value5) && !value5.StartsWith("$"))
								{
									return value5;
								}
							}
							catch
							{
							}
							try
							{
								string value6 = Traverse.Create((object)value3).Field("m_name").GetValue<string>();
								if (!string.IsNullOrEmpty(value6) && value6.StartsWith("$"))
								{
									string text2 = TryGetLocalizedName(value6);
									if (text2 != null)
									{
										return text2;
									}
								}
							}
							catch
							{
							}
							string value7 = Traverse.Create((object)value3).Field("m_description").GetValue<string>();
							if (!string.IsNullOrEmpty(value7) && value7.StartsWith("$"))
							{
								string text3 = TryGetLocalizedName(value7);
								if (text3 != null && !text3.Contains(" "))
								{
									return text3;
								}
							}
						}
					}
				}
				return ((object)(SkillType)(ref skillType)).ToString();
			}
			catch (Exception ex)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"[SLE] Failed to get actual skill name for {skillType}: {ex.Message}");
				}
				return ((object)(SkillType)(ref skillType)).ToString();
			}
		}

		private static string CleanSkillNameForYaml(string skillName)
		{
			if (string.IsNullOrEmpty(skillName))
			{
				return skillName;
			}
			string text = Regex.Replace(skillName, "[^\\w]", "");
			if (text.Length > 0 && char.IsDigit(text[0]))
			{
				text = "_" + text;
			}
			return string.IsNullOrEmpty(text) ? skillName : text;
		}

		internal static int GetCap(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			int result;
			bool flag = int.TryParse(((object)(SkillType)(ref st)).ToString(), out result) && result == 1337;
			if (flag)
			{
				Dictionary<string, YamlExporter.SkillYamlEntry> entriesByName = _entriesByName;
				YamlExporter.SkillYamlEntry value;
				YamlExporter.SkillYamlEntry skillYamlEntry = ((entriesByName != null && entriesByName.TryGetValue(skillKeyForLookup, out value)) ? value : null);
				ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)$"[SLE] Skill 1337 - Key: '{skillKeyForLookup}', Cap: {skillYamlEntry?.Cap ?? 250}");
					}
				}
			}
			if (!_isServerConfig)
			{
				ConfigEntry<bool> enableYamlOverride = EnableYamlOverride;
				if (enableYamlOverride != null && enableYamlOverride.Value && _entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value2) && value2 != null && value2.Cap > 0)
				{
					if (flag)
					{
						ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
						{
							ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
							if (logger2 != null)
							{
								logger2.LogInfo((object)$"[SLE] Skill 1337 using client cap: {value2.Cap}");
							}
						}
					}
					return value2.Cap;
				}
			}
			if (_isServerConfig && _entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value3) && value3 != null && value3.Cap > 0)
			{
				if (flag)
				{
					ConfigEntry<bool> enableGrowthCurveDebug3 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
					if (enableGrowthCurveDebug3 != null && enableGrowthCurveDebug3.Value)
					{
						ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogInfo((object)$"[SLE] Skill 1337 using server cap: {value3.Cap}");
						}
					}
				}
				return value3.Cap;
			}
			if (flag)
			{
				ConfigEntry<bool> enableGrowthCurveDebug4 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug4 != null && enableGrowthCurveDebug4.Value)
				{
					ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogInfo((object)$"[SLE] Skill 1337 using fallback cap: {250}");
					}
				}
			}
			return 250;
		}

		[Obsolete("Use GetCap with proper skill type instead")]
		internal static int GetCartographySkillCap()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SkillType st = (SkillType)1337;
				return GetCap(st);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("[SLE] Error getting CartographySkill cap via generic method: " + ex.Message));
				}
				return 250;
			}
		}

		internal static int GetBonusCap(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			if (!_isServerConfig)
			{
				ConfigEntry<bool> enableYamlOverride = EnableYamlOverride;
				if (enableYamlOverride != null && enableYamlOverride.Value && _entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value) && value != null && value.BonusCap > 0)
				{
					return value.BonusCap;
				}
			}
			if (_isServerConfig && _entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value2) && value2 != null && value2.BonusCap > 0)
			{
				return value2.BonusCap;
			}
			return 100;
		}

		internal static bool IsRelative(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			if (_entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value) && value != null)
			{
				return value.Relative;
			}
			return true;
		}

		internal static float GetGrowthExponent(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			if (_entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value) && value != null)
			{
				return value.GrowthExponent;
			}
			return 1.5f;
		}

		internal static float GetGrowthMultiplier(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			if (_entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value) && value != null)
			{
				return value.GrowthMultiplier;
			}
			return 0.5f;
		}

		internal static float GetGrowthConstant(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			if (_entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value) && value != null)
			{
				return value.GrowthConstant;
			}
			return 0.5f;
		}

		internal static bool UseCustomGrowthCurve(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string skillKeyForLookup = GetSkillKeyForLookup(st);
			if (_entriesByName != null && _entriesByName.TryGetValue(skillKeyForLookup, out YamlExporter.SkillYamlEntry value) && value != null)
			{
				return value.UseCustomGrowthCurve;
			}
			return false;
		}

		internal static float GetFactorDenominator(SkillType st)
		{
			return 100f;
		}

		internal static float GetUiDenominator()
		{
			try
			{
				int num = Math.Max(1, 250);
				if (num <= 0 || float.IsNaN(num) || float.IsInfinity(num))
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"[SLE] GetUiDenominator: Invalid result, using fallback 100f");
					}
					return 100f;
				}
				return num;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("[SLE] GetUiDenominator failed: " + ex.Message + ", using fallback 100f"));
				}
				return 100f;
			}
		}

		internal static float GetUiDenominatorForSkill(SkillType st)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Math.Max(1, GetCap(st));
		}

		internal static float GetUiDenominatorForSkillSafe(object? skillMaybe)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Skill val = (Skill)((skillMaybe is Skill) ? skillMaybe : null);
				if (val != null)
				{
					SkillDef value = Traverse.Create((object)val).Field("m_info").GetValue<SkillDef>();
					if (value != null)
					{
						SkillType value2 = Traverse.Create((object)value).Field("m_skill").GetValue<SkillType>();
						float uiDenominatorForSkill = GetUiDenominatorForSkill(value2);
						ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
						{
							ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
							if (logger != null)
							{
								logger.LogDebug((object)$"[SLE] UI denominator for {value2}: {uiDenominatorForSkill} (level={val.m_level})");
							}
						}
						return uiDenominatorForSkill;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)("[SLE] GetUiDenominatorForSkillSafe failed: " + ex.Message));
				}
			}
			float uiDenominator = GetUiDenominator();
			ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
			if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
			{
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogDebug((object)$"[SLE] UI denominator fallback: {uiDenominator}");
				}
			}
			return uiDenominator;
		}

		internal static void SendConfigToClients()
		{
			ZNet instance = ZNet.instance;
			if (instance == null || !instance.IsServer() || !(ServerConfigLocked?.Value ?? false))
			{
				return;
			}
			try
			{
				string yamlPath = YamlExporter.GetYamlPath();
				string text = (File.Exists(yamlPath) ? File.ReadAllText(yamlPath) : string.Empty);
				int num = 2;
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "SLE_YamlSync", new object[2] { text, num });
				_lastYamlHash = ComputeHash(text ?? string.Empty);
				ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)$"[SLE] Server YAML sent to clients (length={text?.Length ?? 0}, proto={num})");
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)$"[SLE] Failed to send YAML to clients: {arg}");
				}
			}
		}

		internal static void SendConfigToClientsIfChanged()
		{
			ZNet instance = ZNet.instance;
			if (instance == null || !instance.IsServer() || !(ServerConfigLocked?.Value ?? false))
			{
				return;
			}
			try
			{
				string yamlPath = YamlExporter.GetYamlPath();
				string text = (File.Exists(yamlPath) ? File.ReadAllText(yamlPath) : string.Empty);
				string text2 = ComputeHash(text ?? string.Empty);
				if (string.Equals(_lastYamlHash, text2, StringComparison.Ordinal))
				{
					ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
					if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
					{
						ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
						if (logger != null)
						{
							logger.LogDebug((object)"[SLE] YAML unchanged; broadcast skipped.");
						}
					}
					return;
				}
				int num = 2;
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "SLE_YamlSync", new object[2] { text, num });
				_lastYamlHash = text2;
				ConfigEntry<bool> enableGrowthCurveDebug2 = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug2 != null && enableGrowthCurveDebug2.Value)
				{
					ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogInfo((object)$"[SLE] Server YAML broadcasted to everybody (length={text?.Length ?? 0}, proto={num})");
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)$"[SLE] Failed to broadcast YAML: {arg}");
				}
			}
		}

		private static void OnYamlReceived(long sender, string yamlContent, int protocolVersion)
		{
			//IL_00af: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				return;
			}
			try
			{
				_isServerConfig = true;
				if (!VersionInfo.IsCompatible(protocolVersion))
				{
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)$"[SLE] Protocol version mismatch: remote={protocolVersion}, local={2}");
					}
					return;
				}
				if (!string.IsNullOrEmpty(yamlContent))
				{
					IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).IgnoreUnmatchedProperties().Build();
					try
					{
						Dictionary<string, YamlExporter.SkillYamlEntry> dictionary = val.Deserialize<Dictionary<string, YamlExporter.SkillYamlEntry>>(yamlContent);
						_entriesByName = dictionary ?? new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
					}
					catch (YamlException val2)
					{
						YamlException val3 = val2;
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogWarning((object)("[SLE] YAML parsing failed, trying legacy format: " + ((Exception)(object)val3).Message));
						}
						Dictionary<string, int> dictionary2 = val.Deserialize<Dictionary<string, int>>(yamlContent) ?? new Dictionary<string, int>();
						Dictionary<string, YamlExporter.SkillYamlEntry> dictionary3 = new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
						foreach (KeyValuePair<string, int> item in dictionary2)
						{
							dictionary3[item.Key] = new YamlExporter.SkillYamlEntry
							{
								Cap = item.Value,
								BonusCap = 100,
								Relative = true,
								UseCustomGrowthCurve = false,
								GrowthExponent = 1.5f,
								GrowthMultiplier = 0.5f,
								GrowthConstant = 0.5f
							};
						}
						_entriesByName = dictionary3;
					}
					catch (Exception arg)
					{
						ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogError((object)$"[SLE] Failed to parse server YAML: {arg}");
						}
						_entriesByName = new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
					}
				}
				else
				{
					_entriesByName = new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
				}
				_skillKeyCache.Clear();
				ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
				if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
				{
					ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogInfo((object)$"[SLE] Received server YAML (entries={_entriesByName.Count})");
					}
				}
			}
			catch (Exception arg2)
			{
				ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)$"[SLE] Failed to apply server YAML: {arg2}");
				}
				_entriesByName = new Dictionary<string, YamlExporter.SkillYamlEntry>(StringComparer.Ordinal);
			}
		}

		internal static void OnPlayerConnected()
		{
			SendConfigToClients();
		}

		internal static int GetCapByName(string name)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(name))
			{
				return 250;
			}
			if (Enum.TryParse<SkillType>(name, ignoreCase: true, out SkillType result) && (int)result != 0 && (int)result != 999)
			{
				return GetCap(result);
			}
			return 250;
		}

		internal static int GetSkillLimit(SkillType st)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return GetCap(st);
		}

		private static string ComputeHash(string text)
		{
			try
			{
				using SHA256 sHA = SHA256.Create();
				byte[] bytes = Encoding.UTF8.GetBytes(text ?? string.Empty);
				byte[] array = sHA.ComputeHash(bytes);
				return BitConverter.ToString(array).Replace("-", "");
			}
			catch
			{
				return string.Empty;
			}
		}

		internal static string GetSkillDisplayName(SkillType st)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((int)st > 999)
				{
					Player safeLocalPlayer = SLE_SkillHelpers.GetSafeLocalPlayer();
					Skills val = ((safeLocalPlayer != null) ? ((Character)safeLocalPlayer).GetSkills() : null);
					if ((Object)(object)val != (Object)null)
					{
						Dictionary<SkillType, Skill> value = Traverse.Create((object)val).Field("m_skillData").GetValue<Dictionary<SkillType, Skill>>();
						if (value != null && value.TryGetValue(st, out var value2))
						{
							SkillDef value3 = Traverse.Create((object)value2).Field("m_info").GetValue<SkillDef>();
							if (value3 != null)
							{
								string value4 = Traverse.Create((object)value3).Field("m_description").GetValue<string>();
								string text = TryGetLocalizedName(value4);
								if (text != null)
								{
									return text;
								}
								if (!string.IsNullOrEmpty(value4) && !value4.StartsWith("$"))
								{
									return value4;
								}
							}
						}
					}
					return ((object)(SkillType)(ref st)).ToString();
				}
				return ((object)(SkillType)(ref st)).ToString();
			}
			catch
			{
				return ((object)(SkillType)(ref st)).ToString();
			}
		}
	}
	[BepInPlugin("SkillLimitExtender", "SkillLimitExtender", "1.2.0")]
	public class SkillLimitExtenderPlugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "SkillLimitExtender";

		internal const string PluginName = "SkillLimitExtender";

		internal const string PluginVersion = "1.2.0";

		private readonly Harmony _harmony = new Harmony("SkillLimitExtender");

		internal static ManualLogSource Logger { get; private set; }

		internal static ConfigEntry<bool> EnableGrowthCurveDebug { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			EnableGrowthCurveDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Growth Curve Debug", false, "Enable debug logging for skill growth curve calculations");
			try
			{
				Logger.LogInfo((object)("[SLE] " + VersionInfo.VersionString));
				SkillConfigManager.Initialize(((BaseUnityPlugin)this).Config);
				YamlExporter.EnsureYamlExists();
				_harmony.PatchAll(typeof(SkillLimitExtenderPlugin).Assembly);
				SLE_Hook_ModSkills.Initialize(_harmony);
				SLE_TerminalCommands.Register();
				Logger.LogInfo((object)"[SLE] Plugin loaded successfully (v1.2.0)");
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"[SLE] Awake failed: {arg}");
			}
		}

		private void Start()
		{
			if (!((Object)(object)ZNet.instance != (Object)null))
			{
				return;
			}
			try
			{
				ZRoutedRpc.instance.Register<string, int>("SLE_YamlSync", (Action<long, string, int>)SkillConfigManager.OnYamlReceivedStatic);
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"[SLE] RPC registered successfully");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger2 = Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)$"[SLE] RPC registration failed: {arg}");
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"[SLE] UnpatchSelf failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class SLE_Hook_PlayerSpawned
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance)
		{
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer() && (Object)(object)__instance != (Object)null)
			{
				SkillConfigManager.SendConfigToClientsIfChanged();
			}
		}
	}
	internal static class SLE_Hook_ModSkills
	{
		private static Harmony? _harmony;

		private static readonly List<string> _patchedAssemblies = new List<string>();

		private static readonly HashSet<string> _checkedAssemblies = new HashSet<string>();

		private static readonly HashSet<string> _modSkillAssemblies = new HashSet<string>();

		private static readonly Dictionary<string, bool> _assemblySkillCheckCache = new Dictionary<string, bool>();

		private static readonly Dictionary<string, List<MethodInfo>> _assemblyMethodCache = new Dictionary<string, List<MethodInfo>>();

		private static readonly Dictionary<string, SkillType> _typeNameCache = new Dictionary<string, SkillType>();

		private static readonly Dictionary<SkillType, int> _skillCapCache = new Dictionary<SkillType, int>();

		private static DateTime _lastCacheUpdate = DateTime.MinValue;

		private static readonly TimeSpan CacheExpiry = TimeSpan.FromSeconds(30.0);

		internal static void Initialize(Harmony harmony)
		{
			_harmony = harmony;
			ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
			if (logger != null)
			{
				logger.LogInfo((object)"[SLE] ModSkills: Starting universal MOD skill patch system...");
			}
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				int num = 0;
				Assembly[] array = assemblies;
				foreach (Assembly assembly in array)
				{
					try
					{
						string name = assembly.GetName().Name;
						if (_checkedAssemblies.Contains(name))
						{
							if (_modSkillAssemblies.Contains(name))
							{
								int num2 = PatchModSkillAssembly(assembly);
								if (num2 > 0)
								{
									num += num2;
									_patchedAssemblies.Add(name);
								}
							}
							continue;
						}
						_checkedAssemblies.Add(name);
						if (IsModSkillAssembly(assembly))
						{
							_modSkillAssemblies.Add(name);
							int num3 = PatchModSkillAssembly(assembly);
							if (num3 > 0)
							{
								num += num3;
								_patchedAssemblies.Add(name);
							}
						}
					}
					catch (Exception ex)
					{
						ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
						{
							ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
							if (logger2 != null)
							{
								logger2.LogDebug((object)("[SLE] ModSkills: Skipping assembly " + assembly.GetName().Name + ": " + ex.Message));
							}
						}
					}
				}
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogInfo((object)$"[SLE] ModSkills loaded: {num} methods patched across {_patchedAssemblies.Count} MOD assemblies");
				}
				if (_patchedAssemblies.Count > 0)
				{
					ManualLogSource logger4 = SkillLimitExtenderPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogInfo((object)("[SLE] Additional skills found: " + string.Join(", ", _patchedAssemblies)));
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger5 = SkillLimitExtenderPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)$"[SLE] ModSkills: Initialization failed: {arg}");
				}
			}
		}

		private static bool IsModSkillAssembly(Assembly assembly)
		{
			try
			{
				string name = assembly.GetName().Name;
				if (_assemblySkillCheckCache.TryGetValue(name, out var value))
				{
					return value;
				}
				if (name.StartsWith("Assembly-CSharp") || name.StartsWith("UnityEngine") || name.StartsWith("System") || name.StartsWith("mscorlib") || name.StartsWith("BepInEx") || name.StartsWith("0Harmony") || name.StartsWith("Jotunn") || name.StartsWith("Microsoft") || name.StartsWith("netstandard") || name == "SkillLimitExtender")
				{
					_assemblySkillCheckCache[name] = false;
					return false;
				}
				Type[] types = assembly.GetTypes();
				bool flag = false;
				Type[] array = types;
				foreach (Type type in array)
				{
					if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length == 0)
					{
						continue;
					}
					MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					MethodInfo[] array2 = methods;
					foreach (MethodInfo methodInfo in array2)
					{
						string name2 = methodInfo.Name;
						if (name2.Contains("Skill") || name2.Contains("Raise") || name2.Contains("Cheat"))
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						break;
					}
				}
				_assemblySkillCheckCache[name] = flag;
				return flag;
			}
			catch
			{
				return false;
			}
		}

		private static int PatchModSkillAssembly(Assembly assembly)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			int num = 0;
			try
			{
				string name = assembly.GetName().Name;
				if (!_assemblyMethodCache.TryGetValue(name, out List<MethodInfo> value))
				{
					value = new List<MethodInfo>();
					Type[] types = assembly.GetTypes();
					Type[] array = types;
					foreach (Type type in array)
					{
						MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						MethodInfo[] array2 = methods;
						foreach (MethodInfo methodInfo in array2)
						{
							if (IsSkillLimitMethod(methodInfo))
							{
								value.Add(methodInfo);
							}
						}
					}
					_assemblyMethodCache[name] = value;
				}
				foreach (MethodInfo item in value)
				{
					try
					{
						HarmonyMethod val = new HarmonyMethod(typeof(SLE_Hook_ModSkills), "UniversalSkillLimitTranspiler", (Type[])null);
						Harmony? harmony = _harmony;
						if (harmony != null)
						{
							harmony.Patch((MethodBase)item, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null);
						}
						ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
						if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
						{
							ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
							if (logger != null)
							{
								logger.LogInfo((object)("[SLE] ModSkills: Patched " + name + "." + item.DeclaringType?.Name + "." + item.Name));
							}
						}
						num++;
					}
					catch (Exception ex)
					{
						ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogWarning((object)("[SLE] ModSkills: Failed to patch " + item.DeclaringType?.Name + "." + item.Name + ": " + ex.Message));
						}
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger3 = SkillLimitExtenderPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)$"[SLE] ModSkills: Error processing assembly {assembly.GetName().Name}: {arg}");
				}
			}
			return num;
		}

		private static bool IsSkillLimitMethod(MethodInfo method)
		{
			try
			{
				if (!method.Name.Contains("Skill") && !method.Name.Contains("Raise") && !method.Name.Contains("Cheat") && !method.Name.Contains("Level"))
				{
					return false;
				}
				List<CodeInstruction> currentInstructions = PatchProcessor.GetCurrentInstructions((MethodBase)method, int.MaxValue, (ILGenerator)null);
				if (currentInstructions.Any((CodeInstruction instr) => instr.opcode == OpCodes.Ldc_R4 && instr.operand is float num && Math.Abs(num - 100f) < 0.001f))
				{
					return currentInstructions.Any(delegate(CodeInstruction instr)
					{
						int result;
						if (instr.opcode == OpCodes.Call)
						{
							object operand = instr.operand;
							result = ((operand != null && (operand.ToString()?.Contains("Clamp")).GetValueOrDefault()) ? 1 : 0);
						}
						else
						{
							result = 0;
						}
						return (byte)result != 0;
					});
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> UniversalSkillLimitTranspiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			try
			{
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (!(val.opcode == OpCodes.Ldc_R4) || !(val.operand is float num) || !(Math.Abs(num - 100f) < 0.001f))
					{
						continue;
					}
					bool flag = false;
					for (int j = Math.Max(0, i - 5); j < Math.Min(list.Count, i + 5); j++)
					{
						if (list[j].opcode == OpCodes.Call)
						{
							object operand = list[j].operand;
							if (operand != null && (operand.ToString()?.Contains("Clamp")).GetValueOrDefault())
							{
								flag = true;
								break;
							}
						}
					}
					if (!flag)
					{
						continue;
					}
					List<CodeInstruction> list2 = new List<CodeInstruction>();
					list2.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(SLE_Hook_ModSkills), "GetUniversalSkillCap", (Type[])null, (Type[])null)));
					list2.Add(new CodeInstruction(OpCodes.Conv_R4, (object)null));
					List<CodeInstruction> list3 = list2;
					list[i] = list3[0];
					list.InsertRange(i + 1, list3.GetRange(1, list3.Count - 1));
					ConfigEntry<bool> enableGrowthCurveDebug = SkillLimitExtenderPlugin.EnableGrowthCurveDebug;
					if (enableGrowthCurveDebug != null && enableGrowthCurveDebug.Value)
					{
						ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
						if (logger != null)
						{
							logger.LogInfo((object)("[SLE] ModSkills: Replaced 100f in " + original.DeclaringType?.Name + "." + original.Name));
						}
					}
					break;
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)$"[SLE] ModSkills: Transpiler error in {original.DeclaringType?.Name}.{original.Name}: {arg}");
				}
			}
			return list;
		}

		private static int GetUniversalSkillCap()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Invalid comparison between Unknown and I4
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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_01db: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (DateTime.Now - _lastCacheUpdate > CacheExpiry)
				{
					_skillCapCache.Clear();
					_lastCacheUpdate = DateTime.Now;
				}
				SkillType val = (SkillType)0;
				MethodBase currentMethod = MethodBase.GetCurrentMethod();
				MethodBase methodBase = new StackFrame(1)?.GetMethod();
				if (methodBase?.DeclaringType != null)
				{
					string text = methodBase.DeclaringType.FullName ?? methodBase.DeclaringType.Name;
					if (_typeNameCache.TryGetValue(text, out var value))
					{
						val = value;
					}
					else if (text.Contains("CartographySkill"))
					{
						val = (SkillType)1337;
						_typeNameCache[text] = val;
					}
					else if (text.Contains("AgilitySkill") || text.Contains("Agility"))
					{
						val = (SkillType)410134081;
						_typeNameCache[text] = val;
					}
					else
					{
						StackTrace stackTrace = new StackTrace();
						int num = Math.Min(5, stackTrace.FrameCount);
						for (int i = 2; i < num; i++)
						{
							Type type = (stackTrace.GetFrame(i)?.GetMethod())?.DeclaringType;
							if (type != null)
							{
								string text2 = type.FullName ?? type.Name;
								if (text2.Contains("CartographySkill"))
								{
									val = (SkillType)1337;
									_typeNameCache[text2] = val;
									break;
								}
								if (text2.Contains("AgilitySkill") || text2.Contains("Agility"))
								{
									val = (SkillType)410134081;
									_typeNameCache[text2] = val;
									break;
								}
							}
						}
					}
				}
				if ((int)val > 0)
				{
					if (_skillCapCache.TryGetValue(val, out var value2))
					{
						return value2;
					}
					int cap = SkillConfigManager.GetCap(val);
					_skillCapCache[val] = cap;
					return cap;
				}
				return 250;
			}
			catch
			{
				return 250;
			}
		}
	}
	internal static class VersionInfo
	{
		public const string Version = "1.2.0";

		public const string Prerelease = "";

		public const string Build = "20251001";

		public const bool IsDevelopmentVersion = false;

		public const string FullVersion = "1.2.0";

		public const string FullVersionWithBuild = "1.2.0.0";

		public const int ProtocolVersion = 2;

		public const int ConfigSchemaVersion = 2;

		public static string DisplayVersion => string.IsNullOrEmpty("") ? "1.2.0" : "1.2.0-";

		public static string VersionString => string.Format("v{0} (build {1}, proto={2}, cfg={3})", DisplayVersion, "20251001", 2, 2);

		public static bool IsCompatible(int remoteProtocolVersion)
		{
			return remoteProtocolVersion == 2;
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public bool? ShowRangeAsPercent { get; set; }

		public bool? IsAdvanced { get; set; }

		public int? Order { get; set; }

		public string? Category { get; set; }

		public bool? Browsable { get; set; }

		public object? DefaultValue { get; set; }

		public string? ReadOnly { get; set; }

		public bool? HideDefaultButton { get; set; }

		public bool? HideSettingName { get; set; }

		public bool? IsAdminOnly { get; set; }
	}
	internal static class YamlExporter
	{
		internal sealed class SkillYamlEntry
		{
			public int Cap { get; set; } = 250;


			public int BonusCap { get; set; } = 100;


			public bool Relative { get; set; } = true;


			public bool UseCustomGrowthCurve { get; set; } = false;


			public float GrowthExponent { get; set; } = 1.5f;


			public float GrowthMultiplier { get; set; } = 0.5f;


			public float GrowthConstant { get; set; } = 0.5f;

		}

		private static readonly string ConfigDir = Path.Combine(Paths.ConfigPath, "SkillLimitExtender");

		private static string YamlPath = Path.Combine(ConfigDir, "SLE_Skill_List.yaml");

		internal static string GetYamlPath()
		{
			return YamlPath;
		}

		internal static void EnsureYamlExists()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			Directory.CreateDirectory(ConfigDir);
			if (File.Exists(YamlPath))
			{
				return;
			}
			Dictionary<string, SkillYamlEntry> dictionary = new Dictionary<string, SkillYamlEntry>();
			try
			{
				foreach (SkillType value in Enum.GetValues(typeof(SkillType)))
				{
					SkillType val = value;
					if ((int)val != 0 && (int)val != 999)
					{
						dictionary[((object)(SkillType)(ref val)).ToString()] = new SkillYamlEntry
						{
							Cap = 250,
							BonusCap = 100,
							Relative = true,
							UseCustomGrowthCurve = false,
							GrowthExponent = 1.5f,
							GrowthMultiplier = 0.5f,
							GrowthConstant = 0.5f
						};
					}
				}
			}
			catch
			{
			}
			SaveYamlEntries(dictionary);
			ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
			if (logger != null)
			{
				logger.LogInfo((object)$"[SLE] Created YAML: {YamlPath} (seed={dictionary.Count} vanilla skills, fields: cap/bonusCap/relative)");
			}
		}

		internal static Dictionary<string, SkillYamlEntry> LoadYamlEntries()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			try
			{
				if (!File.Exists(YamlPath))
				{
					return new Dictionary<string, SkillYamlEntry>();
				}
				string text = File.ReadAllText(YamlPath, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
				IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).IgnoreUnmatchedProperties().Build();
				try
				{
					Dictionary<string, SkillYamlEntry> dictionary = val.Deserialize<Dictionary<string, SkillYamlEntry>>(text);
					if (dictionary != null)
					{
						return dictionary;
					}
				}
				catch
				{
				}
				Dictionary<string, int> dictionary2 = val.Deserialize<Dictionary<string, int>>(text) ?? new Dictionary<string, int>();
				Dictionary<string, SkillYamlEntry> dictionary3 = new Dictionary<string, SkillYamlEntry>(StringComparer.Ordinal);
				foreach (KeyValuePair<string, int> item in dictionary2)
				{
					dictionary3[item.Key] = new SkillYamlEntry
					{
						Cap = item.Value,
						BonusCap = 100,
						Relative = true,
						UseCustomGrowthCurve = false,
						GrowthExponent = 1.5f,
						GrowthMultiplier = 0.5f,
						GrowthConstant = 0.5f
					};
				}
				return dictionary3;
			}
			catch (Exception arg)
			{
				ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)$"[SLE] LoadYaml error: {arg}");
				}
				return new Dictionary<string, SkillYamlEntry>();
			}
		}

		internal static void SaveYamlEntries(Dictionary<string, SkillYamlEntry> map)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			try
			{
				Directory.CreateDirectory(ConfigDir);
				ISerializer val = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
				string contents = val.Serialize((object)map.OrderBy<KeyValuePair<string, SkillYamlEntry>, string>((KeyValuePair<string, SkillYamlEntry> kv) => kv.Key, StringComparer.Ordinal).ToDictionary((KeyValuePair<string, SkillYamlEntry> kv) => kv.Key, (KeyValuePair<string, SkillYamlEntry> kv) => kv.Value));
				if (!TryWriteAllText(YamlPath, contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), out Exception error))
				{
					string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SkillLimitExtender");
					string text2 = Path.Combine(text, "SLE_Skill_List.yaml");
					Directory.CreateDirectory(text);
					File.WriteAllText(text2, contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					YamlPath = text2;
					ManualLogSource logger = SkillLimitExtenderPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)("[SLE] SaveYaml primary failed: " + error?.GetType().Name + " " + error?.Message + "; switched to fallback: " + text2));
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger2 = SkillLimitExtenderPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)$"[SLE] SaveYaml error: