using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CaptainSkillTree.Audio; using CaptainSkillTree.Gui; using CaptainSkillTree.Localization; using CaptainSkillTree.MMO_System; using CaptainSkillTree.Mods; using CaptainSkillTree.Prefab; using CaptainSkillTree.SkillTree; using CaptainSkillTree.SkillTree.CriticalSystem; using CaptainSkillTree.VFX; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CaptainSkillTree")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CaptainSkillTree")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d1b6e7e2-1c2a-4b8a-9e2b-123456789abc")] [assembly: AssemblyFileVersion("1.22.65.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.22.65.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CaptainSkillTree { public static class DifficultyManager { private const string PRESET_DIR_NAME = "CaptainSkillTree"; private const string PRESET_NORMAL = "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"; private const string PRESET_VERYHARD = "Veryhard_CaptainSkillTree.SkillTreeMod.cfg"; private const string PRESET_USER = "User_CaptainSkillTree.SkillTreeMod.cfg"; private const string DIFF_VER_EXT = ".difficulty_ver"; private static bool _initialized = false; private static string _configFilePath = ""; private static FieldInfo _entriesField; private static bool _entriesFieldSearched; public static bool NeedsSelection { get; private set; } public static bool IsApplyingPreset { get; private set; } public static void InitializeIfNeeded() { if (!_initialized) { _initialized = true; Plugin? instance = Plugin.Instance; object obj; if (instance == null) { obj = null; } else { ConfigFile config = ((BaseUnityPlugin)instance).Config; obj = ((config != null) ? config.ConfigFilePath : null); } if (obj == null) { obj = Path.Combine(Paths.ConfigPath, "CaptainSkillTree.SkillTreeMod.cfg"); } _configFilePath = (string)obj; string path = Path.ChangeExtension(_configFilePath, ".version"); string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver"); string text = (File.Exists(path) ? File.ReadAllText(path).Trim() : ""); string text2 = (File.Exists(path2) ? File.ReadAllText(path2).Trim() : ""); EnsurePresetDirectory(); Application.quitting += SaveUserBackupOnQuit; if (string.IsNullOrEmpty(text2)) { NeedsSelection = true; } else if (text != text2) { ApplyVeryhardWithUserOverlay(); SaveUserBackupNow(); NeedsSelection = true; } else { NeedsSelection = false; } } } public static bool HasUserPreset() { return File.Exists(Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg")); } private static void ApplyVeryhardWithUserOverlay() { Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)"[Difficulty] ApplyVeryhardWithUserOverlay: Config가 null입니다."); } return; } Dictionary dictionary = new Dictionary(); foreach (KeyValuePair item in val) { dictionary[item.Key] = item.Value.GetSerializedValue(); } ApplyVeryHard(); HashSet hashSet = new HashSet { "Language", "Config_Schema_Version", "GameDifficulty", "EnableLiveConfigSync" }; bool saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; int num = 0; int num2 = 0; foreach (KeyValuePair item2 in dictionary) { if (hashSet.Contains(item2.Key.Key)) { num2++; continue; } ConfigEntryBase val2 = val[item2.Key]; if (val2 != null) { try { val2.SetSerializedValue(item2.Value); num++; } catch { } } } ConfigEntry gameDifficulty = SkillTreeConfig.GameDifficulty; if (gameDifficulty != null) { gameDifficulty.Value = "UserSettings"; } val.Save(); val.SaveOnConfigSet = saveOnConfigSet; } public static void ApplyNormal() { ApplyPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"); } public static void ApplyVeryHard() { ApplyPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg"); } public static void ApplyUser() { ApplyPreset("User_CaptainSkillTree.SkillTreeMod.cfg"); } private static void ApplyPreset(string presetFileName) { IsApplyingPreset = true; string text = Path.Combine(GetPresetDirectory(), presetFileName); if (File.Exists(text)) { try { File.Copy(text, _configFilePath, overwrite: true); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)("[Difficulty] 파일 복사 실패: " + ex.Message)); } } Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val != null) { bool saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; val.Reload(); int num = ApplyPresetValuesToConfig(text); string value = ((presetFileName == "Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg") ? "Vanilla" : ((presetFileName == "Veryhard_CaptainSkillTree.SkillTreeMod.cfg") ? "VeryHard" : "UserSettings")); ConfigEntry gameDifficulty = SkillTreeConfig.GameDifficulty; if (gameDifficulty != null) { gameDifficulty.Value = value; } val.Save(); val.SaveOnConfigSet = saveOnConfigSet; } } else { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] ⚠\ufe0f 프리셋 파일 없음: " + text + "\n → 현재 설정을 그대로 유지합니다.")); } } SaveDifficultyVersion(); NeedsSelection = false; IsApplyingPreset = false; } private static FieldInfo GetEntriesField() { if (_entriesFieldSearched) { return _entriesField; } _entriesFieldSearched = true; Type typeFromHandle = typeof(Dictionary); Type type = typeof(ConfigFile); while (type != null && type != typeof(object)) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeFromHandle) { _entriesField = fieldInfo; return fieldInfo; } } type = type.BaseType; } type = typeof(ConfigFile); while (type != null && type != typeof(object)) { FieldInfo[] fields2 = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo2 in fields2) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] Field: " + type.Name + "." + fieldInfo2.Name + " : " + fieldInfo2.FieldType.FullName)); } } type = type.BaseType; } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[Difficulty] entries field not found"); } return null; } private static int ApplyPresetValuesToConfig(string presetPath) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown Plugin? instance = Plugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val == null) { return 0; } if (!(GetEntriesField()?.GetValue(val) is Dictionary dictionary)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Difficulty] entries 딕셔너리 접근 실패"); } return -1; } int num = 0; string text = ""; HashSet hashSet = new HashSet(); try { string[] array = File.ReadAllLines(presetPath); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.StartsWith("[") && text3.EndsWith("]")) { text = text3.Substring(1, text3.Length - 2); } else { if (text3.StartsWith("#") || !text3.Contains(" = ")) { continue; } int num2 = text3.IndexOf(" = "); string text4 = text3.Substring(0, num2).Trim(); string serializedValue = text3.Substring(num2 + 3); ConfigDefinition val2 = new ConfigDefinition(text, text4); if (dictionary.TryGetValue(val2, out var value)) { try { value.SetSerializedValue(serializedValue); hashSet.Add(val2); num++; } catch { } } } } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] 값 직접 적용 실패: " + ex.Message)); } } int num3 = 0; foreach (KeyValuePair item in dictionary) { if (!hashSet.Contains(item.Key)) { try { item.Value.BoxedValue = item.Value.DefaultValue; num3++; } catch { } } } return num + num3; } public static string GetPresetDirectory() { return Path.Combine(Paths.ConfigPath, "CaptainSkillTree"); } public static void EnsurePresetDirectory() { try { Directory.CreateDirectory(GetPresetDirectory()); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 폴더 생성 실패: " + ex.Message)); } } ExtractEmbeddedPreset("Vanilra_Config_CaptainSkillTree.SkillTreeMod.cfg"); ExtractEmbeddedPreset("Veryhard_CaptainSkillTree.SkillTreeMod.cfg"); } private static void ExtractEmbeddedPreset(string fileName) { string path = Path.Combine(GetPresetDirectory(), fileName); string text = "CaptainSkillTree.asset." + fileName; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 내장 리소스 없음: " + text)); } return; } using FileStream destination = new FileStream(path, FileMode.Create, FileAccess.Write); stream.CopyTo(destination); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] 프리셋 추출 실패 (" + fileName + "): " + ex.Message)); } } } private static void SaveUserBackupOnQuit() { if (string.IsNullOrEmpty(_configFilePath) || !File.Exists(_configFilePath)) { return; } string destFileName = Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg"); try { File.Copy(_configFilePath, destFileName, overwrite: true); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[Difficulty] User 설정 백업 저장 완료"); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Difficulty] User 백업 저장 실패: " + ex.Message)); } } } private static void SaveUserBackupNow() { if (string.IsNullOrEmpty(_configFilePath) || !File.Exists(_configFilePath)) { return; } string destFileName = Path.Combine(GetPresetDirectory(), "User_CaptainSkillTree.SkillTreeMod.cfg"); try { File.Copy(_configFilePath, destFileName, overwrite: true); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] User 백업 갱신 실패: " + ex.Message)); } } } private static void SaveDifficultyVersion() { try { string path = Path.ChangeExtension(_configFilePath, ".version"); string path2 = Path.ChangeExtension(_configFilePath, ".difficulty_ver"); string contents = (File.Exists(path) ? File.ReadAllText(path).Trim() : ""); File.WriteAllText(path2, contents); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Difficulty] 버전 기록 실패: " + ex.Message)); } } } } public class SkillTreeInputListener : MonoBehaviour { public SkillTreeUI? skillTreeUI; private float lastLogTime = 0f; public static SkillTreeInputListener? Instance { get; private set; } private void Awake() { lastLogTime = Time.time; if ((Object)(object)Instance == (Object)null) { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); LevelSyncManager.Instance.Initialize(); } else { Debug.LogWarning((object)"[SkillTreeInputListener] 중복 생성 감지, 즉시 파괴, this={this.GetHashCode()} (name={gameObject.name})"); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Update() { try { SkillTreeManager.Instance?.OnUpdate(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SkillTree] SkillTreeManager 업데이트 실패: " + ex.Message)); } try { LevelSyncManager.Instance?.Update(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[SkillTree] LevelSyncManager 업데이트 실패: " + ex2.Message)); } if (IsChatOrConsoleOpen()) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { if (Input.GetKeyDown((KeyCode)114)) { SkillEffect.HandleRKeySkills(localPlayer); } if (Input.GetKeyDown((KeyCode)103)) { SkillEffect.HandleGKeySkills(localPlayer); } if (Input.GetKeyUp((KeyCode)103)) { SkillEffect.HandleGKeyUpSkills(localPlayer); } if (Input.GetKeyDown((KeyCode)104)) { SkillEffect.HandleHKeySkills(localPlayer); } if (Input.GetKeyUp((KeyCode)104)) { SkillEffect.HandleHKeyUpSkills(localPlayer); } if (Input.GetKeyDown((KeyCode)121)) { SkillTreeManager.Instance.HandleActiveSkillKeyInput(); } if (Input.GetKeyDown((KeyCode)93)) { try { long expToNextLevel = CaptainMMOBridge.GetExpToNextLevel(); CaptainMMOBridge.AddExp((int)expToNextLevel); Plugin.SkillTreePoint += 3; } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[SkillTree] 레벨업 실패 (경험치 추가): " + ex3.Message)); } } } if ((Object)(object)skillTreeUI == (Object)null || (Object)(object)skillTreeUI.panel == (Object)null || !skillTreeUI.panel.activeInHierarchy) { return; } bool keyDown = Input.GetKeyDown((KeyCode)27); bool keyDown2 = Input.GetKeyDown((KeyCode)9); if (keyDown) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } else { Plugin.Log.LogError((object)"[\ud83d\udd11 ESC] ❌ SkillTreeBGMManager.Instance가 null - ESC키 처리 실패"); } } if (keyDown2) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } else { Plugin.Log.LogError((object)"[\ud83d\udd11 TAB] ❌ SkillTreeBGMManager.Instance가 null - Tab키 처리 실패"); } } } private bool IsChatOrConsoleOpen() { try { if (IsChatInputActive()) { Plugin.Log.LogDebug((object)"[키 입력 차단] 채팅 입력이 활성화됨 - 스킬 키 입력 차단"); return true; } if (IsConsoleActive()) { Plugin.Log.LogDebug((object)"[키 입력 차단] 콘솔이 활성화됨 - 스킬 키 입력 차단"); return true; } return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[키 입력 차단] 채팅/콘솔 상태 확인 중 오류: " + ex.Message)); return false; } } private bool IsChatInputActive() { try { EventSystem current = EventSystem.current; if ((Object)(object)((current != null) ? current.currentSelectedGameObject : null) != (Object)null) { InputField component = current.currentSelectedGameObject.GetComponent(); 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(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isFocused) { return true; } } catch (Exception ex) { Plugin.Log.LogDebug((object)("[채팅 감지] GetComponentInChildren 실패: " + ex.Message)); } } } return false; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[채팅 감지] 오류: " + ex2.Message)); return false; } } private bool IsConsoleActive() { try { Type type = Type.GetType("Console, assembly_valheim"); if (type != null) { MethodInfo method = type.GetMethod("IsVisible", BindingFlags.Static | BindingFlags.Public); if (method != null && (bool)method.Invoke(null, null)) { return true; } } return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[콘솔 감지] 오류: " + ex.Message)); return false; } } private void OnDestroy() { ((MonoBehaviour)this).StopAllCoroutines(); LevelSyncManager.Instance?.Cleanup(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(Player), "OnDeath")] public static class Player_OnDeath_StopCoroutines_Patch { [HarmonyPostfix] public static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)SkillTreeInputListener.Instance != (Object)null) { ((MonoBehaviour)SkillTreeInputListener.Instance).StopAllCoroutines(); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("CaptainSkillTree.SkillTreeMod", "Captain SkillTree Mod", "1.22.65")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryShowPatch { private static bool Prepare() { return true; } public static void Postfix() { try { ShowSkillTreeIcon(); } catch (Exception ex) { Log.LogError((object)("[스킬트리] InventoryShowPatch 오류: " + ex.Message)); Log.LogError((object)("[스킬트리] StackTrace: " + ex.StackTrace)); } } } [HarmonyPatch(typeof(FejdStartup), "Awake")] private static class FejdStartup_DifficultyPatch { [HarmonyPostfix] private static void Postfix(FejdStartup __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown DifficultyManager.InitializeIfNeeded(); if (DifficultyManager.NeedsSelection) { Canvas val = ((Component)__instance).GetComponentInChildren(true) ?? Object.FindObjectOfType(); 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(); val2.transform.SetAsLastSibling(); } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(400)] public static class WeaponCriticalSystemPatch { public static void Prefix(Character __instance, ref bool showDamageText, ref HitData hit) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Invalid comparison between Unknown and I4 //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Invalid comparison between Unknown and I4 //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Invalid comparison between Unknown and I4 //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && Sword_Skill.IsRushSlashInvincible(val)) { hit.m_damage = default(DamageTypes); return; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || !(attacker is Player)) { return; } Player val2 = (Player)(object)((attacker is Player) ? attacker : null); ItemData currentWeapon = ((Humanoid)val2).GetCurrentWeapon(); bool flag = currentWeapon != null && (int)(currentWeapon.m_shared?.m_skillType).GetValueOrDefault() == 5 && SkillEffect.IsRecentSpearSecondaryAttack(val2); if (flag && SkillEffect.IsSpearComboThrowBuffActive(val2)) { SkillEffect.ConsumeSpearSecondaryAttack(val2); float spearStep6ComboDamageValue = SkillTreeConfig.SpearStep6ComboDamageValue; float num = 1f + spearStep6ComboDamageValue / 100f; hit.m_damage.m_pierce *= num; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_chop *= num; Log.LogInfo((object)$"[창 연공] 콤보 강화 투창 데미지 +{spearStep6ComboDamageValue}% 적용!"); if ((Object)(object)__instance != (Object)null && !__instance.IsPlayer()) { Vector3 position = ((Component)__instance).transform.position + Vector3.up * 1f; SimpleVFX.Play("confetti_directional_multicolor", position, 2f); Log.LogDebug((object)"[창 연공] confetti 이펙트 시작"); } SkillEffect.ConsumeSpearComboThrowUse(val2); return; } if (flag && SkillEffect.HasSkill("spear_Step1_throw") && SkillEffect.CanUseSpearThrowPassive(val2)) { SkillEffect.ConsumeSpearSecondaryAttack(val2); float spearStep2ThrowDamageValue = SkillTreeConfig.SpearStep2ThrowDamageValue; float num2 = 1f + spearStep2ThrowDamageValue / 100f; hit.m_damage.m_pierce *= num2; hit.m_damage.m_blunt *= num2; hit.m_damage.m_slash *= num2; hit.m_damage.m_chop *= num2; Log.LogInfo((object)$"[투창 패시브] 기본 투창 보너스 +{spearStep2ThrowDamageValue}% 적용!"); SkillEffect.ShowSkillEffectText(val2, L.Get("spear_throw_passive_activated", $"{spearStep2ThrowDamageValue:F0}"), new Color(1f, 0.8f, 0.2f), SkillEffect.SkillEffectTextType.Combat); SkillEffect.SetSpearThrowPassiveCooldown(val2); } ItemData currentWeapon2 = ((Humanoid)val2).GetCurrentWeapon(); if (currentWeapon2 == null) { return; } SkillType skillType = currentWeapon2.m_shared.m_skillType; if ((int)skillType == 8 && SkillEffect.HasSkill("bow_Step2_focus") && Critical.IsHeadshot(__instance, hit.m_point)) { float critMultiplier = CriticalDamage.CalculateCritDamageMultiplier(val2, skillType); CriticalDamage.ApplyCriticalDamage(val2, ref hit, critMultiplier, skillType); SkillEffect.ShowSkillEffectText(val2, L.Get("bow_headshot_text") + "!", new Color(1f, 0.3f, 0.1f), SkillEffect.SkillEffectTextType.Combat); VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point); showDamageText = false; Log.LogInfo((object)"[헤드샷] 헤드샷 발생 시 100% 치명타 발동!"); return; } float critChance = Critical.CalculateCritChance(val2, skillType); if (Critical.RollCritical(critChance)) { float critMultiplier2 = CriticalDamage.CalculateCritDamageMultiplier(val2, skillType); CriticalDamage.ApplyCriticalDamage(val2, ref hit, critMultiplier2, skillType); if ((int)skillType == 2 || (int)skillType == 11) { VFXManager.PlayVFXMultiplayer("fx_crit", "", hit.m_point); } showDamageText = false; } } } [HarmonyPatch(typeof(SEMan), "ModifyAttackStaminaUsage")] public static class KnifeSkillTreeStaminaPatch { public static void Postfix(SEMan __instance, ref float staminaUse) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 2) { float knifeStaminaReduction = SkillEffect.GetKnifeStaminaReduction(0f); staminaUse *= 1f - knifeStaminaReduction / 100f; } } } } [HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")] public static class KnifeSkillTreeStaminaRegenPatch { public static void Postfix(SEMan __instance, ref float staminaMultiplier) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { staminaMultiplier += SkillEffect.GetStaminaRegen(0f) / 100f; } } } [HarmonyPatch(typeof(SEMan), "ModifyRunStaminaDrain")] public static class KnifeSkillTreeRunStaminaPatch { public static void Postfix(ref float drain) { float staminaReduction = SkillEffect.GetStaminaReduction(0f); drain *= 1f - staminaReduction / 100f; } } [HarmonyPatch(typeof(SEMan), "ModifyJumpStaminaUsage")] public static class KnifeSkillTreeJumpStaminaPatch { public static void Postfix(ref float staminaUse) { float staminaReduction = SkillEffect.GetStaminaReduction(0f); staminaUse *= 1f - staminaReduction / 100f; float jumpStaminaReduction = SkillEffect.GetJumpStaminaReduction(); staminaUse *= 1f - jumpStaminaReduction / 100f; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(600)] public static class KnifeSkillTreeArmorPatch { public static void Prefix(Character __instance, HitData hit) { if (__instance.IsPlayer()) { float physicArmor = SkillEffect.GetPhysicArmor(0f); float num = 1f - physicArmor / 100f; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; hit.m_damage.m_chop *= num; hit.m_damage.m_pickaxe *= num; float magicArmor = SkillEffect.GetMagicArmor(0f); float num2 = 1f - magicArmor / 100f; hit.m_damage.m_fire *= num2; hit.m_damage.m_frost *= num2; hit.m_damage.m_lightning *= num2; hit.m_damage.m_poison *= num2; hit.m_damage.m_spirit *= num2; } } } [HarmonyPatch(typeof(Humanoid), "BlockAttack")] public static class SwordSkillTreeParryPatch { public static void Postfix(Character __instance, bool __result, HitData hit, Character attacker) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if (!__result) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !((Character)val).IsPlayer()) { return; } ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 1) { SkillTreeManager instance = SkillTreeManager.Instance; SEMan sEMan = ((Character)val).GetSEMan(); if (instance.GetSkillLevel("sword_counter") > 0) { SE_SwordCounter sE_SwordCounter = ScriptableObject.CreateInstance(); ((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(); ((StatusEffect)sE_SwordRiposte).m_ttl = 5f; sEMan.AddStatusEffect((StatusEffect)(object)sE_SwordRiposte, true, 0, 0f); } } } } [HarmonyPatch(typeof(Character), "Stagger")] public static class ParryRush_Stagger_Patch { public static void Postfix(Character __instance) { try { if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer()) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && Sword_Skill.IsParryRushActive(localPlayer) && ((Character)localPlayer).IsBlocking()) { Sword_Skill.OnParryRushTrigger(localPlayer, __instance); } } } catch (Exception) { } } } public class SE_SwordCounter : StatusEffect { public SE_SwordCounter() { base.m_name = "移쇰궇 ?섏튂湲?"; base.m_tooltip = "?ㅼ쓬 怨듦꺽???쇳빐?됱씠 20% 利앷??⑸땲??"; base.m_icon = null; base.m_ttl = 5f; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)skill == 1) { ((DamageTypes)(ref hitData.m_damage)).Modify(1.2f); base.m_character.GetSEMan().RemoveStatusEffect((StatusEffect)(object)this, true); } } } public class SE_SwordRiposte : StatusEffect { public SE_SwordRiposte() { base.m_name = "移쇰궇 ?섏튂湲?"; base.m_tooltip = "?ㅼ쓬 怨듦꺽???쇳빐?됱씠 20% 利앷??⑸땲??"; base.m_icon = null; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class SwordRiposteDamagePatch { private static readonly int SwordCounterHash = Animator.StringToHash("移쇰궇 ?섏튂湲?"); private static readonly int SwordRiposteHash = Animator.StringToHash("諛섍꺽 ?먯꽭"); private static void Prefix(Character __instance, HitData hit) { try { if (hit == null) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && (Object)(object)val != (Object)null) { SEMan sEMan = ((Character)val).GetSEMan(); if (sEMan != null && sEMan.HaveStatusEffect(SwordRiposteHash)) { hit.m_damage.m_blunt *= 1.2f; hit.m_damage.m_slash *= 1.2f; hit.m_damage.m_pierce *= 1.2f; sEMan.RemoveStatusEffect(SwordRiposteHash, false); } } } catch (Exception) { } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class InventoryHidePatch { public static void Postfix() { try { if ((Object)(object)skillTreeUI != (Object)null && (Object)(object)skillTreeUI.panel != (Object)null && skillTreeUI.panel.activeSelf) { skillTreeUI.panel.SetActive(false); if ((Object)(object)SkillTreeBGMManager.Instance != (Object)null) { SkillTreeBGMManager.Instance.PauseSkillTreeBGM(); } } if ((Object)(object)skillTreeIconObj != (Object)null) { skillTreeIconObj.SetActive(false); } } catch (Exception ex) { Log.LogError((object)("[?ㅽ궗?몃━] InventoryHidePatch ?ㅻ쪟: " + ex.Message)); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryShowIconPositionPatch { private static bool _iconPositionAdjusted; public static void Postfix(InventoryGui __instance) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)skillTreeIconObj == (Object)null) { return; } skillTreeIconObj.SetActive(true); if (!EpicMMOReflectionHelper.IsInitialized) { EpicMMOReflectionHelper.Initialize(); } if (EpicMMOReflectionHelper.IsAvailable || _iconPositionAdjusted) { return; } RectTransform component = skillTreeIconObj.GetComponent(); if (!((Object)(object)component == (Object)null)) { Canvas componentInParent = skillTreeIconObj.GetComponentInParent(); 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 d__1 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(d__1))] private static IEnumerator DelayedHideIcon() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0); } } [HarmonyPatch(typeof(ZNet), "Awake")] public static class ZNet_Awake_Patch { private static void Postfix() { SkillTreeConfig.DetectServerClientMode(); InitializeServerSync(); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] public static class Terminal_InitTerminal_Patch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; public static ConsoleEvent <>9__0_3; public static ConsoleEvent <>9__0_4; public static ConsoleEvent <>9__0_5; public static ConsoleEvent <>9__0_6; public static ConsoleEvent <>9__0_7; public static ConsoleEvent <>9__0_8; public static ConsoleEvent <>9__0_9; public static ConsoleEvent <>9__0_10; public static ConsoleEvent <>9__0_11; public static ConsoleEvent <>9__0_12; public static ConsoleEvent <>9__0_13; public static ConsoleEvent <>9__0_14; public static ConsoleEvent <>9__0_15; public static ConsoleEvent <>9__0_16; public static ConsoleEvent <>9__0_17; public static ConsoleEvent <>9__0_18; public static ConsoleEvent <>9__0_19; internal void b__0_0(ConsoleEventArgs args) { SetAttackConfig("AttackRootDamageBonus", args); } internal void b__0_1(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusChance", args); } internal void b__0_2(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusDamage", args); } internal void b__0_3(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusChance", args); } internal void b__0_4(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusDamage", args); } internal void b__0_5(ConsoleEventArgs args) { SetSpeedConfig("Speed_Expert_MoveSpeed", args); } internal void b__0_6(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step1_DodgeSpeed", args); } internal void b__0_7(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_MeleeComboBonus", args); } internal void b__0_8(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_BowHitBonus", args); } internal void b__0_9(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step8_MeleeAttackSpeed", args); } internal void b__0_10(ConsoleEventArgs args) { SkillTreeConfig.ReloadAndBroadcast(); } internal void b__0_11(ConsoleEventArgs args) { ShowCurrentConfig(); } internal void b__0_12(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowCount", args); } internal void b__0_13(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowConsumption", args); } internal void b__0_14(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_DamagePercent", args); } internal void b__0_15(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv1_Chance", args); } internal void b__0_16(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv2_Chance", args); } internal void b__0_17(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowCount", args); } internal void b__0_18(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowConsumption", args); } internal void b__0_19(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_DamagePercent", args); } } private static void Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Expected O, but got Unknown //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Expected O, but got Unknown //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Expected O, but got Unknown //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Expected O, but got Unknown //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Expected O, but got Unknown //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackRootDamageBonus", args); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("skilltree_attack_root", "怨듦꺽 ?꾨Ц媛\u0080 猷⑦듃 ?곕?吏\u0080 蹂대꼫???ㅼ젙 (?? skilltree_attack_root 7)", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusChance", args); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("skilltree_melee_chance", "洹쇱젒 ?뱁솕 諛쒕룞 ?뺣쪧 ?ㅼ젙 (?? skilltree_melee_chance 25)", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackMeleeBonusDamage", args); }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } new ConsoleCommand("skilltree_melee_damage", "洹쇱젒 ?뱁솕 ?쇳빐???ㅼ젙 (?? skilltree_melee_damage 15)", (ConsoleEvent)obj3, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj4 = <>c.<>9__0_3; if (obj4 == null) { ConsoleEvent val4 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusChance", args); }; <>c.<>9__0_3 = val4; obj4 = (object)val4; } new ConsoleCommand("skilltree_bow_chance", "???뱁솕 諛쒕룞 ?뺣쪧 ?ㅼ젙 (?? skilltree_bow_chance 30)", (ConsoleEvent)obj4, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj5 = <>c.<>9__0_4; if (obj5 == null) { ConsoleEvent val5 = delegate(ConsoleEventArgs args) { SetAttackConfig("AttackBowBonusDamage", args); }; <>c.<>9__0_4 = val5; obj5 = (object)val5; } new ConsoleCommand("skilltree_bow_damage", "???뱁솕 ?쇳빐???ㅼ젙 (?? skilltree_bow_damage 18)", (ConsoleEvent)obj5, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj6 = <>c.<>9__0_5; if (obj6 == null) { ConsoleEvent val6 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Expert_MoveSpeed", args); }; <>c.<>9__0_5 = val6; obj6 = (object)val6; } new ConsoleCommand("skilltree_speed_root", "?띾룄 ?꾨Ц媛\u0080 猷⑦듃 ?대룞?띾룄 ?ㅼ젙 (?? skilltree_speed_root 5)", (ConsoleEvent)obj6, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj7 = <>c.<>9__0_6; if (obj7 == null) { ConsoleEvent val7 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step1_DodgeSpeed", args); }; <>c.<>9__0_6 = val7; obj7 = (object)val7; } new ConsoleCommand("skilltree_speed_dodge", "援щⅤ湲??띾룄 蹂대꼫???ㅼ젙 (?? skilltree_speed_dodge 15)", (ConsoleEvent)obj7, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj8 = <>c.<>9__0_7; if (obj8 == null) { ConsoleEvent val8 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_MeleeComboBonus", args); }; <>c.<>9__0_7 = val8; obj8 = (object)val8; } new ConsoleCommand("skilltree_speed_melee_combo", "洹쇱젒 肄ㅻ낫 ?대룞?띾룄 ?ㅼ젙 (?? skilltree_speed_melee_combo 6)", (ConsoleEvent)obj8, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj9 = <>c.<>9__0_8; if (obj9 == null) { ConsoleEvent val9 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step2_BowHitBonus", args); }; <>c.<>9__0_8 = val9; obj9 = (object)val9; } new ConsoleCommand("skilltree_speed_bow_hit", "???곸쨷 ?대룞?띾룄 ?ㅼ젙 (?? skilltree_speed_bow_hit 8)", (ConsoleEvent)obj9, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj10 = <>c.<>9__0_9; if (obj10 == null) { ConsoleEvent val10 = delegate(ConsoleEventArgs args) { SetSpeedConfig("Speed_Step8_MeleeAttackSpeed", args); }; <>c.<>9__0_9 = val10; obj10 = (object)val10; } new ConsoleCommand("skilltree_speed_attack", "怨듦꺽?띾룄 利앷? ?ㅼ젙 (?? skilltree_speed_attack 10)", (ConsoleEvent)obj10, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj11 = <>c.<>9__0_10; if (obj11 == null) { ConsoleEvent val11 = delegate { SkillTreeConfig.ReloadAndBroadcast(); }; <>c.<>9__0_10 = val11; obj11 = (object)val11; } new ConsoleCommand("skilltree_config_reload", "?ㅼ젙 由щ줈??諛??ъ쟾??", (ConsoleEvent)obj11, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj12 = <>c.<>9__0_11; if (obj12 == null) { ConsoleEvent val12 = delegate { ShowCurrentConfig(); }; <>c.<>9__0_11 = val12; obj12 = (object)val12; } new ConsoleCommand("skilltree_config_show", "?꾩옱 ?ㅼ젙 ?쒖떆", (ConsoleEvent)obj12, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj13 = <>c.<>9__0_12; if (obj13 == null) { ConsoleEvent val13 = delegate(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowCount", args); }; <>c.<>9__0_12 = val13; obj13 = (object)val13; } new ConsoleCommand("skilltree_archer_arrows", "?꾩쿂 硫\u0080?곗꺑 ?붿궡 ???ㅼ젙 (?? skilltree_archer_arrows 7)", (ConsoleEvent)obj13, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj14 = <>c.<>9__0_13; if (obj14 == null) { ConsoleEvent val14 = delegate(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_ArrowConsumption", args); }; <>c.<>9__0_13 = val14; obj14 = (object)val14; } new ConsoleCommand("skilltree_archer_consume", "?꾩쿂 硫\u0080?곗꺑 ?붿궡 ?뚮え???ㅼ젙 (?? skilltree_archer_consume 2)", (ConsoleEvent)obj14, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj15 = <>c.<>9__0_14; if (obj15 == null) { ConsoleEvent val15 = delegate(ConsoleEventArgs args) { SetArcherConfig("Archer_MultiShot_DamagePercent", args); }; <>c.<>9__0_14 = val15; obj15 = (object)val15; } new ConsoleCommand("skilltree_archer_damage", "?꾩쿂 硫\u0080?곗꺑 ?곕?吏\u0080 鍮꾩쑉 ?ㅼ젙 (?? skilltree_archer_damage 80)", (ConsoleEvent)obj15, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj16 = <>c.<>9__0_15; if (obj16 == null) { ConsoleEvent val16 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv1_Chance", args); }; <>c.<>9__0_15 = val16; obj16 = (object)val16; } new ConsoleCommand("skilltree_bow_lv1_chance", "???꾨Ц媛\u0080 硫\u0080?곗꺑 Lv1 ?뺣쪧 ?ㅼ젙 (?? skilltree_bow_lv1_chance 15)", (ConsoleEvent)obj16, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj17 = <>c.<>9__0_16; if (obj17 == null) { ConsoleEvent val17 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_Lv2_Chance", args); }; <>c.<>9__0_16 = val17; obj17 = (object)val17; } new ConsoleCommand("skilltree_bow_lv2_chance", "???꾨Ц媛\u0080 硫\u0080?곗꺑 Lv2 ?뺣쪧 ?ㅼ젙 (?? skilltree_bow_lv2_chance 36)", (ConsoleEvent)obj17, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj18 = <>c.<>9__0_17; if (obj18 == null) { ConsoleEvent val18 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowCount", args); }; <>c.<>9__0_17 = val18; obj18 = (object)val18; } new ConsoleCommand("skilltree_bow_arrows", "???꾨Ц媛\u0080 硫\u0080?곗꺑 ?붿궡 ???ㅼ젙 (?? skilltree_bow_arrows 2)", (ConsoleEvent)obj18, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj19 = <>c.<>9__0_18; if (obj19 == null) { ConsoleEvent val19 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_ArrowConsumption", args); }; <>c.<>9__0_18 = val19; obj19 = (object)val19; } new ConsoleCommand("skilltree_bow_consume", "???꾨Ц媛\u0080 硫\u0080?곗꺑 ?붿궡 ?뚮え???ㅼ젙 (?? skilltree_bow_consume 0)", (ConsoleEvent)obj19, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj20 = <>c.<>9__0_19; if (obj20 == null) { ConsoleEvent val20 = delegate(ConsoleEventArgs args) { SetBowConfig("Bow_MultiShot_DamagePercent", args); }; <>c.<>9__0_19 = val20; obj20 = (object)val20; } new ConsoleCommand("skilltree_bow_damage", "???꾨Ц媛\u0080 硫\u0080?곗꺑 ?곕?吏\u0080 鍮꾩쑉 ?ㅼ젙 (?? skilltree_bow_damage 70)", (ConsoleEvent)obj20, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } [HarmonyPatch(typeof(Player), "OnDestroy")] public static class Plugin_Player_OnDestroy_DamagePatch_Cleanup { private static void Postfix(Player __instance) { try { NerveEnhancementSystem.Damage_Patch.CleanupPlayerData(__instance); } catch { } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__47_0; internal void 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(); 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.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 d__24 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Plugin <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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 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(); 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(d__24))] private IEnumerator Start() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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(); 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(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("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(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(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(); 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(); 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(((Component)val4).gameObject, val2); ((Object)skillTreeIconObj).name = "ButtonSkillTree"; Image val5 = skillTreeIconObj.GetComponent(); if ((Object)(object)val5 == (Object)null) { val5 = skillTreeIconObj.GetComponentInChildren(); } 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(); 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 component3 = ((Component)val4).GetComponent(); 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() == (Object)null) { ((Component)val6).gameObject.SetActive(false); } } SetupIconClickEvent(); Canvas componentInParent = skillTreeIconObj.GetComponentInParent(); 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(); 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(); 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(); 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(); 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