Please disclose if your mod was created primarily 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.2.29
AnimationSpeedManager.dll
Decompiled a day 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 a day 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.Prefab; using CaptainSkillTree.SkillTree; using CaptainSkillTree.SkillTree.CriticalSystem; using CaptainSkillTree.VFX; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CaptainSkillTree")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CaptainSkillTree")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d1b6e7e2-1c2a-4b8a-9e2b-123456789abc")] [assembly: AssemblyFileVersion("1.2.267.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.267.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CaptainSkillTree { public static class DifficultyManager { private const string PRESET_DIR_NAME = "CaptainSkillTree"; private const string PRESET_NORMAL = "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"; private const string PRESET_VERYHARD = "Veryhard_CaptainSkillTree.SkillTreeMod.cfg"; private const string PRESET_USER = "User_CaptainSkillTree.SkillTreeMod.cfg"; private const string DIFF_VER_EXT = ".difficulty_ver"; private static bool _initialized = false; private static string _configFilePath = ""; private static FieldInfo _entriesField; private static bool _entriesFieldSearched; public static bool NeedsSelection { get; private set; } public static bool IsApplyingPreset { get; private set; } public static void InitializeIfNeeded() { if (_initialized) { return; } _initialized = true; Plugin? instance = Plugin.Instance; object obj; if (instance == null) { obj = null; } else { ConfigFile config = ((BaseUnityPlugin)instance).Config; obj = ((config != null) ? config.ConfigFilePath : null); } if (obj == null) { obj = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg"); } _configFilePath = (string)obj; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[Difficulty] Config path: " + _configFilePath)); } string path = Path.ChangeExtension(_configFilePath, ".version"); string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver"); string text = (File.Exists(path) ? File.ReadAllText(path).Trim() : ""); string text2 = (File.Exists(path2) ? File.ReadAllText(path2).Trim() : ""); NeedsSelection = text != text2; if (NeedsSelection) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[Difficulty] 난이도 선택 필요 (모드 버전: " + text + " / 마지막 선택: " + text2 + ")")); } } EnsurePresetDirectory(); Application.quitting += SaveUserBackupOnQuit; } public static bool HasUserPreset() { return File.Exists(Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg")); } public static void ApplyNormal() { ApplyPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"); } public static void ApplyVeryHard() { ApplyPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg"); } public static void ApplyUser() { ApplyPreset("User_CaptainSkillTree.SkillTreeMod.cfg"); } private static void ApplyPreset(string presetFileName) { IsApplyingPreset = true; string text = Path.Combine(GetPresetDirectory(), presetFileName); if (File.Exists(text)) { try { File.Copy(text, _configFilePath, overwrite: true); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[Difficulty] 파일 복사 완료: " + presetFileName)); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)("[Difficulty] 파일 복사 실패: " + ex.Message)); } } Plugin? instance = Plugin.Instance; object obj; if (instance == null) { obj = null; } else { ConfigFile config = ((BaseUnityPlugin)instance).Config; obj = ((config != null) ? config.ConfigFilePath : null); } if (obj == null) { obj = "(null)"; } string text2 = (string)obj; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[Difficulty] _configFilePath = " + _configFilePath)); } ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)("[Difficulty] Config.FilePath = " + text2)); } ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"[Difficulty] 경로 일치: {string.Equals(_configFilePath, text2, StringComparison.OrdinalIgnoreCase)}"); } Plugin? instance2 = Plugin.Instance; ConfigFile val = ((instance2 != null) ? ((BaseUnityPlugin)instance2).Config : null); if (val != null) { bool saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; val.Reload(); int num = ApplyPresetValuesToConfig(text); string text3 = ((presetFileName == "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg") ? "Vanilla" : ((presetFileName == "Veryhard_CaptainSkillTree.SkillTreeMod.cfg") ? "HardMode" : "UserSettings")); ConfigEntry<string> gameDifficulty = SkillTreeConfig.GameDifficulty; if (gameDifficulty != null) { gameDifficulty.Value = text3; } val.Save(); val.SaveOnConfigSet = saveOnConfigSet; ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogInfo((object)$"[Difficulty] ✅ 프리셋 적용 완료: {presetFileName} ({num}개), 난이도={text3}"); } } } else { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogWarning((object)("[Difficulty] ⚠\ufe0f 프리셋 파일 없음: " + text + "\n → 현재 설정을 그대로 유지합니다.")); } } SaveDifficultyVersion(); NeedsSelection = false; IsApplyingPreset = false; } private static FieldInfo GetEntriesField() { if (_entriesFieldSearched) { return _entriesField; } _entriesFieldSearched = true; Type typeFromHandle = typeof(Dictionary<ConfigDefinition, ConfigEntryBase>); Type type = typeof(ConfigFile); while (type != null && type != typeof(object)) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeFromHandle) { _entriesField = fieldInfo; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[Difficulty] entries field: " + type.Name + "." + fieldInfo.Name)); } return fieldInfo; } } type = type.BaseType; } type = typeof(ConfigFile); while (type != null && type != typeof(object)) { FieldInfo[] fields2 = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo2 in fields2) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] Field: " + type.Name + "." + fieldInfo2.Name + " : " + fieldInfo2.FieldType.FullName)); } } type = type.BaseType; } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)"[Difficulty] entries field not found"); } return null; } private static int ApplyPresetValuesToConfig(string presetPath) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val == null) { return 0; } if (!(GetEntriesField()?.GetValue(val) is Dictionary<ConfigDefinition, ConfigEntryBase> dictionary)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Difficulty] entries 딕셔너리 접근 실패"); } return -1; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[Difficulty] 등록된 ConfigEntry 수: {dictionary.Count}"); } int num = 0; string text = ""; HashSet<ConfigDefinition> hashSet = new HashSet<ConfigDefinition>(); try { string[] array = File.ReadAllLines(presetPath); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.StartsWith("[") && text3.EndsWith("]")) { text = text3.Substring(1, text3.Length - 2); } else { if (text3.StartsWith("#") || !text3.Contains(" = ")) { continue; } int num2 = text3.IndexOf(" = "); string text4 = text3.Substring(0, num2).Trim(); string serializedValue = text3.Substring(num2 + 3); ConfigDefinition val2 = new ConfigDefinition(text, text4); if (!dictionary.TryGetValue(val2, out var value)) { continue; } try { value.SetSerializedValue(serializedValue); hashSet.Add(val2); if (num == 0) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("[Difficulty] 첫 항목: [" + text + "] " + text4 + " = " + value.GetSerializedValue())); } } num++; } catch { } } } } catch (Exception ex) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)("[Difficulty] 값 직접 적용 실패: " + ex.Message)); } } int num3 = 0; foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in dictionary) { if (!hashSet.Contains(item.Key)) { try { item.Value.BoxedValue = item.Value.DefaultValue; num3++; } catch { } } } if (num3 > 0) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"[Difficulty] 미포함 항목 기본값 리셋: {num3}개"); } } return num + num3; } public static string GetPresetDirectory() { return Path.Combine(Paths.ConfigPath, "CaptainSkillTree"); } public static void EnsurePresetDirectory() { try { Directory.CreateDirectory(GetPresetDirectory()); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 폴더 생성 실패: " + ex.Message)); } } ExtractEmbeddedPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"); ExtractEmbeddedPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg"); } private static void ExtractEmbeddedPreset(string fileName) { string path = Path.Combine(GetPresetDirectory(), fileName); string text = "CaptainSkillTree.asset." + fileName; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using (Stream stream = executingAssembly.GetManifestResourceStream(text)) { if (stream == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 내장 리소스 없음: " + text)); } return; } using FileStream destination = new FileStream(path, FileMode.Create, FileAccess.Write); stream.CopyTo(destination); } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[Difficulty] 프리셋 추출 완료: " + fileName)); } } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[Difficulty] 프리셋 추출 실패 (" + fileName + "): " + ex.Message)); } } } private static void SaveUserBackupOnQuit() { if (string.IsNullOrEmpty(_configFilePath) || !File.Exists(_configFilePath)) { return; } string destFileName = Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg"); try { File.Copy(_configFilePath, destFileName, overwrite: true); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[Difficulty] User 설정 백업 저장 완료"); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] User 백업 저장 실패: " + ex.Message)); } } } private static void SaveDifficultyVersion() { try { string path = Path.ChangeExtension(_configFilePath, ".version"); string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver"); string contents = (File.Exists(path) ? File.ReadAllText(path).Trim() : ""); File.WriteAllText(path2, contents); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 버전 기록 실패: " + ex.Message)); } } } } public class SkillTreeInputListener : MonoBehaviour { public SkillTreeUI? skillTreeUI; private float lastLogTime = 0f; public static SkillTreeInputListener? Instance { get; private set; } private void Awake() { lastLogTime = Time.time; if ((Object)(object)Instance == (Object)null) { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); LevelSyncManager.Instance.Initialize(); } else { Debug.LogWarning((object)"[SkillTreeInputListener] 중복 생성 감지, 즉시 파괴, this={this.GetHashCode()} (name={gameObject.name})"); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Update() { try { SkillTreeManager.Instance?.OnUpdate(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SkillTree] SkillTreeManager 업데이트 실패: " + ex.Message)); } try { LevelSyncManager.Instance?.Update(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[SkillTree] LevelSyncManager 업데이트 실패: " + ex2.Message)); } if (IsChatOrConsoleOpen()) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { if (Input.GetKeyDown((KeyCode)114)) { SkillEffect.HandleRKeySkills(localPlayer); } if (Input.GetKeyDown((KeyCode)103)) { SkillEffect.HandleGKeySkills(localPlayer); } if (Input.GetKeyUp((KeyCode)103)) { SkillEffect.HandleGKeyUpSkills(localPlayer); } if (Input.GetKeyDown((KeyCode)104)) { SkillEffect.HandleHKeySkills(localPlayer); } if (Input.GetKeyUp((KeyCode)104)) { SkillEffect.HandleHKeyUpSkills(localPlayer); } if (Input.GetKeyDown((KeyCode)121)) { SkillTreeManager.Instance.HandleActiveSkillKeyInput(); } if (Input.GetKeyDown((KeyCode)93)) { try { long expToNextLevel = CaptainMMOBridge.GetExpToNextLevel(); CaptainMMOBridge.AddExp((int)expToNextLevel); Plugin.SkillTreePoint += 3; } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[SkillTree] 레벨업 실패 (경험치 추가): " + ex3.Message)); } } } if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || !skillTreeUI.panel.activeInHierarchy) { return; } bool keyDown = Input.GetKeyDown((KeyCode)27); bool keyDown2 = Input.GetKeyDown((KeyCode)9); if (keyDown) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } else { Plugin.Log.LogError((object)"[\ud83d\udd11 ESC] ❌ SkillTreeBGMManager.Instance가 null - ESC키 처리 실패"); } } if (keyDown2) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } else { Plugin.Log.LogError((object)"[\ud83d\udd11 TAB] ❌ SkillTreeBGMManager.Instance가 null - Tab키 처리 실패"); } } } private bool IsChatOrConsoleOpen() { try { if (IsChatInputActive()) { Plugin.Log.LogDebug((object)"[키 입력 차단] 채팅 입력이 활성화됨 - 스킬 키 입력 차단"); return true; } if (IsConsoleActive()) { Plugin.Log.LogDebug((object)"[키 입력 차단] 콘솔이 활성화됨 - 스킬 키 입력 차단"); return true; } return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[키 입력 차단] 채팅/콘솔 상태 확인 중 오류: " + ex.Message)); return false; } } private bool IsChatInputActive() { try { EventSystem current = EventSystem.current; if ((Object)(object)((current != null) ? current.currentSelectedGameObject : null) != (Object)null) { InputField component = current.currentSelectedGameObject.GetComponent<InputField>(); if ((Object)(object)component != (Object)null && component.isFocused) { return true; } } if ((Object)(object)Chat.instance != (Object)null) { GameObject gameObject = ((Component)Chat.instance).gameObject; if ((Object)(object)gameObject != (Object)null && gameObject.activeInHierarchy) { try { InputField componentInChildren = ((Component)Chat.instance).GetComponentInChildren<InputField>(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isFocused) { return true; } } catch (Exception ex) { Plugin.Log.LogDebug((object)("[채팅 감지] GetComponentInChildren 실패: " + ex.Message)); } } } return false; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[채팅 감지] 오류: " + ex2.Message)); return false; } } private bool IsConsoleActive() { try { Type type = Type.GetType("Console, assembly_valheim"); if (type != null) { MethodInfo method = type.GetMethod("IsVisible", BindingFlags.Static | BindingFlags.Public); if (method != null && (bool)method.Invoke(null, null)) { return true; } } return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[콘솔 감지] 오류: " + ex.Message)); return false; } } private void OnDestroy() { ((MonoBehaviour)this).StopAllCoroutines(); LevelSyncManager.Instance?.Cleanup(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(Player), "OnDeath")] public static class Player_OnDeath_StopCoroutines_Patch { [HarmonyPostfix] public static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)SkillTreeInputListener.Instance != (Object)null) { ((MonoBehaviour)SkillTreeInputListener.Instance).StopAllCoroutines(); } } } [BepInPlugin("CaptainSkillTree.SkillTreeMod", "Captain SkillTree Mod", "1.2.267")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryShowPatch { private static bool Prepare() { return true; } public static void Postfix() { try { ShowSkillTreeIcon(); } catch (Exception ex) { Log.LogError((object)("[스킬트리] InventoryShowPatch 오류: " + ex.Message)); Log.LogError((object)("[스킬트리] StackTrace: " + ex.StackTrace)); } } } [HarmonyPatch(typeof(FejdStartup), "Awake")] private static class FejdStartup_DifficultyPatch { [HarmonyPostfix] private static void Postfix(FejdStartup __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown DifficultyManager.InitializeIfNeeded(); if (DifficultyManager.NeedsSelection) { Canvas val = ((Component)__instance).GetComponentInChildren<Canvas>(true) ?? Object.FindObjectOfType<Canvas>(); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"[Difficulty] Canvas를 찾을 수 없어 난이도 선택 창을 열 수 없습니다. 기본값 VeryHard 적용."); DifficultyManager.ApplyVeryHard(); return; } GameObject val2 = new GameObject("DifficultySelectUI"); val2.transform.SetParent(((Component)val).transform, false); val2.AddComponent<DifficultySelectUI>(); val2.transform.SetAsLastSibling(); Log.LogInfo((object)"[Difficulty] 난이도 선택 창 표시"); } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(400)] public static class WeaponCriticalSystemPatch { public static void Prefix(Character __instance, ref bool showDamageText, ref HitData hit) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Invalid comparison between Unknown and I4 //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Invalid comparison between Unknown and I4 //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Invalid comparison between Unknown and I4 //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Invalid comparison between Unknown and I4 //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || !(attacker is Player)) { return; } Player val = (Player)(object)((attacker is Player) ? attacker : null); ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (currentWeapon == null) { return; } SkillType skillType = currentWeapon.m_shared.m_skillType; if ((int)skillType == 5 && SkillEffect.spearEnhancedThrowBuffEndTime.TryGetValue(val, out var value) && Time.time < value) { float spearStep6ComboDamageValue = SkillTreeConfig.SpearStep6ComboDamageValue; float num = 1f + spearStep6ComboDamageValue / 100f; hit.m_damage.m_pierce *= num; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_chop *= num; Log.LogInfo((object)$"[연공창] ✅ 강화된 투창 데미지 +{spearStep6ComboDamageValue}% 적용!"); if ((Object)(object)__instance != (Object)null && !__instance.IsPlayer()) { Vector3 position = ((Component)__instance).transform.position + Vector3.up * 1f; SimpleVFX.Play("confetti_directional_multicolor", position, 2f); Log.LogDebug((object)"[연공창] confetti 효과 재생"); } SkillEffect.spearEnhancedThrowBuffEndTime.Remove(val); return; } if ((int)skillType == 5 && SkillEffect.HasSkill("spear_Step1_throw") && SkillEffect.CanUseSpearThrowPassive(val)) { float spearStep2ThrowDamageValue = SkillTreeConfig.SpearStep2ThrowDamageValue; float num2 = 1f + spearStep2ThrowDamageValue / 100f; hit.m_damage.m_pierce *= num2; hit.m_damage.m_blunt *= num2; hit.m_damage.m_slash *= num2; hit.m_damage.m_chop *= num2; Log.LogInfo((object)$"[투창 전문가] ✅ 투창 공격력 +{spearStep2ThrowDamageValue}% 적용!"); SkillEffect.ShowSkillEffectText(val, $"\ud83d\udca5 투창 +{spearStep2ThrowDamageValue}%!", new Color(1f, 0.8f, 0.2f), SkillEffect.SkillEffectTextType.Combat); SkillEffect.SetSpearThrowPassiveCooldown(val); } if ((int)skillType == 8 && SkillEffect.HasSkill("bow_Step2_focus") && Critical.IsHeadshot(__instance, hit.m_point)) { float critMultiplier = CriticalDamage.CalculateCritDamageMultiplier(val, skillType); CriticalDamage.ApplyCriticalDamage(val, ref hit, critMultiplier, skillType); SkillEffect.ShowSkillEffectText(val, L.Get("bow_headshot_text") + "!", new Color(1f, 0.3f, 0.1f), SkillEffect.SkillEffectTextType.Combat); VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point); showDamageText = false; Log.LogInfo((object)"[헤드샷] 머리 적중 → 100% 크리티컬 발동!"); return; } float critChance = Critical.CalculateCritChance(val, skillType); if (Critical.RollCritical(critChance)) { float critMultiplier2 = CriticalDamage.CalculateCritDamageMultiplier(val, skillType); CriticalDamage.ApplyCriticalDamage(val, ref hit, critMultiplier2, skillType); if ((int)skillType == 2 || (int)skillType == 11) { VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point); } showDamageText = false; } } } [HarmonyPatch(typeof(SEMan), "ModifyAttackStaminaUsage")] public static class KnifeSkillTreeStaminaPatch { public static void Postfix(SEMan __instance, ref float staminaUse) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 2) { float knifeStaminaReduction = SkillEffect.GetKnifeStaminaReduction(0f); staminaUse *= 1f - knifeStaminaReduction / 100f; } } } } [HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")] public static class KnifeSkillTreeStaminaRegenPatch { public static void Postfix(SEMan __instance, ref float staminaMultiplier) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { staminaMultiplier += SkillEffect.GetStaminaRegen(0f) / 100f; } } } [HarmonyPatch(typeof(SEMan), "ModifyRunStaminaDrain")] public static class KnifeSkillTreeRunStaminaPatch { public static void Postfix(ref float drain) { float staminaReduction = SkillEffect.GetStaminaReduction(0f); drain *= 1f - staminaReduction / 100f; } } [HarmonyPatch(typeof(SEMan), "ModifyJumpStaminaUsage")] public static class KnifeSkillTreeJumpStaminaPatch { public static void Postfix(ref float staminaUse) { float staminaReduction = SkillEffect.GetStaminaReduction(0f); staminaUse *= 1f - staminaReduction / 100f; float jumpStaminaReduction = SkillEffect.GetJumpStaminaReduction(); staminaUse *= 1f - jumpStaminaReduction / 100f; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(600)] public static class KnifeSkillTreeArmorPatch { public static void Prefix(Character __instance, HitData hit) { if (__instance.IsPlayer()) { float physicArmor = SkillEffect.GetPhysicArmor(0f); float num = 1f - physicArmor / 100f; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; hit.m_damage.m_chop *= num; hit.m_damage.m_pickaxe *= num; float magicArmor = SkillEffect.GetMagicArmor(0f); float num2 = 1f - magicArmor / 100f; hit.m_damage.m_fire *= num2; hit.m_damage.m_frost *= num2; hit.m_damage.m_lightning *= num2; hit.m_damage.m_poison *= num2; hit.m_damage.m_spirit *= num2; } } } [HarmonyPatch(typeof(Humanoid), "BlockAttack")] public static class SwordSkillTreeParryPatch { public static void Postfix(Character __instance, bool __result, HitData hit, Character attacker) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if (!__result) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !((Character)val).IsPlayer()) { return; } ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 1) { SkillTreeManager instance = SkillTreeManager.Instance; SEMan sEMan = ((Character)val).GetSEMan(); if (instance.GetSkillLevel("sword_counter") > 0) { SE_SwordCounter sE_SwordCounter = ScriptableObject.CreateInstance<SE_SwordCounter>(); ((StatusEffect)sE_SwordCounter).m_ttl = 5f; sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordCounter, true, 0, 0f); } if (instance.GetSkillLevel("sword_riposte") > 0) { SE_SwordRiposte sE_SwordRiposte = ScriptableObject.CreateInstance<SE_SwordRiposte>(); ((StatusEffect)sE_SwordRiposte).m_ttl = 5f; sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordRiposte, true, 0, 0f); } } } } [HarmonyPatch(typeof(Character), "Stagger")] public static class ParryRush_Stagger_Patch { public static void Postfix(Character __instance) { try { if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer()) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && Sword_Skill.IsParryRushActive(localPlayer) && ((Character)localPlayer).IsBlocking()) { Sword_Skill.OnParryRushTrigger(localPlayer, __instance); Log.LogInfo((object)"[패링 돌격] Stagger 감지 → 패링 돌격 발동"); } } } catch (Exception ex) { Log.LogError((object)("[패링 돌격] Stagger 패치 오류: " + ex.Message)); } } } public class SE_SwordCounter : StatusEffect { public SE_SwordCounter() { base.m_name = "칼날 되치기"; base.m_tooltip = "다음 공격의 피해량이 20% 증가합니다."; base.m_icon = null; base.m_ttl = 5f; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)skill == 1) { ((DamageTypes)(ref hitData.m_damage)).Modify(1.2f); base.m_character.GetSEMan().RemoveStatusEffect((StatusEffect)(object)this, true); } } } public class SE_SwordRiposte : StatusEffect { public SE_SwordRiposte() { base.m_name = "칼날 되치기"; base.m_tooltip = "다음 공격의 피해량이 20% 증가합니다."; base.m_icon = null; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class SwordRiposteDamagePatch { private static readonly int SwordCounterHash = Animator.StringToHash("칼날 되치기"); private static readonly int SwordRiposteHash = Animator.StringToHash("반격 자세"); private static void Prefix(Character __instance, HitData hit) { try { if (hit == null) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && (Object)(object)val != (Object)null) { SEMan sEMan = ((Character)val).GetSEMan(); if (sEMan != null && sEMan.HaveStatusEffect(SwordRiposteHash)) { hit.m_damage.m_blunt *= 1.2f; hit.m_damage.m_slash *= 1.2f; hit.m_damage.m_pierce *= 1.2f; sEMan.RemoveStatusEffect(SwordRiposteHash, false); } } } catch (Exception ex) { Log.LogError((object)("[반격 자세] ApplyDamage 패치 오류: " + ex.Message)); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class InventoryHidePatch { public static void Postfix() { try { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(false); } } catch (Exception ex) { Log.LogError((object)("[스킬트리] InventoryHidePatch 오류: " + ex.Message)); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryShowIconPositionPatch { private static bool _iconPositionAdjusted; public static void Postfix(InventoryGui __instance) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)skillTreeIconObj == (Object)null) { return; } skillTreeIconObj.SetActive(true); if (!EpicMMOReflectionHelper.IsInitialized) { EpicMMOReflectionHelper.Initialize(); } if (EpicMMOReflectionHelper.IsAvailable || _iconPositionAdjusted) { return; } RectTransform component = skillTreeIconObj.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { ((Transform)component).SetParent(((Component)componentInParent).transform, false); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 150f); component.sizeDelta = new Vector2(60f, 60f); _iconPositionAdjusted = true; } } } catch (Exception ex) { Log.LogError((object)("[스킬트리] 아이콘 위치 조정 실패: " + ex.Message)); } } } [HarmonyPatch(typeof(Hud), "Awake")] public static class HudAwakeHideIconPatch { [CompilerGenerated] private sealed class <DelayedHideIcon>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedHideIcon>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(false); Log.LogInfo((object)"[스킬트리] 아이콘 초기 숨김 완료 - 인벤토리(Tab) 열 때 표시됨"); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void Postfix() { ProducerEnchantUI.PreloadSprite(); if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(DelayedHideIcon()); } } [IteratorStateMachine(typeof(<DelayedHideIcon>d__1))] private static IEnumerator DelayedHideIcon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedHideIcon>d__1(0); } } [HarmonyPatch(typeof(ZNet), "Awake")] public static class ZNet_Awake_Patch { private static void Postfix() { SkillTreeConfig.DetectServerClientMode(); InitializeServerSync(); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class ZNet_OnNewConnection_Patch { [CompilerGenerated] private sealed class <DelayedConfigBroadcast>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedConfigBroadcast>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; SkillTreeConfig.BroadcastConfigToClients(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static void Postfix(ZNet __instance) { if (__instance.IsServer()) { ((MonoBehaviour)__instance).StartCoroutine(DelayedConfigBroadcast()); } } [IteratorStateMachine(typeof(<DelayedConfigBroadcast>d__1))] private static IEnumerator DelayedConfigBroadcast() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedConfigBroadcast>d__1(0); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] public static class Terminal_InitTerminal_Patch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; public static ConsoleEvent <>9__0_3; public static ConsoleEvent <>9__0_4; public static ConsoleEvent <>9__0_5; public static ConsoleEvent <>9__0_6; public static ConsoleEvent <>9__0_7; public static ConsoleEvent <>9__0_8; public static ConsoleEvent <>9__0_9; public static ConsoleEvent <>9__0_10; public static ConsoleEvent <>9__0_11; public static ConsoleEvent <>9__0_12; public static ConsoleEvent <>9__0_13; public static ConsoleEvent <>9__0_14; public static ConsoleEvent <>9__0_15; public static ConsoleEvent <>9__0_16; public static ConsoleEvent <>9__0_17; public static ConsoleEvent <>9__0_18; public static ConsoleEvent <>9__0_19; internal void <Postfix>b__0_0(ConsoleEventArgs args) { SetAttackConfig("AttackRootDamageBonus", args); } internal void <Postfix>b__0_1(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusChance", args); } internal void <Postfix>b__0_2(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusDamage", args); } internal void <Postfix>b__0_3(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusChance", args); } internal void <Postfix>b__0_4(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusDamage", args); } internal void <Postfix>b__0_5(ConsoleEventArgs args) { SetSpeedConfig("Speed_Expert_MoveSpeed", args); } internal void <Postfix>b__0_6(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step1_DodgeSpeed", args); } internal void <Postfix>b__0_7(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_MeleeComboBonus", args); } internal void <Postfix>b__0_8(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_BowHitBonus", args); } internal void <Postfix>b__0_9(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step8_MeleeAttackSpeed", args); } internal void <Postfix>b__0_10(ConsoleEventArgs args) { SkillTreeConfig.ReloadAndBroadcast(); } internal void <Postfix>b__0_11(ConsoleEventArgs args) { ShowCurrentConfig(); } internal void <Postfix>b__0_12(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowCount", args); } internal void <Postfix>b__0_13(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowConsumption", args); } internal void <Postfix>b__0_14(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_DamagePercent", args); } internal void <Postfix>b__0_15(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv1_Chance", args); } internal void <Postfix>b__0_16(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv2_Chance", args); } internal void <Postfix>b__0_17(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowCount", args); } internal void <Postfix>b__0_18(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowConsumption", args); } internal void <Postfix>b__0_19(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_DamagePercent", args); } } private static void Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Expected O, but got Unknown //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Expected O, but got Unknown //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Expected O, but got Unknown //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Expected O, but got Unknown //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Expected O, but got Unknown //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackRootDamageBonus", args); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("skilltree_attack_root", "공격 전문가 루트 데미지 보너스 설정 (예: skilltree_attack_root 7)", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusChance", args); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("skilltree_melee_chance", "근접 특화 발동 확률 설정 (예: skilltree_melee_chance 25)", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusDamage", args); }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } new ConsoleCommand("skilltree_melee_damage", "근접 특화 피해량 설정 (예: skilltree_melee_damage 15)", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj4 = <>c.<>9__0_3; if (obj4 == null) { ConsoleEvent val4 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusChance", args); }; <>c.<>9__0_3 = val4; obj4 = (object)val4; } new ConsoleCommand("skilltree_bow_chance", "활 특화 발동 확률 설정 (예: skilltree_bow_chance 30)", (ConsoleEvent)obj4, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj5 = <>c.<>9__0_4; if (obj5 == null) { ConsoleEvent val5 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusDamage", args); }; <>c.<>9__0_4 = val5; obj5 = (object)val5; } new ConsoleCommand("skilltree_bow_damage", "활 특화 피해량 설정 (예: skilltree_bow_damage 18)", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj6 = <>c.<>9__0_5; if (obj6 == null) { ConsoleEvent val6 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Expert_MoveSpeed", args); }; <>c.<>9__0_5 = val6; obj6 = (object)val6; } new ConsoleCommand("skilltree_speed_root", "속도 전문가 루트 이동속도 설정 (예: skilltree_speed_root 5)", (ConsoleEvent)obj6, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj7 = <>c.<>9__0_6; if (obj7 == null) { ConsoleEvent val7 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step1_DodgeSpeed", args); }; <>c.<>9__0_6 = val7; obj7 = (object)val7; } new ConsoleCommand("skilltree_speed_dodge", "구르기 속도 보너스 설정 (예: skilltree_speed_dodge 15)", (ConsoleEvent)obj7, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj8 = <>c.<>9__0_7; if (obj8 == null) { ConsoleEvent val8 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_MeleeComboBonus", args); }; <>c.<>9__0_7 = val8; obj8 = (object)val8; } new ConsoleCommand("skilltree_speed_melee_combo", "근접 콤보 이동속도 설정 (예: skilltree_speed_melee_combo 6)", (ConsoleEvent)obj8, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj9 = <>c.<>9__0_8; if (obj9 == null) { ConsoleEvent val9 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_BowHitBonus", args); }; <>c.<>9__0_8 = val9; obj9 = (object)val9; } new ConsoleCommand("skilltree_speed_bow_hit", "활 적중 이동속도 설정 (예: skilltree_speed_bow_hit 8)", (ConsoleEvent)obj9, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj10 = <>c.<>9__0_9; if (obj10 == null) { ConsoleEvent val10 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step8_MeleeAttackSpeed", args); }; <>c.<>9__0_9 = val10; obj10 = (object)val10; } new ConsoleCommand("skilltree_speed_attack", "공격속도 증가 설정 (예: skilltree_speed_attack 10)", (ConsoleEvent)obj10, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj11 = <>c.<>9__0_10; if (obj11 == null) { ConsoleEvent val11 = delegate { SkillTreeConfig.ReloadAndBroadcast(); }; <>c.<>9__0_10 = val11; obj11 = (object)val11; } new ConsoleCommand("skilltree_config_reload", "설정 리로드 및 재전송", (ConsoleEvent)obj11, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj12 = <>c.<>9__0_11; if (obj12 == null) { ConsoleEvent val12 = delegate { ShowCurrentConfig(); }; <>c.<>9__0_11 = val12; obj12 = (object)val12; } new ConsoleCommand("skilltree_config_show", "현재 설정 표시", (ConsoleEvent)obj12, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj13 = <>c.<>9__0_12; if (obj13 == null) { ConsoleEvent val13 = delegate(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowCount", args); }; <>c.<>9__0_12 = val13; obj13 = (object)val13; } new ConsoleCommand("skilltree_archer_arrows", "아처 멀티샷 화살 수 설정 (예: skilltree_archer_arrows 7)", (ConsoleEvent)obj13, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj14 = <>c.<>9__0_13; if (obj14 == null) { ConsoleEvent val14 = delegate(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowConsumption", args); }; <>c.<>9__0_13 = val14; obj14 = (object)val14; } new ConsoleCommand("skilltree_archer_consume", "아처 멀티샷 화살 소모량 설정 (예: skilltree_archer_consume 2)", (ConsoleEvent)obj14, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj15 = <>c.<>9__0_14; if (obj15 == null) { ConsoleEvent val15 = delegate(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_DamagePercent", args); }; <>c.<>9__0_14 = val15; obj15 = (object)val15; } new ConsoleCommand("skilltree_archer_damage", "아처 멀티샷 데미지 비율 설정 (예: skilltree_archer_damage 80)", (ConsoleEvent)obj15, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj16 = <>c.<>9__0_15; if (obj16 == null) { ConsoleEvent val16 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv1_Chance", args); }; <>c.<>9__0_15 = val16; obj16 = (object)val16; } new ConsoleCommand("skilltree_bow_lv1_chance", "활 전문가 멀티샷 Lv1 확률 설정 (예: skilltree_bow_lv1_chance 15)", (ConsoleEvent)obj16, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj17 = <>c.<>9__0_16; if (obj17 == null) { ConsoleEvent val17 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv2_Chance", args); }; <>c.<>9__0_16 = val17; obj17 = (object)val17; } new ConsoleCommand("skilltree_bow_lv2_chance", "활 전문가 멀티샷 Lv2 확률 설정 (예: skilltree_bow_lv2_chance 36)", (ConsoleEvent)obj17, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj18 = <>c.<>9__0_17; if (obj18 == null) { ConsoleEvent val18 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowCount", args); }; <>c.<>9__0_17 = val18; obj18 = (object)val18; } new ConsoleCommand("skilltree_bow_arrows", "활 전문가 멀티샷 화살 수 설정 (예: skilltree_bow_arrows 2)", (ConsoleEvent)obj18, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj19 = <>c.<>9__0_18; if (obj19 == null) { ConsoleEvent val19 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowConsumption", args); }; <>c.<>9__0_18 = val19; obj19 = (object)val19; } new ConsoleCommand("skilltree_bow_consume", "활 전문가 멀티샷 화살 소모량 설정 (예: skilltree_bow_consume 0)", (ConsoleEvent)obj19, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj20 = <>c.<>9__0_19; if (obj20 == null) { ConsoleEvent val20 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_DamagePercent", args); }; <>c.<>9__0_19 = val20; obj20 = (object)val20; } new ConsoleCommand("skilltree_bow_damage", "활 전문가 멀티샷 데미지 비율 설정 (예: skilltree_bow_damage 70)", (ConsoleEvent)obj20, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } [HarmonyPatch(typeof(Player), "OnDestroy")] public static class Plugin_Player_OnDestroy_DamagePatch_Cleanup { private static void Postfix(Player __instance) { try { NerveEnhancementSystem.Damage_Patch.CleanupPlayerData(__instance); } catch { } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__47_0; internal void <SetupIconClickEvent>b__47_0() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!"); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled) { SkillTreeBGMManager.Instance.PlaySkillTreeBGM(); } else if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { Log.LogInfo((object)"[BGM] BGM이 비활성화되어 있어 재생하지 않음"); } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Debug.LogWarning((object)"[스킬트리] InventoryGui.instance를 찾을 수 없음"); return; } Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>(); if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || (Object)(object)skillTreeUI.panel.transform.parent != (Object)(object)((Component)componentInChildren).transform) { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null) { Object.Destroy((Object)(object)skillTreeUI.panel); } GameObject val = new GameObject("SkillTreeUI"); val.transform.SetParent(((Component)componentInChildren).transform, false); skillTreeUI = val.AddComponent<SkillTreeUI>(); skillTreeUI.CreateUI(componentInChildren); } if (!skillTreeUI.panel.activeSelf) { skillTreeUI.RefreshUI(); skillTreeUI.panel.SetActive(true); return; } skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } } [CompilerGenerated] private sealed class <Start>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Plugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Start>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: { <>1__state = -1; ConfigEntry<string> languageConfig = LocalizationManager.LanguageConfig; if (languageConfig != null && (languageConfig.Value?.Equals("Auto", StringComparison.OrdinalIgnoreCase)).GetValueOrDefault()) { LocalizationManager.ReloadLanguage(); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static ManualLogSource Log; private static GameObject skillTreeIconObj; private static Sprite swordIcon; private static AssetBundle iconAssetBundle; private static AssetBundle uiAssetBundle; private static AssetBundle customIconBundle; private static AssetBundle jobIconBundle; private static AssetBundle vfxBundle; private static AssetBundle jobVfxBundle; public static int SkillTreePoint = 0; private static SkillTreeUI skillTreeUI; private static Sprite customSkillTreeIcon; private static Plugin? _instance; private static bool _coreSystemsInitialized = false; private static bool _emergencyMode = false; private static int _iconCreationAttempts = 0; private const int MAX_ICON_ATTEMPTS = 5; private static Type _cachedMmoType = null; private static bool _mmoTypeChecked = false; private static readonly bool _earlyUserBackup = CreateEarlyUserBackup(); public static bool IsSkillTreeOpen => (Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf; public static Plugin? Instance => _instance; private void Awake() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _instance = this; string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string path = Path.ChangeExtension(configFilePath, ".version"); string contents = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString(); File.WriteAllText(path, contents); CaptainLevelConfig.Bind(((BaseUnityPlugin)this).Config); Log.LogDebug((object)"[Captain Level System] Config 바인딩 완료"); SkillTreeConfig.Initialize(((BaseUnityPlugin)this).Config); LocalizationManager.Initialize(((BaseUnityPlugin)this).Config); Log.LogInfo((object)"[Plugin] ✓ 로컬라이제이션 시스템 초기화 완료"); Staff_Config.InitConfig(((BaseUnityPlugin)this).Config); CaptainMMOBridge.Initialize(); InitializeCoreSafeguards(); Harmony val = new Harmony("CaptainSkillTree.Mod"); Log.LogInfo((object)"========== Captain SkillTree 초기화 중... =========="); try { val.PatchAll(); Log.LogInfo((object)("========== Captain SkillTree 초기화 완료! (MMO: " + (EpicMMOReflectionHelper.IsAvailable ? "연동" : "독립") + ") ==========")); Log.LogDebug((object)"[Harmony] 패치 등록 완료"); } catch (Exception ex) { Log.LogError((object)("=== [CRITICAL] Harmony.PatchAll() 실패: " + ex.Message + " ===")); Log.LogError((object)("=== [CRITICAL] StackTrace: " + ex.StackTrace + " ===")); } InitializeInputListener(); SkillTreeData.RegisterAll(); SafeLoadCustomIcon(); InitializeBGMSystem(); InitializePrefabSystem(); GameObject val2 = new GameObject("ActiveSkillHUD"); val2.AddComponent<ActiveSkillHUD>(); Object.DontDestroyOnLoad((Object)(object)val2); RegisterJotunnCommands(); _coreSystemsInitialized = true; try { Type type = typeof(BaseUnityPlugin).Assembly.GetType("BepInEx.ConsoleManager"); MethodInfo methodInfo = type?.GetMethod("SetConsoleColor", BindingFlags.Static | BindingFlags.Public); TextWriter textWriter = type?.GetProperty("StandardOutStream", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as TextWriter; if (methodInfo != null && textWriter != null) { methodInfo.Invoke(null, new object[1] { ConsoleColor.Cyan }); textWriter.WriteLine("================================ Captain SkillTree Mod Load Success ================================"); textWriter.WriteLine(" === == === ==== == ==== = ="); textWriter.WriteLine(" = = = = = == = = == == ="); textWriter.WriteLine(" = ==== === == ==== == = =="); textWriter.WriteLine(" = = = = == = = == = ="); textWriter.WriteLine(" === = = = == = = ==== = ="); textWriter.WriteLine(""); textWriter.WriteLine(" === = = ==== = = ==== === ==== ===="); textWriter.WriteLine(" = = = == = = == = = = = "); textWriter.WriteLine(" === == == = = == === === === "); textWriter.WriteLine(" = = = == = = == = = = = "); textWriter.WriteLine(" === = = ==== ==== ==== == = = ==== ===="); textWriter.WriteLine("================================ Captain SkillTree Mod Load Success ================================"); methodInfo.Invoke(null, new object[1] { ConsoleColor.Gray }); } else { Log.LogMessage((object)"================================ Captain SkillTree Mod Load Success ================================"); } } catch { Log.LogMessage((object)"================================ Captain SkillTree Mod Load Success ================================"); } } [IteratorStateMachine(typeof(<Start>d__24))] private IEnumerator Start() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Start>d__24(0) { <>4__this = this }; } private void RegisterJotunnCommands() { try { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkillAddConsoleCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkillResetConsoleCommand()); Log.LogInfo((object)"[Jotunn] 콘솔 명령어 등록 완료: skilladd, skillreset"); } catch (Exception ex) { Log.LogError((object)("[Jotunn] 콘솔 명령어 등록 실패: " + ex.Message)); } } private static void InitializeCoreSafeguards() { try { if (!_coreSystemsInitialized) { ValidateEssentialResources(); } } catch (Exception ex) { Log.LogError((object)("[안전 장치] 초기화 실패: " + ex.Message)); _emergencyMode = true; } } private static void InitializeInputListener() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown try { if ((Object)(object)SkillTreeInputListener.Instance == (Object)null) { GameObject val = new GameObject("SkillTreeInputListener"); val.AddComponent<SkillTreeInputListener>(); Object.DontDestroyOnLoad((Object)(object)val); } } catch (Exception ex) { Log.LogError((object)("[안전 장치] InputListener 초기화 실패: " + ex.Message)); } } private static void ValidateEssentialResources() { string[] array = new string[4] { "CaptainSkillTree.asset.Resources.skill_node", "CaptainSkillTree.asset.Resources.captainskilltreeui", "CaptainSkillTree.asset.Resources.skill_start", "CaptainSkillTree.asset.Resources.job_icon" }; string[] array2 = array; foreach (string text in array2) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream(text); if (manifestResourceStream == null) { throw new Exception("필수 리소스 누락: " + text); } manifestResourceStream.Close(); } ResetEmergencyMode(); } private static void ResetEmergencyMode() { _emergencyMode = false; _iconCreationAttempts = 0; } private static void SafeLoadCustomIcon() { try { Log.LogDebug((object)"[아이콘] 커스텀 아이콘 로드 시작"); AssetBundle val = GetJobIconBundle(); if ((Object)(object)val != (Object)null) { Log.LogDebug((object)"[아이콘] job_icon 번들 로드 성공"); string[] array = new string[12] { "Paladin_unlock", "Tanker_unlock", "Berserker_unlock", "Archer_unlock", "Mage_unlock", "Rogue_unlock", "Paladin", "Tanker", "Berserker", "Archer", "Mage", "Rogue" }; string[] array2 = array; foreach (string text in array2) { Sprite val2 = val.LoadAsset<Sprite>(text); if ((Object)(object)val2 != (Object)null) { Log.LogDebug((object)("[아이콘] job_icon에서 " + text + " 로드 성공: " + ((Object)val2).name)); } } } AssetBundle val3 = GetCustomIconBundle(); if ((Object)(object)val3 != (Object)null) { Log.LogDebug((object)"[아이콘] 커스텀 아이콘 번들 로드 성공"); string[] allAssetNames = val3.GetAllAssetNames(); Log.LogDebug((object)$"[아이콘] 번들 에셋 수: {allAssetNames.Length}"); string[] array3 = allAssetNames; foreach (string text2 in array3) { Log.LogDebug((object)("[아이콘] 번들 에셋: " + text2)); } customSkillTreeIcon = val3.LoadAsset<Sprite>("skill_start"); if ((Object)(object)customSkillTreeIcon != (Object)null) { Log.LogDebug((object)"[아이콘] skill_start 스프라이트 로드 성공"); } else { TryAlternativeIconNames(val3); } } } catch (Exception ex) { Log.LogError((object)("[아이콘] 커스텀 아이콘 로드 중 오류: " + ex.Message)); Log.LogError((object)("[아이콘] StackTrace: " + ex.StackTrace)); } } private static void TryAlternativeIconNames(AssetBundle bundle) { string[] array = new string[7] { "skill_start", "SkillStart", "skill_tree_start", "captainskilltreeicon", "CaptainSkillTreeIcon", "SkillTreeIcon", "skilltreeicon" }; string[] array2 = array; foreach (string text in array2) { Sprite val = bundle.LoadAsset<Sprite>(text); if ((Object)(object)val != (Object)null) { customSkillTreeIcon = val; Log.LogDebug((object)("[아이콘] 대체 이름으로 아이콘 로드 성공: " + text)); return; } } Log.LogWarning((object)"[아이콘] 모든 아이콘 이름 시도 실패 - 게임 기본 아이콘 사용"); } public static AssetBundle GetIconAssetBundle() { if ((Object)(object)iconAssetBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.skill_node"); if (manifestResourceStream != null) { iconAssetBundle = AssetBundle.LoadFromStream(manifestResourceStream); } } return iconAssetBundle; } public static AssetBundle GetUIAssetBundle() { if ((Object)(object)uiAssetBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.captainskilltreeui"); if (manifestResourceStream != null) { uiAssetBundle = AssetBundle.LoadFromStream(manifestResourceStream); } } return uiAssetBundle; } public static AssetBundle GetCustomIconBundle() { if ((Object)(object)customIconBundle == (Object)null) { try { Assembly assembly = typeof(Plugin).Assembly; Log.LogDebug((object)("[번들] Assembly: " + assembly.FullName)); string[] manifestResourceNames = assembly.GetManifestResourceNames(); Log.LogDebug((object)$"[번들] 사용 가능한 리소스 수: {manifestResourceNames.Length}"); bool flag = false; string[] array = manifestResourceNames; foreach (string text in array) { Log.LogDebug((object)("[번들] 리소스: " + text)); if (text.Contains("skill_start")) { flag = true; Log.LogDebug((object)("[번들] 시작 아이콘 리소스 발견: " + text)); } } if (!flag) { Log.LogError((object)"[번들] skill_start 리소스가 DLL에 포함되지 않음!"); } Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.skill_start"); if (manifestResourceStream != null) { Log.LogDebug((object)$"[번들] 스트림 로드 성공, 크기: {manifestResourceStream.Length} bytes"); customIconBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)customIconBundle != (Object)null) { Log.LogDebug((object)"[번들] AssetBundle 로드 성공"); } else { Log.LogError((object)"[번들] AssetBundle.LoadFromStream 실패"); } } else { Log.LogError((object)"[번들] 리소스 스트림이 null"); } } catch (Exception ex) { Log.LogError((object)("[번들] GetCustomIconBundle 오류: " + ex.Message)); } } return customIconBundle; } public static AssetBundle GetJobIconBundle() { if ((Object)(object)jobIconBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.job_icon"); if (manifestResourceStream != null) { jobIconBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)jobIconBundle != (Object)null) { Log.LogDebug((object)"[아이콘] job_icon 번들 로드 성공"); string[] allAssetNames = jobIconBundle.GetAllAssetNames(); Log.LogDebug((object)$"[아이콘] job_icon 번들 에셋 수: {allAssetNames.Length}"); string[] array = allAssetNames; foreach (string text in array) { Log.LogDebug((object)("[아이콘] job_icon 에셋: " + text)); } } else { Log.LogError((object)"[아이콘] job_icon AssetBundle.LoadFromStream 실패"); } } else { Log.LogWarning((object)"[아이콘] job_icon 리소스 스트림이 null"); } } return jobIconBundle; } public static AssetBundle GetVfxBundle() { if ((Object)(object)vfxBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.VFX.vfxbundle"); if (manifestResourceStream != null) { vfxBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)vfxBundle != (Object)null) { Log.LogDebug((object)"[VFX] VFX 폴더에서 vfxbundle 번들 로드 성공"); } else { Log.LogError((object)"[VFX] VFX 폴더에서 vfxbundle 번들 로드 실패"); } } else { Log.LogError((object)"[VFX] VFX 폴더에서 vfxbundle 리소스 스트림을 찾을 수 없음"); } } return vfxBundle; } public static AssetBundle GetJobVfxBundle() { if ((Object)(object)jobVfxBundle == (Object)null) { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream("CaptainSkillTree.asset.Resources.job_vfx"); if (manifestResourceStream != null) { jobVfxBundle = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)jobVfxBundle != (Object)null) { Log.LogDebug((object)"[VFX] job_vfx 번들 로드 성공"); } else { Log.LogError((object)"[VFX] job_vfx 번들 로드 실패"); } } else { Log.LogError((object)"[VFX] job_vfx 리소스 스트림을 찾을 수 없음"); } } return jobVfxBundle; } public static T LoadEmbeddedAsset<T>(string resourcePath) where T : Object { try { Assembly assembly = typeof(Plugin).Assembly; Stream manifestResourceStream = assembly.GetManifestResourceStream(resourcePath); if (manifestResourceStream == null) { Log.LogWarning((object)("[LoadEmbeddedAsset] 리소스를 찾을 수 없음: " + resourcePath)); return default(T); } AssetBundle val = AssetBundle.LoadFromStream(manifestResourceStream); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)("[LoadEmbeddedAsset] AssetBundle 로드 실패: " + resourcePath)); manifestResourceStream.Close(); return default(T); } T[] array = val.LoadAllAssets<T>(); if (array.Length != 0) { T val2 = array[0]; Log.LogInfo((object)("[LoadEmbeddedAsset] 에셋 로드 성공: " + resourcePath + " -> " + ((Object)val2).name)); return val2; } Log.LogWarning((object)("[LoadEmbeddedAsset] " + typeof(T).Name + " 타입의 에셋을 찾을 수 없음: " + resourcePath)); val.Unload(false); manifestResourceStream.Close(); return default(T); } catch (Exception ex) { Log.LogError((object)("[LoadEmbeddedAsset] 에셋 로드 오류: " + resourcePath + " - " + ex.Message)); return default(T); } } private static void ShowSkillTreeIcon() { if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(true); return; } if (_emergencyMode || _iconCreationAttempts >= 5) { Log.LogWarning((object)"[안전 장치] 비상 모드 또는 최대 시도 횟수 초과 - 아이콘 생성 건너뛰기"); return; } try { if (!ValidatePrerequisites()) { Log.LogWarning((object)"[안전 장치] 전제 조건 미충족 - 아이콘 생성 연기"); return; } if (!_mmoTypeChecked) { _cachedMmoType = Type.GetType("EpicMMOSystem.MyUI, EpicMMOSystem"); _mmoTypeChecked = true; } Type cachedMmoType = _cachedMmoType; if (cachedMmoType != null && TryCreateMMOStyleIcon()) { ResetIconAttempts(); } else { CreateFallbackSkillTreeIcon(); } } catch (Exception ex) { _iconCreationAttempts++; Log.LogError((object)$"[안전 장치] SkillTreeIcon 생성 중 예외 (시도 {_iconCreationAttempts}/{5}): {ex.Message}"); Log.LogError((object)("[안전 장치] StackTrace: " + ex.StackTrace)); if (_iconCreationAttempts < 5) { try { CreateFallbackSkillTreeIcon(); return; } catch (Exception ex2) { Log.LogError((object)("[안전 장치] 대체 아이콘 생성도 실패: " + ex2.Message)); return; } } Log.LogError((object)"[안전 장치] 최대 시도 횟수 도달 - 비상 모드 활성화"); _emergencyMode = true; } } private static bool ValidatePrerequisites() { try { if ((Object)(object)Player.m_localPlayer == (Object)null) { Log.LogDebug((object)"[안전 장치] Player가 아직 로드되지 않음"); return false; } if ((Object)(object)InventoryGui.instance == (Object)null) { Log.LogDebug((object)"[안전 장치] InventoryGui가 아직 준비되지 않음"); return false; } if ((Object)(object)GetCustomIconBundle() == (Object)null && (Object)(object)swordIcon == (Object)null) { Log.LogWarning((object)"[안전 장치] 아이콘 리소스가 준비되지 않음 - 로드 시도"); SafeLoadCustomIcon(); LoadGameDefaultIcon(); } return true; } catch (Exception ex) { Log.LogError((object)("[안전 장치] 전제 조건 검증 실패: " + ex.Message)); return false; } } private static void LoadGameDefaultIcon() { try { if (!((Object)(object)swordIcon == (Object)null) || !((Object)(object)ObjectDB.instance != (Object)null)) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { swordIcon = component.m_itemData.GetIcon(); Log.LogDebug((object)"[안전 장치] 게임 기본 아이콘 로드 성공"); } } } catch (Exception) { } } private static void ResetIconAttempts() { _iconCreationAttempts = 0; } private static bool TryCreateMMOStyleIcon() { //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown try { Type cachedMmoType = _cachedMmoType; if (cachedMmoType == null) { Log.LogWarning((object)"EpicMMOSystem.MyUI 타입을 찾을 수 없음"); return false; } FieldInfo field = cachedMmoType.GetField("navigationPanel", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { Log.LogWarning((object)"navigationPanel 필드를 찾을 수 없음"); return false; } object? value = field.GetValue(null); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"navigationPanel이 null"); return false; } Transform val2 = val.transform.Find("Buttons"); if ((Object)(object)val2 == (Object)null) { Log.LogWarning((object)"Buttons 오브젝트를 찾을 수 없음"); return false; } Transform val3 = val2.Find("ButtonSkillTree"); if ((Object)(object)val3 != (Object)null) { skillTreeIconObj = ((Component)val3).gameObject; skillTreeIconObj.SetActive(true); return true; } Transform val4 = val2.Find("ButtonLevelSystem"); if ((Object)(object)val4 == (Object)null) { Log.LogWarning((object)"ButtonLevelSystem 오브젝트를 찾을 수 없음"); return false; } skillTreeIconObj = Object.Instantiate<GameObject>(((Component)val4).gameObject, val2); ((Object)skillTreeIconObj).name = "ButtonSkillTree"; Image val5 = skillTreeIconObj.GetComponent<Image>(); if ((Object)(object)val5 == (Object)null) { val5 = skillTreeIconObj.GetComponentInChildren<Image>(); } if ((Object)(object)customSkillTreeIcon != (Object)null) { val5.sprite = customSkillTreeIcon; } else { if ((Object)(object)swordIcon == (Object)null) { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { Log.LogWarning((object)"ObjectDB.instance가 null"); return false; } GameObject itemPrefab = instance.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab == (Object)null) { Log.LogWarning((object)"SwordIron 프리팹을 찾을 수 없음"); return false; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Log.LogWarning((object)"SwordIron에 ItemDrop 컴포넌트가 없음"); return false; } swordIcon = component.m_itemData.GetIcon(); if ((Object)(object)swordIcon == (Object)null) { Log.LogWarning((object)"SwordIron 아이콘(Sprite)을 찾을 수 없음"); return false; } } val5.sprite = swordIcon; } RectTransform component2 = skillTreeIconObj.GetComponent<RectTransform>(); RectTransform component3 = ((Component)val4).GetComponent<RectTransform>(); component2.anchoredPosition = component3.anchoredPosition + new Vector2(80f, 0f); component2.sizeDelta = component3.sizeDelta; component2.anchorMin = component3.anchorMin; component2.anchorMax = component3.anchorMax; component2.pivot = component3.pivot; ((Transform)component2).localScale = ((Transform)component3).localScale; foreach (Transform item in skillTreeIconObj.transform) { Transform val6 = item; if ((Object)(object)((Component)val6).GetComponent<Image>() == (Object)null) { ((Component)val6).gameObject.SetActive(false); } } SetupIconClickEvent(); Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { Log.LogDebug((object)$"[시작 아이콘] 부모 Canvas sortingOrder: {componentInParent.sortingOrder}"); } skillTreeIconObj.SetActive(true); Log.LogDebug((object)"[시작 아이콘] 아이콘 생성 및 활성화 완료"); return true; } catch (Exception ex) { Log.LogWarning((object)("아이콘 생성 실패: " + ex.Message)); return false; } } private static void CreateFallbackSkillTreeIcon() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Log.LogWarning((object)"[디버그] InventoryGui.instance가 null, 아이콘 생성 불가"); return; } Log.LogInfo((object)"[디버그] InventoryGui 인스턴스 확인됨"); if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(true); Log.LogDebug((object)"기존 대체 아이콘 활성화"); return; } try { Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>(); if ((Object)(object)componentInChildren == (Object)null) { Log.LogWarning((object)"InventoryGui에서 Canvas를 찾을 수 없음"); return; } Transform val = ((Component)componentInChildren).transform.Find("Player"); if ((Object)(object)val == (Object)null) { val = ((Component)componentInChildren).transform; } GameObject val2 = new GameObject("ButtonSkillTree_Fallback"); val2.transform.SetParent(val, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = new Vector2(0.5f, 0f); val3.anchorMax = new Vector2(0.5f, 0f); val3.pivot = new Vector2(0.5f, 0f); val3.anchoredPosition = new Vector2(100f, 10f); val3.sizeDelta = new Vector2(60f, 60f); Image val4 = val2.AddComponent<Image>(); if ((Object)(object)customSkillTreeIcon != (Object)null) { val4.sprite = customSkillTreeIcon; } else { if ((Object)(object)swordIcon == (Object)null) { ObjectDB instance2 = ObjectDB.instance; if ((Object)(object)instance2 != (Object)null) { GameObject itemPrefab = instance2.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { swordIcon = component.m_itemData.GetIcon(); } } } } val4.sprite = swordIcon; } if ((Object)(object)val4.sprite == (Object)null) { ((Graphic)val4).color = new Color(0.2f, 0.6f, 1f, 0.8f); Log.LogInfo((object)"스프라이트가 없어 단색으로 표시"); } Button val5 = val2.AddComponent<Button>(); ((Selectable)val5).targetGraphic = (Graphic)(object)val4; skillTreeIconObj = val2; SetupIconClickEvent(); Canvas componentInParent = skillTreeIconObj.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { Log.LogDebug((object)$"[대체 아이콘] 부모 Canvas sortingOrder: {componentInParent.sortingOrder}"); } skillTreeIconObj.SetActive(true); Log.LogDebug((object)"아이콘 생성 성공"); } catch (Exception ex) { Log.LogError((object)("대체 아이콘 생성 실패: " + ex.Message)); } } private static void SetupIconSprite(Image image) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) bool flag = false; try { SafeLoadCustomIcon(); if ((Object)(object)customSkillTreeIcon != (Object)null) { image.sprite = customSkillTreeIcon; ((Graphic)image).color = Color.white; flag = true; Log.LogDebug((object)"[아이콘] 커스텀 아이콘 적용 성공"); } } catch (Exception ex) { Log.LogDebug((object)("[아이콘] 커스텀 아이콘 로드 실패: " + ex.Message)); } if (!flag) { try { if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { Sprite icon = component.m_itemData.GetIcon(); if ((Object)(object)icon != (Object)null) { image.sprite = icon; ((Graphic)image).color = Color.white; flag = true; Log.LogDebug((object)"[아이콘] 게임 기본 아이콘(검) 적용 성공"); } } } } } catch (Exception ex2) { Log.LogDebug((object)("[아이콘] 기본 아이콘 로드 실패: " + ex2.Message)); } } if (!flag && (Object)(object)((Component)image).transform.parent != (Object)null) { GameObject val = new GameObject("IconText"); val.transform.SetParent(((Component)image).transform.parent, false); Text val2 = val.AddComponent<Text>(); val2.text = "스킬\n트리"; val2.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); val2.fontSize = 14; ((Graphic)val2).color = Color.white; val2.alignment = (TextAnchor)4; RectTransform component2 = ((Component)val2).GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; } } private static void SetupIconClickEvent() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown Button val = skillTreeIconObj.GetComponent<Button>() ?? skillTreeIconObj.AddComponent<Button>(); ((Selectable)val).interactable = true; Image component = skillTreeIconObj.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).raycastTarget = true; } ((UnityEventBase)val.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = val.onClick; object obj = <>c.<>9__47_0; if (obj == null) { UnityAction val2 = delegate { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown Log.LogDebug((object)"[시작 아이콘] 클릭 이벤트 감지됨!"); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null && SkillTreeBGMManager.Instance.IsBGMEnabled) { SkillTreeBGMManager.Instance.PlaySkillTreeBGM(); } else if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { Log.LogInfo((object)"[BGM] BGM이 비활성화되어 있어 재생하지 않음"); } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { Debug.LogWarning((object)"[스킬트리] InventoryGui.instance를 찾을 수 없음"); } else { Canvas componentInChildren = ((Component)instance).GetComponentInChildren<Canvas>(); if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || (Object)(object)skillTreeUI.panel.transform.parent != (Object)(object)((Component)componentInChildren).transform) { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null) { Object.Destroy((Object)(object)skillTreeUI.panel); } GameObject val3 = new GameObject("SkillTreeUI"); val3.transform.SetParent(((Component)componentInChildren).transform, false); skillTreeUI = val3.AddComponent<SkillTreeUI>(); skillTreeUI.CreateUI(componentInChildren); } if (!skillTreeUI.panel.activeSelf) { skillTreeUI.RefreshUI(); skillTreeUI.panel.SetActive(true); } else { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } } }; <>c.<>9__47_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } private void OnGUI() { try { SkillTreeManager.Instance.OnGUIShowMessage(); } catch (Exception ex) { Log.LogWarning((object)("OnGUI 메시지 표시 중 오류: " + ex.Message)); } } private static void InitializeBGMSystem() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown try { GameObject val = new GameObject("SkillTreeBGMManager"); val.AddComponent<SkillTreeBGMManager>(); Object.DontDestroyOnLoad((Object)(object)val); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.Initialize(); Log.LogDebug((object)"[BGM] 스킬트리 BGM 시스템 초기화 완료"); } else { Log.LogWarning((object)"[BGM] SkillTreeBGMManager.Instance가 null"); } } catch (Exception ex) { Log.LogError((object)("[BGM] 초기화 실패: " + ex.Message)); } } private static void InitializePrefabSystem() { try { PrefabRegistry.Initialize(); } catch (Exception ex) { Log.LogError((object)("[프리팹] 초기화 실패: " + ex.Message)); } } private static bool CreateEarlyUserBackup() { try { string text = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg"); string text2 = Path.Combine(Paths.ConfigPath, "CaptainSkillTree"); string text3 = Path.Combine(text2, "User_CaptainSkillTree.SkillTreeMod.cfg"); if (!File.Exists(text3) && File.Exists(text)) { Directory.CreateDirectory(text2); File.Copy(text, text3, overwrite: false); } } catch { } return true; } internal static void InitializeServerSync() { if (ZRoutedRpc.instance != null) { try { ZRoutedRpc.instance.Register<string>("CaptainSkillTree.SkillTreeMod_ConfigSync", (Action<long, string>)RPC_ReceiveConfigSync); return; } catch (ArgumentException ex) { Log.LogWarning((object)("[서버 싱크] RPC가 이미