Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of NachoAchievementsGlobalSave v2.3.3
NachoAchievementsGlobalSave.dll
Decompiled 10 months 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.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NachoAchievementsGlobalSave")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Global Save Addon for NachoAchievements")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5")] [assembly: AssemblyProduct("NachoAchievementsGlobalSave")] [assembly: AssemblyTitle("NachoAchievementsGlobalSave")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NachoAchievementsGlobalSave { [BepInPlugin("NachoAchievementsGlobalSave", "Nacho Achievements Global Save", "2.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class GlobalSavePlugin : BaseUnityPlugin { public const string GUID = "NachoAchievementsGlobalSave"; public const string NAME = "Nacho Achievements Global Save"; public const string VERSION = "2.3.0"; private const string RESET_VERSION = "2.0.3"; private const string VersionKey = "NachoGlobalSave_Version"; internal static ManualLogSource Logger; private static Harmony _harmony; internal static FieldInfo AchievementsField; internal static MethodInfo ES3SaveMethod; internal static MethodInfo ES3LoadMethod; internal static MethodInfo ES3KeyExistsMethod; internal static MethodInfo ES3DeleteKeyMethod; internal static ulong CachedSteamId; internal static bool IsInitialized; private const string SaveFileName = "LCGeneralSaveData"; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Expected O, but got Unknown //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Expected O, but got Unknown //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Expected O, but got Unknown //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("NachoAchievementsGlobalSave"); Logger.LogInfo((object)"Initializing Global Save Add-on v2.3.0 (Steam ID Mode)..."); Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); if (type == null) { Logger.LogError((object)"Could not find NachoAchievements. Is the mod installed?"); return; } AchievementsField = AccessTools.Field(type, "Achievements"); Type type2 = AccessTools.TypeByName("ES3"); if (type2 != null) { List<MethodInfo> declaredMethods = AccessTools.GetDeclaredMethods(type2); foreach (MethodInfo item in declaredMethods) { ParameterInfo[] parameters = item.GetParameters(); if (item.Name == "Save" && item.IsGenericMethod && parameters.Length == 3 && parameters[2].ParameterType == typeof(string)) { ES3SaveMethod = item; } if (item.Name == "Load" && item.IsGenericMethod && parameters.Length == 3 && parameters[1].ParameterType == typeof(string) && parameters[2].ParameterType.IsGenericParameter) { ES3LoadMethod = item; } if (item.Name == "KeyExists" && !item.IsGenericMethod && parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string)) { ES3KeyExistsMethod = item; } if (item.Name == "DeleteKey" && !item.IsGenericMethod && parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string)) { ES3DeleteKeyMethod = item; } } Logger.LogInfo((object)"Applying patches manually..."); MethodInfo methodInfo = AccessTools.Method(type, "CreateAchievements", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "WriteAchievements", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(SavePatches), "PostCreateAchievements", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(SavePatches), "PostWriteAchievements", (Type[])null, (Type[])null); if (methodInfo != null && methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Logger.LogInfo((object)"Hooked CreateAchievements successfully."); } else { Logger.LogError((object)"Failed to hook CreateAchievements."); } if (methodInfo2 != null && methodInfo4 != null) { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Logger.LogInfo((object)"Hooked WriteAchievements successfully."); } Type type3 = AccessTools.TypeByName("QuickMenuManager"); if (type3 != null) { MethodInfo methodInfo5 = AccessTools.Method(type3, "Update", (Type[])null, (Type[])null); if (methodInfo5 != null) { MethodInfo methodInfo6 = AccessTools.Method(typeof(MenuPatches), "PostQuickMenuUpdate", (Type[])null, (Type[])null); _harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Logger.LogInfo((object)"Hooked QuickMenuManager.Update for controller support."); } } Type type4 = AccessTools.TypeByName("GameNetcodeStuff.PlayerControllerB"); if (type4 != null) { MethodInfo methodInfo7 = AccessTools.Method(type4, "ConnectClientToPlayerObject", (Type[])null, (Type[])null); if (methodInfo7 != null) { MethodInfo methodInfo8 = AccessTools.Method(typeof(SavePatches), "PostPlayerConnect", (Type[])null, (Type[])null); _harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Logger.LogInfo((object)"Hooked PlayerControllerB.ConnectClientToPlayerObject for Steam ID caching."); } } MethodInfo methodInfo9 = AccessTools.Method(type, "CreateAchievementGetText", (Type[])null, (Type[])null); if (methodInfo9 != null) { MethodInfo methodInfo10 = AccessTools.Method(typeof(AchievementPopupPatches), "CreateEnhancedAchievementPopup", (Type[])null, (Type[])null); _harmony.Patch((MethodBase)methodInfo9, new HarmonyMethod(methodInfo10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Logger.LogInfo((object)"Hooked CreateAchievementGetText for enhanced popup UI."); } Logger.LogInfo((object)"Global Save loaded successfully."); } else { Logger.LogError((object)"Could not find ES3. Is Lethal Company loaded correctly?"); } } private void Update() { if (Keyboard.current != null && ((ButtonControl)Keyboard.current.f9Key).wasPressedThisFrame && DebugMenu.IsAuthorizedUser()) { DebugMenu.ToggleDebugMenu(); } } internal static string GetSaveKey() { if (CachedSteamId != 0) { return $"NachoAchievements_Player_{CachedSteamId}"; } return "NachoAchievements_GlobalData"; } internal static void CheckVersionAndReset() { try { if (ES3LoadMethod == null || ES3SaveMethod == null) { return; } MethodInfo methodInfo = ES3LoadMethod.MakeGenericMethod(typeof(string)); string text = methodInfo.Invoke(null, new object[3] { "NachoGlobalSave_Version", "LCGeneralSaveData", "" }) as string; if (text != "2.0.3") { Logger.LogWarning((object)("Version mismatch detected. Saved: '" + text + "', Current: '2.0.3'")); Logger.LogWarning((object)"Performing one-time achievement data reset for data integrity..."); string text2 = "NachoAchievements_GlobalData"; if (ES3KeyExistsMethod != null && (bool)ES3KeyExistsMethod.Invoke(null, new object[2] { text2, "LCGeneralSaveData" }) && ES3DeleteKeyMethod != null) { ES3DeleteKeyMethod.Invoke(null, new object[2] { text2, "LCGeneralSaveData" }); Logger.LogInfo((object)("Deleted old global data key: " + text2)); } string saveKey = GetSaveKey(); if (ES3KeyExistsMethod != null && saveKey != text2 && (bool)ES3KeyExistsMethod.Invoke(null, new object[2] { saveKey, "LCGeneralSaveData" }) && ES3DeleteKeyMethod != null) { ES3DeleteKeyMethod.Invoke(null, new object[2] { saveKey, "LCGeneralSaveData" }); Logger.LogInfo((object)("Deleted player data key: " + saveKey)); } ResetAchievementsInMemory(); MethodInfo methodInfo2 = ES3SaveMethod.MakeGenericMethod(typeof(string)); methodInfo2.Invoke(null, new object[3] { "NachoGlobalSave_Version", "2.0.3", "LCGeneralSaveData" }); Logger.LogInfo((object)"Saved new version marker: 2.0.3"); } } catch (Exception arg) { Logger.LogError((object)$"Version check failed: {arg}"); } } internal static void ResetAchievementsInMemory() { try { if (AchievementsField == null) { return; } object value = AchievementsField.GetValue(null); if (!(value is Dictionary<string, Dictionary<string, string>> dictionary) || dictionary.Count == 0) { return; } int num = 0; int num2 = 0; foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary) { string key = item.Key; if (ES3KeyExistsMethod != null && ES3DeleteKeyMethod != null) { try { if ((bool)ES3KeyExistsMethod.Invoke(null, new object[2] { key, "LCGeneralSaveData" })) { ES3DeleteKeyMethod.Invoke(null, new object[2] { key, "LCGeneralSaveData" }); num2++; } } catch { } } if (item.Value.ContainsKey("progress")) { item.Value["progress"] = "0"; } if (item.Value.ContainsKey("completed")) { item.Value["completed"] = "False"; } num++; } Logger.LogInfo((object)$"Reset {num} achievements in memory. Deleted {num2} ES3 keys."); try { string text = null; Type type = AccessTools.TypeByName("NachoAchievements.Util.Paths"); if (type != null) { PropertyInfo propertyInfo = AccessTools.Property(type, "DataFolder"); if (propertyInfo != null) { text = propertyInfo.GetValue(null) as string; } } if (string.IsNullOrEmpty(text)) { string directoryName = Path.GetDirectoryName(Application.dataPath); text = Path.Combine(directoryName, "BepInEx", "config", "NachosAchievements"); } if (!string.IsNullOrEmpty(text) && Directory.Exists(text)) { Directory.Delete(text, recursive: true); Logger.LogInfo((object)("Deleted NachosAchievements folder: " + text)); } else { Logger.LogInfo((object)"NachosAchievements folder does not exist, skipping deletion."); } } catch (Exception ex) { Logger.LogWarning((object)("Could not delete NachosAchievements folder: " + ex.Message)); } Type type2 = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); if (type2 != null) { AccessTools.Method(type2, "WriteAchievements", (Type[])null, (Type[])null)?.Invoke(null, null); Logger.LogInfo((object)"Wrote fresh achievements to file."); } } catch (Exception arg) { Logger.LogError((object)$"Failed to reset achievements in memory: {arg}"); } } } public static class SavePatches { private const string SaveFileName = "LCGeneralSaveData"; public static void PostPlayerConnect(object __instance) { try { FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "playerSteamId"); if (!(fieldInfo != null)) { return; } ulong num = (ulong)fieldInfo.GetValue(__instance); if (num != 0) { GlobalSavePlugin.CachedSteamId = num; GlobalSavePlugin.Logger.LogInfo((object)$"Cached Steam ID: {num}"); if (!GlobalSavePlugin.IsInitialized) { GlobalSavePlugin.CheckVersionAndReset(); GlobalSavePlugin.IsInitialized = true; LoadAchievementsFromGlobal(); } } } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to cache Steam ID: {arg}"); } } public static void PostCreateAchievements() { if (GlobalSavePlugin.CachedSteamId == 0) { GlobalSavePlugin.Logger.LogInfo((object)"Steam ID not yet available, will load achievements after player connects."); } else { LoadAchievementsFromGlobal(); } } private static void LoadAchievementsFromGlobal() { try { if (GlobalSavePlugin.AchievementsField == null || GlobalSavePlugin.ES3LoadMethod == null) { return; } object value = GlobalSavePlugin.AchievementsField.GetValue(null); if (!(value is Dictionary<string, Dictionary<string, string>> dictionary)) { return; } string saveKey = GlobalSavePlugin.GetSaveKey(); MethodInfo methodInfo = GlobalSavePlugin.ES3LoadMethod.MakeGenericMethod(dictionary.GetType()); object obj = Activator.CreateInstance(dictionary.GetType()); if (methodInfo.Invoke(null, new object[3] { saveKey, "LCGeneralSaveData", obj }) is Dictionary<string, Dictionary<string, string>> dictionary2 && dictionary2.Count > 0) { int num = 0; foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary2) { if (dictionary.ContainsKey(item.Key)) { if (item.Value.ContainsKey("progress")) { dictionary[item.Key]["progress"] = item.Value["progress"]; } if (item.Value.ContainsKey("completed")) { dictionary[item.Key]["completed"] = item.Value["completed"]; } num++; } } GlobalSavePlugin.Logger.LogInfo((object)$"[Steam ID: {GlobalSavePlugin.CachedSteamId}] Restored {num} achievements from Global Save."); } else { GlobalSavePlugin.Logger.LogInfo((object)$"[Steam ID: {GlobalSavePlugin.CachedSteamId}] No saved achievement data found, starting fresh."); } } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to load achievements: {arg}"); } } public static void PostWriteAchievements() { try { if (!(GlobalSavePlugin.AchievementsField == null) && !(GlobalSavePlugin.ES3SaveMethod == null)) { object value = GlobalSavePlugin.AchievementsField.GetValue(null); if (value != null) { string saveKey = GlobalSavePlugin.GetSaveKey(); MethodInfo methodInfo = GlobalSavePlugin.ES3SaveMethod.MakeGenericMethod(value.GetType()); methodInfo.Invoke(null, new object[3] { saveKey, value, "LCGeneralSaveData" }); GlobalSavePlugin.Logger.LogInfo((object)$"[Steam ID: {GlobalSavePlugin.CachedSteamId}] Saved achievements to Global Save."); } } } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to save achievements: {arg}"); } } } public static class MenuPatches { private static bool _wasStartPressed = false; private static bool _wasBPressed = false; private static bool _wasDPadUpPressed = false; private static bool _wasDPadDownPressed = false; private static float _stickScrollCooldown = 0f; private const float STICK_SCROLL_DELAY = 0.12f; private static bool _wasUpArrowPressed = false; private static bool _wasDownArrowPressed = false; private static bool _wasEscapePressed = false; private static float _keyboardScrollCooldown = 0f; private static bool _isControllerMode = false; private static float _lastControllerInput = 0f; private static float _lastMouseInput = 0f; private static bool _wasMouseLeftPressed = false; private static bool _isDraggingScrollbar = false; private static int _selectedIndex = 0; private static TMP_FontAsset _gameFont = null; private static bool _fontLoaded = false; private static GameObject _uiContainer = null; private static GameObject _backgroundPanel = null; private static GameObject _contentArea = null; private static GameObject _titleBar = null; private static GameObject _progressBar = null; private static GameObject _scrollbarBg = null; private static GameObject _scrollbarHandle = null; private static GameObject _selectionHighlight = null; private static GameObject _descriptionPanel = null; private static TextMeshProUGUI _descriptionText = null; private static TextMeshProUGUI _titleText = null; private static TextMeshProUGUI _progressText = null; private static bool _cacheInitialized = false; private static Type _nachoType; private static FieldInfo _achievementsTextField; private static FieldInfo _achievementsField; private static FieldInfo _tmpField; private static FieldInfo _prevTextField; private static Type _gameNetworkManagerType; private static PropertyInfo _gnmInstanceProp; private static FieldInfo _localPlayerField; private static FieldInfo _quickMenuField; private static FieldInfo _mainButtonsField; private static readonly Color PANEL_BG_COLOR = new Color(0.08f, 0.08f, 0.12f, 0.95f); private static readonly Color TITLE_BAR_COLOR = new Color(0.15f, 0.12f, 0.08f, 1f); private static readonly Color ACCENT_COLOR = new Color(1f, 0.8f, 0.2f, 1f); private static readonly Color COMPLETED_COLOR = new Color(0.3f, 0.9f, 0.3f, 1f); private static readonly Color LOCKED_COLOR = new Color(0.5f, 0.5f, 0.5f, 1f); private static readonly Color HIGHLIGHT_COLOR = new Color(1f, 0.8f, 0.2f, 0.25f); private static Dictionary<int, Sprite> _badgeSprites = new Dictionary<int, Sprite>(); private static Sprite _unlockedOverlay = null; private static Sprite _lockedOverlay = null; private static bool _badgesLoaded = false; private static string _badgesPath = null; private static AssetBundle _badgeBundle = null; public static int GetBadgeCount() { LoadBadgeImages(); return _badgeSprites.Count; } public static bool HasBadgeSprite(int index) { LoadBadgeImages(); return _badgeSprites.ContainsKey(index); } public static Sprite GetBadgeSprite(int index) { LoadBadgeImages(); return _badgeSprites.ContainsKey(index) ? _badgeSprites[index] : null; } private static void LoadBadgeImages() { if (_badgesLoaded) { return; } _badgesLoaded = true; try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, "nachoachievementsbadges"); if (File.Exists(text)) { LoadFromAssetBundle(text); if (_badgeSprites.Count > 0) { GlobalSavePlugin.Logger.LogInfo((object)$"Loaded {_badgeSprites.Count} badges from AssetBundle"); return; } } _badgesPath = Path.Combine(directoryName, "Badges"); if (!Directory.Exists(_badgesPath)) { _badgesPath = Path.Combine(Directory.GetParent(directoryName)?.FullName ?? directoryName, "Badges"); } if (!Directory.Exists(_badgesPath)) { GlobalSavePlugin.Logger.LogWarning((object)"No AssetBundle or Badges folder found"); } else { LoadFromPngFolder(); } } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to load badges: {arg}"); } } private static void LoadFromAssetBundle(string bundlePath) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) try { _badgeBundle = AssetBundle.LoadFromFile(bundlePath); if ((Object)(object)_badgeBundle == (Object)null) { GlobalSavePlugin.Logger.LogWarning((object)"Failed to load AssetBundle"); return; } Sprite[] array = _badgeBundle.LoadAllAssets<Sprite>(); GlobalSavePlugin.Logger.LogInfo((object)$"AssetBundle contains {array.Length} sprites"); if (array.Length != 0) { Sprite[] array2 = array; foreach (Sprite val in array2) { MatchAndStoreBadge(((Object)val).name, val); } return; } Texture2D[] array3 = _badgeBundle.LoadAllAssets<Texture2D>(); GlobalSavePlugin.Logger.LogInfo((object)$"AssetBundle contains {array3.Length} textures"); Texture2D[] array4 = array3; foreach (Texture2D val2 in array4) { try { Sprite sprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)); MatchAndStoreBadge(((Object)val2).name, sprite); } catch (Exception ex) { GlobalSavePlugin.Logger.LogWarning((object)("Failed to create sprite from " + ((Object)val2).name + ": " + ex.Message)); } } } catch (Exception ex2) { GlobalSavePlugin.Logger.LogError((object)("AssetBundle load error: " + ex2.Message)); } } private static void MatchAndStoreBadge(string name, Sprite sprite) { for (int i = 1; i <= 32; i++) { string value = $"{i:D2}_"; if (name.StartsWith(value)) { _badgeSprites[i] = sprite; GlobalSavePlugin.Logger.LogInfo((object)$"Loaded badge {i}: {name}"); return; } } if (name.StartsWith("Overlay_Unlocked")) { _unlockedOverlay = sprite; GlobalSavePlugin.Logger.LogInfo((object)("Loaded overlay: " + name)); } else if (name.StartsWith("Overlay_Locked")) { _lockedOverlay = sprite; GlobalSavePlugin.Logger.LogInfo((object)("Loaded overlay: " + name)); } } private static void LoadFromPngFolder() { try { GlobalSavePlugin.Logger.LogInfo((object)("Loading badges from " + _badgesPath)); for (int i = 1; i <= 32; i++) { string searchPattern = $"{i:D2}_*.png"; string[] files = Directory.GetFiles(_badgesPath, searchPattern); if (files.Length != 0) { Sprite val = LoadSpriteFromFile(files[0]); if ((Object)(object)val != (Object)null) { _badgeSprites[i] = val; } } } string text = Path.Combine(_badgesPath, "Overlay_Unlocked.png"); string text2 = Path.Combine(_badgesPath, "Overlay_Locked.png"); if (File.Exists(text)) { _unlockedOverlay = LoadSpriteFromFile(text); } if (File.Exists(text2)) { _lockedOverlay = LoadSpriteFromFile(text2); } GlobalSavePlugin.Logger.LogInfo((object)$"Loaded {_badgeSprites.Count} badge images from PNG"); } catch (Exception ex) { GlobalSavePlugin.Logger.LogError((object)("PNG folder load error: " + ex.Message)); } } private static Sprite LoadSpriteFromFile(string filePath) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) try { byte[] array = File.ReadAllBytes(filePath); Texture2D val = new Texture2D(2, 2); if (ImageConversion.LoadImage(val, array)) { ((Texture)val).filterMode = (FilterMode)1; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } catch { } return null; } private static void LoadGameFont() { if (_fontLoaded) { return; } _fontLoaded = true; try { if (_nachoType != null) { FieldInfo fieldInfo = AccessTools.Field(_nachoType, "AchievementsFont"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(null); _gameFont = (TMP_FontAsset)((value is TMP_FontAsset) ? value : null); if ((Object)(object)_gameFont != (Object)null) { GlobalSavePlugin.Logger.LogInfo((object)"Using NachoAchievements font"); return; } } } TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); TMP_FontAsset[] array2 = array; foreach (TMP_FontAsset val in array2) { if (((Object)val).name.Contains("3270")) { _gameFont = val; GlobalSavePlugin.Logger.LogInfo((object)("Found game font: " + ((Object)val).name)); return; } } if (array.Length != 0) { _gameFont = array[0]; GlobalSavePlugin.Logger.LogInfo((object)("Using fallback font: " + ((Object)_gameFont).name)); } } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to load game font: {arg}"); } } private static void InitializeCache() { if (!_cacheInitialized) { _nachoType = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); if (_nachoType != null) { _achievementsTextField = AccessTools.Field(_nachoType, "AchievementsText"); _achievementsField = AccessTools.Field(_nachoType, "Achievements"); _tmpField = AccessTools.Field(_nachoType, "TMP"); _prevTextField = AccessTools.Field(_nachoType, "prevText"); } _gameNetworkManagerType = AccessTools.TypeByName("GameNetworkManager"); if (_gameNetworkManagerType != null) { _gnmInstanceProp = AccessTools.Property(_gameNetworkManagerType, "Instance"); _localPlayerField = AccessTools.Field(_gameNetworkManagerType, "localPlayerController"); } _cacheInitialized = true; } } public static void PostQuickMenuUpdate(object __instance) { try { if (!_cacheInitialized) { InitializeCache(); } if (_nachoType == null || _achievementsTextField == null) { return; } if (!(_achievementsTextField.GetValue(null) is IList list) || list.Count == 0) { CleanupUI(); return; } if ((Object)(object)_uiContainer == (Object)null) { CreateEnhancedUI(list); _selectedIndex = 0; } DetectInputMode(); Gamepad current = Gamepad.current; if (current != null) { HandleGamepadInput(current, list); } Keyboard current2 = Keyboard.current; if (current2 != null) { HandleKeyboardInput(current2, list); } ClearMouseDescription(); UpdateUI(list); } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Menu update failed: {arg}"); } } private static void DetectInputMode() { //IL_0102: 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) Gamepad current = Gamepad.current; if (current != null && (current.dpad.up.isPressed || current.dpad.down.isPressed || Mathf.Abs(((InputControl<float>)(object)((Vector2Control)current.leftStick).y).ReadValue()) > 0.3f || current.buttonSouth.isPressed || current.buttonEast.isPressed)) { _lastControllerInput = Time.time; _isControllerMode = true; } Keyboard current2 = Keyboard.current; if (current2 != null && (((ButtonControl)current2.upArrowKey).isPressed || ((ButtonControl)current2.downArrowKey).isPressed || ((ButtonControl)current2.wKey).isPressed || ((ButtonControl)current2.sKey).isPressed)) { _lastControllerInput = Time.time; _isControllerMode = true; } Mouse current3 = Mouse.current; if (current3 == null) { return; } Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current3).delta).ReadValue(); if (((Vector2)(ref val)).magnitude > 5f) { _lastMouseInput = Time.time; if (_isControllerMode && Time.time - _lastControllerInput > 0.5f) { _isControllerMode = false; } } } private static void ClearMouseDescription() { try { if (_tmpField != null) { object value = _tmpField.GetValue(null); if (value != null) { Object.Destroy((Object)((value is Object) ? value : null)); _tmpField.SetValue(null, null); } } if (_prevTextField != null) { _prevTextField.SetValue(null, string.Empty); } if (!(_achievementsTextField != null) || !(_achievementsTextField.GetValue(null) is IList list)) { return; } foreach (object item in list) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val != (Object)null && val.activeSelf) { val.SetActive(false); } } } catch { } } private static void HandleGamepadInput(Gamepad gamepad, IList achievementsText) { bool isPressed = gamepad.startButton.isPressed; bool isPressed2 = gamepad.buttonEast.isPressed; bool isPressed3 = gamepad.dpad.up.isPressed; bool isPressed4 = gamepad.dpad.down.isPressed; float num = ((InputControl<float>)(object)((Vector2Control)gamepad.leftStick).y).ReadValue(); if (_wasStartPressed && !isPressed) { CloseAchievementsMenu(achievementsText); } else if (_wasBPressed && !isPressed2) { CloseAchievementsMenu(achievementsText); } if (isPressed3 && !_wasDPadUpPressed) { NavigateUp(achievementsText); } if (isPressed4 && !_wasDPadDownPressed) { NavigateDown(achievementsText); } _stickScrollCooldown -= Time.deltaTime; if (_stickScrollCooldown <= 0f) { if (num > 0.5f) { NavigateUp(achievementsText); _stickScrollCooldown = 0.12f; } else if (num < -0.5f) { NavigateDown(achievementsText); _stickScrollCooldown = 0.12f; } } _wasStartPressed = isPressed; _wasBPressed = isPressed2; _wasDPadUpPressed = isPressed3; _wasDPadDownPressed = isPressed4; } private static void HandleKeyboardInput(Keyboard keyboard, IList achievementsText) { bool flag = ((ButtonControl)keyboard.upArrowKey).isPressed || ((ButtonControl)keyboard.wKey).isPressed; bool flag2 = ((ButtonControl)keyboard.downArrowKey).isPressed || ((ButtonControl)keyboard.sKey).isPressed; bool isPressed = ((ButtonControl)keyboard.escapeKey).isPressed; if (_wasEscapePressed && !isPressed) { CloseAchievementsMenu(achievementsText); } if (flag && !_wasUpArrowPressed) { NavigateUp(achievementsText); _keyboardScrollCooldown = 0.4f; } else if (flag2 && !_wasDownArrowPressed) { NavigateDown(achievementsText); _keyboardScrollCooldown = 0.4f; } else if (_keyboardScrollCooldown > 0f) { _keyboardScrollCooldown -= Time.deltaTime; } else if (_keyboardScrollCooldown <= 0f) { if (flag && _wasUpArrowPressed) { NavigateUp(achievementsText); _keyboardScrollCooldown = 0.12f; } else if (flag2 && _wasDownArrowPressed) { NavigateDown(achievementsText); _keyboardScrollCooldown = 0.12f; } } _wasUpArrowPressed = flag; _wasDownArrowPressed = flag2; _wasEscapePressed = isPressed; } private static void NavigateUp(IList achievementsText) { if (_selectedIndex > 0) { _selectedIndex--; ScrollToSelectedItem(achievementsText); UpdateDescription(); } } private static void NavigateDown(IList achievementsText) { if (_selectedIndex < achievementsText.Count - 1) { _selectedIndex++; ScrollToSelectedItem(achievementsText); UpdateDescription(); } } private static void ScrollToSelectedItem(IList achievementsText) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (achievementsText.Count == 0 || (Object)(object)_contentArea == (Object)null) { return; } Transform val = _contentArea.transform.Find($"Card_{_selectedIndex}"); if ((Object)(object)val == (Object)null) { return; } RectTransform component = ((Component)val).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { float y = component.anchoredPosition.y; float num = 200f; float num2 = -200f; if (y > num) { float num3 = y - num + 20f; ScrollAllCards(0f - num3); } else if (y < num2) { float delta = num2 - y + 20f; ScrollAllCards(delta); } } } private static void ScrollAllCards(float delta) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_contentArea == (Object)null) { return; } foreach (Transform item in _contentArea.transform) { Transform val = item; if (!(((Object)val).name == "SelectionHighlight")) { RectTransform component = ((Component)val).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition += new Vector2(0f, delta); } } } } private static void ScrollAllItems(IList achievementsText, float delta) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) foreach (object item in achievementsText) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val != (Object)null) { RectTransform component = val.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition += new Vector2(0f, delta); } } } } private static void CreateEnhancedUI(IList achievementsText) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: 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_0306: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Expected O, but got Unknown //IL_0357: 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_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Expected O, but got Unknown //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Expected O, but got Unknown //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Unknown result type (might be due to invalid IL or missing references) //IL_05bd: Unknown result type (might be due to invalid IL or missing references) //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Expected O, but got Unknown //IL_06bb: Unknown result type (might be due to invalid IL or missing references) //IL_06d1: Unknown result type (might be due to invalid IL or missing references) //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_06eb: Unknown result type (might be due to invalid IL or missing references) try { object? obj = AccessTools.Field(_nachoType, "AchievementsCanvas")?.GetValue(null); Canvas val = (Canvas)((obj is Canvas) ? obj : null); if (!((Object)(object)val == (Object)null)) { _uiContainer = new GameObject("EnhancedAchievementsUI"); _uiContainer.transform.SetParent(((Component)val).transform, false); RectTransform val2 = _uiContainer.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(750f, 700f); _backgroundPanel = CreatePanel(_uiContainer.transform, "BackgroundPanel", Vector2.zero, new Vector2(700f, 680f), new Color(0.05f, 0.05f, 0.08f, 0.97f)); GameObject val3 = CreatePanel(_backgroundPanel.transform, "OuterBorder", Vector2.zero, new Vector2(704f, 684f), new Color(0.4f, 0.35f, 0.15f, 1f)); val3.transform.SetAsFirstSibling(); GameObject val4 = CreatePanel(_backgroundPanel.transform, "InnerBorder", Vector2.zero, new Vector2(702f, 682f), new Color(0.2f, 0.18f, 0.08f, 1f)); val4.transform.SetSiblingIndex(1); GameObject val5 = CreatePanel(_backgroundPanel.transform, "Header", new Vector2(0f, 300f), new Vector2(680f, 70f), new Color(0.12f, 0.1f, 0.06f, 1f)); LoadGameFont(); GameObject val6 = new GameObject("TitleText"); val6.transform.SetParent(val5.transform, false); _titleText = val6.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_titleText).text = "★ 도 전 과 제 ★"; if ((Object)(object)_gameFont != (Object)null) { ((TMP_Text)_titleText).font = _gameFont; } ((TMP_Text)_titleText).fontSize = 36f; ((TMP_Text)_titleText).alignment = (TextAlignmentOptions)514; ((Graphic)_titleText).color = ACCENT_COLOR; ((TMP_Text)_titleText).fontStyle = (FontStyles)1; ((TMP_Text)_titleText).characterSpacing = 8f; RectTransform component = val6.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; GameObject val7 = CreatePanel(_backgroundPanel.transform, "ProgressBg", new Vector2(0f, 255f), new Vector2(660f, 25f), new Color(0.15f, 0.15f, 0.18f, 1f)); GameObject val8 = new GameObject("ProgressFill"); val8.transform.SetParent(val7.transform, false); Image val9 = val8.AddComponent<Image>(); ((Graphic)val9).color = ACCENT_COLOR; RectTransform component2 = val8.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(0f, 1f); component2.pivot = new Vector2(0f, 0.5f); component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; float maxWidth = 660f; GameObject val10 = new GameObject("ProgressText"); val10.transform.SetParent(val7.transform, false); _progressText = val10.AddComponent<TextMeshProUGUI>(); if ((Object)(object)_gameFont != (Object)null) { ((TMP_Text)_progressText).font = _gameFont; } ((TMP_Text)_progressText).fontSize = 16f; ((TMP_Text)_progressText).alignment = (TextAlignmentOptions)514; ((Graphic)_progressText).color = Color.white; RectTransform component3 = val10.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.sizeDelta = Vector2.zero; UpdateProgressBar(val8, maxWidth); _contentArea = new GameObject("ContentArea"); _contentArea.transform.SetParent(_backgroundPanel.transform, false); RectTransform val11 = _contentArea.AddComponent<RectTransform>(); val11.anchoredPosition = new Vector2(0f, -30f); val11.sizeDelta = new Vector2(670f, 500f); Image val12 = _contentArea.AddComponent<Image>(); ((Graphic)val12).color = new Color(0f, 0f, 0f, 0.01f); Mask val13 = _contentArea.AddComponent<Mask>(); val13.showMaskGraphic = false; CreateAchievementCards(achievementsText, _contentArea.transform, 650f); _scrollbarBg = CreatePanel(_backgroundPanel.transform, "ScrollbarBg", new Vector2(335f, -30f), new Vector2(8f, 480f), new Color(0.2f, 0.2f, 0.25f, 0.6f)); _scrollbarHandle = CreatePanel(_scrollbarBg.transform, "ScrollbarHandle", new Vector2(0f, 200f), new Vector2(8f, 60f), ACCENT_COLOR); _descriptionPanel = CreatePanel(_backgroundPanel.transform, "DescriptionPanel", new Vector2(0f, -305f), new Vector2(680f, 60f), new Color(0.08f, 0.08f, 0.1f, 1f)); GameObject val14 = new GameObject("DescriptionText"); val14.transform.SetParent(_descriptionPanel.transform, false); _descriptionText = val14.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_descriptionText).text = "▲ ▼ 도전과제를 선택하세요"; if ((Object)(object)_gameFont != (Object)null) { ((TMP_Text)_descriptionText).font = _gameFont; } ((TMP_Text)_descriptionText).fontSize = 18f; ((TMP_Text)_descriptionText).alignment = (TextAlignmentOptions)514; ((Graphic)_descriptionText).color = new Color(0.7f, 0.7f, 0.7f, 1f); RectTransform component4 = val14.GetComponent<RectTransform>(); component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.sizeDelta = Vector2.zero; HideOriginalItems(achievementsText); if (achievementsText.Count > 0) { _selectedIndex = 0; UpdateDescription(); } } } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to create enhanced UI: {arg}"); } } private static void UpdateProgressBar(GameObject progressFill, float maxWidth) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) try { if (!(_achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary)) { return; } int count = dictionary.Count; int num = dictionary.Values.Count((Dictionary<string, string> a) => a.ContainsKey("completed") && a["completed"] == "True"); float num2 = ((count > 0) ? ((float)num / (float)count) : 0f); bool flag = num == count && count > 0; RectTransform component = progressFill.GetComponent<RectTransform>(); Image component2 = progressFill.GetComponent<Image>(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(num2, 1f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; if (flag) { RainbowGradientAnimator component3 = progressFill.GetComponent<RainbowGradientAnimator>(); if ((Object)(object)component3 == (Object)null) { component3 = progressFill.AddComponent<RainbowGradientAnimator>(); component3.speed = 0.4f; component3.waveLength = 0.6f; component3.saturation = 0.65f; component3.brightness = 0.95f; } ProgressGlowAnimator component4 = progressFill.GetComponent<ProgressGlowAnimator>(); if ((Object)(object)component4 != (Object)null) { Object.Destroy((Object)(object)component4); } } else if ((Object)(object)component2 != (Object)null) { RainbowGradientAnimator component5 = progressFill.GetComponent<RainbowGradientAnimator>(); if ((Object)(object)component5 != (Object)null) { Object.Destroy((Object)(object)component5); } ((Graphic)component2).color = ACCENT_COLOR; if (num2 > 0.01f) { ProgressGlowAnimator component6 = progressFill.GetComponent<ProgressGlowAnimator>(); if ((Object)(object)component6 == (Object)null) { component6 = progressFill.AddComponent<ProgressGlowAnimator>(); component6.pulseSpeed = 3f; component6.minAlpha = 0.4f; component6.maxAlpha = 0.9f; component6.glowWidth = 12f; } } } if ((Object)(object)_progressText != (Object)null) { if (flag) { ((TMP_Text)_progressText).text = $"★ {num}/{count} (100%) - 완전 정복! ★"; ((Graphic)_progressText).color = new Color(0.15f, 0.1f, 0f, 1f); ((TMP_Text)_progressText).fontStyle = (FontStyles)1; } else { ((TMP_Text)_progressText).text = $"{num}/{count} ({num2 * 100f:F1}%)"; ((Graphic)_progressText).color = Color.white; ((TMP_Text)_progressText).fontStyle = (FontStyles)0; } } } catch { } } private static void CreateAchievementCards(IList achievementsText, Transform parent, float cardWidth) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: 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_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Expected O, but got Unknown //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Expected O, but got Unknown //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Expected O, but got Unknown //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) if (!(_achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary)) { return; } LoadBadgeImages(); LoadGameFont(); string[] array = dictionary.Keys.ToArray(); float num = 220f; float num2 = 70f; float num3 = 8f; _selectionHighlight = CreatePanel(parent, "SelectionHighlight", new Vector2(0f, num), new Vector2(cardWidth, num2), HIGHLIGHT_COLOR); _selectionHighlight.transform.SetAsFirstSibling(); for (int i = 0; i < achievementsText.Count && i < array.Length; i++) { string text = array[i]; Dictionary<string, string> dictionary2 = dictionary[text]; bool flag = dictionary2.ContainsKey("completed") && dictionary2["completed"] == "True"; float num4 = num - (float)i * (num2 + num3); GameObject val = CreatePanel(parent, $"Card_{i}", new Vector2(0f, num4), new Vector2(cardWidth, num2), flag ? new Color(0.12f, 0.18f, 0.12f, 0.9f) : new Color(0.1f, 0.1f, 0.12f, 0.9f)); GameObject val2 = CreatePanel(val.transform, "Border", Vector2.zero, new Vector2(cardWidth + 2f, num2 + 2f), flag ? new Color(0.4f, 0.6f, 0.3f, 0.5f) : new Color(0.3f, 0.3f, 0.35f, 0.5f)); val2.transform.SetAsFirstSibling(); int key = i + 1; bool flag2 = _badgeSprites.ContainsKey(key); bool flag3 = flag2 && flag; GameObject val3 = CreatePanel(val.transform, "IconBg", new Vector2(0f - cardWidth / 2f + 45f, 0f), new Vector2(75f, 75f), flag3 ? Color.clear : (flag ? ACCENT_COLOR : LOCKED_COLOR)); if (flag3) { GameObject val4 = new GameObject("BadgeImage"); val4.transform.SetParent(val3.transform, false); Image val5 = val4.AddComponent<Image>(); val5.sprite = _badgeSprites[key]; val5.preserveAspect = true; RectTransform component = val4.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(70f, 70f); component.anchoredPosition = Vector2.zero; } else { GameObject val6 = CreatePanel(val3.transform, "IconInner", Vector2.zero, new Vector2(65f, 65f), flag ? new Color(0.2f, 0.15f, 0.05f, 1f) : new Color(0.25f, 0.25f, 0.28f, 1f)); GameObject val7 = new GameObject("Symbol"); val7.transform.SetParent(val3.transform, false); TextMeshProUGUI val8 = val7.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val8).text = (flag ? "✓" : "?"); ((TMP_Text)val8).fontSize = (flag ? 28f : 32f); ((TMP_Text)val8).alignment = (TextAlignmentOptions)514; ((Graphic)val8).color = (Color)(flag ? ACCENT_COLOR : new Color(0.5f, 0.5f, 0.5f, 1f)); ((TMP_Text)val8).fontStyle = (FontStyles)1; RectTransform component2 = val7.GetComponent<RectTransform>(); component2.sizeDelta = new Vector2(55f, 55f); } GameObject val9 = new GameObject("Title"); val9.transform.SetParent(val.transform, false); TextMeshProUGUI val10 = val9.AddComponent<TextMeshProUGUI>(); object? obj = achievementsText[i]; GameObject val11 = (GameObject)((obj is GameObject) ? obj : null); TextMeshProUGUI val12 = ((val11 != null) ? val11.GetComponent<TextMeshProUGUI>() : null); ((TMP_Text)val10).text = ((val12 != null) ? ((TMP_Text)val12).text : null) ?? text; if ((Object)(object)_gameFont != (Object)null) { ((TMP_Text)val10).font = _gameFont; } ((TMP_Text)val10).fontSize = 20f; ((TMP_Text)val10).alignment = (TextAlignmentOptions)513; ((Graphic)val10).color = (Color)(flag ? COMPLETED_COLOR : new Color(0.85f, 0.85f, 0.85f, 1f)); ((TMP_Text)val10).fontStyle = (FontStyles)(flag ? 1 : 0); RectTransform component3 = val9.GetComponent<RectTransform>(); component3.anchoredPosition = new Vector2(40f, 8f); component3.sizeDelta = new Vector2(cardWidth - 100f, 30f); GameObject val13 = new GameObject("Status"); val13.transform.SetParent(val.transform, false); TextMeshProUGUI val14 = val13.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val14).text = (flag ? "★ 달성 완료" : "○ 미달성"); if ((Object)(object)_gameFont != (Object)null) { ((TMP_Text)val14).font = _gameFont; } ((TMP_Text)val14).fontSize = 14f; ((TMP_Text)val14).alignment = (TextAlignmentOptions)513; ((Graphic)val14).color = (flag ? new Color(0.7f, 0.7f, 0.4f, 1f) : new Color(0.5f, 0.5f, 0.5f, 1f)); RectTransform component4 = val13.GetComponent<RectTransform>(); component4.anchoredPosition = new Vector2(40f, -15f); component4.sizeDelta = new Vector2(cardWidth - 100f, 20f); } } private static void HideOriginalItems(IList achievementsText) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown foreach (object item in achievementsText) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val != (Object)null) { val.SetActive(false); RectTransform component = val.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(-9999f, -9999f); } } } try { object? obj = AccessTools.Field(_nachoType, "AchievementsCanvas")?.GetValue(null); Canvas val2 = (Canvas)((obj is Canvas) ? obj : null); if (!((Object)(object)val2 != (Object)null)) { return; } foreach (Transform item2 in ((Component)val2).transform) { Transform val3 = item2; if (((Object)((Component)val3).gameObject).name.StartsWith("AchievementsText")) { ((Component)val3).gameObject.SetActive(false); } } } catch { } } private static void ReparentAchievementItems(IList achievementsText, Transform parent) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) float num = 250f; float num2 = 75f; for (int i = 0; i < achievementsText.Count; i++) { object? obj = achievementsText[i]; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val == (Object)null)) { val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(-50f, num - (float)i * num2); } } } } private static GameObject CreatePanel(Transform parent, string name, Vector2 position, Vector2 size, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = color; RectTransform component = val.GetComponent<RectTransform>(); component.anchoredPosition = position; component.sizeDelta = size; return val; } private static void StyleAchievementItems(IList achievementsText) { } private static void UpdateProgressText() { try { if (!((Object)(object)_progressText == (Object)null) && _achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary) { int count = dictionary.Count; int num = dictionary.Values.Count((Dictionary<string, string> a) => a.ContainsKey("completed") && a["completed"] == "True"); float num2 = ((count > 0) ? ((float)num / (float)count * 100f) : 0f); ((TMP_Text)_progressText).text = $"진행률: {num}/{count} ({num2:F1}%)"; } } catch { } } private static void UpdateDescription() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_descriptionText == (Object)null || !(_achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary)) { return; } string[] array = dictionary.Keys.ToArray(); if (_selectedIndex >= 0 && _selectedIndex < array.Length) { string key = array[_selectedIndex]; if (dictionary[key].ContainsKey("description")) { ((TMP_Text)_descriptionText).text = dictionary[key]["description"]; ((TMP_Text)_descriptionText).fontStyle = (FontStyles)0; ((Graphic)_descriptionText).color = Color.white; } } } catch { } } private static void DetectMouseClick(IList achievementsText) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Invalid comparison between Unknown and I4 //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_contentArea == (Object)null) { return; } Mouse current = Mouse.current; if (current == null) { return; } bool isPressed = current.leftButton.isPressed; bool flag = isPressed && !_wasMouseLeftPressed; _wasMouseLeftPressed = isPressed; if (!flag) { return; } Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue(); for (int i = 0; i < achievementsText.Count; i++) { Transform val2 = _contentArea.transform.Find($"Card_{i}"); if ((Object)(object)val2 == (Object)null) { continue; } RectTransform component = ((Component)val2).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); Camera val3 = null; object? obj = AccessTools.Field(_nachoType, "AchievementsCanvas")?.GetValue(null); Canvas val4 = (Canvas)((obj is Canvas) ? obj : null); if ((Object)(object)val4 != (Object)null && (int)val4.renderMode > 0) { val3 = val4.worldCamera ?? Camera.main; } Vector2 val5; Vector2 val6; if ((Object)(object)val3 != (Object)null) { val5 = RectTransformUtility.WorldToScreenPoint(val3, array[0]); val6 = RectTransformUtility.WorldToScreenPoint(val3, array[2]); } else { val5 = Vector2.op_Implicit(array[0]); val6 = Vector2.op_Implicit(array[2]); } if (val.x >= val5.x && val.x <= val6.x && val.y >= val5.y && val.y <= val6.y) { _selectedIndex = i; _isControllerMode = false; UpdateDescription(); break; } } } } private static void HandleMouseScroll(IList achievementsText) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_contentArea == (Object)null) { return; } Mouse current = Mouse.current; if (current == null) { return; } float num = ((InputControl<float>)(object)((Vector2Control)current.scroll).y).ReadValue(); if (Mathf.Abs(num) < 1f) { return; } float num2 = 0.5f; float num3 = num * num2; float num4 = 70f; float num5 = 8f; float num6 = 220f; float num7 = (float)achievementsText.Count * (num4 + num5); float num8 = 500f; float num9 = Mathf.Max(0f, num7 - num8); Transform val = _contentArea.transform.Find("Card_0"); if (!((Object)(object)val == (Object)null)) { RectTransform component = ((Component)val).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { float y = component.anchoredPosition.y; float num10 = y - num6; float num11 = Mathf.Clamp(num10 - num3, 0f, num9); float delta = num11 - num10; ScrollAllCards(delta); } } } private static void HandleScrollbarClick(IList achievementsText) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scrollbarBg == (Object)null || (Object)(object)_contentArea == (Object)null) { return; } Mouse current = Mouse.current; if (current == null) { return; } bool isPressed = current.leftButton.isPressed; Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue(); RectTransform component = _scrollbarBg.GetComponent<RectTransform>(); if ((Object)(object)component == (Object)null) { return; } Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); Vector2 val2 = Vector2.op_Implicit(array[0]); Vector2 val3 = Vector2.op_Implicit(array[2]); bool flag = val.x >= val2.x && val.x <= val3.x && val.y >= val2.y && val.y <= val3.y; if (isPressed && flag && !_isDraggingScrollbar) { _isDraggingScrollbar = true; } if (!isPressed) { _isDraggingScrollbar = false; } if (_isDraggingScrollbar && isPressed) { float num = Mathf.Clamp(val.y, val2.y, val3.y); float num2 = 1f - (num - val2.y) / (val3.y - val2.y); float num3 = 70f; float num4 = 8f; float num5 = 220f; float num6 = (float)achievementsText.Count * (num3 + num4); float num7 = 500f; float num8 = Mathf.Max(0f, num6 - num7); float num9 = num2 * num8; Transform val4 = _contentArea.transform.Find("Card_0"); if (!((Object)(object)val4 == (Object)null)) { RectTransform component2 = ((Component)val4).GetComponent<RectTransform>(); float y = component2.anchoredPosition.y; float num10 = y - num5; float delta = num9 - num10; ScrollAllCards(delta); } } } private static void UpdateUI(IList achievementsText) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) HandleMouseScroll(achievementsText); HandleScrollbarClick(achievementsText); DetectMouseClick(achievementsText); if ((Object)(object)_selectionHighlight != (Object)null && (Object)(object)_contentArea != (Object)null && _selectedIndex >= 0 && _selectedIndex < achievementsText.Count) { _selectionHighlight.SetActive(true); Transform val = _contentArea.transform.Find($"Card_{_selectedIndex}"); if ((Object)(object)val != (Object)null) { RectTransform component = ((Component)val).GetComponent<RectTransform>(); RectTransform component2 = _selectionHighlight.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { component2.anchoredPosition = component.anchoredPosition; } } Image component3 = _selectionHighlight.GetComponent<Image>(); if ((Object)(object)component3 != (Object)null) { ((Graphic)component3).color = (_isControllerMode ? new Color(1f, 0.8f, 0.2f, 0.35f) : new Color(1f, 0.8f, 0.2f, 0.15f)); } } UpdateScrollbar(achievementsText); } private static void UpdateScrollbar(IList achievementsText) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scrollbarHandle == (Object)null || (Object)(object)_contentArea == (Object)null || achievementsText.Count == 0) { return; } try { int count = achievementsText.Count; float num = 70f; float num2 = 8f; float num3 = (float)count * (num + num2); float num4 = 500f; float num5 = Mathf.Max(0f, num3 - num4); if (num5 <= 0f) { _scrollbarHandle.SetActive(false); return; } _scrollbarHandle.SetActive(true); Transform val = _contentArea.transform.Find("Card_0"); if (!((Object)(object)val == (Object)null)) { RectTransform component = ((Component)val).GetComponent<RectTransform>(); float num6 = 220f; float y = component.anchoredPosition.y; float num7 = y - num6; float num8 = Mathf.Clamp01(num7 / num5); RectTransform component2 = _scrollbarHandle.GetComponent<RectTransform>(); float num9 = num4 - 40f; float num10 = Mathf.Max(40f, num9 * (num4 / num3)); component2.sizeDelta = new Vector2(8f, num10); float num11 = (num9 - num10) / 2f - num8 * (num9 - num10); component2.anchoredPosition = new Vector2(0f, num11); } } catch { } } private static void CleanupUI() { if ((Object)(object)_uiContainer != (Object)null) { Object.Destroy((Object)(object)_uiContainer); _uiContainer = null; _backgroundPanel = null; _contentArea = null; _titleBar = null; _progressBar = null; _scrollbarBg = null; _scrollbarHandle = null; _selectionHighlight = null; _descriptionPanel = null; _descriptionText = null; _titleText = null; _progressText = null; } _selectedIndex = 0; _isControllerMode = false; _wasUpArrowPressed = false; _wasDownArrowPressed = false; _wasEscapePressed = false; } private static void CloseAchievementsMenu(IList achievementsText) { try { CleanupUI(); ClearMouseDescription(); foreach (object item in achievementsText) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } achievementsText.Clear(); if (_gnmInstanceProp != null && _localPlayerField != null) { object value = _gnmInstanceProp.GetValue(null); if (value != null) { object value2 = _localPlayerField.GetValue(value); if (value2 != null) { if (_quickMenuField == null) { _quickMenuField = AccessTools.Field(value2.GetType(), "quickMenuManager"); } object obj = _quickMenuField?.GetValue(value2); if (obj != null) { if (_mainButtonsField == null) { _mainButtonsField = AccessTools.Field(obj.GetType(), "mainButtonsPanel"); } object? obj2 = _mainButtonsField?.GetValue(obj); GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val2 != null) { val2.SetActive(true); } } } } } GlobalSavePlugin.Logger.LogInfo((object)"Closed achievements menu."); } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Failed to close achievements menu: {arg}"); } } } public static class AchievementPopupPatches { private static GameObject _popupContainer = null; private const float POPUP_DURATION = 4f; private const float SLIDE_DURATION = 0.4f; private static readonly Color POPUP_BG_COLOR = new Color(0.05f, 0.05f, 0.08f, 0.95f); private static readonly Color GOLD_COLOR = new Color(1f, 0.85f, 0.2f, 1f); private static int _currentBadgeIndex = -1; private static Queue<string> _popupQueue = new Queue<string>(); private static bool _isShowingPopup = false; private static float _nextPopupDelay = 0f; private static int FindBadgeIndex(string achievementKey) { try { Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); if (AccessTools.Field(type, "Achievements")?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary) { int num = 1; foreach (string key in dictionary.Keys) { if (key == achievementKey) { GlobalSavePlugin.Logger.LogInfo((object)$"Found badge index {num} for achievement key: {achievementKey}"); return num; } num++; } } GlobalSavePlugin.Logger.LogWarning((object)("Badge not found for achievement key: " + achievementKey)); } catch (Exception ex) { GlobalSavePlugin.Logger.LogError((object)("FindBadgeIndex error: " + ex.Message)); } return -1; } private static string GetAchievementName(string achievementKey) { try { Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); if (AccessTools.Field(type, "Achievements")?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary && dictionary.ContainsKey(achievementKey)) { Dictionary<string, string> dictionary2 = dictionary[achievementKey]; if (dictionary2.ContainsKey("name")) { return dictionary2["name"]; } } } catch { } return achievementKey; } public static bool CreateEnhancedAchievementPopup(string text) { try { if (_isShowingPopup && (Object)(object)_popupContainer != (Object)null) { _popupQueue.Enqueue(text); GlobalSavePlugin.Logger.LogInfo((object)$"Achievement queued: {text} (Queue size: {_popupQueue.Count})"); SetOriginalFields(); return false; } ShowPopup(text); return false; } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"Enhanced popup failed: {arg}"); return true; } } private static void ShowPopup(string achievementKey) { try { CleanupPopup(); _isShowingPopup = true; _currentBadgeIndex = FindBadgeIndex(achievementKey); string achievementName = GetAchievementName(achievementKey); Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); FieldInfo fieldInfo = AccessTools.Field(type, "AchievementsCanvas"); object? obj = fieldInfo?.GetValue(null); Canvas val = (Canvas)((obj is Canvas) ? obj : null); if ((Object)(object)val == (Object)null) { AccessTools.Method(type, "CreateAchievementsCanvas", (Type[])null, (Type[])null)?.Invoke(null, null); object? obj2 = fieldInfo?.GetValue(null); val = (Canvas)((obj2 is Canvas) ? obj2 : null); } if ((Object)(object)val == (Object)null) { _isShowingPopup = false; return; } CreatePopupUI(val, achievementName); PlayAchievementSound(); AccessTools.Field(type, "destroyTimer")?.SetValue(null, 0f); SetOriginalFields(); StartPopupAnimation(); GlobalSavePlugin.Logger.LogInfo((object)("Showing popup for: " + achievementKey + " (" + achievementName + ")")); } catch (Exception arg) { GlobalSavePlugin.Logger.LogError((object)$"ShowPopup failed: {arg}"); _isShowingPopup = false; } } private static void SetOriginalFields() { try { Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements"); FieldInfo fieldInfo = AccessTools.Field(type, "achievementGetText"); FieldInfo fieldInfo2 = AccessTools.Field(type, "achievementGetTextSubtitle"); if ((Object)(object)_popupContainer != (Object)null) { fieldInfo?.SetValue(null, _popupContainer); fieldInfo2?.SetValue(null, _popupContainer); } } catch { } } public static void OnPopupComplete() { _isShowingPopup = false; _popupContainer = null; if (_popupQueue.Count > 0) { string text = _popupQueue.Dequeue(); GlobalSavePlugin.Logger.LogInfo((object)$"Showing next queued popup: {text} (Remaining: {_popupQueue.Count})"); ShowPopup(text); } } private static void CreatePopupUI(Canvas canvas, string achievementName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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) //IL_00f5: 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) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Expected O, but got Unknown //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_0307: 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_0328: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Expected O, but got Unknown //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Expected O, but got Unknown //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Expected O, but got Unknown //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_061f: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Expected O, but got Unknown //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_06a4: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Unknown result type (might be due to invalid IL or missing references) //IL_06be: Unknown result type (might be due to invalid IL or missing references) _popupContainer = new GameObject("EnhancedAchievementPopup"); _popupContainer.transform.SetParent(((Component)canvas).transform, false); RectTransform val = _popupContainer.AddComponent<RectTransform>(); val.anchorMin = new Vector2(0.5f, 1f); val.anchorMax = new Vector2(0.5f, 1f); val.pivot = new Vector2(0.5f, 1f); val.anchoredPosition = new Vector2(0f, 200f); val.sizeDelta = new Vector2(700f, 140f); GameObject val2 = new GameObject("Background"); val2.transform.SetParent(_popupContainer.transform, false); Image val3 = val2.AddComponent<Image>(); ((Graphic)val3).color = POPUP_BG_COLOR; RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; component.anchoredPosition = Vector2.zero; Outline val4 = val2.AddComponent<Outline>(); ((Shadow)val4).effectColor = GOLD_COLOR; ((Shadow)val4).effectDistance = new Vector2(3f, 3f); GameObject val5 = new GameObject("TopLine"); val5.transform.SetParent(_popupContainer.transform, false); Image val6 = val5.AddComponent<Image>(); ((Graphic)val6).color = GOLD_COLOR; RectTransform component2 = val5.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(1f, 1f); component2.pivot = new Vector2(0.5f, 1f); component2.sizeDelta = new Vector2(0f, 4f); component2.anchoredPosition = Vector2.zero; GameObject val7 = new GameObject("BottomLine"); val7.transform.SetParent(_popupContainer.transform, false); Image val8 = val7.AddComponent<Image>(); ((Graphic)val8).color = GOLD_COLOR; RectTransform component3 = val7.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 0f); component3.anchorMax = new Vector2(1f, 0f); component3.pivot = new Vector2(0.5f, 0f); component3.sizeDelta = new Vector2(0f, 4f); component3.anchoredPosition = Vector2.zero; GameObject val9 = new GameObject("TrophyIcon"); val9.transform.SetParent(_popupContainer.transform, false); Image val10 = val9.AddComponent<Image>(); if (_currentBadgeIndex > 0 && MenuPatches.HasBadgeSprite(_currentBadgeIndex)) { val10.sprite = MenuPatches.GetBadgeSprite(_currentBadgeIndex); val10.preserveAspect = true; ((Graphic)val10).color = Color.white; } else { ((Graphic)val10).color = GOLD_COLOR; } RectTransform component4 = val9.GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0f, 0.5f); component4.anchorMax = new Vector2(0f, 0.5f); component4.pivot = new Vector2(0f, 0.5f); component4.anchoredPosition = new Vector2(25f, 0f); component4.sizeDelta = new Vector2(90f, 90f); BadgeBounceAnimator badgeBounceAnimator = val9.AddComponent<BadgeBounceAnimator>(); GameObject val11 = new GameObject("Title"); val11.transform.SetParent(_popupContainer.transform, false); TextMeshProUGUI val12 = val11.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val12).text = "★ 도전과제 달성! ★"; ((TMP_Text)val12).fontSize = 28f; ((TMP_Text)val12).fontStyle = (FontStyles)1; ((TMP_Text)val12).alignment = (TextAlignmentOptions)513; ((Graphic)val12).color = GOLD_COLOR; RectTransform component5 = val11.GetComponent<RectTransform>(); component5.anchorMin = new Vector2(0f, 0.5f); component5.anchorMax = new Vector2(1f, 1f); component5.pivot = new Vector2(0f, 0.5f); component5.anchoredPosition = new Vector2(120f, -15f); component5.sizeDelta = new Vector2(-140f, 50f); GameObject val13 = new GameObject("AchievementName"); val13.transform.SetParent(_popupContainer.transform, false); TextMeshProUGUI val14 = val13.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val14).text = achievementName; ((TMP_Text)val14).fontSize = 24f; ((TMP_Text)val14).fontStyle = (FontStyles)0; ((TMP_Text)val14).alignment = (TextAlignmentOptions)513; ((Graphic)val14).color = Color.white; RectTransform component6 = val13.GetComponent<RectTransform>(); component6.anchorMin = new Vector2(0f, 0f); component6.anchorMax = new Vector2(1f, 0.5f); component6.pivot = new Vector2(0f, 0.5f); component6.anchoredPosition = new Vector2(120f, 15f); component6.sizeDelta = new Vector2(-140f, 50f); GameObject val15 = new GameObject("ProgressBg"); val15.transform.SetParent(_popupContainer.transform, false); Image val16 = val15.AddComponent<Image>(); ((Graphic)val16).color = new Color(0.2f, 0.2f, 0.2f, 1f); RectTransform component7 = val15.GetComponent<RectTransform>(); component7.anchorMin = new Vector2(0f, 0f); component7.anchorMax = new Vector2(1f, 0f); component7.pivot = new Vector2(0f, 0f); component7.anchoredPosition = new Vector2(0f, 4f); component7.sizeDelta = new Vector2(0f, 3f); GameObject val17 = new GameObject("ProgressFill"); val17.transform.SetParent(val15.transform, false); Image val18 = val17.AddComponent<Image>(); ((Graphic)val18).color = GOLD_COLOR; RectTransform component8 = val17.GetComponent<RectTransform>(); component8.anchorMin = new Vector2(0f, 0f); component8.anchorMax = new Vector2(1f, 1f); component8.pivot = new Vector2(0f, 0.5f); component8.anchoredPosition = Vector2.zero; component8.sizeDelta = Vector2.zero; PopupProgressAnimator popupProgressAnimator = val17.AddComponent<PopupProgressAnimator>(); popupProgressAnimator.duration = 4f; } private static void PlayAchievementSound() { try { Type type = AccessTools.TypeByName("HUDManager"); object obj = AccessTools.Property(type, "Instance")?.GetValue(null); if (obj != null) { FieldInfo fieldInfo = AccessTools.Field(type, "UIAudio"); FieldInfo fieldInfo2 = AccessTools.Field(type, "levelIncreaseSFX"); object? obj2 = fieldInfo?.GetValue(obj); AudioSource val = (AudioSource)((obj2 is AudioSource) ? obj2 : null); object? obj3 = fieldInfo2?.GetValue(obj); AudioClip val2 = (AudioClip)((obj3 is AudioClip) ? obj3 : null); if (val != null) { val.PlayOneShot(val2); } } } catch { } } private static void StartPopupAnimation() { if (!((Object)(object)_popupContainer == (Object)null)) { PopupAnimator popupAnimator = _popupContainer.AddComponent<PopupAnimator>(); popupAnimator.slideInDuration = 0.4f; popupAnimator.displayDuration = 4f; popupAnimator.slideOutDuration = 0.4f; popupAnimator.targetY = -20f; popupAnimator.startY = 200f; } } private static void CleanupPopup() { if ((Object)(object)_popupContainer != (Object)null) { Object.Destroy((Object)(object)_popupContainer); _popupContainer = null; } } } public class PopupAnimator : MonoBehaviour { private enum AnimState { SlideIn, Display, SlideOut, Done } public float slideInDuration = 0.5f; public float displayDuration = 5f; public float slideOutDuration = 0.5f; public float targetY = -20f; public float startY = 200f; private float _timer = 0f; private RectTransform _rect; private AnimState _state = AnimState.SlideIn; private void Start() { _rect = ((Component)this).GetComponent<RectTransform>(); } private void Update() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) _timer += Time.deltaTime; switch (_state) { case AnimState.SlideIn: { float num5 = Mathf.Clamp01(_timer / slideInDuration); float num6 = EaseOutBack(num5); float num7 = Mathf.Lerp(startY, targetY, num6); _rect.anchoredPosition = new Vector2(0f, num7); if (num5 >= 1f) { _state = AnimState.Display; _timer = 0f; } break; } case AnimState.Display: { float num4 = Mathf.Sin(_timer * 2f) * 2f; _rect.anchoredPosition = new Vector2(0f, targetY + num4); if (_timer >= displayDuration) { _state = AnimState.SlideOut; _timer = 0f; } break; } case AnimState.SlideOut: { float num = Mathf.Clamp01(_timer / slideOutDuration); float num2 = EaseInBack(num); float num3 = Mathf.Lerp(targetY, startY, num2); _rect.anchoredPosition = new Vector2(0f, num3); CanvasGroup val = ((Component)this).GetComponent<CanvasGroup>(); if ((Object)(object)val == (Object)null) { val = ((Component)this).gameObject.AddComponent<CanvasGroup>(); } val.alpha = 1f - num; if (num >= 1f) { _state = AnimState.Done; AchievementPopupPatches.OnPopupComplete(); Object.Destroy((Object)(object)((Component)this).gameObject); } break; } } } private float EaseOutBack(float t) { return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f); } private float EaseInBack(float t) { return 2.70158f * t * t * t - 1.70158f * t * t; } } public class PopupProgressAnimator : MonoBehaviour { public float duration = 5f; private float _timer = 0f; private RectTransform _rect; private void Start() { _rect = ((Component)this).GetComponent<RectTransform>(); } private void Update() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) _timer += Time.deltaTime; float num = Mathf.Clamp01(_timer / duration); _rect.anchorMax = new Vector2(1f - num, 1f); } } public class BadgeBounceAnimator : MonoBehaviour { public float bounceDuration = 0.6f; public float bounceScale = 1.3f; public float rotationAmount = 15f; private float _timer = 0f; private RectTransform _rect; private Vector3 _originalScale; private bool _animationComplete = false; private void Start() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) _rect = ((Component)this).GetComponent<RectTransform>(); _originalScale = ((Transform)_rect).localScale; ((Transform)_rect).localScale = Vector3.zero; } private void Update() { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (!_animationComplete) { _timer += Time.deltaTime; float num = Mathf.Clamp01(_timer / bounceDuration); if (num < 0.5f) { float num2 = num * 2f; float num3 = EaseOutBack(num2) * bounceScale; float num4 = Mathf.Sin(num2 * MathF.PI) * rotationAmount; ((Transform)_rect).localScale = _originalScale * num3; ((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, num4); } else { float num5 = (num - 0.5f) * 2f; float num6 = Mathf.Lerp(bounceScale, 1f, EaseOutBounce(num5)); float num7 = Mathf.Sin((1f - num5) * MathF.PI * 0.5f) * rotationAmount * 0.3f; ((Transform)_rect).localScale = _originalScale * num6; ((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, num7); } if (num >= 1f) { _animationComplete = true; ((Transform)_rect).localScale = _originalScale; ((Transform)_rect).localRotation = Quaternion.identity; } } } private float EaseOutBack(float t) { return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f); } private float EaseOutBounce(float t) { if (t < 0.36363637f) { return 7.5625f * t * t; } if (t < 0.72727275f) { return 7.5625f * (t -= 0.54545456f) * t + 0.75f; } if (t < 0.90909094f) { return 7.5625f * (t -= 0.8181818f) * t + 0.9375f; } return 7.5625f * (t -= 21f / 22f) * t + 63f / 64f; } } public class RainbowGradientAnimator : MonoBehaviour { public float speed = 0.15f; public float waveLength = 1.5f; public float saturation = 0.55f; public float brightness = 0.92f; private Image _image; private float _timeOffset = 0f; private List<Image> _segments = new List<Image>(); private const int SEGMENT_COUNT = 128; private bool _initialized = false; private static Color[] _colorLUT; private const int LUT_SIZE = 256; private int _frameCounter = 0; private const int UPDATE_INTERVAL = 3; static RainbowGradientAnimator() { _colorLUT = null; BuildColorLUT(0.55f, 0.92f); } private static void BuildColorLUT(float sat, float bright) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) _colorLUT = (Color[])(object)new Color[256]; for (int i = 0; i < 256; i++) { float num = (float)i / 256f; _colorLUT[i] = Color.HSVToRGB(num, sat, bright); } } private void Start() { InitializeIfNeeded(); } private void InitializeIfNeeded() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!_initialized) { _initialized = true; _image = ((Component)this).GetComponent<Image>(); if ((Object)(object)_image != (Object)null) { ((Graphic)_image).color = new Color(0f, 0f, 0f, 0f); CreateSegments(); } } } private void CreateSegments() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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) if (_segments.Count <= 0) { for (int i = 0; i < 128; i++) { GameObject val = new GameObject($"Seg{i}"); val.transform.SetParent(((Component)this).transform, false); Image item = val.AddComponent<Image>(); RectTransform component = val.GetComponent<RectTransform>(); float num = 1f / 128f; float num2 = 0.003f; component.anchorMin = new Vector2(Mathf.Max(0f, num * (float)i - num2), 0f); component.anchorMax = new Vector2(Mathf.Min(1f, num * (float)(i + 1) + num2), 1f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; _segments.Add(item); } UpdateColors(); } } private void Update() { if (!_initialized || _segments.Count == 0) { return; } _frameCounter++; if (_frameCounter >= 3) { _frameCounter = 0; _timeOffset += Time.deltaTime * speed * 3f; if (_timeOffset > 1f) { _timeOffset -= 1f; } UpdateColors(); } } private void UpdateColors() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _segments.Count; i++) { if (!((Object)(object)_segments[i] == (Object)null)) { float num = (float)i / 128f; float num2 = (num * waveLength - _timeOffset) % 1f; if (num2 < 0f) { num2 += 1f; } int num3 = (int)(num2 * 255f); ((Graphic)_segments[i]).color = _colorLUT[num3]; } } } private void OnDestroy() { for (int num = _segments.Count - 1; num >= 0; num--) { if ((Object)(object)_segments[num] != (Object)null && (Object)(object)((Component)_segments[num]).gameObject != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)_segments[num]).gameObject); } } _segments.Clear(); _initialized = false; } } public class ProgressGlowAnimator : MonoBehaviour { public float pulseSpeed = 2.5f; public float minAlpha = 0.3f; public float maxAlpha = 0.8f; public float glowWidth = 15f; private Image _glowImage; private RectTransform _glowRect; private float _timer = 0f; private bool _initialized = false; private void Start() { InitializeIfNeeded(); } private void InitializeIfNeeded() { if (!_initialized) { _initialized = true; CreateGlow(); } } private void CreateGlow() { //IL_001b: Unknown result type (might