Decompiled source of CaptainSkillTree v0.1.447

AnimationSpeedManager.dll

Decompiled 15 hours 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 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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.Configuration;
using BepInEx.Logging;
using CaptainSkillTree.Audio;
using CaptainSkillTree.Gui;
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("0.1.477.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.477.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 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", "0.1.477")]
	[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(Character), "ApplyDamage")]
		[HarmonyPriority(400)]
		public static class WeaponCriticalSystemPatch
		{
			public static void Prefix(Character __instance, ref bool showDamageText, ref HitData hit)
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Invalid comparison between Unknown and I4
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Invalid comparison between Unknown and I4
				//IL_0240: Unknown result type (might be due to invalid IL or missing references)
				//IL_0255: Unknown result type (might be due to invalid IL or missing references)
				//IL_0261: Unknown result type (might be due to invalid IL or missing references)
				//IL_022a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0133: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					return;
				}
				ItemData currentWeapon = ((Humanoid)Player.m_localPlayer).GetCurrentWeapon();
				if (currentWeapon == null)
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				SkillType skillType = currentWeapon.m_shared.m_skillType;
				if ((int)skillType == 5 && SkillEffect.spearEnhancedThrowBuffEndTime.TryGetValue(localPlayer, 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(localPlayer);
					return;
				}
				if ((int)skillType == 5 && SkillEffect.HasSkill("spear_Step1_throw") && SkillEffect.CanUseSpearThrowPassive(localPlayer))
				{
					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(localPlayer, $"\ud83d\udca5 투창 +{spearStep2ThrowDamageValue}%!", new Color(1f, 0.8f, 0.2f), SkillEffect.SkillEffectTextType.Combat);
					SkillEffect.SetSpearThrowPassiveCooldown(localPlayer);
				}
				float critChance = Critical.CalculateCritChance(localPlayer, skillType);
				if (Critical.RollCritical(critChance))
				{
					float critMultiplier = CriticalDamage.CalculateCritDamageMultiplier(localPlayer, skillType);
					CriticalDamage.ApplyCriticalDamage(localPlayer, ref hit, critMultiplier, skillType);
					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)
			{
				Character attacker = hit.GetAttacker();
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (val != null)
				{
					SEMan sEMan = ((Character)val).GetSEMan();
					if (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);
					}
				}
			}
		}

		[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;
							Log.LogInfo((object)"[스킬트리] 아이콘 위치 조정: 화면 중앙 캐릭터 머리 위 (EpicMMO 미사용)");
						}
					}
				}
				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()
			{
				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()
			{
				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);
			}
		}

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

			public static UnityAction <>9__44_0;

			internal void <SetupIconClickEvent>b__44_0()
			{
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Expected O, but got Unknown
				Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!");
				if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled)
				{
					SkillTreeBGMManager.Instance.PlaySkillTreeBGM();
					Log.LogInfo((object)"[BGM] 스킬트리 BGM 재생 시작 (BGM 활성화 상태)");
				}
				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);
					Log.LogInfo((object)"[스킬트리] skillTreeUI 새로 생성 및 Canvas 하위에 배치");
				}
				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();
				}
			}
		}

		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;

		private static SkillTreeUI skillTreeUI;

		private static Sprite customSkillTreeIcon;

		private static Plugin? _instance;

		private static bool _coreSystemsInitialized;

		private static bool _emergencyMode;

		private static int _iconCreationAttempts;

		private const int MAX_ICON_ATTEMPTS = 5;

		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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_instance = this;
			CaptainLevelConfig.Bind(((BaseUnityPlugin)this).Config);
			Log.LogInfo((object)"[Captain Level System] Config 바인딩 완료");
			SkillTreeConfig.Initialize(((BaseUnityPlugin)this).Config);
			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();
			RegisterJotunnCommands();
			_coreSystemsInitialized = true;
			Log.LogWarning((object)"========== Captain SkillTree Mod 로딩 성공 ==========");
		}

		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 (_emergencyMode || _iconCreationAttempts >= 5)
			{
				Log.LogWarning((object)"[안전 장치] 비상 모드 또는 최대 시도 횟수 초과 - 아이콘 생성 건너뛰기");
				return;
			}
			try
			{
				if (!ValidatePrerequisites())
				{
					Log.LogWarning((object)"[안전 장치] 전제 조건 미충족 - 아이콘 생성 연기");
					return;
				}
				Type type = Type.GetType("EpicMMOSystem.MyUI, EpicMMOSystem");
				if (type != 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_02ba: 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_02ce: 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_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Expected O, but got Unknown
			try
			{
				Type type = Type.GetType("EpicMMOSystem.MyUI, EpicMMOSystem");
				if (type == null)
				{
					Log.LogWarning((object)"EpicMMOSystem.MyUI 타입을 찾을 수 없음");
					return false;
				}
				FieldInfo field = type.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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: 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)
				{
					Log.LogWarning((object)"Player 패널을 찾을 수 없음, Canvas에 직접 배치");
					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__44_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					//IL_0122: Unknown result type (might be due to invalid IL or missing references)
					//IL_0129: Expected O, but got Unknown
					Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!");
					if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled)
					{
						SkillTreeBGMManager.Instance.PlaySkillTreeBGM();
						Log.LogInfo((object)"[BGM] 스킬트리 BGM 재생 시작 (BGM 활성화 상태)");
					}
					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);
							Log.LogInfo((object)"[스킬트리] skillTreeUI 새로 생성 및 Canvas 하위에 배치");
						}
						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__44_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));
			}
		}

		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가 이미 등록되어 있습니다: " + ex.Message));
					return;
				}
				catch (Exception ex2)
				{
					Log.LogError((object)("[서버 싱크] RPC 등록 중 예외 발생: " + ex2.Message));
					return;
				}
			}
			Log.LogWarning((object)"[서버 싱크] ZRoutedRpc.instance가 null입니다. 월드 로드 후 재시도 필요.");
		}

		private static void RPC_ReceiveConfigSync(long sender, string jsonData)
		{
			try
			{
				SkillTreeConfig.ReceiveServerConfig(jsonData);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[서버 싱크] 설정 수신 실패: " + ex.Message));
			}
		}

		internal static void SetAttackConfig(string key, ConsoleEventArgs args)
		{
			float result;
			if (args.Length < 2)
			{
				args.Context.AddString("사용법: " + args[0] + " <값>");
			}
			else if (float.TryParse(args[1], out result))
			{
				if (SkillTreeConfig.SetConfigValue(key, result))
				{
					args.Context.AddString($"[SkillTree] {key} = {result} 설정 완료");
				}
				else
				{
					args.Context.AddString("[SkillTree] 설정 실패 (서버만 가능)");
				}
			}
			else
			{
				args.Context.AddString("[SkillTree] 잘못된 값: " + args[1]);
			}
		}

		internal static void SetSpeedConfig(string key, ConsoleEventArgs args)
		{
			float result;
			if (args.Length < 2)
			{
				args.Context.AddString("사용법: " + args[0] + " <값>");
			}
			else if (float.TryParse(args[1], out result))
			{
				if (SkillTreeConfig.SetConfigValue(key, result))
				{
					args.Context.AddString($"[SkillTree] {key} = {result} 설정 완료");
				}
				else
				{
					args.Context.AddString("[SkillTree] 설정 실패 (서버만 가능)");
				}
			}
			else
			{
				args.Context.AddString("[SkillTree] 잘못된 값: " + args[1]);
			}
		}

		internal static void SetArcherConfig(string key, ConsoleEventArgs args)
		{
			float result;
			if (args.Length < 2)
			{
				args.Context.AddString("사용법: " + args[0] + " <값>");
			}
			else if (float.TryParse(args[1], out result))
			{
				if (SkillTreeConfig.SetConfigValue(key, result))
				{
					args.Context.AddString($"[SkillTree] {key} = {result} 설정 완료");
				}
				else
				{
					args.Context.AddString("[SkillTree] 설정 실패 (서버만 가능)");
				}
			}
			else
			{
				args.Context.AddString("[SkillTree] 잘못된 값: " + args[1]);
			}
		}

		internal static void SetBowConfig(string key, ConsoleEventArgs args)
		{
			float result;
			if (args.Length < 2)
			{
				args.Context.AddString("사용법: " + args[0] + " <값>");
			}
			else if (float.TryParse(args[1], out result))
			{
				if (SkillTreeConfig.SetConfigValue(key, result))
				{
					args.Context.AddString($"[SkillTree] {key} = {result} 설정 완료");
				}
				else
				{
					args.Context.AddString("[SkillTree] 설정 실패 (서버만 가능)");
				}
			}
			else
			{
				args.Context.AddString("[SkillTree] 잘못된 값: " + args[1]);
			}
		}

		internal static void ShowCurrentConfig()
		{
			Log.LogInfo((object)"=== 현재 공격 전문가 설정 ===");
			Log.LogInfo((object)$"공격 루트 데미지: {SkillTreeConfig.AttackRootDamageBonusValue}%");
			Log.LogInfo((object)$"근접 특화 확률: {SkillTreeConfig.AttackMeleeBonusChanceValue}%");
			Log.LogInfo((object)$"근접 특화 피해: {SkillTreeConfig.AttackMeleeBonusDamageValue}%");
			Log.LogInfo((object)$"활 특화 확률: {SkillTreeConfig.AttackBowBonusChanceValue}%");
			Log.LogInfo((object)$"활 특화 피해: {SkillTreeConfig.AttackBowBonusDamageValue}%");
			Log.LogInfo((object)$"석궁 특화 확률: {SkillTreeConfig.AttackCrossbowBonusChanceValue}%");
			Log.LogInfo((object)$"석궁 특화 피해: {SkillTreeConfig.AttackCrossbowBonusDamageValue}%");
			Log.LogInfo((object)$"지팡이 특화 확률: {SkillTreeConfig.AttackStaffBonusChanceValue}%");
			Log.LogInfo((object)$"지팡이 특화 피해: {SkillTreeConfig.AttackStaffBonusDamageValue}%");
			Log.LogInfo((object)$"치명타 피해 보너스: {SkillTreeConfig.AttackCritDamageBonusValue}%");
			Log.LogInfo((object)$"양손 무기 보너스: {SkillTreeConfig.AttackTwoHandedBonusValue}%");
			Log.LogInfo((object)$"한손 무기 보너스: {SkillTreeConfig.AttackOneHandedBonusValue}%");
			Log.LogInfo((object)$"연속 근접 보너스: {SkillTreeConfig.AttackFinisherMeleeBonusValue}%");
			Log.LogInfo((object)"=== 현재 속도 전문가 설정 ===");
			Log.LogInfo((object)$"속도 루트 이동속도: {SkillTreeConfig.SpeedRootMoveSpeedValue}%");
			Log.LogInfo((object)$"기초 이동속도: {SkillTreeConfig.SpeedBaseMoveSpeedValue}%");
			Log.LogInfo((object)$"구르기 속도: {SkillTreeConfig.SpeedBaseDodgeSpeedValue}%");
			Log.LogInfo((object)$"근접 콤보 보너스: {SkillTreeConfig.SpeedMeleeComboBonusValue}%");
			Log.LogInfo((object)$"근접 콤보 지속시간: {SkillTreeConfig.SpeedMeleeComboDurationValue}초");
			Log.LogInfo((object)$"석궁 장전 속도: {SkillTreeConfig.SpeedCrossbowReloadSpeedValue}%");
			Log.LogInfo((object)$"활 적중 보너스: {SkillTreeConfig.SpeedBowHitBonusValue}%");
			Log.LogInfo((object)$"활 적중 지속시간: {SkillTreeConfig.SpeedBowHitDurationValue}초");
			Log.LogInfo((object)$"지팡이 시전 속도: {SkillTreeConfig.SpeedStaffCastSpeedValue}%");
			Log.LogInfo((object)$"음식 효율: {SkillTreeConfig.SpeedFoodEfficiencyValue}%");
			Log.LogInfo((object)$"배 속도: {SkillTreeConfig.SpeedShipBonusValue}%");
			Log.LogInfo((object)$"쿨타임 감소: {SkillTreeConfig.SpeedCooldownReductionValue}초");
			Log.LogInfo((object)$"근접 공격속도: {SkillTreeConfig.SpeedMeleeAttackSpeedValue}%");
			Log.LogInfo((object)$"석궁 장전속도: {SkillTreeConfig.SpeedCrossbowDrawSpeedValue}%");
			Log.LogInfo((object)$"활 장전속도: {SkillTreeConfig.SpeedBowDrawSpeedValue}%");
			Log.LogInfo((object)$"지팡이 시전속도: {SkillTreeConfig.SpeedStaffCastSpeedFinalValue}%");
			Log.LogInfo((object)"=== 현재 아처 멀티샷 설정 ===");
			Log.LogInfo((object)$"발사할 화살 수: {Archer_Config.ArcherMultiShotArrowCountValue}발");
			Log.LogInfo((object)$"화살 소모량: {Archer_Config.ArcherMultiShotArrowConsumptionValue}개");
			Log.LogInfo((object)$"화살당 데미지: {Archer_Config.ArcherMultiShotDamagePercentValue}%");
			Log.LogInfo((object)"=== 현재 활 전문가 멀티샷 설정 ===");
			Log.LogInfo((object)$"Lv1 발동 확률: {SkillTreeConfig.BowMultishotLv1ChanceValue}%");
			Log.LogInfo((object)$"Lv2 발동 확률: {SkillTreeConfig.BowMultishotLv2ChanceValue}%");
			Log.LogInfo((object)$"추가 화살 수: {SkillTreeConfig.BowMultishotArrowCountValue}발");
			Log.LogInfo((object)$"화살 소모량: {SkillTreeConfig.BowMultishotArrowConsumptionValue}개");
			Log.LogInfo((object)$"화살당 데미지: {SkillTreeConfig.BowMultishotDamagePercentValue}%");
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	public static class Player_OnDeath_StopPluginCoroutines_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)Plugin.Instance != (Object)null)
			{
				try
				{
					TankerSkills.CleanupTankerOnDeath(__instance);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[탱커 정리] 실패 (무시): " + ex.Message));
				}
				try
				{
					JobSkills.CleanupAllJobSkillsOnDeath(__instance);
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("[스킬 정리] 실패 (무시): " + ex2.Message));
				}
				Plugin.Log.LogInfo((object)"[플레이어 사망] 모든 정리 완료 후 코루틴 중지");
				((MonoBehaviour)Plugin.Instance).StopAllCoroutines();
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Awake")]
	public static class AttackSpeedHandler_Game_Awake_Patch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Handler <>9__1_0;

			internal double <Postfix>b__1_0(Character character, double speed)
			{
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val != null && ((Character)val).InAttack())
				{
					if (Sword_Skill.IsSlashActive(val))
					{
						return 1.0 + (double)Sword_Config.RushSlashAttackSpeedBonusValue / 100.0;
					}
					float totalAttackSpeedBonus = SkillEffect.GetTotalAttackSpeedBonus(val);
					if (totalAttackSpeedBonus > 0f)
					{
						double num = 1.0 + (double)totalAttackSpeedBonus / 100.0;
						return speed * num;
					}
					return speed;
				}
				return speed;
			}
		}

		private static bool _attackSpeedHandlerRegistered;

		[HarmonyPostfix]
		public static void Postfix()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (_attackSpeedHandlerRegistered)
			{
				return;
			}
			try
			{
				object obj = <>c.<>9__1_0;
				if (obj == null)
				{
					Handler val = delegate(Character character, double speed)
					{
						Player val2 = (Player)(object)((character is Player) ? character : null);
						if (val2 != null && ((Character)val2).InAttack())
						{
							if (Sword_Skill.IsSlashActive(val2))
							{
								return 1.0 + (double)Sword_Config.RushSlashAttackSpeedBonusValue / 100.0;
							}
							float totalAttackSpeedBonus = SkillEffect.GetTotalAttackSpeedBonus(val2);
							if (totalAttackSpeedBonus > 0f)
							{
								double num = 1.0 + (double)totalAttackSpeedBonus / 100.0;
								return speed * num;
							}
							return speed;
						}
						return speed;
					};
					<>c.<>9__1_0 = val;
					obj = (object)val;
				}
				AnimationSpeedManager.Add((Handler)obj, 400);
				_attackSpeedHandlerRegistered = true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[공격 속도] AnimationSpeedManager 등록 실패: " + ex.Message));
			}
		}
	}
	public static class NerveEnhancementSystem
	{
		public class SE_NerveEnhancement : SE_Stats
		{
			public SE_NerveEnhancement()
			{
				((StatusEffect)this).m_name = "신경 강화";
				((StatusEffect)this).m_tooltip = "이동속도 +12%";
				((StatusEffect)this).m_ttl = 4f;
				base.m_speedModifier = 1.12f;
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		public static class Damage_Patch
		{
			private static Dictionary<Player, float> stompCooldowns = new Dictionary<Player, float>();

			private static bool Prefix(Character __instance, HitData hit)
			{
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				if (__instance.IsPlayer())
				{
					Player val = (Player)(object)((__instance is Player) ? __instance : null);
					SkillEffect.SaveOriginalDamage(val, hit);
					float customDodgeChance = val.GetCustomDodgeChance();
					if (customDodgeChance > 0f)
					{
						float num = Random.Range(0f, 1f);
						if (num < customDodgeChance)
						{
							hit.m_damage.m_blunt = 0f;
							hit.m_damage.m_slash = 0f;
							hit.m_damage.m_pierce = 0f;
							hit.m_damage.m_chop = 0f;
							hit.m_damage.m_pickaxe = 0f;
							hit.m_damage.m_fire = 0f;
							hit.m_damage.m_frost = 0f;
							hit.m_damage.m_lightning = 0f;
							hit.m_damage.m_poison = 0f;
							hit.m_damage.m_spirit = 0f;
							val.m_dodgeEffects.Create(((Component)val).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
							SkillTreeManager instance = SkillTreeManager.Instance;
							bool flag = instance != null && instance.GetSkillLevel("knife_step2_evasion") > 0;
							bool flag2 = (instance != null && instance.GetSkillLevel("defense_Step3_agile") > 0) || (instance != null && instance.GetSkillLevel("defense_Step5_stamina") > 0) || (instance != null && instance.GetSkillLevel("defense_Step6_attack") > 0);
							string text = "회피 성공!";
							if (flag && flag2)
							{
								text = "\ud83d\udde1\ufe0f 회피 숙련 + 방어 트리 회피!";
							}
							else if (flag)
							{
								text = "\ud83d\udde1\ufe0f 회피 숙련!";
							}
							else if (flag2)
							{
								text = "\ud83d\udee1\ufe0f 방어 트리 회피!";
							}
							((Character)val).Message((MessageType)2, text, 0, (Sprite)null);
							return false;
						}
					}
					SkillTreeManager instance2 = SkillTreeManager.Instance;
					if (instance2 != null && instance2.GetSkillLevel("Tanker") > 0)
					{
						float totalDamage = hit.GetTotalDamage();
						if (totalDamage > 0f)
						{
							float num2 = 1f - Tanker_Config.TankerPassiveDamageReductionValue / 100f;
							hit.m_damage.m_damage *= num2;
							hit.m_damage.m_blunt *= num2;
							hit.m_damage.m_slash *= num2;
							hit.m_damage.m_pierce *= num2;
							hit.m_damage.m_chop *= num2;
							hit.m_damage.m_pickaxe *= num2;
							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;
							float totalDamage2 = hit.GetTotalDamage();
							float num3 = totalDamage - totalDamage2;
							if (num3 > 0f)
							{
								Plugin.Log.LogDebug((object)$"[탱커 패시브] {val.GetPlayerName()} 피해 감소 적용 - 원래: {totalDamage:F1} → 감소후: {totalDamage2:F1} (감소량: {num3:F1})");
								((Character)val).Message((MessageType)1, $"탱커 방어: -{num3:F0} 피해 차단!", 0, (Sprite)null);
							}
						}
					}
				}
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker != (Object)null && attacker.IsPlayer())
				{
					Player player = (Player)(object)((attacker is Player) ? attacker : null);
					SkillTreeManager instance3 = SkillTreeManager.Instance;
					if (instance3 != null && instance3.GetSkillLevel("knife_step8_assassination") > 0)
					{
						Knife_Skill.ApplyKnifeAssassinationBonus(player, ref hit, __instance);
					}
				}
				return true;
			}

			private static void Postfix(Character __instance, HitData hit)
			{
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker != (Object)null && attacker.IsPlayer())
				{
					TryApplyDodgeAndSpeedBuff((Player)(object)((attacker is Player) ? attacker : null));
				}
				if (__instance.IsPlayer())
				{
					Player player = (Player)(object)((__instance is Player) ? __instance : null);
					CheckStompAutoTrigger(player);
				}
			}

			private static void CheckStompAutoTrigger(Player player)
			{
				if ((Object)(object)player == (Object)null || ((Character)player).IsDead())
				{
					return;
				}
				SkillTreeManager instance = SkillTreeManager.Instance;
				if (instance != null && instance.GetSkillLevel("defense_Step4_instant") <= 0)
				{
					return;
				}
				float healthPercentage = ((Character)player).GetHealthPercentage();
				float stompHealthThresholdValue = Defense_Config.StompHealthThresholdValue;
				if (healthPercentage > stompHealthThresholdValue)
				{
					return;
				}
				float stompCooldownValue = Defense_Config.StompCooldownValue;
				if (stompCooldowns.ContainsKey(player))
				{
					float num = Time.time - stompCooldowns[player];
					if (num < stompCooldownValue)
					{
						float num2 = stompCooldownValue - num;
						((Character)player).Message((MessageType)2, $"발구르기 쿨타임 ({num2:F0}초 남음)", 0, (Sprite)null);
						return;
					}
				}
				SkillEffect.ExecuteStompSkill(player);
				stompCooldowns[player] = Time.time;
			}
		}

		private static readonly Dictionary<long, float> lastTriggeredTime = new Dictionary<long, float>();

		private static readonly Dictionary<long, float> dodgeChanceMap = new Dictionary<long, float>();

		private const float BuffDuration = 4f;

		private const float BuffCooldown = 8f;

		public static float GetCustomDodgeChance(this Player player)
		{
			float value;
			return dodgeChanceMap.TryGetValue(player.GetPlayerID(), out value) ? value : 0f;
		}

		public static void SetCustomDodgeChance(this Player player, float value)
		{
			dodgeChanceMap[player.GetPlayerID()] = value;
		}

		public static void TryApplyDodgeAndSpeedBuff(Player player)
		{
			if (SkillTreeManager.Instance.GetSkillLevel("defense_Step6_attack") > 0)
			{
			}
		}
	}
	public static class SimpleVFX
	{
		private static Dictionary<string, GameObject> _cachedPrefabs = new Dictionary<string, GameObject>();

		private static AssetBundle _debuffBundle = null;

		private static bool _initialized = false;

		private static readonly HashSet<string> _customVFXNames = new HashSet<string>
		{
			"area_circles_blue", "area_fire_red", "area_heal_green", "area_magic_multicolor", "area_star_ellow", "buff_01", "buff_02a", "buff_03a", "buff_03a_aura", "debuff",
			"debuff_03", "debuff_03_aura", "statusailment_01", "statusailment_01_aura", "confetti_blast_multicolor", "confetti_directional_multicolor", "dust_permanently_blue", "flash_blue_purple", "flash_ellow", "flash_ellow_pink",
			"flash_magic_blue_pink", "flash_magic_ellow_blue", "flash_round_ellow", "flash_star_ellow_green", "flash_star_ellow_purple", "guard_01", "healing", "hit_01", "hit_02", "hit_03",
			"hit_04", "plexus", "shine_blue", "shine_ellow", "shine_pink", "sparkle_ellow", "taunt", "water_blast_blue", "water_blast_green"
		};

		public static GameObject PlayerVFX = null;

		public static GameObject MonsterVFX = null;

		public static bool IsInitialized => _initialized && ((Object)(object)PlayerVFX != (Object)null || (Object)(object)MonsterVFX != (Object)null);

		public static void Initialize()
		{
			if (_initialized)
			{
				return;
			}
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[SimpleVFX] 초기화 시작...");
				}
				LoadFromPrefabRegistry();
				LoadDebuffBundle();
				CacheValheimPrefabs();
				_initialized = true;
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"[SimpleVFX] 초기화 완료 - 캐시된 프리팹: {_cachedPrefabs.Count}개");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)("[SimpleVFX] 초기화 실패: " + ex.Message));
				}
			}
		}

		private static void LoadFromPrefabRegistry()
		{
			try
			{
				Dictionary<string, GameObject> allRegisteredPrefabs = PrefabRegistry.GetAllRegisteredPrefabs();
				int num = 0;
				foreach (KeyValuePair<string, GameObject> item in allRegisteredPrefabs)
				{
					string key = item.Key;
					GameObject value = item.Value;
					if (!((Object)(object)value == (Object)null))
					{
						if (_customVFXNames.Contains(key) && !_cachedPrefabs.ContainsKey(key))
						{
							_cachedPrefabs[key] = value;
							num++;
						}
						string text = key.ToLowerInvariant();
						if (_customVFXNames.Contains(text) && !_cachedPrefabs.ContainsKey(text))
						{
							_cachedPrefabs[text] = value;
							num++;
						}
					}
				}
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[SimpleVFX] PrefabRegistry에서 {num}개 VFX 로드됨");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[SimpleVFX] PrefabRegistry 로드 실패: " + ex.Message));
				}
			}
		}

		private static void LoadDebuffBundle()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string text = null;
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				foreach (string text2 in manifestResourceNames)
				{
					if (text2.EndsWith(".debuff") || text2.Contains(".VFX.debuff"))
					{
						text = text2;
						break;
					}
				}
				if (text == null)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)"[SimpleVFX] 'debuff' 리소스 없음");
					}
					return;
				}
				using (Stream stream = executingAssembly.GetManifestResourceStream(text))
				{
					if (stream == null)
					{
						return;
					}
					_debuffBundle = AssetBundle.LoadFromStream(stream);
				}
				if (!((Object)(object)_debuffBundle != (Object)null))
				{
					return;
				}
				GameObject[] array = _debuffBundle.LoadAllAssets<GameObject>();
				if (array.Length != 0)
				{
					_cachedPrefabs["debuff"] = array[0];
					PlayerVFX = array[0];
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("[SimpleVFX] 'debuff' 프리팹 로드 완료: " + ((Object)array[0]).name));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)("[SimpleVFX] debuff 번들 로드 실패: " + ex.Message));
				}
			}
		}

		public static void