Decompiled source of CaptainSkillTree v1.2.29

AnimationSpeedManager.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AnimationSpeedManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AnimationSpeedManager")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("B3A6D52C-449A-4665-9FD0-BB48C8CF2CDF")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class AnimationSpeedManager
{
	public delegate double Handler(Character character, double speed);

	private static readonly Harmony harmony = new Harmony("AnimationSpeedManager");

	private static bool hasMarkerPatch = false;

	private static readonly MethodInfo method = AccessTools.DeclaredMethod(typeof(CharacterAnimEvent), "CustomFixedUpdate", (Type[])null, (Type[])null);

	private static int index = 0;

	private static bool changed = false;

	private static Handler[][] handlers = Array.Empty<Handler[]>();

	private static readonly Dictionary<int, List<Handler>> handlersPriorities = new Dictionary<int, List<Handler>>();

	[PublicAPI]
	public static void Add(Handler handler, int priority = 400)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		if (!hasMarkerPatch)
		{
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "markerPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null);
			hasMarkerPatch = true;
		}
		if (!handlersPriorities.TryGetValue(priority, out List<Handler> value))
		{
			handlersPriorities.Add(priority, value = new List<Handler>());
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "wrapper", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		value.Add(handler);
		handlers = (from kv in handlersPriorities
			orderby kv.Key
			select kv.Value.ToArray()).ToArray();
	}

	private static void wrapper(Character ___m_character, Animator ___m_animator)
	{
		Character ___m_character2 = ___m_character;
		double num = (double)___m_animator.speed * 10000000.0 % 100.0;
		if ((!(num > 10.0) || !(num < 30.0)) && !(___m_animator.speed <= 0.001f))
		{
			double num2 = ___m_animator.speed;
			double num3 = handlers[index++].Aggregate(num2, (double current, Handler handler) => handler(___m_character2, current));
			if (num3 != num2)
			{
				___m_animator.speed = (float)(num3 - num3 % 1E-05);
				changed = true;
			}
		}
	}

	private static void markerPatch(Animator ___m_animator)
	{
		if (changed)
		{
			double num = (double)___m_animator.speed * 10000000.0 % 100.0;
			if ((num < 10.0 || num > 30.0) ? true : false)
			{
				___m_animator.speed += 1.9E-06f;
			}
			changed = false;
		}
		index = 0;
	}
}

CaptainSkillTree.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CaptainSkillTree.Audio;
using CaptainSkillTree.Gui;
using CaptainSkillTree.Localization;
using CaptainSkillTree.MMO_System;
using CaptainSkillTree.Prefab;
using CaptainSkillTree.SkillTree;
using CaptainSkillTree.SkillTree.CriticalSystem;
using CaptainSkillTree.VFX;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CaptainSkillTree")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CaptainSkillTree")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d1b6e7e2-1c2a-4b8a-9e2b-123456789abc")]
[assembly: AssemblyFileVersion("1.2.267.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.267.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CaptainSkillTree
{
	public static class DifficultyManager
	{
		private const string PRESET_DIR_NAME = "CaptainSkillTree";

		private const string PRESET_NORMAL = "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg";

		private const string PRESET_VERYHARD = "Veryhard_CaptainSkillTree.SkillTreeMod.cfg";

		private const string PRESET_USER = "User_CaptainSkillTree.SkillTreeMod.cfg";

		private const string DIFF_VER_EXT = ".difficulty_ver";

		private static bool _initialized = false;

		private static string _configFilePath = "";

		private static FieldInfo _entriesField;

		private static bool _entriesFieldSearched;

		public static bool NeedsSelection { get; private set; }

		public static bool IsApplyingPreset { get; private set; }

		public static void InitializeIfNeeded()
		{
			if (_initialized)
			{
				return;
			}
			_initialized = true;
			Plugin? instance = Plugin.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				ConfigFile config = ((BaseUnityPlugin)instance).Config;
				obj = ((config != null) ? config.ConfigFilePath : null);
			}
			if (obj == null)
			{
				obj = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg");
			}
			_configFilePath = (string)obj;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("[Difficulty] Config path: " + _configFilePath));
			}
			string path = Path.ChangeExtension(_configFilePath, ".version");
			string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver");
			string text = (File.Exists(path) ? File.ReadAllText(path).Trim() : "");
			string text2 = (File.Exists(path2) ? File.ReadAllText(path2).Trim() : "");
			NeedsSelection = text != text2;
			if (NeedsSelection)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("[Difficulty] 난이도 선택 필요 (모드 버전: " + text + " / 마지막 선택: " + text2 + ")"));
				}
			}
			EnsurePresetDirectory();
			Application.quitting += SaveUserBackupOnQuit;
		}

		public static bool HasUserPreset()
		{
			return File.Exists(Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg"));
		}

		public static void ApplyNormal()
		{
			ApplyPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg");
		}

		public static void ApplyVeryHard()
		{
			ApplyPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg");
		}

		public static void ApplyUser()
		{
			ApplyPreset("User_CaptainSkillTree.SkillTreeMod.cfg");
		}

		private static void ApplyPreset(string presetFileName)
		{
			IsApplyingPreset = true;
			string text = Path.Combine(GetPresetDirectory(), presetFileName);
			if (File.Exists(text))
			{
				try
				{
					File.Copy(text, _configFilePath, overwrite: true);
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("[Difficulty] 파일 복사 완료: " + presetFileName));
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogError((object)("[Difficulty] 파일 복사 실패: " + ex.Message));
					}
				}
				Plugin? instance = Plugin.Instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					ConfigFile config = ((BaseUnityPlugin)instance).Config;
					obj = ((config != null) ? config.ConfigFilePath : null);
				}
				if (obj == null)
				{
					obj = "(null)";
				}
				string text2 = (string)obj;
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)("[Difficulty] _configFilePath  = " + _configFilePath));
				}
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)("[Difficulty] Config.FilePath  = " + text2));
				}
				ManualLogSource log5 = Plugin.Log;
				if (log5 != null)
				{
					log5.LogInfo((object)$"[Difficulty] 경로 일치: {string.Equals(_configFilePath, text2, StringComparison.OrdinalIgnoreCase)}");
				}
				Plugin? instance2 = Plugin.Instance;
				ConfigFile val = ((instance2 != null) ? ((BaseUnityPlugin)instance2).Config : null);
				if (val != null)
				{
					bool saveOnConfigSet = val.SaveOnConfigSet;
					val.SaveOnConfigSet = false;
					val.Reload();
					int num = ApplyPresetValuesToConfig(text);
					string text3 = ((presetFileName == "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg") ? "Vanilla" : ((presetFileName == "Veryhard_CaptainSkillTree.SkillTreeMod.cfg") ? "HardMode" : "UserSettings"));
					ConfigEntry<string> gameDifficulty = SkillTreeConfig.GameDifficulty;
					if (gameDifficulty != null)
					{
						gameDifficulty.Value = text3;
					}
					val.Save();
					val.SaveOnConfigSet = saveOnConfigSet;
					ManualLogSource log6 = Plugin.Log;
					if (log6 != null)
					{
						log6.LogInfo((object)$"[Difficulty] ✅ 프리셋 적용 완료: {presetFileName} ({num}개), 난이도={text3}");
					}
				}
			}
			else
			{
				ManualLogSource log7 = Plugin.Log;
				if (log7 != null)
				{
					log7.LogWarning((object)("[Difficulty] ⚠\ufe0f 프리셋 파일 없음: " + text + "\n  → 현재 설정을 그대로 유지합니다."));
				}
			}
			SaveDifficultyVersion();
			NeedsSelection = false;
			IsApplyingPreset = false;
		}

		private static FieldInfo GetEntriesField()
		{
			if (_entriesFieldSearched)
			{
				return _entriesField;
			}
			_entriesFieldSearched = true;
			Type typeFromHandle = typeof(Dictionary<ConfigDefinition, ConfigEntryBase>);
			Type type = typeof(ConfigFile);
			while (type != null && type != typeof(object))
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (fieldInfo.FieldType == typeFromHandle)
					{
						_entriesField = fieldInfo;
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogInfo((object)("[Difficulty] entries field: " + type.Name + "." + fieldInfo.Name));
						}
						return fieldInfo;
					}
				}
				type = type.BaseType;
			}
			type = typeof(ConfigFile);
			while (type != null && type != typeof(object))
			{
				FieldInfo[] fields2 = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo2 in fields2)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[Difficulty] Field: " + type.Name + "." + fieldInfo2.Name + " : " + fieldInfo2.FieldType.FullName));
					}
				}
				type = type.BaseType;
			}
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogWarning((object)"[Difficulty] entries field not found");
			}
			return null;
		}

		private static int ApplyPresetValuesToConfig(string presetPath)
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			Plugin? instance = Plugin.Instance;
			ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null);
			if (val == null)
			{
				return 0;
			}
			if (!(GetEntriesField()?.GetValue(val) is Dictionary<ConfigDefinition, ConfigEntryBase> dictionary))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[Difficulty] entries 딕셔너리 접근 실패");
				}
				return -1;
			}
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)$"[Difficulty] 등록된 ConfigEntry 수: {dictionary.Count}");
			}
			int num = 0;
			string text = "";
			HashSet<ConfigDefinition> hashSet = new HashSet<ConfigDefinition>();
			try
			{
				string[] array = File.ReadAllLines(presetPath);
				foreach (string text2 in array)
				{
					string text3 = text2.Trim();
					if (text3.StartsWith("[") && text3.EndsWith("]"))
					{
						text = text3.Substring(1, text3.Length - 2);
					}
					else
					{
						if (text3.StartsWith("#") || !text3.Contains(" = "))
						{
							continue;
						}
						int num2 = text3.IndexOf(" = ");
						string text4 = text3.Substring(0, num2).Trim();
						string serializedValue = text3.Substring(num2 + 3);
						ConfigDefinition val2 = new ConfigDefinition(text, text4);
						if (!dictionary.TryGetValue(val2, out var value))
						{
							continue;
						}
						try
						{
							value.SetSerializedValue(serializedValue);
							hashSet.Add(val2);
							if (num == 0)
							{
								ManualLogSource log3 = Plugin.Log;
								if (log3 != null)
								{
									log3.LogInfo((object)("[Difficulty] 첫 항목: [" + text + "] " + text4 + " = " + value.GetSerializedValue()));
								}
							}
							num++;
						}
						catch
						{
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogWarning((object)("[Difficulty] 값 직접 적용 실패: " + ex.Message));
				}
			}
			int num3 = 0;
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in dictionary)
			{
				if (!hashSet.Contains(item.Key))
				{
					try
					{
						item.Value.BoxedValue = item.Value.DefaultValue;
						num3++;
					}
					catch
					{
					}
				}
			}
			if (num3 > 0)
			{
				ManualLogSource log5 = Plugin.Log;
				if (log5 != null)
				{
					log5.LogInfo((object)$"[Difficulty] 미포함 항목 기본값 리셋: {num3}개");
				}
			}
			return num + num3;
		}

		public static string GetPresetDirectory()
		{
			return Path.Combine(Paths.ConfigPath, "CaptainSkillTree");
		}

		public static void EnsurePresetDirectory()
		{
			try
			{
				Directory.CreateDirectory(GetPresetDirectory());
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Difficulty] 폴더 생성 실패: " + ex.Message));
				}
			}
			ExtractEmbeddedPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg");
			ExtractEmbeddedPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg");
		}

		private static void ExtractEmbeddedPreset(string fileName)
		{
			string path = Path.Combine(GetPresetDirectory(), fileName);
			string text = "CaptainSkillTree.asset." + fileName;
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				using (Stream stream = executingAssembly.GetManifestResourceStream(text))
				{
					if (stream == null)
					{
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogWarning((object)("[Difficulty] 내장 리소스 없음: " + text));
						}
						return;
					}
					using FileStream destination = new FileStream(path, FileMode.Create, FileAccess.Write);
					stream.CopyTo(destination);
				}
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("[Difficulty] 프리셋 추출 완료: " + fileName));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("[Difficulty] 프리셋 추출 실패 (" + fileName + "): " + ex.Message));
				}
			}
		}

		private static void SaveUserBackupOnQuit()
		{
			if (string.IsNullOrEmpty(_configFilePath) || !File.Exists(_configFilePath))
			{
				return;
			}
			string destFileName = Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg");
			try
			{
				File.Copy(_configFilePath, destFileName, overwrite: true);
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[Difficulty] User 설정 백업 저장 완료");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Difficulty] User 백업 저장 실패: " + ex.Message));
				}
			}
		}

		private static void SaveDifficultyVersion()
		{
			try
			{
				string path = Path.ChangeExtension(_configFilePath, ".version");
				string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver");
				string contents = (File.Exists(path) ? File.ReadAllText(path).Trim() : "");
				File.WriteAllText(path2, contents);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Difficulty] 버전 기록 실패: " + ex.Message));
				}
			}
		}
	}
	public class SkillTreeInputListener : MonoBehaviour
	{
		public SkillTreeUI? skillTreeUI;

		private float lastLogTime = 0f;

		public static SkillTreeInputListener? Instance { get; private set; }

		private void Awake()
		{
			lastLogTime = Time.time;
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				LevelSyncManager.Instance.Initialize();
			}
			else
			{
				Debug.LogWarning((object)"[SkillTreeInputListener] 중복 생성 감지, 즉시 파괴, this={this.GetHashCode()} (name={gameObject.name})");
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void Update()
		{
			try
			{
				SkillTreeManager.Instance?.OnUpdate();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[SkillTree] SkillTreeManager 업데이트 실패: " + ex.Message));
			}
			try
			{
				LevelSyncManager.Instance?.Update();
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("[SkillTree] LevelSyncManager 업데이트 실패: " + ex2.Message));
			}
			if (IsChatOrConsoleOpen())
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead())
			{
				if (Input.GetKeyDown((KeyCode)114))
				{
					SkillEffect.HandleRKeySkills(localPlayer);
				}
				if (Input.GetKeyDown((KeyCode)103))
				{
					SkillEffect.HandleGKeySkills(localPlayer);
				}
				if (Input.GetKeyUp((KeyCode)103))
				{
					SkillEffect.HandleGKeyUpSkills(localPlayer);
				}
				if (Input.GetKeyDown((KeyCode)104))
				{
					SkillEffect.HandleHKeySkills(localPlayer);
				}
				if (Input.GetKeyUp((KeyCode)104))
				{
					SkillEffect.HandleHKeyUpSkills(localPlayer);
				}
				if (Input.GetKeyDown((KeyCode)121))
				{
					SkillTreeManager.Instance.HandleActiveSkillKeyInput();
				}
				if (Input.GetKeyDown((KeyCode)93))
				{
					try
					{
						long expToNextLevel = CaptainMMOBridge.GetExpToNextLevel();
						CaptainMMOBridge.AddExp((int)expToNextLevel);
						Plugin.SkillTreePoint += 3;
					}
					catch (Exception ex3)
					{
						Plugin.Log.LogWarning((object)("[SkillTree] 레벨업 실패 (경험치 추가): " + ex3.Message));
					}
				}
			}
			if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || !skillTreeUI.panel.activeInHierarchy)
			{
				return;
			}
			bool keyDown = Input.GetKeyDown((KeyCode)27);
			bool keyDown2 = Input.GetKeyDown((KeyCode)9);
			if (keyDown)
			{
				skillTreeUI.panel.SetActive(false);
				if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
				{
					SkillTreeBGMManager.Instance.PauseSkillTreeBGM();
				}
				else
				{
					Plugin.Log.LogError((object)"[\ud83d\udd11 ESC] ❌ SkillTreeBGMManager.Instance가 null - ESC키 처리 실패");
				}
			}
			if (keyDown2)
			{
				skillTreeUI.panel.SetActive(false);
				if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
				{
					SkillTreeBGMManager.Instance.PauseSkillTreeBGM();
				}
				else
				{
					Plugin.Log.LogError((object)"[\ud83d\udd11 TAB] ❌ SkillTreeBGMManager.Instance가 null - Tab키 처리 실패");
				}
			}
		}

		private bool IsChatOrConsoleOpen()
		{
			try
			{
				if (IsChatInputActive())
				{
					Plugin.Log.LogDebug((object)"[키 입력 차단] 채팅 입력이 활성화됨 - 스킬 키 입력 차단");
					return true;
				}
				if (IsConsoleActive())
				{
					Plugin.Log.LogDebug((object)"[키 입력 차단] 콘솔이 활성화됨 - 스킬 키 입력 차단");
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[키 입력 차단] 채팅/콘솔 상태 확인 중 오류: " + ex.Message));
				return false;
			}
		}

		private bool IsChatInputActive()
		{
			try
			{
				EventSystem current = EventSystem.current;
				if ((Object)(object)((current != null) ? current.currentSelectedGameObject : null) != (Object)null)
				{
					InputField component = current.currentSelectedGameObject.GetComponent<InputField>();
					if ((Object)(object)component != (Object)null && component.isFocused)
					{
						return true;
					}
				}
				if ((Object)(object)Chat.instance != (Object)null)
				{
					GameObject gameObject = ((Component)Chat.instance).gameObject;
					if ((Object)(object)gameObject != (Object)null && gameObject.activeInHierarchy)
					{
						try
						{
							InputField componentInChildren = ((Component)Chat.instance).GetComponentInChildren<InputField>(true);
							if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isFocused)
							{
								return true;
							}
						}
						catch (Exception ex)
						{
							Plugin.Log.LogDebug((object)("[채팅 감지] GetComponentInChildren 실패: " + ex.Message));
						}
					}
				}
				return false;
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("[채팅 감지] 오류: " + ex2.Message));
				return false;
			}
		}

		private bool IsConsoleActive()
		{
			try
			{
				Type type = Type.GetType("Console, assembly_valheim");
				if (type != null)
				{
					MethodInfo method = type.GetMethod("IsVisible", BindingFlags.Static | BindingFlags.Public);
					if (method != null && (bool)method.Invoke(null, null))
					{
						return true;
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[콘솔 감지] 오류: " + ex.Message));
				return false;
			}
		}

		private void OnDestroy()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			LevelSyncManager.Instance?.Cleanup();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	public static class Player_OnDeath_StopCoroutines_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)SkillTreeInputListener.Instance != (Object)null)
			{
				((MonoBehaviour)SkillTreeInputListener.Instance).StopAllCoroutines();
			}
		}
	}
	[BepInPlugin("CaptainSkillTree.SkillTreeMod", "Captain SkillTree Mod", "1.2.267")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class InventoryShowPatch
		{
			private static bool Prepare()
			{
				return true;
			}

			public static void Postfix()
			{
				try
				{
					ShowSkillTreeIcon();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[스킬트리] InventoryShowPatch 오류: " + ex.Message));
					Log.LogError((object)("[스킬트리] StackTrace: " + ex.StackTrace));
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "Awake")]
		private static class FejdStartup_DifficultyPatch
		{
			[HarmonyPostfix]
			private static void Postfix(FejdStartup __instance)
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Expected O, but got Unknown
				DifficultyManager.InitializeIfNeeded();
				if (DifficultyManager.NeedsSelection)
				{
					Canvas val = ((Component)__instance).GetComponentInChildren<Canvas>(true) ?? Object.FindObjectOfType<Canvas>();
					if ((Object)(object)val == (Object)null)
					{
						Log.LogWarning((object)"[Difficulty] Canvas를 찾을 수 없어 난이도 선택 창을 열 수 없습니다. 기본값 VeryHard 적용.");
						DifficultyManager.ApplyVeryHard();
						return;
					}
					GameObject val2 = new GameObject("DifficultySelectUI");
					val2.transform.SetParent(((Component)val).transform, false);
					val2.AddComponent<DifficultySelectUI>();
					val2.transform.SetAsLastSibling();
					Log.LogInfo((object)"[Difficulty] 난이도 선택 창 표시");
				}
			}
		}

		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		[HarmonyPriority(400)]
		public static class WeaponCriticalSystemPatch
		{
			public static void Prefix(Character __instance, ref bool showDamageText, ref HitData hit)
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Invalid comparison between Unknown and I4
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Invalid comparison between Unknown and I4
				//IL_0251: Unknown result type (might be due to invalid IL or missing references)
				//IL_0253: Invalid comparison between Unknown and I4
				//IL_023c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Unknown result type (might be due to invalid IL or missing references)
				//IL_0307: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0288: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0145: Unknown result type (might be due to invalid IL or missing references)
				//IL_031e: Unknown result type (might be due to invalid IL or missing references)
				//IL_032a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0331: Unknown result type (might be due to invalid IL or missing references)
				//IL_0333: Invalid comparison between Unknown and I4
				//IL_0335: Unknown result type (might be due to invalid IL or missing references)
				//IL_0338: Invalid comparison between Unknown and I4
				//IL_0350: Unknown result type (might be due to invalid IL or missing references)
				//IL_0357: Unknown result type (might be due to invalid IL or missing references)
				//IL_035d: Unknown result type (might be due to invalid IL or missing references)
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker == (Object)null || !(attacker is Player))
				{
					return;
				}
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
				if (currentWeapon == null)
				{
					return;
				}
				SkillType skillType = currentWeapon.m_shared.m_skillType;
				if ((int)skillType == 5 && SkillEffect.spearEnhancedThrowBuffEndTime.TryGetValue(val, out var value) && Time.time < value)
				{
					float spearStep6ComboDamageValue = SkillTreeConfig.SpearStep6ComboDamageValue;
					float num = 1f + spearStep6ComboDamageValue / 100f;
					hit.m_damage.m_pierce *= num;
					hit.m_damage.m_blunt *= num;
					hit.m_damage.m_slash *= num;
					hit.m_damage.m_chop *= num;
					Log.LogInfo((object)$"[연공창] ✅ 강화된 투창 데미지 +{spearStep6ComboDamageValue}% 적용!");
					if ((Object)(object)__instance != (Object)null && !__instance.IsPlayer())
					{
						Vector3 position = ((Component)__instance).transform.position + Vector3.up * 1f;
						SimpleVFX.Play("confetti_directional_multicolor", position, 2f);
						Log.LogDebug((object)"[연공창] confetti 효과 재생");
					}
					SkillEffect.spearEnhancedThrowBuffEndTime.Remove(val);
					return;
				}
				if ((int)skillType == 5 && SkillEffect.HasSkill("spear_Step1_throw") && SkillEffect.CanUseSpearThrowPassive(val))
				{
					float spearStep2ThrowDamageValue = SkillTreeConfig.SpearStep2ThrowDamageValue;
					float num2 = 1f + spearStep2ThrowDamageValue / 100f;
					hit.m_damage.m_pierce *= num2;
					hit.m_damage.m_blunt *= num2;
					hit.m_damage.m_slash *= num2;
					hit.m_damage.m_chop *= num2;
					Log.LogInfo((object)$"[투창 전문가] ✅ 투창 공격력 +{spearStep2ThrowDamageValue}% 적용!");
					SkillEffect.ShowSkillEffectText(val, $"\ud83d\udca5 투창 +{spearStep2ThrowDamageValue}%!", new Color(1f, 0.8f, 0.2f), SkillEffect.SkillEffectTextType.Combat);
					SkillEffect.SetSpearThrowPassiveCooldown(val);
				}
				if ((int)skillType == 8 && SkillEffect.HasSkill("bow_Step2_focus") && Critical.IsHeadshot(__instance, hit.m_point))
				{
					float critMultiplier = CriticalDamage.CalculateCritDamageMultiplier(val, skillType);
					CriticalDamage.ApplyCriticalDamage(val, ref hit, critMultiplier, skillType);
					SkillEffect.ShowSkillEffectText(val, L.Get("bow_headshot_text") + "!", new Color(1f, 0.3f, 0.1f), SkillEffect.SkillEffectTextType.Combat);
					VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point);
					showDamageText = false;
					Log.LogInfo((object)"[헤드샷] 머리 적중 → 100% 크리티컬 발동!");
					return;
				}
				float critChance = Critical.CalculateCritChance(val, skillType);
				if (Critical.RollCritical(critChance))
				{
					float critMultiplier2 = CriticalDamage.CalculateCritDamageMultiplier(val, skillType);
					CriticalDamage.ApplyCriticalDamage(val, ref hit, critMultiplier2, skillType);
					if ((int)skillType == 2 || (int)skillType == 11)
					{
						VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point);
					}
					showDamageText = false;
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyAttackStaminaUsage")]
		public static class KnifeSkillTreeStaminaPatch
		{
			public static void Postfix(SEMan __instance, ref float staminaUse)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon();
					if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 2)
					{
						float knifeStaminaReduction = SkillEffect.GetKnifeStaminaReduction(0f);
						staminaUse *= 1f - knifeStaminaReduction / 100f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")]
		public static class KnifeSkillTreeStaminaRegenPatch
		{
			public static void Postfix(SEMan __instance, ref float staminaMultiplier)
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					staminaMultiplier += SkillEffect.GetStaminaRegen(0f) / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyRunStaminaDrain")]
		public static class KnifeSkillTreeRunStaminaPatch
		{
			public static void Postfix(ref float drain)
			{
				float staminaReduction = SkillEffect.GetStaminaReduction(0f);
				drain *= 1f - staminaReduction / 100f;
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyJumpStaminaUsage")]
		public static class KnifeSkillTreeJumpStaminaPatch
		{
			public static void Postfix(ref float staminaUse)
			{
				float staminaReduction = SkillEffect.GetStaminaReduction(0f);
				staminaUse *= 1f - staminaReduction / 100f;
				float jumpStaminaReduction = SkillEffect.GetJumpStaminaReduction();
				staminaUse *= 1f - jumpStaminaReduction / 100f;
			}
		}

		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		[HarmonyPriority(600)]
		public static class KnifeSkillTreeArmorPatch
		{
			public static void Prefix(Character __instance, HitData hit)
			{
				if (__instance.IsPlayer())
				{
					float physicArmor = SkillEffect.GetPhysicArmor(0f);
					float num = 1f - physicArmor / 100f;
					hit.m_damage.m_blunt *= num;
					hit.m_damage.m_slash *= num;
					hit.m_damage.m_pierce *= num;
					hit.m_damage.m_chop *= num;
					hit.m_damage.m_pickaxe *= num;
					float magicArmor = SkillEffect.GetMagicArmor(0f);
					float num2 = 1f - magicArmor / 100f;
					hit.m_damage.m_fire *= num2;
					hit.m_damage.m_frost *= num2;
					hit.m_damage.m_lightning *= num2;
					hit.m_damage.m_poison *= num2;
					hit.m_damage.m_spirit *= num2;
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
		public static class SwordSkillTreeParryPatch
		{
			public static void Postfix(Character __instance, bool __result, HitData hit, Character attacker)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Invalid comparison between Unknown and I4
				if (!__result)
				{
					return;
				}
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val == null || !((Character)val).IsPlayer())
				{
					return;
				}
				ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
				if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 1)
				{
					SkillTreeManager instance = SkillTreeManager.Instance;
					SEMan sEMan = ((Character)val).GetSEMan();
					if (instance.GetSkillLevel("sword_counter") > 0)
					{
						SE_SwordCounter sE_SwordCounter = ScriptableObject.CreateInstance<SE_SwordCounter>();
						((StatusEffect)sE_SwordCounter).m_ttl = 5f;
						sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordCounter, true, 0, 0f);
					}
					if (instance.GetSkillLevel("sword_riposte") > 0)
					{
						SE_SwordRiposte sE_SwordRiposte = ScriptableObject.CreateInstance<SE_SwordRiposte>();
						((StatusEffect)sE_SwordRiposte).m_ttl = 5f;
						sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordRiposte, true, 0, 0f);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Stagger")]
		public static class ParryRush_Stagger_Patch
		{
			public static void Postfix(Character __instance)
			{
				try
				{
					if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer())
					{
						Player localPlayer = Player.m_localPlayer;
						if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && Sword_Skill.IsParryRushActive(localPlayer) && ((Character)localPlayer).IsBlocking())
						{
							Sword_Skill.OnParryRushTrigger(localPlayer, __instance);
							Log.LogInfo((object)"[패링 돌격] Stagger 감지 → 패링 돌격 발동");
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[패링 돌격] Stagger 패치 오류: " + ex.Message));
				}
			}
		}

		public class SE_SwordCounter : StatusEffect
		{
			public SE_SwordCounter()
			{
				base.m_name = "칼날 되치기";
				base.m_tooltip = "다음 공격의 피해량이 20% 증가합니다.";
				base.m_icon = null;
				base.m_ttl = 5f;
			}

			public override void ModifyAttack(SkillType skill, ref HitData hitData)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Invalid comparison between Unknown and I4
				if ((int)skill == 1)
				{
					((DamageTypes)(ref hitData.m_damage)).Modify(1.2f);
					base.m_character.GetSEMan().RemoveStatusEffect((StatusEffect)(object)this, true);
				}
			}
		}

		public class SE_SwordRiposte : StatusEffect
		{
			public SE_SwordRiposte()
			{
				base.m_name = "칼날 되치기";
				base.m_tooltip = "다음 공격의 피해량이 20% 증가합니다.";
				base.m_icon = null;
			}
		}

		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		public static class SwordRiposteDamagePatch
		{
			private static readonly int SwordCounterHash = Animator.StringToHash("칼날 되치기");

			private static readonly int SwordRiposteHash = Animator.StringToHash("반격 자세");

			private static void Prefix(Character __instance, HitData hit)
			{
				try
				{
					if (hit == null)
					{
						return;
					}
					Character attacker = hit.GetAttacker();
					Player val = (Player)(object)((attacker is Player) ? attacker : null);
					if (val != null && (Object)(object)val != (Object)null)
					{
						SEMan sEMan = ((Character)val).GetSEMan();
						if (sEMan != null && sEMan.HaveStatusEffect(SwordRiposteHash))
						{
							hit.m_damage.m_blunt *= 1.2f;
							hit.m_damage.m_slash *= 1.2f;
							hit.m_damage.m_pierce *= 1.2f;
							sEMan.RemoveStatusEffect(SwordRiposteHash, false);
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[반격 자세] ApplyDamage 패치 오류: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		public static class InventoryHidePatch
		{
			public static void Postfix()
			{
				try
				{
					if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf)
					{
						skillTreeUI.panel.SetActive(false);
						if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
						{
							SkillTreeBGMManager.Instance.PauseSkillTreeBGM();
						}
					}
					if ((Object)(object)skillTreeIconObj != (Object)null)
					{
						skillTreeIconObj.SetActive(false);
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[스킬트리] InventoryHidePatch 오류: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class InventoryShowIconPositionPatch
		{
			private static bool _iconPositionAdjusted;

			public static void Postfix(InventoryGui __instance)
			{
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if ((Object)(object)skillTreeIconObj == (Object)null)
					{
						return;
					}
					skillTreeIconObj.SetActive(true);
					if (!EpicMMOReflectionHelper.IsInitialized)
					{
						EpicMMOReflectionHelper.Initialize();
					}
					if (EpicMMOReflectionHelper.IsAvailable || _iconPositionAdjusted)
					{
						return;
					}
					RectTransform component = skillTreeIconObj.GetComponent<RectTransform>();
					if (!((Object)(object)component == (Object)null))
					{
						Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>();
						if ((Object)(object)componentInParent != (Object)null)
						{
							((Transform)component).SetParent(((Component)componentInParent).transform, false);
							component.anchorMin = new Vector2(0.5f, 0.5f);
							component.anchorMax = new Vector2(0.5f, 0.5f);
							component.pivot = new Vector2(0.5f, 0.5f);
							component.anchoredPosition = new Vector2(0f, 150f);
							component.sizeDelta = new Vector2(60f, 60f);
							_iconPositionAdjusted = true;
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[스킬트리] 아이콘 위치 조정 실패: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Awake")]
		public static class HudAwakeHideIconPatch
		{
			[CompilerGenerated]
			private sealed class <DelayedHideIcon>d__1 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <DelayedHideIcon>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Expected O, but got Unknown
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitForSeconds(1f);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						if ((Object)(object)skillTreeIconObj != (Object)null)
						{
							skillTreeIconObj.SetActive(false);
							Log.LogInfo((object)"[스킬트리] 아이콘 초기 숨김 완료 - 인벤토리(Tab) 열 때 표시됨");
						}
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			public static void Postfix()
			{
				ProducerEnchantUI.PreloadSprite();
				if ((Object)(object)Instance != (Object)null)
				{
					((MonoBehaviour)Instance).StartCoroutine(DelayedHideIcon());
				}
			}

			[IteratorStateMachine(typeof(<DelayedHideIcon>d__1))]
			private static IEnumerator DelayedHideIcon()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <DelayedHideIcon>d__1(0);
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		public static class ZNet_Awake_Patch
		{
			private static void Postfix()
			{
				SkillTreeConfig.DetectServerClientMode();
				InitializeServerSync();
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		public static class ZNet_OnNewConnection_Patch
		{
			[CompilerGenerated]
			private sealed class <DelayedConfigBroadcast>d__1 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <DelayedConfigBroadcast>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Expected O, but got Unknown
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitForSeconds(2f);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						SkillTreeConfig.BroadcastConfigToClients();
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			private static void Postfix(ZNet __instance)
			{
				if (__instance.IsServer())
				{
					((MonoBehaviour)__instance).StartCoroutine(DelayedConfigBroadcast());
				}
			}

			[IteratorStateMachine(typeof(<DelayedConfigBroadcast>d__1))]
			private static IEnumerator DelayedConfigBroadcast()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <DelayedConfigBroadcast>d__1(0);
			}
		}

		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		public static class Terminal_InitTerminal_Patch
		{
			[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;

				public static ConsoleEvent <>9__0_2;

				public static ConsoleEvent <>9__0_3;

				public static ConsoleEvent <>9__0_4;

				public static ConsoleEvent <>9__0_5;

				public static ConsoleEvent <>9__0_6;

				public static ConsoleEvent <>9__0_7;

				public static ConsoleEvent <>9__0_8;

				public static ConsoleEvent <>9__0_9;

				public static ConsoleEvent <>9__0_10;

				public static ConsoleEvent <>9__0_11;

				public static ConsoleEvent <>9__0_12;

				public static ConsoleEvent <>9__0_13;

				public static ConsoleEvent <>9__0_14;

				public static ConsoleEvent <>9__0_15;

				public static ConsoleEvent <>9__0_16;

				public static ConsoleEvent <>9__0_17;

				public static ConsoleEvent <>9__0_18;

				public static ConsoleEvent <>9__0_19;

				internal void <Postfix>b__0_0(ConsoleEventArgs args)
				{
					SetAttackConfig("AttackRootDamageBonus", args);
				}

				internal void <Postfix>b__0_1(ConsoleEventArgs args)
				{
					SetAttackConfig("AttackMeleeBonusChance", args);
				}

				internal void <Postfix>b__0_2(ConsoleEventArgs args)
				{
					SetAttackConfig("AttackMeleeBonusDamage", args);
				}

				internal void <Postfix>b__0_3(ConsoleEventArgs args)
				{
					SetAttackConfig("AttackBowBonusChance", args);
				}

				internal void <Postfix>b__0_4(ConsoleEventArgs args)
				{
					SetAttackConfig("AttackBowBonusDamage", args);
				}

				internal void <Postfix>b__0_5(ConsoleEventArgs args)
				{
					SetSpeedConfig("Speed_Expert_MoveSpeed", args);
				}

				internal void <Postfix>b__0_6(ConsoleEventArgs args)
				{
					SetSpeedConfig("Speed_Step1_DodgeSpeed", args);
				}

				internal void <Postfix>b__0_7(ConsoleEventArgs args)
				{
					SetSpeedConfig("Speed_Step2_MeleeComboBonus", args);
				}

				internal void <Postfix>b__0_8(ConsoleEventArgs args)
				{
					SetSpeedConfig("Speed_Step2_BowHitBonus", args);
				}

				internal void <Postfix>b__0_9(ConsoleEventArgs args)
				{
					SetSpeedConfig("Speed_Step8_MeleeAttackSpeed", args);
				}

				internal void <Postfix>b__0_10(ConsoleEventArgs args)
				{
					SkillTreeConfig.ReloadAndBroadcast();
				}

				internal void <Postfix>b__0_11(ConsoleEventArgs args)
				{
					ShowCurrentConfig();
				}

				internal void <Postfix>b__0_12(ConsoleEventArgs args)
				{
					SetArcherConfig("Archer_MultiShot_ArrowCount", args);
				}

				internal void <Postfix>b__0_13(ConsoleEventArgs args)
				{
					SetArcherConfig("Archer_MultiShot_ArrowConsumption", args);
				}

				internal void <Postfix>b__0_14(ConsoleEventArgs args)
				{
					SetArcherConfig("Archer_MultiShot_DamagePercent", args);
				}

				internal void <Postfix>b__0_15(ConsoleEventArgs args)
				{
					SetBowConfig("Bow_MultiShot_Lv1_Chance", args);
				}

				internal void <Postfix>b__0_16(ConsoleEventArgs args)
				{
					SetBowConfig("Bow_MultiShot_Lv2_Chance", args);
				}

				internal void <Postfix>b__0_17(ConsoleEventArgs args)
				{
					SetBowConfig("Bow_MultiShot_ArrowCount", args);
				}

				internal void <Postfix>b__0_18(ConsoleEventArgs args)
				{
					SetBowConfig("Bow_MultiShot_ArrowConsumption", args);
				}

				internal void <Postfix>b__0_19(ConsoleEventArgs args)
				{
					SetBowConfig("Bow_MultiShot_DamagePercent", args);
				}
			}

			private static void Postfix()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Expected O, but got Unknown
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Expected O, but got Unknown
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Expected O, but got Unknown
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Expected O, but got Unknown
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Expected O, but got Unknown
				//IL_0183: Unknown result type (might be due to invalid IL or missing references)
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0174: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Expected O, but got Unknown
				//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b2: Expected O, but got Unknown
				//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01df: 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_01ea: Expected O, but got Unknown
				//IL_022b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0217: Unknown result type (might be due to invalid IL or missing references)
				//IL_021c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0222: Expected O, but got Unknown
				//IL_0263: Unknown result type (might be due to invalid IL or missing references)
				//IL_024f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0254: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Expected O, but got Unknown
				//IL_029b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0287: Unknown result type (might be due to invalid IL or missing references)
				//IL_028c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0292: Expected O, but got Unknown
				//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ca: Expected O, but got Unknown
				//IL_030b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f7: 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_0302: Expected O, but got Unknown
				//IL_0343: Unknown result type (might be due to invalid IL or missing references)
				//IL_032f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0334: Unknown result type (might be due to invalid IL or missing references)
				//IL_033a: Expected O, but got Unknown
				//IL_037b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0367: Unknown result type (might be due to invalid IL or missing references)
				//IL_036c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0372: Expected O, but got Unknown
				//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_039f: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03aa: Expected O, but got Unknown
				//IL_03eb: 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_03e2: Expected O, but got Unknown
				//IL_0423: Unknown result type (might be due to invalid IL or missing references)
				//IL_040f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0414: Unknown result type (might be due to invalid IL or missing references)
				//IL_041a: Expected O, but got Unknown
				//IL_045b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0447: Unknown result type (might be due to invalid IL or missing references)
				//IL_044c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0452: Expected O, but got Unknown
				object obj = <>c.<>9__0_0;
				if (obj == null)
				{
					ConsoleEvent val = delegate(ConsoleEventArgs args)
					{
						SetAttackConfig("AttackRootDamageBonus", args);
					};
					<>c.<>9__0_0 = val;
					obj = (object)val;
				}
				new ConsoleCommand("skilltree_attack_root", "공격 전문가 루트 데미지 보너스 설정 (예: skilltree_attack_root 7)", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj2 = <>c.<>9__0_1;
				if (obj2 == null)
				{
					ConsoleEvent val2 = delegate(ConsoleEventArgs args)
					{
						SetAttackConfig("AttackMeleeBonusChance", args);
					};
					<>c.<>9__0_1 = val2;
					obj2 = (object)val2;
				}
				new ConsoleCommand("skilltree_melee_chance", "근접 특화 발동 확률 설정 (예: skilltree_melee_chance 25)", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj3 = <>c.<>9__0_2;
				if (obj3 == null)
				{
					ConsoleEvent val3 = delegate(ConsoleEventArgs args)
					{
						SetAttackConfig("AttackMeleeBonusDamage", args);
					};
					<>c.<>9__0_2 = val3;
					obj3 = (object)val3;
				}
				new ConsoleCommand("skilltree_melee_damage", "근접 특화 피해량 설정 (예: skilltree_melee_damage 15)", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj4 = <>c.<>9__0_3;
				if (obj4 == null)
				{
					ConsoleEvent val4 = delegate(ConsoleEventArgs args)
					{
						SetAttackConfig("AttackBowBonusChance", args);
					};
					<>c.<>9__0_3 = val4;
					obj4 = (object)val4;
				}
				new ConsoleCommand("skilltree_bow_chance", "활 특화 발동 확률 설정 (예: skilltree_bow_chance 30)", (ConsoleEvent)obj4, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj5 = <>c.<>9__0_4;
				if (obj5 == null)
				{
					ConsoleEvent val5 = delegate(ConsoleEventArgs args)
					{
						SetAttackConfig("AttackBowBonusDamage", args);
					};
					<>c.<>9__0_4 = val5;
					obj5 = (object)val5;
				}
				new ConsoleCommand("skilltree_bow_damage", "활 특화 피해량 설정 (예: skilltree_bow_damage 18)", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj6 = <>c.<>9__0_5;
				if (obj6 == null)
				{
					ConsoleEvent val6 = delegate(ConsoleEventArgs args)
					{
						SetSpeedConfig("Speed_Expert_MoveSpeed", args);
					};
					<>c.<>9__0_5 = val6;
					obj6 = (object)val6;
				}
				new ConsoleCommand("skilltree_speed_root", "속도 전문가 루트 이동속도 설정 (예: skilltree_speed_root 5)", (ConsoleEvent)obj6, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj7 = <>c.<>9__0_6;
				if (obj7 == null)
				{
					ConsoleEvent val7 = delegate(ConsoleEventArgs args)
					{
						SetSpeedConfig("Speed_Step1_DodgeSpeed", args);
					};
					<>c.<>9__0_6 = val7;
					obj7 = (object)val7;
				}
				new ConsoleCommand("skilltree_speed_dodge", "구르기 속도 보너스 설정 (예: skilltree_speed_dodge 15)", (ConsoleEvent)obj7, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj8 = <>c.<>9__0_7;
				if (obj8 == null)
				{
					ConsoleEvent val8 = delegate(ConsoleEventArgs args)
					{
						SetSpeedConfig("Speed_Step2_MeleeComboBonus", args);
					};
					<>c.<>9__0_7 = val8;
					obj8 = (object)val8;
				}
				new ConsoleCommand("skilltree_speed_melee_combo", "근접 콤보 이동속도 설정 (예: skilltree_speed_melee_combo 6)", (ConsoleEvent)obj8, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj9 = <>c.<>9__0_8;
				if (obj9 == null)
				{
					ConsoleEvent val9 = delegate(ConsoleEventArgs args)
					{
						SetSpeedConfig("Speed_Step2_BowHitBonus", args);
					};
					<>c.<>9__0_8 = val9;
					obj9 = (object)val9;
				}
				new ConsoleCommand("skilltree_speed_bow_hit", "활 적중 이동속도 설정 (예: skilltree_speed_bow_hit 8)", (ConsoleEvent)obj9, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj10 = <>c.<>9__0_9;
				if (obj10 == null)
				{
					ConsoleEvent val10 = delegate(ConsoleEventArgs args)
					{
						SetSpeedConfig("Speed_Step8_MeleeAttackSpeed", args);
					};
					<>c.<>9__0_9 = val10;
					obj10 = (object)val10;
				}
				new ConsoleCommand("skilltree_speed_attack", "공격속도 증가 설정 (예: skilltree_speed_attack 10)", (ConsoleEvent)obj10, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj11 = <>c.<>9__0_10;
				if (obj11 == null)
				{
					ConsoleEvent val11 = delegate
					{
						SkillTreeConfig.ReloadAndBroadcast();
					};
					<>c.<>9__0_10 = val11;
					obj11 = (object)val11;
				}
				new ConsoleCommand("skilltree_config_reload", "설정 리로드 및 재전송", (ConsoleEvent)obj11, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj12 = <>c.<>9__0_11;
				if (obj12 == null)
				{
					ConsoleEvent val12 = delegate
					{
						ShowCurrentConfig();
					};
					<>c.<>9__0_11 = val12;
					obj12 = (object)val12;
				}
				new ConsoleCommand("skilltree_config_show", "현재 설정 표시", (ConsoleEvent)obj12, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj13 = <>c.<>9__0_12;
				if (obj13 == null)
				{
					ConsoleEvent val13 = delegate(ConsoleEventArgs args)
					{
						SetArcherConfig("Archer_MultiShot_ArrowCount", args);
					};
					<>c.<>9__0_12 = val13;
					obj13 = (object)val13;
				}
				new ConsoleCommand("skilltree_archer_arrows", "아처 멀티샷 화살 수 설정 (예: skilltree_archer_arrows 7)", (ConsoleEvent)obj13, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj14 = <>c.<>9__0_13;
				if (obj14 == null)
				{
					ConsoleEvent val14 = delegate(ConsoleEventArgs args)
					{
						SetArcherConfig("Archer_MultiShot_ArrowConsumption", args);
					};
					<>c.<>9__0_13 = val14;
					obj14 = (object)val14;
				}
				new ConsoleCommand("skilltree_archer_consume", "아처 멀티샷 화살 소모량 설정 (예: skilltree_archer_consume 2)", (ConsoleEvent)obj14, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj15 = <>c.<>9__0_14;
				if (obj15 == null)
				{
					ConsoleEvent val15 = delegate(ConsoleEventArgs args)
					{
						SetArcherConfig("Archer_MultiShot_DamagePercent", args);
					};
					<>c.<>9__0_14 = val15;
					obj15 = (object)val15;
				}
				new ConsoleCommand("skilltree_archer_damage", "아처 멀티샷 데미지 비율 설정 (예: skilltree_archer_damage 80)", (ConsoleEvent)obj15, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj16 = <>c.<>9__0_15;
				if (obj16 == null)
				{
					ConsoleEvent val16 = delegate(ConsoleEventArgs args)
					{
						SetBowConfig("Bow_MultiShot_Lv1_Chance", args);
					};
					<>c.<>9__0_15 = val16;
					obj16 = (object)val16;
				}
				new ConsoleCommand("skilltree_bow_lv1_chance", "활 전문가 멀티샷 Lv1 확률 설정 (예: skilltree_bow_lv1_chance 15)", (ConsoleEvent)obj16, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj17 = <>c.<>9__0_16;
				if (obj17 == null)
				{
					ConsoleEvent val17 = delegate(ConsoleEventArgs args)
					{
						SetBowConfig("Bow_MultiShot_Lv2_Chance", args);
					};
					<>c.<>9__0_16 = val17;
					obj17 = (object)val17;
				}
				new ConsoleCommand("skilltree_bow_lv2_chance", "활 전문가 멀티샷 Lv2 확률 설정 (예: skilltree_bow_lv2_chance 36)", (ConsoleEvent)obj17, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj18 = <>c.<>9__0_17;
				if (obj18 == null)
				{
					ConsoleEvent val18 = delegate(ConsoleEventArgs args)
					{
						SetBowConfig("Bow_MultiShot_ArrowCount", args);
					};
					<>c.<>9__0_17 = val18;
					obj18 = (object)val18;
				}
				new ConsoleCommand("skilltree_bow_arrows", "활 전문가 멀티샷 화살 수 설정 (예: skilltree_bow_arrows 2)", (ConsoleEvent)obj18, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj19 = <>c.<>9__0_18;
				if (obj19 == null)
				{
					ConsoleEvent val19 = delegate(ConsoleEventArgs args)
					{
						SetBowConfig("Bow_MultiShot_ArrowConsumption", args);
					};
					<>c.<>9__0_18 = val19;
					obj19 = (object)val19;
				}
				new ConsoleCommand("skilltree_bow_consume", "활 전문가 멀티샷 화살 소모량 설정 (예: skilltree_bow_consume 0)", (ConsoleEvent)obj19, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				object obj20 = <>c.<>9__0_19;
				if (obj20 == null)
				{
					ConsoleEvent val20 = delegate(ConsoleEventArgs args)
					{
						SetBowConfig("Bow_MultiShot_DamagePercent", args);
					};
					<>c.<>9__0_19 = val20;
					obj20 = (object)val20;
				}
				new ConsoleCommand("skilltree_bow_damage", "활 전문가 멀티샷 데미지 비율 설정 (예: skilltree_bow_damage 70)", (ConsoleEvent)obj20, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			}
		}

		[HarmonyPatch(typeof(Player), "OnDestroy")]
		public static class Plugin_Player_OnDestroy_DamagePatch_Cleanup
		{
			private static void Postfix(Player __instance)
			{
				try
				{
					NerveEnhancementSystem.Damage_Patch.CleanupPlayerData(__instance);
				}
				catch
				{
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__47_0;

			internal void <SetupIconClickEvent>b__47_0()
			{
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0116: Expected O, but got Unknown
				Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!");
				if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled)
				{
					SkillTreeBGMManager.Instance.PlaySkillTreeBGM();
				}
				else if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
				{
					Log.LogInfo((object)"[BGM] BGM이 비활성화되어 있어 재생하지 않음");
				}
				InventoryGui instance = InventoryGui.instance;
				if ((Object)(object)instance == (Object)null)
				{
					Debug.LogWarning((object)"[스킬트리] InventoryGui.instance를 찾을 수 없음");
					return;
				}
				Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>();
				if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || (Object)(object)skillTreeUI.panel.transform.parent != (Object)(object)((Component)componentInChildren).transform)
				{
					if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null)
					{
						Object.Destroy((Object)(object)skillTreeUI.panel);
					}
					GameObject val = new GameObject("SkillTreeUI");
					val.transform.SetParent(((Component)componentInChildren).transform, false);
					skillTreeUI = val.AddComponent<SkillTreeUI>();
					skillTreeUI.CreateUI(componentInChildren);
				}
				if (!skillTreeUI.panel.activeSelf)
				{
					skillTreeUI.RefreshUI();
					skillTreeUI.panel.SetActive(true);
					return;
				}
				skillTreeUI.panel.SetActive(false);
				if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
				{
					SkillTreeBGMManager.Instance.PauseSkillTreeBGM();
				}
			}
		}

		[CompilerGenerated]
		private sealed class <Start>d__24 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Start>d__24(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					ConfigEntry<string> languageConfig = LocalizationManager.LanguageConfig;
					if (languageConfig != null && (languageConfig.Value?.Equals("Auto", StringComparison.OrdinalIgnoreCase)).GetValueOrDefault())
					{
						LocalizationManager.ReloadLanguage();
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static ManualLogSource Log;

		private static GameObject skillTreeIconObj;

		private static Sprite swordIcon;

		private static AssetBundle iconAssetBundle;

		private static AssetBundle uiAssetBundle;

		private static AssetBundle customIconBundle;

		private static AssetBundle jobIconBundle;

		private static AssetBundle vfxBundle;

		private static AssetBundle jobVfxBundle;

		public static int SkillTreePoint = 0;

		private static SkillTreeUI skillTreeUI;

		private static Sprite customSkillTreeIcon;

		private static Plugin? _instance;

		private static bool _coreSystemsInitialized = false;

		private static bool _emergencyMode = false;

		private static int _iconCreationAttempts = 0;

		private const int MAX_ICON_ATTEMPTS = 5;

		private static Type _cachedMmoType = null;

		private static bool _mmoTypeChecked = false;

		private static readonly bool _earlyUserBackup = CreateEarlyUserBackup();

		public static bool IsSkillTreeOpen => (Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf;

		public static Plugin? Instance => _instance;

		private void Awake()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_instance = this;
			string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
			string path = Path.ChangeExtension(configFilePath, ".version");
			string contents = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString();
			File.WriteAllText(path, contents);
			CaptainLevelConfig.Bind(((BaseUnityPlugin)this).Config);
			Log.LogDebug((object)"[Captain Level System] Config 바인딩 완료");
			SkillTreeConfig.Initialize(((BaseUnityPlugin)this).Config);
			LocalizationManager.Initialize(((BaseUnityPlugin)this).Config);
			Log.LogInfo((object)"[Plugin] ✓ 로컬라이제이션 시스템 초기화 완료");
			Staff_Config.InitConfig(((BaseUnityPlugin)this).Config);
			CaptainMMOBridge.Initialize();
			InitializeCoreSafeguards();
			Harmony val = new Harmony("CaptainSkillTree.Mod");
			Log.LogInfo((object)"========== Captain SkillTree 초기화 중... ==========");
			try
			{
				val.PatchAll();
				Log.LogInfo((object)("========== Captain SkillTree 초기화 완료! (MMO: " + (EpicMMOReflectionHelper.IsAvailable ? "연동" : "독립") + ") =========="));
				Log.LogDebug((object)"[Harmony] 패치 등록 완료");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("=== [CRITICAL] Harmony.PatchAll() 실패: " + ex.Message + " ==="));
				Log.LogError((object)("=== [CRITICAL] StackTrace: " + ex.StackTrace + " ==="));
			}
			InitializeInputListener();
			SkillTreeData.RegisterAll();
			SafeLoadCustomIcon();
			InitializeBGMSystem();
			InitializePrefabSystem();
			GameObject val2 = new GameObject("ActiveSkillHUD");
			val2.AddComponent<ActiveSkillHUD>();
			Object.DontDestroyOnLoad((Object)(object)val2);
			RegisterJotunnCommands();
			_coreSystemsInitialized = true;
			try
			{
				Type type = typeof(BaseUnityPlugin).Assembly.GetType("BepInEx.ConsoleManager");
				MethodInfo methodInfo = type?.GetMethod("SetConsoleColor", BindingFlags.Static | BindingFlags.Public);
				TextWriter textWriter = type?.GetProperty("StandardOutStream", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as TextWriter;
				if (methodInfo != null && textWriter != null)
				{
					methodInfo.Invoke(null, new object[1] { ConsoleColor.Cyan });
					textWriter.WriteLine("================================ Captain SkillTree Mod Load Success ================================");
					textWriter.WriteLine("     ===   ==   ===   ====   ==   ====  =  =");
					textWriter.WriteLine("    =     =  =  =  =   ==   =  =   ==   == =");
					textWriter.WriteLine("    =     ====  ===    ==   ====   ==   = ==");
					textWriter.WriteLine("    =     =  =  =      ==   =  =   ==   =  =");
					textWriter.WriteLine("     ===   =  =  =      ==   =  =  ====  =  =");
					textWriter.WriteLine("");
					textWriter.WriteLine("     ===  =  =  ====  =     =     ====  ===   ====  ====");
					textWriter.WriteLine("    =     = =   ==   =     =      ==  =  =  =     =   ");
					textWriter.WriteLine("    ===   ==    ==   =     =      ==  ===   ===   === ");
					textWriter.WriteLine("       =  = =   ==   =     =      ==  = =   =     =   ");
					textWriter.WriteLine("    ===   =  =  ====  ====  ====   ==  =  =  ====  ====");
					textWriter.WriteLine("================================ Captain SkillTree Mod Load Success ================================");
					methodInfo.Invoke(null, new object[1] { ConsoleColor.Gray });
				}
				else
				{
					Log.LogMessage((object)"================================ Captain SkillTree Mod Load Success ================================");
				}
			}
			catch
			{
				Log.LogMessage((object)"================================ Captain SkillTree Mod Load Success ================================");
			}
		}

		[IteratorStateMachine(typeof(<Start>d__24))]
		private IEnumerator Start()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Start>d__24(0)
			{
				<>4__this = this
			};
		}

		private void RegisterJotunnCommands()
		{
			try
			{
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkillAddConsoleCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkillResetConsoleCommand());
				Log.LogInfo((object)"[Jotunn] 콘솔 명령어 등록 완료: skilladd, skillreset");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[Jotunn] 콘솔 명령어 등록 실패: " + ex.Message));
			}
		}

		private static void InitializeCoreSafeguards()
		{
			try
			{
				if (!_coreSystemsInitialized)
				{
					ValidateEssentialResources();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[안전 장치] 초기화 실패: " + ex.Message));
				_emergencyMode = true;
			}
		}

		private static void InitializeInputListener()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			try
			{
				if ((Object)(object)SkillTreeInputListener.Instance == (Object)null)
				{
					GameObject val = new GameObject("SkillTreeInputListener");
					val.AddComponent<SkillTreeInputListener>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[안전 장치] InputListener 초기화 실패: " + ex.Message));
			}
		}

		private static void ValidateEssentialResources()
		{
			string[] array = new string[4] { "CaptainSkillTree.asset.Resources.skill_node", "CaptainSkillTree.asset.Resources.captainskilltreeui", "CaptainSkillTree.asset.Resources.skill_start", "CaptainSkillTree.asset.Resources.job_icon" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream(text);
				if (manifestResourceStream == null)
				{
					throw new Exception("필수 리소스 누락: " + text);
				}
				manifestResourceStream.Close();
			}
			ResetEmergencyMode();
		}

		private static void ResetEmergencyMode()
		{
			_emergencyMode = false;
			_iconCreationAttempts = 0;
		}

		private static void SafeLoadCustomIcon()
		{
			try
			{
				Log.LogDebug((object)"[아이콘] 커스텀 아이콘 로드 시작");
				AssetBundle val = GetJobIconBundle();
				if ((Object)(object)val != (Object)null)
				{
					Log.LogDebug((object)"[아이콘] job_icon 번들 로드 성공");
					string[] array = new string[12]
					{
						"Paladin_unlock", "Tanker_unlock", "Berserker_unlock", "Archer_unlock", "Mage_unlock", "Rogue_unlock", "Paladin", "Tanker", "Berserker", "Archer",
						"Mage", "Rogue"
					};
					string[] array2 = array;
					foreach (string text in array2)
					{
						Sprite val2 = val.LoadAsset<Sprite>(text);
						if ((Object)(object)val2 != (Object)null)
						{
							Log.LogDebug((object)("[아이콘] job_icon에서 " + text + " 로드 성공: " + ((Object)val2).name));
						}
					}
				}
				AssetBundle val3 = GetCustomIconBundle();
				if ((Object)(object)val3 != (Object)null)
				{
					Log.LogDebug((object)"[아이콘] 커스텀 아이콘 번들 로드 성공");
					string[] allAssetNames = val3.GetAllAssetNames();
					Log.LogDebug((object)$"[아이콘] 번들 에셋 수: {allAssetNames.Length}");
					string[] array3 = allAssetNames;
					foreach (string text2 in array3)
					{
						Log.LogDebug((object)("[아이콘] 번들 에셋: " + text2));
					}
					customSkillTreeIcon = val3.LoadAsset<Sprite>("skill_start");
					if ((Object)(object)customSkillTreeIcon != (Object)null)
					{
						Log.LogDebug((object)"[아이콘] skill_start 스프라이트 로드 성공");
					}
					else
					{
						TryAlternativeIconNames(val3);
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[아이콘] 커스텀 아이콘 로드 중 오류: " + ex.Message));
				Log.LogError((object)("[아이콘] StackTrace: " + ex.StackTrace));
			}
		}

		private static void TryAlternativeIconNames(AssetBundle bundle)
		{
			string[] array = new string[7] { "skill_start", "SkillStart", "skill_tree_start", "captainskilltreeicon", "CaptainSkillTreeIcon", "SkillTreeIcon", "skilltreeicon" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				Sprite val = bundle.LoadAsset<Sprite>(text);
				if ((Object)(object)val != (Object)null)
				{
					customSkillTreeIcon = val;
					Log.LogDebug((object)("[아이콘] 대체 이름으로 아이콘 로드 성공: " + text));
					return;
				}
			}
			Log.LogWarning((object)"[아이콘] 모든 아이콘 이름 시도 실패 - 게임 기본 아이콘 사용");
		}

		public static AssetBundle GetIconAssetBundle()
		{
			if ((Object)(object)iconAssetBundle == (Object)null)
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.skill_node");
				if (manifestResourceStream != null)
				{
					iconAssetBundle = AssetBundle.LoadFromStream(manifestResourceStream);
				}
			}
			return iconAssetBundle;
		}

		public static AssetBundle GetUIAssetBundle()
		{
			if ((Object)(object)uiAssetBundle == (Object)null)
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.captainskilltreeui");
				if (manifestResourceStream != null)
				{
					uiAssetBundle = AssetBundle.LoadFromStream(manifestResourceStream);
				}
			}
			return uiAssetBundle;
		}

		public static AssetBundle GetCustomIconBundle()
		{
			if ((Object)(object)customIconBundle == (Object)null)
			{
				try
				{
					Assembly assembly = typeof(Plugin).Assembly;
					Log.LogDebug((object)("[번들] Assembly: " + assembly.FullName));
					string[] manifestResourceNames = assembly.GetManifestResourceNames();
					Log.LogDebug((object)$"[번들] 사용 가능한 리소스 수: {manifestResourceNames.Length}");
					bool flag = false;
					string[] array = manifestResourceNames;
					foreach (string text in array)
					{
						Log.LogDebug((object)("[번들] 리소스: " + text));
						if (text.Contains("skill_start"))
						{
							flag = true;
							Log.LogDebug((object)("[번들] 시작 아이콘 리소스 발견: " + text));
						}
					}
					if (!flag)
					{
						Log.LogError((object)"[번들] skill_start 리소스가 DLL에 포함되지 않음!");
					}
					Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.skill_start");
					if (manifestResourceStream != null)
					{
						Log.LogDebug((object)$"[번들] 스트림 로드 성공, 크기: {manifestResourceStream.Length} bytes");
						customIconBundle = AssetBundle.LoadFromStream(manifestResourceStream);
						if ((Object)(object)customIconBundle != (Object)null)
						{
							Log.LogDebug((object)"[번들] AssetBundle 로드 성공");
						}
						else
						{
							Log.LogError((object)"[번들] AssetBundle.LoadFromStream 실패");
						}
					}
					else
					{
						Log.LogError((object)"[번들] 리소스 스트림이 null");
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[번들] GetCustomIconBundle 오류: " + ex.Message));
				}
			}
			return customIconBundle;
		}

		public static AssetBundle GetJobIconBundle()
		{
			if ((Object)(object)jobIconBundle == (Object)null)
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.job_icon");
				if (manifestResourceStream != null)
				{
					jobIconBundle = AssetBundle.LoadFromStream(manifestResourceStream);
					if ((Object)(object)jobIconBundle != (Object)null)
					{
						Log.LogDebug((object)"[아이콘] job_icon 번들 로드 성공");
						string[] allAssetNames = jobIconBundle.GetAllAssetNames();
						Log.LogDebug((object)$"[아이콘] job_icon 번들 에셋 수: {allAssetNames.Length}");
						string[] array = allAssetNames;
						foreach (string text in array)
						{
							Log.LogDebug((object)("[아이콘] job_icon 에셋: " + text));
						}
					}
					else
					{
						Log.LogError((object)"[아이콘] job_icon AssetBundle.LoadFromStream 실패");
					}
				}
				else
				{
					Log.LogWarning((object)"[아이콘] job_icon 리소스 스트림이 null");
				}
			}
			return jobIconBundle;
		}

		public static AssetBundle GetVfxBundle()
		{
			if ((Object)(object)vfxBundle == (Object)null)
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.VFX.vfxbundle");
				if (manifestResourceStream != null)
				{
					vfxBundle = AssetBundle.LoadFromStream(manifestResourceStream);
					if ((Object)(object)vfxBundle != (Object)null)
					{
						Log.LogDebug((object)"[VFX] VFX 폴더에서 vfxbundle 번들 로드 성공");
					}
					else
					{
						Log.LogError((object)"[VFX] VFX 폴더에서 vfxbundle 번들 로드 실패");
					}
				}
				else
				{
					Log.LogError((object)"[VFX] VFX 폴더에서 vfxbundle 리소스 스트림을 찾을 수 없음");
				}
			}
			return vfxBundle;
		}

		public static AssetBundle GetJobVfxBundle()
		{
			if ((Object)(object)jobVfxBundle == (Object)null)
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.job_vfx");
				if (manifestResourceStream != null)
				{
					jobVfxBundle = AssetBundle.LoadFromStream(manifestResourceStream);
					if ((Object)(object)jobVfxBundle != (Object)null)
					{
						Log.LogDebug((object)"[VFX] job_vfx 번들 로드 성공");
					}
					else
					{
						Log.LogError((object)"[VFX] job_vfx 번들 로드 실패");
					}
				}
				else
				{
					Log.LogError((object)"[VFX] job_vfx 리소스 스트림을 찾을 수 없음");
				}
			}
			return jobVfxBundle;
		}

		public static T LoadEmbeddedAsset<T>(string resourcePath) where T : Object
		{
			try
			{
				Assembly assembly = typeof(Plugin).Assembly;
				Stream manifestResourceStream = assembly.GetManifestResourceStream(resourcePath);
				if (manifestResourceStream == null)
				{
					Log.LogWarning((object)("[LoadEmbeddedAsset] 리소스를 찾을 수 없음: " + resourcePath));
					return default(T);
				}
				AssetBundle val = AssetBundle.LoadFromStream(manifestResourceStream);
				if ((Object)(object)val == (Object)null)
				{
					Log.LogWarning((object)("[LoadEmbeddedAsset] AssetBundle 로드 실패: " + resourcePath));
					manifestResourceStream.Close();
					return default(T);
				}
				T[] array = val.LoadAllAssets<T>();
				if (array.Length != 0)
				{
					T val2 = array[0];
					Log.LogInfo((object)("[LoadEmbeddedAsset] 에셋 로드 성공: " + resourcePath + " -> " + ((Object)val2).name));
					return val2;
				}
				Log.LogWarning((object)("[LoadEmbeddedAsset] " + typeof(T).Name + " 타입의 에셋을 찾을 수 없음: " + resourcePath));
				val.Unload(false);
				manifestResourceStream.Close();
				return default(T);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[LoadEmbeddedAsset] 에셋 로드 오류: " + resourcePath + " - " + ex.Message));
				return default(T);
			}
		}

		private static void ShowSkillTreeIcon()
		{
			if ((Object)(object)skillTreeIconObj != (Object)null)
			{
				skillTreeIconObj.SetActive(true);
				return;
			}
			if (_emergencyMode || _iconCreationAttempts >= 5)
			{
				Log.LogWarning((object)"[안전 장치] 비상 모드 또는 최대 시도 횟수 초과 - 아이콘 생성 건너뛰기");
				return;
			}
			try
			{
				if (!ValidatePrerequisites())
				{
					Log.LogWarning((object)"[안전 장치] 전제 조건 미충족 - 아이콘 생성 연기");
					return;
				}
				if (!_mmoTypeChecked)
				{
					_cachedMmoType = Type.GetType("EpicMMOSystem.MyUI, EpicMMOSystem");
					_mmoTypeChecked = true;
				}
				Type cachedMmoType = _cachedMmoType;
				if (cachedMmoType != null && TryCreateMMOStyleIcon())
				{
					ResetIconAttempts();
				}
				else
				{
					CreateFallbackSkillTreeIcon();
				}
			}
			catch (Exception ex)
			{
				_iconCreationAttempts++;
				Log.LogError((object)$"[안전 장치] SkillTreeIcon 생성 중 예외 (시도 {_iconCreationAttempts}/{5}): {ex.Message}");
				Log.LogError((object)("[안전 장치] StackTrace: " + ex.StackTrace));
				if (_iconCreationAttempts < 5)
				{
					try
					{
						CreateFallbackSkillTreeIcon();
						return;
					}
					catch (Exception ex2)
					{
						Log.LogError((object)("[안전 장치] 대체 아이콘 생성도 실패: " + ex2.Message));
						return;
					}
				}
				Log.LogError((object)"[안전 장치] 최대 시도 횟수 도달 - 비상 모드 활성화");
				_emergencyMode = true;
			}
		}

		private static bool ValidatePrerequisites()
		{
			try
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					Log.LogDebug((object)"[안전 장치] Player가 아직 로드되지 않음");
					return false;
				}
				if ((Object)(object)InventoryGui.instance == (Object)null)
				{
					Log.LogDebug((object)"[안전 장치] InventoryGui가 아직 준비되지 않음");
					return false;
				}
				if ((Object)(object)GetCustomIconBundle() == (Object)null && (Object)(object)swordIcon == (Object)null)
				{
					Log.LogWarning((object)"[안전 장치] 아이콘 리소스가 준비되지 않음 - 로드 시도");
					SafeLoadCustomIcon();
					LoadGameDefaultIcon();
				}
				return true;
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[안전 장치] 전제 조건 검증 실패: " + ex.Message));
				return false;
			}
		}

		private static void LoadGameDefaultIcon()
		{
			try
			{
				if (!((Object)(object)swordIcon == (Object)null) || !((Object)(object)ObjectDB.instance != (Object)null))
				{
					return;
				}
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron");
				if ((Object)(object)itemPrefab != (Object)null)
				{
					ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
					if ((Object)(object)component != (Object)null)
					{
						swordIcon = component.m_itemData.GetIcon();
						Log.LogDebug((object)"[안전 장치] 게임 기본 아이콘 로드 성공");
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private static void ResetIconAttempts()
		{
			_iconCreationAttempts = 0;
		}

		private static bool TryCreateMMOStyleIcon()
		{
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Expected O, but got Unknown
			try
			{
				Type cachedMmoType = _cachedMmoType;
				if (cachedMmoType == null)
				{
					Log.LogWarning((object)"EpicMMOSystem.MyUI 타입을 찾을 수 없음");
					return false;
				}
				FieldInfo field = cachedMmoType.GetField("navigationPanel", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					Log.LogWarning((object)"navigationPanel 필드를 찾을 수 없음");
					return false;
				}
				object? value = field.GetValue(null);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if ((Object)(object)val == (Object)null)
				{
					Log.LogWarning((object)"navigationPanel이 null");
					return false;
				}
				Transform val2 = val.transform.Find("Buttons");
				if ((Object)(object)val2 == (Object)null)
				{
					Log.LogWarning((object)"Buttons 오브젝트를 찾을 수 없음");
					return false;
				}
				Transform val3 = val2.Find("ButtonSkillTree");
				if ((Object)(object)val3 != (Object)null)
				{
					skillTreeIconObj = ((Component)val3).gameObject;
					skillTreeIconObj.SetActive(true);
					return true;
				}
				Transform val4 = val2.Find("ButtonLevelSystem");
				if ((Object)(object)val4 == (Object)null)
				{
					Log.LogWarning((object)"ButtonLevelSystem 오브젝트를 찾을 수 없음");
					return false;
				}
				skillTreeIconObj = Object.Instantiate<GameObject>(((Component)val4).gameObject, val2);
				((Object)skillTreeIconObj).name = "ButtonSkillTree";
				Image val5 = skillTreeIconObj.GetComponent<Image>();
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = skillTreeIconObj.GetComponentInChildren<Image>();
				}
				if ((Object)(object)customSkillTreeIcon != (Object)null)
				{
					val5.sprite = customSkillTreeIcon;
				}
				else
				{
					if ((Object)(object)swordIcon == (Object)null)
					{
						ObjectDB instance = ObjectDB.instance;
						if ((Object)(object)instance == (Object)null)
						{
							Log.LogWarning((object)"ObjectDB.instance가 null");
							return false;
						}
						GameObject itemPrefab = instance.GetItemPrefab("SwordIron");
						if ((Object)(object)itemPrefab == (Object)null)
						{
							Log.LogWarning((object)"SwordIron 프리팹을 찾을 수 없음");
							return false;
						}
						ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
						if ((Object)(object)component == (Object)null)
						{
							Log.LogWarning((object)"SwordIron에 ItemDrop 컴포넌트가 없음");
							return false;
						}
						swordIcon = component.m_itemData.GetIcon();
						if ((Object)(object)swordIcon == (Object)null)
						{
							Log.LogWarning((object)"SwordIron 아이콘(Sprite)을 찾을 수 없음");
							return false;
						}
					}
					val5.sprite = swordIcon;
				}
				RectTransform component2 = skillTreeIconObj.GetComponent<RectTransform>();
				RectTransform component3 = ((Component)val4).GetComponent<RectTransform>();
				component2.anchoredPosition = component3.anchoredPosition + new Vector2(80f, 0f);
				component2.sizeDelta = component3.sizeDelta;
				component2.anchorMin = component3.anchorMin;
				component2.anchorMax = component3.anchorMax;
				component2.pivot = component3.pivot;
				((Transform)component2).localScale = ((Transform)component3).localScale;
				foreach (Transform item in skillTreeIconObj.transform)
				{
					Transform val6 = item;
					if ((Object)(object)((Component)val6).GetComponent<Image>() == (Object)null)
					{
						((Component)val6).gameObject.SetActive(false);
					}
				}
				SetupIconClickEvent();
				Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					Log.LogDebug((object)$"[시작 아이콘] 부모 Canvas sortingOrder: {componentInParent.sortingOrder}");
				}
				skillTreeIconObj.SetActive(true);
				Log.LogDebug((object)"[시작 아이콘] 아이콘 생성 및 활성화 완료");
				return true;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("아이콘 생성 실패: " + ex.Message));
				return false;
			}
		}

		private static void CreateFallbackSkillTreeIcon()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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)
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Log.LogWarning((object)"[디버그] InventoryGui.instance가 null, 아이콘 생성 불가");
				return;
			}
			Log.LogInfo((object)"[디버그] InventoryGui 인스턴스 확인됨");
			if ((Object)(object)skillTreeIconObj != (Object)null)
			{
				skillTreeIconObj.SetActive(true);
				Log.LogDebug((object)"기존 대체 아이콘 활성화");
				return;
			}
			try
			{
				Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					Log.LogWarning((object)"InventoryGui에서 Canvas를 찾을 수 없음");
					return;
				}
				Transform val = ((Component)componentInChildren).transform.Find("Player");
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)componentInChildren).transform;
				}
				GameObject val2 = new GameObject("ButtonSkillTree_Fallback");
				val2.transform.SetParent(val, false);
				RectTransform val3 = val2.AddComponent<RectTransform>();
				val3.anchorMin = new Vector2(0.5f, 0f);
				val3.anchorMax = new Vector2(0.5f, 0f);
				val3.pivot = new Vector2(0.5f, 0f);
				val3.anchoredPosition = new Vector2(100f, 10f);
				val3.sizeDelta = new Vector2(60f, 60f);
				Image val4 = val2.AddComponent<Image>();
				if ((Object)(object)customSkillTreeIcon != (Object)null)
				{
					val4.sprite = customSkillTreeIcon;
				}
				else
				{
					if ((Object)(object)swordIcon == (Object)null)
					{
						ObjectDB instance2 = ObjectDB.instance;
						if ((Object)(object)instance2 != (Object)null)
						{
							GameObject itemPrefab = instance2.GetItemPrefab("SwordIron");
							if ((Object)(object)itemPrefab != (Object)null)
							{
								ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
								if ((Object)(object)component != (Object)null)
								{
									swordIcon = component.m_itemData.GetIcon();
								}
							}
						}
					}
					val4.sprite = swordIcon;
				}
				if ((Object)(object)val4.sprite == (Object)null)
				{
					((Graphic)val4).color = new Color(0.2f, 0.6f, 1f, 0.8f);
					Log.LogInfo((object)"스프라이트가 없어 단색으로 표시");
				}
				Button val5 = val2.AddComponent<Button>();
				((Selectable)val5).targetGraphic = (Graphic)(object)val4;
				skillTreeIconObj = val2;
				SetupIconClickEvent();
				Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					Log.LogDebug((object)$"[대체 아이콘] 부모 Canvas sortingOrder: {componentInParent.sortingOrder}");
				}
				skillTreeIconObj.SetActive(true);
				Log.LogDebug((object)"아이콘 생성 성공");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("대체 아이콘 생성 실패: " + ex.Message));
			}
		}

		private static void SetupIconSprite(Image image)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			try
			{
				SafeLoadCustomIcon();
				if ((Object)(object)customSkillTreeIcon != (Object)null)
				{
					image.sprite = customSkillTreeIcon;
					((Graphic)image).color = Color.white;
					flag = true;
					Log.LogDebug((object)"[아이콘] 커스텀 아이콘 적용 성공");
				}
			}
			catch (Exception ex)
			{
				Log.LogDebug((object)("[아이콘] 커스텀 아이콘 로드 실패: " + ex.Message));
			}
			if (!flag)
			{
				try
				{
					if ((Object)(object)ObjectDB.instance != (Object)null)
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron");
						if ((Object)(object)itemPrefab != (Object)null)
						{
							ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
							if ((Object)(object)component != (Object)null)
							{
								Sprite icon = component.m_itemData.GetIcon();
								if ((Object)(object)icon != (Object)null)
								{
									image.sprite = icon;
									((Graphic)image).color = Color.white;
									flag = true;
									Log.LogDebug((object)"[아이콘] 게임 기본 아이콘(검) 적용 성공");
								}
							}
						}
					}
				}
				catch (Exception ex2)
				{
					Log.LogDebug((object)("[아이콘] 기본 아이콘 로드 실패: " + ex2.Message));
				}
			}
			if (!flag && (Object)(object)((Component)image).transform.parent != (Object)null)
			{
				GameObject val = new GameObject("IconText");
				val.transform.SetParent(((Component)image).transform.parent, false);
				Text val2 = val.AddComponent<Text>();
				val2.text = "스킬\n트리";
				val2.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
				val2.fontSize = 14;
				((Graphic)val2).color = Color.white;
				val2.alignment = (TextAnchor)4;
				RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = Vector2.one;
				component2.offsetMin = Vector2.zero;
				component2.offsetMax = Vector2.zero;
			}
		}

		private static void SetupIconClickEvent()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			Button val = skillTreeIconObj.GetComponent<Button>() ?? skillTreeIconObj.AddComponent<Button>();
			((Selectable)val).interactable = true;
			Image component = skillTreeIconObj.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).raycastTarget = true;
			}
			((UnityEventBase)val.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick = val.onClick;
			object obj = <>c.<>9__47_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					//IL_010f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0116: Expected O, but got Unknown
					Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!");
					if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled)
					{
						SkillTreeBGMManager.Instance.PlaySkillTreeBGM();
					}
					else if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
					{
						Log.LogInfo((object)"[BGM] BGM이 비활성화되어 있어 재생하지 않음");
					}
					InventoryGui instance = InventoryGui.instance;
					if ((Object)(object)instance == (Object)null)
					{
						Debug.LogWarning((object)"[스킬트리] InventoryGui.instance를 찾을 수 없음");
					}
					else
					{
						Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>();
						if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || (Object)(object)skillTreeUI.panel.transform.parent != (Object)(object)((Component)componentInChildren).transform)
						{
							if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null)
							{
								Object.Destroy((Object)(object)skillTreeUI.panel);
							}
							GameObject val3 = new GameObject("SkillTreeUI");
							val3.transform.SetParent(((Component)componentInChildren).transform, false);
							skillTreeUI = val3.AddComponent<SkillTreeUI>();
							skillTreeUI.CreateUI(componentInChildren);
						}
						if (!skillTreeUI.panel.activeSelf)
						{
							skillTreeUI.RefreshUI();
							skillTreeUI.panel.SetActive(true);
						}
						else
						{
							skillTreeUI.panel.SetActive(false);
							if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
							{
								SkillTreeBGMManager.Instance.PauseSkillTreeBGM();
							}
						}
					}
				};
				<>c.<>9__47_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}

		private void OnGUI()
		{
			try
			{
				SkillTreeManager.Instance.OnGUIShowMessage();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("OnGUI 메시지 표시 중 오류: " + ex.Message));
			}
		}

		private static void InitializeBGMSystem()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("SkillTreeBGMManager");
				val.AddComponent<SkillTreeBGMManager>();
				Object.DontDestroyOnLoad((Object)(object)val);
				if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null)
				{
					SkillTreeBGMManager.Instance.Initialize();
					Log.LogDebug((object)"[BGM] 스킬트리 BGM 시스템 초기화 완료");
				}
				else
				{
					Log.LogWarning((object)"[BGM] SkillTreeBGMManager.Instance가 null");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[BGM] 초기화 실패: " + ex.Message));
			}
		}

		private static void InitializePrefabSystem()
		{
			try
			{
				PrefabRegistry.Initialize();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[프리팹] 초기화 실패: " + ex.Message));
			}
		}

		private static bool CreateEarlyUserBackup()
		{
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg");
				string text2 = Path.Combine(Paths.ConfigPath, "CaptainSkillTree");
				string text3 = Path.Combine(text2, "User_CaptainSkillTree.SkillTreeMod.cfg");
				if (!File.Exists(text3) && File.Exists(text))
				{
					Directory.CreateDirectory(text2);
					File.Copy(text, text3, overwrite: false);
				}
			}
			catch
			{
			}
			return true;
		}

		internal static void InitializeServerSync()
		{
			if (ZRoutedRpc.instance != null)
			{
				try
				{
					ZRoutedRpc.instance.Register<string>("CaptainSkillTree.SkillTreeMod_ConfigSync", (Action<long, string>)RPC_ReceiveConfigSync);
					return;
				}
				catch (ArgumentException ex)
				{
					Log.LogWarning((object)("[서버 싱크] RPC가 이미