Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CaptainSkillTree v1.22.66
AnimationSpeedManager.dll
Decompiled an hour agousing 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 an hour ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CaptainSkillTree.Audio; using CaptainSkillTree.Gui; using CaptainSkillTree.Localization; using CaptainSkillTree.MMO_System; using CaptainSkillTree.Mods; using CaptainSkillTree.Prefab; using CaptainSkillTree.SkillTree; using CaptainSkillTree.SkillTree.CriticalSystem; using CaptainSkillTree.VFX; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CaptainSkillTree")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CaptainSkillTree")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d1b6e7e2-1c2a-4b8a-9e2b-123456789abc")] [assembly: AssemblyFileVersion("1.22.65.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.22.65.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CaptainSkillTree { public static class DifficultyManager { private const string PRESET_DIR_NAME = "CaptainSkillTree"; private const string PRESET_NORMAL = "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"; private const string PRESET_VERYHARD = "Veryhard_CaptainSkillTree.SkillTreeMod.cfg"; private const string PRESET_USER = "User_CaptainSkillTree.SkillTreeMod.cfg"; private const string DIFF_VER_EXT = ".difficulty_ver"; private static bool _initialized = false; private static string _configFilePath = ""; private static FieldInfo _entriesField; private static bool _entriesFieldSearched; public static bool NeedsSelection { get; private set; } public static bool IsApplyingPreset { get; private set; } public static void InitializeIfNeeded() { if (!_initialized) { _initialized = true; Plugin? instance = Plugin.Instance; object obj; if (instance == null) { obj = null; } else { ConfigFile config = ((BaseUnityPlugin)instance).Config; obj = ((config != null) ? config.ConfigFilePath : null); } if (obj == null) { obj = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg"); } _configFilePath = (string)obj; string path = Path.ChangeExtension(_configFilePath, ".version"); string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver"); string text = (File.Exists(path) ? File.ReadAllText(path).Trim() : ""); string text2 = (File.Exists(path2) ? File.ReadAllText(path2).Trim() : ""); EnsurePresetDirectory(); Application.quitting += SaveUserBackupOnQuit; if (string.IsNullOrEmpty(text2)) { NeedsSelection = true; } else if (text != text2) { ApplyVeryhardWithUserOverlay(); SaveUserBackupNow(); NeedsSelection = true; } else { NeedsSelection = false; } } } public static bool HasUserPreset() { return File.Exists(Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg")); } private static void ApplyVeryhardWithUserOverlay() { Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)"[Difficulty] ApplyVeryhardWithUserOverlay: Config가 null입니다."); } return; } Dictionary<ConfigDefinition, string> dictionary = new Dictionary<ConfigDefinition, string>(); foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in val) { dictionary[item.Key] = item.Value.GetSerializedValue(); } ApplyVeryHard(); HashSet<string> hashSet = new HashSet<string> { "Language", "Config_Schema_Version", "GameDifficulty", "EnableLiveConfigSync" }; bool saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; int num = 0; int num2 = 0; foreach (KeyValuePair<ConfigDefinition, string> item2 in dictionary) { if (hashSet.Contains(item2.Key.Key)) { num2++; continue; } ConfigEntryBase val2 = val[item2.Key]; if (val2 != null) { try { val2.SetSerializedValue(item2.Value); num++; } catch { } } } ConfigEntry<string> gameDifficulty = SkillTreeConfig.GameDifficulty; if (gameDifficulty != null) { gameDifficulty.Value = "UserSettings"; } val.Save(); val.SaveOnConfigSet = saveOnConfigSet; } public static void ApplyNormal() { ApplyPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"); } public static void ApplyVeryHard() { ApplyPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg"); } public static void ApplyUser() { ApplyPreset("User_CaptainSkillTree.SkillTreeMod.cfg"); } private static void ApplyPreset(string presetFileName) { IsApplyingPreset = true; string text = Path.Combine(GetPresetDirectory(), presetFileName); if (File.Exists(text)) { try { File.Copy(text, _configFilePath, overwrite: true); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)("[Difficulty] 파일 복사 실패: " + ex.Message)); } } Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val != null) { bool saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; val.Reload(); int num = ApplyPresetValuesToConfig(text); string value = ((presetFileName == "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg") ? "Vanilla" : ((presetFileName == "Veryhard_CaptainSkillTree.SkillTreeMod.cfg") ? "VeryHard" : "UserSettings")); ConfigEntry<string> gameDifficulty = SkillTreeConfig.GameDifficulty; if (gameDifficulty != null) { gameDifficulty.Value = value; } val.Save(); val.SaveOnConfigSet = saveOnConfigSet; } } else { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] ⚠\ufe0f 프리셋 파일 없음: " + text + "\n → 현재 설정을 그대로 유지합니다.")); } } SaveDifficultyVersion(); NeedsSelection = false; IsApplyingPreset = false; } private static FieldInfo GetEntriesField() { if (_entriesFieldSearched) { return _entriesField; } _entriesFieldSearched = true; Type typeFromHandle = typeof(Dictionary<ConfigDefinition, ConfigEntryBase>); Type type = typeof(ConfigFile); while (type != null && type != typeof(object)) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeFromHandle) { _entriesField = fieldInfo; return fieldInfo; } } type = type.BaseType; } type = typeof(ConfigFile); while (type != null && type != typeof(object)) { FieldInfo[] fields2 = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo2 in fields2) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] Field: " + type.Name + "." + fieldInfo2.Name + " : " + fieldInfo2.FieldType.FullName)); } } type = type.BaseType; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[Difficulty] entries field not found"); } return null; } private static int ApplyPresetValuesToConfig(string presetPath) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val == null) { return 0; } if (!(GetEntriesField()?.GetValue(val) is Dictionary<ConfigDefinition, ConfigEntryBase> dictionary)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Difficulty] entries 딕셔너리 접근 실패"); } return -1; } int num = 0; string text = ""; HashSet<ConfigDefinition> hashSet = new HashSet<ConfigDefinition>(); try { string[] array = File.ReadAllLines(presetPath); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.StartsWith("[") && text3.EndsWith("]")) { text = text3.Substring(1, text3.Length - 2); } else { if (text3.StartsWith("#") || !text3.Contains(" = ")) { continue; } int num2 = text3.IndexOf(" = "); string text4 = text3.Substring(0, num2).Trim(); string serializedValue = text3.Substring(num2 + 3); ConfigDefinition val2 = new ConfigDefinition(text, text4); if (dictionary.TryGetValue(val2, out var value)) { try { value.SetSerializedValue(serializedValue); hashSet.Add(val2); num++; } catch { } } } } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] 값 직접 적용 실패: " + ex.Message)); } } int num3 = 0; foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in dictionary) { if (!hashSet.Contains(item.Key)) { try { item.Value.BoxedValue = item.Value.DefaultValue; num3++; } catch { } } } return num + num3; } public static string GetPresetDirectory() { return Path.Combine(Paths.ConfigPath, "CaptainSkillTree"); } public static void EnsurePresetDirectory() { try { Directory.CreateDirectory(GetPresetDirectory()); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 폴더 생성 실패: " + ex.Message)); } } ExtractEmbeddedPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"); ExtractEmbeddedPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg"); } private static void ExtractEmbeddedPreset(string fileName) { string path = Path.Combine(GetPresetDirectory(), fileName); string text = "CaptainSkillTree.asset." + fileName; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 내장 리소스 없음: " + text)); } return; } using FileStream destination = new FileStream(path, FileMode.Create, FileAccess.Write); stream.CopyTo(destination); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] 프리셋 추출 실패 (" + fileName + "): " + ex.Message)); } } } private static void SaveUserBackupOnQuit() { if (string.IsNullOrEmpty(_configFilePath) || !File.Exists(_configFilePath)) { return; } string destFileName = Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg"); try { File.Copy(_configFilePath, destFileName, overwrite: true); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[Difficulty] User 설정 백업 저장 완료"); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] User 백업 저장 실패: " + ex.Message)); } } } private static void SaveUserBackupNow() { if (string.IsNullOrEmpty(_configFilePath) || !File.Exists(_configFilePath)) { return; } string destFileName = Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg"); try { File.Copy(_configFilePath, destFileName, overwrite: true); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] User 백업 갱신 실패: " + ex.Message)); } } } private static void SaveDifficultyVersion() { try { string path = Path.ChangeExtension(_configFilePath, ".version"); string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver"); string contents = (File.Exists(path) ? File.ReadAllText(path).Trim() : ""); File.WriteAllText(path2, contents); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 버전 기록 실패: " + ex.Message)); } } } } public class SkillTreeInputListener : MonoBehaviour { public SkillTreeUI? skillTreeUI; private float lastLogTime = 0f; public static SkillTreeInputListener? Instance { get; private set; } private void Awake() { lastLogTime = Time.time; if ((Object)(object)Instance == (Object)null) { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); LevelSyncManager.Instance.Initialize(); } else { Debug.LogWarning((object)"[SkillTreeInputListener] 중복 생성 감지, 즉시 파괴, this={this.GetHashCode()} (name={gameObject.name})"); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Update() { try { SkillTreeManager.Instance?.OnUpdate(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SkillTree] SkillTreeManager 업데이트 실패: " + ex.Message)); } try { LevelSyncManager.Instance?.Update(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[SkillTree] LevelSyncManager 업데이트 실패: " + ex2.Message)); } if (IsChatOrConsoleOpen()) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { if (Input.GetKeyDown((KeyCode)114)) { SkillEffect.HandleRKeySkills(localPlayer); } if (Input.GetKeyDown((KeyCode)103)) { SkillEffect.HandleGKeySkills(localPlayer); } if (Input.GetKeyUp((KeyCode)103)) { SkillEffect.HandleGKeyUpSkills(localPlayer); } if (Input.GetKeyDown((KeyCode)104)) { SkillEffect.HandleHKeySkills(localPlayer); } if (Input.GetKeyUp((KeyCode)104)) { SkillEffect.HandleHKeyUpSkills(localPlayer); } if (Input.GetKeyDown((KeyCode)121)) { SkillTreeManager.Instance.HandleActiveSkillKeyInput(); } if (Input.GetKeyDown((KeyCode)93)) { try { long expToNextLevel = CaptainMMOBridge.GetExpToNextLevel(); CaptainMMOBridge.AddExp((int)expToNextLevel); Plugin.SkillTreePoint += 3; } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[SkillTree] 레벨업 실패 (경험치 추가): " + ex3.Message)); } } } if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || !skillTreeUI.panel.activeInHierarchy) { return; } bool keyDown = Input.GetKeyDown((KeyCode)27); bool keyDown2 = Input.GetKeyDown((KeyCode)9); if (keyDown) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } else { Plugin.Log.LogError((object)"[\ud83d\udd11 ESC] ❌ SkillTreeBGMManager.Instance가 null - ESC키 처리 실패"); } } if (keyDown2) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } else { Plugin.Log.LogError((object)"[\ud83d\udd11 TAB] ❌ SkillTreeBGMManager.Instance가 null - Tab키 처리 실패"); } } } private bool IsChatOrConsoleOpen() { try { if (IsChatInputActive()) { Plugin.Log.LogDebug((object)"[키 입력 차단] 채팅 입력이 활성화됨 - 스킬 키 입력 차단"); return true; } if (IsConsoleActive()) { Plugin.Log.LogDebug((object)"[키 입력 차단] 콘솔이 활성화됨 - 스킬 키 입력 차단"); return true; } return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[키 입력 차단] 채팅/콘솔 상태 확인 중 오류: " + ex.Message)); return false; } } private bool IsChatInputActive() { try { EventSystem current = EventSystem.current; if ((Object)(object)((current != null) ? current.currentSelectedGameObject : null) != (Object)null) { InputField component = current.currentSelectedGameObject.GetComponent<InputField>(); if ((Object)(object)component != (Object)null && component.isFocused) { return true; } } if ((Object)(object)Chat.instance != (Object)null) { GameObject gameObject = ((Component)Chat.instance).gameObject; if ((Object)(object)gameObject != (Object)null && gameObject.activeInHierarchy) { try { InputField componentInChildren = ((Component)Chat.instance).GetComponentInChildren<InputField>(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isFocused) { return true; } } catch (Exception ex) { Plugin.Log.LogDebug((object)("[채팅 감지] GetComponentInChildren 실패: " + ex.Message)); } } } return false; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[채팅 감지] 오류: " + ex2.Message)); return false; } } private bool IsConsoleActive() { try { Type type = Type.GetType("Console, assembly_valheim"); if (type != null) { MethodInfo method = type.GetMethod("IsVisible", BindingFlags.Static | BindingFlags.Public); if (method != null && (bool)method.Invoke(null, null)) { return true; } } return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[콘솔 감지] 오류: " + ex.Message)); return false; } } private void OnDestroy() { ((MonoBehaviour)this).StopAllCoroutines(); LevelSyncManager.Instance?.Cleanup(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(Player), "OnDeath")] public static class Player_OnDeath_StopCoroutines_Patch { [HarmonyPostfix] public static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)SkillTreeInputListener.Instance != (Object)null) { ((MonoBehaviour)SkillTreeInputListener.Instance).StopAllCoroutines(); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("CaptainSkillTree.SkillTreeMod", "Captain SkillTree Mod", "1.22.65")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryShowPatch { private static bool Prepare() { return true; } public static void Postfix() { try { ShowSkillTreeIcon(); } catch (Exception ex) { Log.LogError((object)("[스킬트리] InventoryShowPatch 오류: " + ex.Message)); Log.LogError((object)("[스킬트리] StackTrace: " + ex.StackTrace)); } } } [HarmonyPatch(typeof(FejdStartup), "Awake")] private static class FejdStartup_DifficultyPatch { [HarmonyPostfix] private static void Postfix(FejdStartup __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown DifficultyManager.InitializeIfNeeded(); if (DifficultyManager.NeedsSelection) { Canvas val = ((Component)__instance).GetComponentInChildren<Canvas>(true) ?? Object.FindObjectOfType<Canvas>(); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"[Difficulty] Canvas를 찾을 수 없어 난이도 선택 창을 열 수 없습니다. 기본값 VeryHard 적용."); DifficultyManager.ApplyVeryHard(); return; } GameObject val2 = new GameObject("DifficultySelectUI"); val2.transform.SetParent(((Component)val).transform, false); val2.AddComponent<DifficultySelectUI>(); val2.transform.SetAsLastSibling(); } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(400)] public static class WeaponCriticalSystemPatch { public static void Prefix(Character __instance, ref bool showDamageText, ref HitData hit) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0095: Invalid comparison between Unknown and I4 //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Invalid comparison between Unknown and I4 //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: 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_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039c: 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_03a7: Invalid comparison between Unknown and I4 //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Invalid comparison between Unknown and I4 //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && Sword_Skill.IsRushSlashInvincible(val)) { hit.m_damage = default(DamageTypes); return; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || !(attacker is Player)) { return; } Player val2 = (Player)(object)((attacker is Player) ? attacker : null); ItemData currentWeapon = ((Humanoid)val2).GetCurrentWeapon(); bool flag = currentWeapon != null && (int)(currentWeapon.m_shared?.m_skillType).GetValueOrDefault() == 5 && SkillEffect.IsRecentSpearSecondaryAttack(val2); if (flag && SkillEffect.IsSpearComboThrowBuffActive(val2)) { SkillEffect.ConsumeSpearSecondaryAttack(val2); 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.ConsumeSpearComboThrowUse(val2); return; } if (flag && SkillEffect.HasSkill("spear_Step1_throw") && SkillEffect.CanUseSpearThrowPassive(val2)) { SkillEffect.ConsumeSpearSecondaryAttack(val2); 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(val2, L.Get("spear_throw_passive_activated", $"{spearStep2ThrowDamageValue:F0}"), new Color(1f, 0.8f, 0.2f), SkillEffect.SkillEffectTextType.Combat); SkillEffect.SetSpearThrowPassiveCooldown(val2); } ItemData currentWeapon2 = ((Humanoid)val2).GetCurrentWeapon(); if (currentWeapon2 == null) { return; } SkillType skillType = currentWeapon2.m_shared.m_skillType; if ((int)skillType == 8 && SkillEffect.HasSkill("bow_Step2_focus") && Critical.IsHeadshot(__instance, hit.m_point)) { float critMultiplier = CriticalDamage.CalculateCritDamageMultiplier(val2, skillType); CriticalDamage.ApplyCriticalDamage(val2, ref hit, critMultiplier, skillType); SkillEffect.ShowSkillEffectText(val2, L.Get("bow_headshot_text") + "!", new Color(1f, 0.3f, 0.1f), SkillEffect.SkillEffectTextType.Combat); VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point); showDamageText = false; Log.LogInfo((object)"[헤드샷] 헤드샷 발생 시 100% 치명타 발동!"); return; } float critChance = Critical.CalculateCritChance(val2, skillType); if (Critical.RollCritical(critChance)) { float critMultiplier2 = CriticalDamage.CalculateCritDamageMultiplier(val2, skillType); CriticalDamage.ApplyCriticalDamage(val2, ref hit, critMultiplier2, skillType); if ((int)skillType == 2 || (int)skillType == 11) { VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point); } showDamageText = false; } } } [HarmonyPatch(typeof(SEMan), "ModifyAttackStaminaUsage")] public static class KnifeSkillTreeStaminaPatch { public static void Postfix(SEMan __instance, ref float staminaUse) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 2) { float knifeStaminaReduction = SkillEffect.GetKnifeStaminaReduction(0f); staminaUse *= 1f - knifeStaminaReduction / 100f; } } } } [HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")] public static class KnifeSkillTreeStaminaRegenPatch { public static void Postfix(SEMan __instance, ref float staminaMultiplier) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { staminaMultiplier += SkillEffect.GetStaminaRegen(0f) / 100f; } } } [HarmonyPatch(typeof(SEMan), "ModifyRunStaminaDrain")] public static class KnifeSkillTreeRunStaminaPatch { public static void Postfix(ref float drain) { float staminaReduction = SkillEffect.GetStaminaReduction(0f); drain *= 1f - staminaReduction / 100f; } } [HarmonyPatch(typeof(SEMan), "ModifyJumpStaminaUsage")] public static class KnifeSkillTreeJumpStaminaPatch { public static void Postfix(ref float staminaUse) { float staminaReduction = SkillEffect.GetStaminaReduction(0f); staminaUse *= 1f - staminaReduction / 100f; float jumpStaminaReduction = SkillEffect.GetJumpStaminaReduction(); staminaUse *= 1f - jumpStaminaReduction / 100f; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(600)] public static class KnifeSkillTreeArmorPatch { public static void Prefix(Character __instance, HitData hit) { if (__instance.IsPlayer()) { float physicArmor = SkillEffect.GetPhysicArmor(0f); float num = 1f - physicArmor / 100f; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; hit.m_damage.m_chop *= num; hit.m_damage.m_pickaxe *= num; float magicArmor = SkillEffect.GetMagicArmor(0f); float num2 = 1f - magicArmor / 100f; hit.m_damage.m_fire *= num2; hit.m_damage.m_frost *= num2; hit.m_damage.m_lightning *= num2; hit.m_damage.m_poison *= num2; hit.m_damage.m_spirit *= num2; } } } [HarmonyPatch(typeof(Humanoid), "BlockAttack")] public static class SwordSkillTreeParryPatch { public static void Postfix(Character __instance, bool __result, HitData hit, Character attacker) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if (!__result) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !((Character)val).IsPlayer()) { return; } ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 1) { SkillTreeManager instance = SkillTreeManager.Instance; SEMan sEMan = ((Character)val).GetSEMan(); if (instance.GetSkillLevel("sword_counter") > 0) { SE_SwordCounter sE_SwordCounter = ScriptableObject.CreateInstance<SE_SwordCounter>(); ((StatusEffect)sE_SwordCounter).m_ttl = 5f; sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordCounter, true, 0, 0f); } if (instance.GetSkillLevel("sword_riposte") > 0) { SE_SwordRiposte sE_SwordRiposte = ScriptableObject.CreateInstance<SE_SwordRiposte>(); ((StatusEffect)sE_SwordRiposte).m_ttl = 5f; sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordRiposte, true, 0, 0f); } } } } [HarmonyPatch(typeof(Character), "Stagger")] public static class ParryRush_Stagger_Patch { public static void Postfix(Character __instance) { try { if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer()) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && Sword_Skill.IsParryRushActive(localPlayer) && ((Character)localPlayer).IsBlocking()) { Sword_Skill.OnParryRushTrigger(localPlayer, __instance); } } } catch (Exception) { } } } public class SE_SwordCounter : StatusEffect { public SE_SwordCounter() { base.m_name = "移쇰궇 ?섏튂湲?"; base.m_tooltip = "?ㅼ쓬 怨듦꺽???쇳빐?됱씠 20% 利앷??⑸땲??"; base.m_icon = null; base.m_ttl = 5f; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)skill == 1) { ((DamageTypes)(ref hitData.m_damage)).Modify(1.2f); base.m_character.GetSEMan().RemoveStatusEffect((StatusEffect)(object)this, true); } } } public class SE_SwordRiposte : StatusEffect { public SE_SwordRiposte() { base.m_name = "移쇰궇 ?섏튂湲?"; base.m_tooltip = "?ㅼ쓬 怨듦꺽???쇳빐?됱씠 20% 利앷??⑸땲??"; base.m_icon = null; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class SwordRiposteDamagePatch { private static readonly int SwordCounterHash = Animator.StringToHash("移쇰궇 ?섏튂湲?"); private static readonly int SwordRiposteHash = Animator.StringToHash("諛섍꺽 ?먯꽭"); private static void Prefix(Character __instance, HitData hit) { try { if (hit == null) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && (Object)(object)val != (Object)null) { SEMan sEMan = ((Character)val).GetSEMan(); if (sEMan != null && sEMan.HaveStatusEffect(SwordRiposteHash)) { hit.m_damage.m_blunt *= 1.2f; hit.m_damage.m_slash *= 1.2f; hit.m_damage.m_pierce *= 1.2f; sEMan.RemoveStatusEffect(SwordRiposteHash, false); } } } catch (Exception) { } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class InventoryHidePatch { public static void Postfix() { try { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(false); } } catch (Exception ex) { Log.LogError((object)("[?ㅽ궗?몃━] InventoryHidePatch ?ㅻ쪟: " + ex.Message)); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryShowIconPositionPatch { private static bool _iconPositionAdjusted; public static void Postfix(InventoryGui __instance) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)skillTreeIconObj == (Object)null) { return; } skillTreeIconObj.SetActive(true); if (!EpicMMOReflectionHelper.IsInitialized) { EpicMMOReflectionHelper.Initialize(); } if (EpicMMOReflectionHelper.IsAvailable || _iconPositionAdjusted) { return; } RectTransform component = skillTreeIconObj.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { ((Transform)component).SetParent(((Component)componentInParent).transform, false); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 150f); component.sizeDelta = new Vector2(60f, 60f); _iconPositionAdjusted = true; } } } catch (Exception ex) { Log.LogError((object)("[?ㅽ궗?몃━] ?꾩씠肄??꾩튂 議곗젙 ?ㅽ뙣: " + ex.Message)); } } } [HarmonyPatch(typeof(Hud), "Awake")] public static class HudAwakeHideIconPatch { [CompilerGenerated] private sealed class <DelayedHideIcon>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedHideIcon>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(false); Log.LogInfo((object)"[?ㅽ궗?몃━] ?꾩씠肄?珥덇린 ?④? ?꾨즺 - ?몃깽?좊━(Tab) ?????쒖떆??"); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void Postfix() { ProducerEnchantUI.PreloadSprite(); if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(DelayedHideIcon()); } } [IteratorStateMachine(typeof(<DelayedHideIcon>d__1))] private static IEnumerator DelayedHideIcon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedHideIcon>d__1(0); } } [HarmonyPatch(typeof(ZNet), "Awake")] public static class ZNet_Awake_Patch { private static void Postfix() { SkillTreeConfig.DetectServerClientMode(); InitializeServerSync(); } } [HarmonyPatch(typeof(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", "怨듦꺽 ?꾨Ц媛\u0080 猷⑦듃 ?곕?吏\u0080 蹂대꼫???ㅼ젙 (?? 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", "?띾룄 ?꾨Ц媛\u0080 猷⑦듃 ?대룞?띾룄 ?ㅼ젙 (?? 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", "?꾩쿂 硫\u0080?곗꺑 ?붿궡 ???ㅼ젙 (?? 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", "?꾩쿂 硫\u0080?곗꺑 ?붿궡 ?뚮え???ㅼ젙 (?? 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", "?꾩쿂 硫\u0080?곗꺑 ?곕?吏\u0080 鍮꾩쑉 ?ㅼ젙 (?? 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", "???꾨Ц媛\u0080 硫\u0080?곗꺑 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", "???꾨Ц媛\u0080 硫\u0080?곗꺑 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", "???꾨Ц媛\u0080 硫\u0080?곗꺑 ?붿궡 ???ㅼ젙 (?? 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", "???꾨Ц媛\u0080 硫\u0080?곗꺑 ?붿궡 ?뚮え???ㅼ젙 (?? 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", "???꾨Ц媛\u0080 硫\u0080?곗꺑 ?곕?吏\u0080 鍮꾩쑉 ?ㅼ젙 (?? skilltree_bow_damage 70)", (ConsoleEvent)obj20, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } [HarmonyPatch(typeof(Player), "OnDestroy")] public static class Plugin_Player_OnDestroy_DamagePatch_Cleanup { private static void Postfix(Player __instance) { try { NerveEnhancementSystem.Damage_Patch.CleanupPlayerData(__instance); } catch { } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__47_0; internal void <SetupIconClickEvent>b__47_0() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!"); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled) { SkillTreeBGMManager.Instance.PlaySkillTreeBGM(); } else if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { Log.LogInfo((object)"[BGM] BGM이 비활성화되어 있어 재생하지 않음"); } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Debug.LogWarning((object)"[스킬트리] InventoryGui.instance를 찾을 수 없음"); return; } Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>(); if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || (Object)(object)skillTreeUI.panel.transform.parent != (Object)(object)((Component)componentInChildren).transform) { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null) { Object.Destroy((Object)(object)skillTreeUI.panel); } GameObject val = new GameObject("SkillTreeUI"); val.transform.SetParent(((Component)componentInChildren).transform, false); skillTreeUI = val.AddComponent<SkillTreeUI>(); skillTreeUI.CreateUI(componentInChildren); } if (!skillTreeUI.panel.activeSelf) { skillTreeUI.RefreshUI(); skillTreeUI.panel.SetActive(true); return; } skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } } [CompilerGenerated] private sealed class <Start>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Plugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Start>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: { <>1__state = -1; ConfigEntry<string> languageConfig = LocalizationManager.LanguageConfig; if (languageConfig != null && (languageConfig.Value?.Equals("Auto", StringComparison.OrdinalIgnoreCase)).GetValueOrDefault()) { LocalizationManager.ReloadLanguage(); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static ManualLogSource Log; private static GameObject skillTreeIconObj; private static Sprite swordIcon; private static AssetBundle iconAssetBundle; private static AssetBundle uiAssetBundle; private static AssetBundle customIconBundle; private static AssetBundle jobIconBundle; private static AssetBundle vfxBundle; private static AssetBundle jobVfxBundle; public static int SkillTreePoint = 0; private static SkillTreeUI skillTreeUI; private static Sprite customSkillTreeIcon; private static Plugin? _instance; private static bool _coreSystemsInitialized = false; private static bool _emergencyMode = false; private static int _iconCreationAttempts = 0; private const int MAX_ICON_ATTEMPTS = 5; private static Type _cachedMmoType = null; private static bool _mmoTypeChecked = false; private static readonly bool _earlyUserBackup = CreateEarlyUserBackup(); public static bool IsSkillTreeOpen => (Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf; public static Plugin? Instance => _instance; private void Awake() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _instance = this; string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string path = Path.ChangeExtension(configFilePath, ".version"); string contents = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString(); File.WriteAllText(path, contents); CaptainLevelConfig.Bind(((BaseUnityPlugin)this).Config); Log.LogDebug((object)"[Captain Level System] Config 바인딩 완료"); SkillTreeConfig.Initialize(((BaseUnityPlugin)this).Config); LocalizationManager.Initialize(((BaseUnityPlugin)this).Config); Log.LogInfo((object)"[Plugin] ✓ 로컬라이제이션 시스템 초기화 완료"); Staff_Config.InitConfig(((BaseUnityPlugin)this).Config); CaptainMMOBridge.Initialize(); InitializeCoreSafeguards(); Harmony val = new Harmony("CaptainSkillTree.Mod"); Log.LogInfo((object)"========== Captain SkillTree 초기화 중... =========="); try { val.PatchAll(); Log.LogInfo((object)("========== Captain SkillTree 초기화 완료! (MMO: " + (EpicMMOReflectionHelper.IsAvailable ? "연동" : "독립") + ") ==========")); Log.LogDebug((object)"[Harmony] 패치 등록 완료"); } catch (Exception ex) { Log.LogError((object)("=== [CRITICAL] Harmony.PatchAll() 실패: " + ex.Message + " ===")); Log.LogError((object)("=== [CRITICAL] StackTrace: " + ex.StackTrace + " ===")); } InitializeInputListener(); SkillTreeData.RegisterAll(); SafeLoadCustomIcon(); InitializeBGMSystem(); InitializePrefabSystem(); GameObject val2 = new GameObject("ActiveSkillHUD"); val2.AddComponent<ActiveSkillHUD>(); Object.DontDestroyOnLoad((Object)(object)val2); RegisterJotunnCommands(); _coreSystemsInitialized = true; try { Type type = typeof(BaseUnityPlugin).Assembly.GetType("BepInEx.ConsoleManager"); MethodInfo methodInfo = type?.GetMethod("SetConsoleColor", BindingFlags.Static | BindingFlags.Public); TextWriter textWriter = type?.GetProperty("StandardOutStream", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as TextWriter; if (methodInfo != null && textWriter != null) { methodInfo.Invoke(null, new object[1] { ConsoleColor.Cyan }); textWriter.WriteLine("================================ Captain SkillTree Mod Load Success ================================"); textWriter.WriteLine(" === == === ==== == ==== = ="); textWriter.WriteLine(" = = = = = == = = == == ="); textWriter.WriteLine(" = ==== === == ==== == = =="); textWriter.WriteLine(" = = = = == = = == = ="); textWriter.WriteLine(" === = = = == = = ==== = ="); textWriter.WriteLine(""); textWriter.WriteLine(" === = = ==== = = ==== === ==== ===="); textWriter.WriteLine(" = = = == = = == = = = = "); textWriter.WriteLine(" === == == = = == === === === "); textWriter.WriteLine(" = = = == = = == = = = = "); textWriter.WriteLine(" === = = ==== ==== ==== == = = ==== ===="); textWriter.WriteLine("================================ Captain SkillTree Mod Load Success ================================"); methodInfo.Invoke(null, new object[1] { ConsoleColor.Gray }); } else { Log.LogMessage((object)"================================ Captain SkillTree Mod Load Success ================================"); } } catch { Log.LogMessage((object)"================================ Captain SkillTree Mod Load Success ================================"); } } [IteratorStateMachine(typeof(<Start>d__24))] private IEnumerator Start() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Start>d__24(0) { <>4__this = this }; } private void RegisterJotunnCommands() { try { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkillAddConsoleCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkillResetConsoleCommand()); Log.LogInfo((object)"[Jotunn] 콘솔 명령어 등록 완료: skilladd, skillreset"); } catch (Exception ex) { Log.LogError((object)("[Jotunn] 콘솔 명령어 등록 실패: " + ex.Message)); } } private static void InitializeCoreSafeguards() { try { if (!_coreSystemsInitialized) { ValidateEssentialResources(); } } catch (Exception ex) { Log.LogError((object)("[안전 장치] 초기화 실패: " + ex.Message)); _emergencyMode = true; } } private static void InitializeInputListener() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown try { if ((Object)(object)SkillTreeInputListener.Instance == (Object)null) { GameObject val = new GameObject("SkillTreeInputListener"); val.AddComponent<SkillTreeInputListener>(); Object.DontDestroyOnLoad((Object)(object)val); } } catch (Exception ex) { Log.LogError((object)("[안전 장치] InputListener 초기화 실패: " + ex.Message)); } } private static void ValidateEssentialResources() { string[] array = new string[4] { "CaptainSkillTree.asset.Resources.skill_node", "CaptainSkillTree.asset.Resources.captainskilltreeui", "CaptainSkillTree.asset.Resources.skill_start", "CaptainSkillTree.asset.Resources.job_icon" }; string[] array2 = array; foreach (string text in array2) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream(text); if (manifestResourceStream == null) { throw new Exception("필수 리소스 누락: " + text); } manifestResourceStream.Close(); } ResetEmergencyMode(); } private static void ResetEmergencyMode() { _emergencyMode = false; _iconCreationAttempts = 0; } private static void SafeLoadCustomIcon() { try { Log.LogDebug((object)"[아이콘] 커스텀 아이콘 로드 시작"); AssetBundle val = GetJobIconBundle(); if ((Object)(object)val != (Object)null) { Log.LogDebug((object)"[아이콘] job_icon 번들 로드 성공"); string[] array = new string[12] { "Paladin_unlock", "Tanker_unlock", "Berserker_unlock", "Archer_unlock", "Mage_unlock", "Rogue_unlock", "Paladin", "Tanker", "Berserker", "Archer", "Mage", "Rogue" }; string[] array2 = array; foreach (string text in array2) { Sprite val2 = val.LoadAsset<Sprite>(text); if ((Object)(object)val2 != (Object)null) { Log.LogDebug((object)("[아이콘] job_icon에서 " + text + " 로드 성공: " + ((Object)val2).name)); } } } AssetBundle val3 = GetCustomIconBundle(); if ((Object)(object)val3 != (Object)null) { Log.LogDebug((object)"[아이콘] 커스텀 아이콘 번들 로드 성공"); string[] allAssetNames = val3.GetAllAssetNames(); Log.LogDebug((object)$"[아이콘] 번들 에셋 수: {allAssetNames.Length}"); string[] array3 = allAssetNames; foreach (string text2 in array3) { Log.LogDebug((object)("[아이콘] 번들 에셋: " + text2)); } customSkillTreeIcon = val3.LoadAsset<Sprite>("skill_start"); if ((Object)(object)customSkillTreeIcon != (Object)null) { Log.LogDebug((object)"[아이콘] skill_start 스프라이트 로드 성공"); } else { TryAlternativeIconNames(val3); } } } catch (Exception ex) { Log.LogError((object)("[아이콘] 커스텀 아이콘 로드 중 오류: " + ex.Message)); Log.LogError((object)("[아이콘] StackTrace: " + ex.StackTrace)); } } private static void TryAlternativeIconNames(AssetBundle bundle) { string[] array = new string[7] { "skill_start", "SkillStart", "skill_tree_start", "captainskilltreeicon", "CaptainSkillTreeIcon", "SkillTreeIcon", "skilltreeicon" }; string[] array2 = array; foreach (string text in array2) { Sprite val = bundle.LoadAsset<Sprite>(text); if ((Object)(object)val != (Object)null) { customSkillTreeIcon = val; Log.LogDebug((object)("[아이콘] 대체 이름으로 아이콘 로드 성공: " + text)); return; } } Log.LogWarning((object)"[아이콘] 모든 아이콘 이름 시도 실패 - 게임 기본 아이콘 사용"); } public static AssetBundle GetIconAssetBundle() { if ((Object)(object)iconAssetBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.skill_node"); if (manifestResourceStream != null) { iconAssetBundle = AssetBundle.LoadFromStream(manifestResourceStream); } } return iconAssetBundle; } public static AssetBundle GetUIAssetBundle() { if ((Object)(object)uiAssetBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.captainskilltreeui"); if (manifestResourceStream != null) { uiAssetBundle = AssetBundle.LoadFromStream(manifestResourceStream); } } return uiAssetBundle; } public static AssetBundle GetCustomIconBundle() { if ((Object)(object)customIconBundle == (Object)null) { try { Assembly assembly = typeof(Plugin).Assembly; Log.LogDebug((object)("[번들] Assembly: " + assembly.FullName)); string[] manifestResourceNames = assembly.GetManifestResourceNames(); Log.LogDebug((object)$"[번들] 사용 가능한 리소스 수: {manifestResourceNames.Length}"); bool flag = false; string[] array = manifestResourceNames; foreach (string text in array) { Log.LogDebug((object)("[번들] 리소스: " + text)); if (text.Contains("skill_start")) { flag = true; Log.LogDebug((object)("[번들] 시작 아이콘 리소스 발견: " + text)); } } if (!flag) { Log.LogError((object)"[번들] skill_start 리소스가 DLL에 포함되지 않음!"); } Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.skill_start"); if (manifestResourceStream != null) { Log.LogDebug((object)$"[번들] 스트림 로드 성공, 크기: {manifestResourceStream.Length} bytes"); customIconBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)customIconBundle != (Object)null) { Log.LogDebug((object)"[번들] AssetBundle 로드 성공"); } else { Log.LogError((object)"[번들] AssetBundle.LoadFromStream 실패"); } } else { Log.LogError((object)"[번들] 리소스 스트림이 null"); } } catch (Exception ex) { Log.LogError((object)("[번들] GetCustomIconBundle 오류: " + ex.Message)); } } return customIconBundle; } public static AssetBundle GetJobIconBundle() { if ((Object)(object)jobIconBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.job_icon"); if (manifestResourceStream != null) { jobIconBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)jobIconBundle != (Object)null) { Log.LogDebug((object)"[아이콘] job_icon 번들 로드 성공"); string[] allAssetNames = jobIconBundle.GetAllAssetNames(); Log.LogDebug((object)$"[아이콘] job_icon 번들 에셋 수: {allAssetNames.Length}"); string[] array = allAssetNames; foreach (string text in array) { Log.LogDebug((object)("[아이콘] job_icon 에셋: " + text)); } } else { Log.LogError((object)"[아이콘] job_icon AssetBundle.LoadFromStream 실패"); } } else { Log.LogWarning((object)"[아이콘] job_icon 리소스 스트림이 null"); } } return jobIconBundle; } public static AssetBundle GetVfxBundle() { if ((Object)(object)vfxBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.VFX.vfxbundle"); if (manifestResourceStream != null) { vfxBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)vfxBundle != (Object)null) { Log.LogDebug((object)"[VFX] VFX 폴더에서 vfxbundle 번들 로드 성공"); } else { Log.LogError((object)"[VFX] VFX 폴더에서 vfxbundle 번들 로드 실패"); } } else { Log.LogError((object)"[VFX] VFX 폴더에서 vfxbundle 리소스 스트림을 찾을 수 없음"); } } return vfxBundle; } public static AssetBundle GetJobVfxBundle() { if ((Object)(object)jobVfxBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.job_vfx"); if (manifestResourceStream != null) { jobVfxBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)jobVfxBundle != (Object)null) { Log.LogDebug((object)"[VFX] job_vfx 번들 로드 성공"); } else { Log.LogError((object)"[VFX] job_vfx 번들 로드 실패"); } } else { Log.LogError((object)"[VFX] job_vfx 리소스 스트림을 찾을 수 없음"); } } return jobVfxBundle; } public static T LoadEmbeddedAsset<T>(string resourcePath) where T : Object { try { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream(resourcePath); if (manifestResourceStream == null) { Log.LogWarning((object)("[LoadEmbeddedAsset] 리소스를 찾을 수 없음: " + resourcePath)); return default(T); } AssetBundle val = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)("[LoadEmbeddedAsset] AssetBundle 로드 실패: " + resourcePath)); manifestResourceStream.Close(); return default(T); } T[] array = val.LoadAllAssets<T>(); if (array.Length != 0) { T val2 = array[0]; Log.LogInfo((object)("[LoadEmbeddedAsset] 에셋 로드 성공: " + resourcePath + " -> " + ((Object)val2).name)); return val2; } Log.LogWarning((object)("[LoadEmbeddedAsset] " + typeof(T).Name + " 타입의 에셋을 찾을 수 없음: " + resourcePath)); val.Unload(false); manifestResourceStream.Close(); return default(T); } catch (Exception ex) { Log.LogError((object)("[LoadEmbeddedAsset] 에셋 로드 오류: " + resourcePath + " - " + ex.Message)); return default(T); } } private static void ShowSkillTreeIcon() { if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(true); return; } if (_emergencyMode || _iconCreationAttempts >= 5) { Log.LogWarning((object)"[안전 장치] 비상 모드 또는 최대 시도 횟수 초과 - 아이콘 생성 건너뛰기"); return; } try { if (!ValidatePrerequisites()) { Log.LogWarning((object)"[안전 장치] 전제 조건 미충족 - 아이콘 생성 연기"); return; } if (!_mmoTypeChecked) { _cachedMmoType = Type.GetType("EpicMMOSystem.MyUI, EpicMMOSystem"); _mmoTypeChecked = true; } Type cachedMmoType = _cachedMmoType; if (cachedMmoType != null && TryCreateMMOStyleIcon()) { ResetIconAttempts(); } else { CreateFallbackSkillTreeIcon(); } } catch (Exception ex) { _iconCreationAttempts++; Log.LogError((object)$"[안전 장치] SkillTreeIcon 생성 중 예외 (시도 {_iconCreationAttempts}/{5}): {ex.Message}"); Log.LogError((object)("[안전 장치] StackTrace: " + ex.StackTrace)); if (_iconCreationAttempts < 5) { try { CreateFallbackSkillTreeIcon(); return; } catch (Exception ex2) { Log.LogError((object)("[안전 장치] 대체 아이콘 생성도 실패: " + ex2.Message)); return; } } Log.LogError((object)"[안전 장치] 최대 시도 횟수 도달 - 비상 모드 활성화"); _emergencyMode = true; } } private static bool ValidatePrerequisites() { try { if ((Object)(object)Player.m_localPlayer == (Object)null) { Log.LogDebug((object)"[안전 장치] Player가 아직 로드되지 않음"); return false; } if ((Object)(object)InventoryGui.instance == (Object)null) { Log.LogDebug((object)"[안전 장치] InventoryGui가 아직 준비되지 않음"); return false; } if ((Object)(object)GetCustomIconBundle() == (Object)null && (Object)(object)swordIcon == (Object)null) { Log.LogWarning((object)"[안전 장치] 아이콘 리소스가 준비되지 않음 - 로드 시도"); SafeLoadCustomIcon(); LoadGameDefaultIcon(); } return true; } catch (Exception ex) { Log.LogError((object)("[안전 장치] 전제 조건 검증 실패: " + ex.Message)); return false; } } private static void LoadGameDefaultIcon() { try { if (!((Object)(object)swordIcon == (Object)null) || !((Object)(object)ObjectDB.instance != (Object)null)) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { swordIcon = component.m_itemData.GetIcon(); Log.LogDebug((object)"[안전 장치] 게임 기본 아이콘 로드 성공"); } } } catch (Exception) { } } private static void ResetIconAttempts() { _iconCreationAttempts = 0; } private static bool TryCreateMMOStyleIcon() { //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown try { Type cachedMmoType = _cachedMmoType; if (cachedMmoType == null) { Log.LogWarning((object)"EpicMMOSystem.MyUI 타입을 찾을 수 없음"); return false; } FieldInfo field = cachedMmoType.GetField("navigationPanel", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { Log.LogWarning((object)"navigationPanel 필드를 찾을 수 없음"); return false; } object? value = field.GetValue(null); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"navigationPanel이 null"); return false; } Transform val2 = val.transform.Find("Buttons"); if ((Object)(object)val2 == (Object)null) { Log.LogWarning((object)"Buttons 오브젝트를 찾을 수 없음"); return false; } Transform val3 = val2.Find("ButtonSkillTree"); if ((Object)(object)val3 != (Object)null) { skillTreeIconObj = ((Component)val3).gameObject; skillTreeIconObj.SetActive(true); return true; } Transform val4 = val2.Find("ButtonLevelSystem"); if ((Object)(object)val4 == (Object)null) { Log.LogWarning((object)"ButtonLevelSystem 오브젝트를 찾을 수 없음"); return false; } skillTreeIconObj = Object.Instantiate<GameObject>(((Component)val4).gameObject, val2); ((Object)skillTreeIconObj).name = "ButtonSkillTree"; Image val5 = skillTreeIconObj.GetComponent<Image>(); if ((Object)(object)val5 == (Object)null) { val5 = skillTreeIconObj.GetComponentInChildren<Image>(); } if ((Object)(object)customSkillTreeIcon != (Object)null) { val5.sprite = customSkillTreeIcon; } else { if ((Object)(object)swordIcon == (Object)null) { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { Log.LogWarning((object)"ObjectDB.instance가 null"); return false; } GameObject itemPrefab = instance.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab == (Object)null) { Log.LogWarning((object)"SwordIron 프리팹을 찾을 수 없음"); return false; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Log.LogWarning((object)"SwordIron에 ItemDrop 컴포넌트가 없음"); return false; } swordIcon = component.m_itemData.GetIcon(); if ((Object)(object)swordIcon == (Object)null) { Log.LogWarning((object)"SwordIron 아이콘(Sprite)을 찾을 수 없음"); return false; } } val5.sprite = swordIcon; } RectTransform component2 = skillTreeIconObj.GetComponent<RectTransform>(); RectTransform component3 = ((Component)val4).GetComponent<RectTransform>(); component2.anchoredPosition = component3.anchoredPosition + new Vector2(80f, 0f); component2.sizeDelta = component3.sizeDelta; component2.anchorMin = component3.anchorMin; component2.anchorMax = component3.anchorMax; component2.pivot = component3.pivot; ((Transform)component2).localScale = ((Transform)component3).localScale; foreach (Transform item in skillTreeIconObj.transform) { Transform val6 = item; if ((Object)(object)((Component)val6).GetComponent<Image>() == (Object)null) { ((Component)val6).gameObject.SetActive(false); } } SetupIconClickEvent(); Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { Log.LogDebug((object)$"[시작 아이콘] 부모 Canvas sortingOrder: {componentInParent.sortingOrder}"); } skillTreeIconObj.SetActive(true); Log.LogDebug((object)"[시작 아이콘] 아이콘 생성 및 활성화 완료"); return true; } catch (Exception ex) { Log.LogWarning((object)("아이콘 생성 실패: " + ex.Message)); return false; } } private static void CreateFallbackSkillTreeIcon() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Log.LogWarning((object)"[디버그] InventoryGui.instance가 null, 아이콘 생성 불가"); return; } Log.LogInfo((object)"[디버그] InventoryGui 인스턴스 확인됨"); if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(true); Log.LogDebug((object)"기존 대체 아이콘 활성화"); return; } try { Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>(); if ((Object)(object)componentInChildren == (Object)null) { Log.LogWarning((object)"InventoryGui에서 Canvas를 찾을 수 없음"); return; } Transform val = ((Component)componentInChildren).transform.Find("Player"); if ((Object)(object)val == (Object)null) { val = ((Component)componentInChildren).transform; } GameObject val2 = new GameObject("ButtonSkillTree_Fallback"); val2.transform.SetParent(val, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = new Vector2(0.5f, 0f); val3.anchorMax = new Vector2(0.5f, 0f); val3.pivot = new Vector2(0.5f, 0f); val3.anchoredPosition = new Vector2(100f, 10f); val3.sizeDelta = new Vector2(60f, 60f); Image val4 = val2.AddComponent<Image>(); if ((Object)(object)customSkillTreeIcon != (Object)null) { val4.sprite = customSkillTreeIcon; } else { if ((Object)(object)swordIcon == (Object)null) { ObjectDB instance2 = ObjectDB.instance; if ((Object)(object)instance2 != (Object)null) { GameObject itemPrefab = instance2.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { swordIcon = component.m_itemData.GetIcon(); } } } } val4.sprite = swordIcon; } if ((Object)(object)val4.sprite == (Object)null) { ((Graphic)val4).color = new Color(0.2f, 0.6f, 1f, 0.8f); Log.LogInfo((object)"스프라이트가 없어 단색으로 표시"); } Button val5 = val2.AddComponent<Button>(); ((Selectable)val5).targetGraphic = (Graphic)(object)val4; skillTreeIconObj = val2; SetupIconClickEvent(); Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { Log.LogDebug((object)$"[대체 아이콘] 부모 Canvas sortingOrder: {componentInParent.sortingOrder}"); } skillTreeIconObj.SetActive(true); Log.LogDebug((object)"아이콘 생성 성공"); } catch (Exception ex) { Log.LogError((object)("대체 아이콘 생성 실패: " + ex.Message)); } } private static void SetupIconSprite(Image image) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) bool flag = false; try { SafeLoadCustomIcon(); if ((Object)(object)customSkillTreeIcon != (Object)null) { image.sprite = customSkillTreeIcon; ((Graphic)image).color = Color.white; flag = true; Log.LogDebug((object)"[아이콘] 커스텀 아이콘 적용 성공"); } } catch (Exception ex) { Log.LogDebug((object)("[아이콘] 커스텀 아이콘 로드 실패: " + ex.Message)); } if (!flag) { try { if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { Sprite icon = component.m_itemData.GetIcon(); if ((Object)(object)icon != (Object)null) { image.sprite = icon; ((Graphic)image).color = Color.white; flag = true; Log.LogDebug((object)"[아이콘] 게임 기본 아이콘(검) 적용 성공"); } } } } } catch (Exception ex2) { Log.LogDebug((object)("[아이콘] 기본 아이콘 로드 실패: " + ex2.Message)); } } if (!flag && (Object)(object)((Component)image).transform.parent != (Object)null) { GameObject val = new GameObject("IconText"); val.transform.SetParent(((Component)image).transform.parent, false); Text val2 = val.AddComponent<Text>(); val2.text = "스킬\n트리"; val2.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); val2.fontSize = 14; ((Graphic)val2).color = Color.white; val2.alignment = (TextAnchor)4; RectTransform component2 = ((Component)val2).GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; } } private static void SetupIconClickEvent() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown Button val = skillTreeIconObj.GetComponent<Button>() ?? skillTreeIconObj.AddComponent<Button>(); ((Selectable)val).interactable = true; Image component = skillTreeIconObj.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).raycastTarget = true; } ((UnityEventBase)val.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = val.onClick; object obj = <>c.<>9__47_0; if (obj == null) { UnityAction val2 = delegate { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!"); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled) { SkillTreeBGMManager.Instance.PlaySkillTreeBGM(); } else if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { Log.LogInfo((object)"[BGM] BGM이 비활성화되어 있어 재생하지 않음"); } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Debug.LogWarning((object)"[스킬트리] InventoryGui.instance를 찾을 수 없음"); } else { Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>(); if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || (Object)(object)skillTreeUI.panel.transform.parent != (Object)(object)((Component)componentInChildren).transform) { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null) { Object.Destroy((Object)(object)skillTreeUI.panel); } GameObject val3 = new GameObject("SkillTreeUI"); val3.transform.SetParent(((Component)componentInChildren).transform, false); skillTreeUI = val3.AddComponent<SkillTreeUI>(); skillTreeUI.CreateUI(componentInChildren); } if (!skillTreeUI.panel.activeSelf) { skillTreeUI.RefreshUI(); skillTreeUI.panel.SetActive(true); } else { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } } }; <>c.<>9__47_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } private void OnGUI() { try { SkillTreeManager.Instance.OnGUIShowMessage(); } catch (Exception ex) { Log.LogWarning((object)("OnGUI 메시지 표시 중 오류: " + ex.Message)); } } private static void InitializeBGMSystem() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown try { GameObject val = new GameObject("SkillTreeBGMManager"); val.AddComponent<SkillTreeBGMManager>(); Object.DontDestroyOnLoad((Object)(object)val); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.Initialize(); Log.LogDebug((object)"[BGM] 스킬트리 BGM 시스템 초기화 완료"); } else { Log.LogWarning((object)"[BGM] SkillTreeBGMManager.Instance가 null"); } } catch (Exception ex) { Log.LogError((object)("[BGM] 초기화 실패: " + ex.Message)); } } private static void InitializePrefabSystem() { try { PrefabRegistry.Initialize(); } catch (Exception ex) { Log.LogError((object)("[프리팹] 초기화 실패: " + ex.Message)); } } private static bool CreateEarlyUserBackup() { try { string text = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg"); string text2 = Path.Combine(Paths.ConfigPath, "CaptainSkillTree"); string text3 = Path.Combine(text2, "User_CaptainSkillTree.SkillTreeMod.cfg"); if (!File.Exists(text3) && File.Exists(text)) { Directory.CreateDirectory(text2); File.Copy(text, text3, overwrite: false); } } catch { } return true; } internal static void InitializeServerSync() { if (ZRoutedRpc.instance != null) { try { ZRoutedRpc.instance.Register<string>("CaptainSkillTree.SkillTreeMod_ConfigSync", (Action<long, string>)RPC_ReceiveConfigSync); ZRoutedRpc.instance.Register<string>("CaptainSkillTree.AdminConfigUpdate", (Action<long, string>)SkillTreeConfig.RPC_AdminConfigUpdate); ZRoutedRpc.instance.Register<string>("CaptainSkillTree.AdminBatchSync", (Action<long, string>)SkillTreeConfig.RPC_AdminBatchSync); 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))