using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MechGaming")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MonsterGuide")] [assembly: AssemblyTitle("MonsterGuide")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MechGaming.REPO.MonsterGuide { internal static class HotkeyInput { private const int KeyDownMask = 32768; private const float TextInputScanInterval = 0.15f; private static readonly Dictionary PreviousStates = new Dictionary(); private static readonly Type? UnityInputFieldType = Type.GetType("UnityEngine.UI.InputField, UnityEngine.UI"); private static readonly Type? TmpInputFieldType = Type.GetType("TMPro.TMP_InputField, Unity.TextMeshPro"); private static int _currentProcessId; private static float _nextTextInputScanTime; private static bool _cachedNoTextInputActive = true; private static int CurrentProcessId { get { if (_currentProcessId == 0) { _currentProcessId = Process.GetCurrentProcess().Id; } return _currentProcessId; } } internal static bool GetKeyDown(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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) if ((int)key == 0) { return false; } bool flag = GetUnityKeyDown(key) || GetWindowsKey(key); bool value; bool flag2 = PreviousStates.TryGetValue(key, out value) && value; PreviousStates[key] = flag; if (flag) { return !flag2; } return false; } internal static bool NoTextInputActive() { if (Time.unscaledTime < _nextTextInputScanTime) { return _cachedNoTextInputActive; } _nextTextInputScanTime = Time.unscaledTime + 0.15f; _cachedNoTextInputActive = !AnyFocusedTextInput(); return _cachedNoTextInputActive; } private static bool GetUnityKeyDown(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) try { return Input.GetKeyDown(key); } catch { return false; } } private static bool GetWindowsKey(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) int num = ToVirtualKey(key); if (num != 0 && IsForegroundProcess()) { return IsVirtualKeyDown(num); } return false; } private static bool IsVirtualKeyDown(int virtualKey) { try { return (GetAsyncKeyState(virtualKey) & 0x8000) != 0; } catch { return false; } } private static bool IsForegroundProcess() { try { IntPtr foregroundWindow = GetForegroundWindow(); if (foregroundWindow == IntPtr.Zero) { return false; } GetWindowThreadProcessId(foregroundWindow, out var processId); return processId == CurrentProcessId; } catch { return false; } } private static int ToVirtualKey(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected I4, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_00bc: 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_00e0: Expected I4, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected I4, but got Unknown if ((int)key >= 97 && (int)key <= 122) { return 65 + (key - 97); } if ((int)key >= 48 && (int)key <= 57) { return 48 + (key - 48); } if ((int)key >= 282 && (int)key <= 678) { return 112 + (key - 282); } if ((int)key <= 27) { if ((int)key <= 9) { if ((int)key == 8) { return 8; } if ((int)key == 9) { return 9; } } else { if ((int)key == 13) { return 13; } if ((int)key == 27) { return 27; } } } else if ((int)key <= 127) { if ((int)key == 32) { return 32; } if ((int)key == 127) { return 46; } } else { switch (key - 273) { case 7: return 33; case 8: return 34; case 6: return 35; case 5: return 36; case 3: return 37; case 0: return 38; case 2: return 39; case 1: return 40; case 4: return 45; } switch (key - 303) { case 1: return 160; case 0: return 161; case 3: return 162; case 2: return 163; case 5: return 164; case 4: return 165; } switch (key - 323) { case 0: return 1; case 1: return 2; case 2: return 4; } } return 0; } private static bool AnyFocusedTextInput() { if (!TypeHasFocusedInput(UnityInputFieldType)) { return TypeHasFocusedInput(TmpInputFieldType); } return true; } private static bool TypeHasFocusedInput(Type? inputType) { if (inputType == null) { return false; } try { Object[] array = Resources.FindObjectsOfTypeAll(inputType); for (int i = 0; i < array.Length; i++) { if (IsFocusedInput(array[i])) { return true; } } } catch { return false; } return false; } private static bool IsFocusedInput(Object input) { Component val = (Component)(object)((input is Component) ? input : null); if (val == null || !val.gameObject.activeInHierarchy) { return false; } Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 != null && !val2.enabled) { return false; } PropertyInfo property = ((object)input).GetType().GetProperty("isFocused", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || property.PropertyType != typeof(bool)) { return false; } try { return (bool)property.GetValue(input, null); } catch { return false; } } [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int virtualKey); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr windowHandle, out uint processId); } internal sealed class ImageLoader { private readonly string _imagesDirectory; private readonly ManualLogSource _logger; private readonly Dictionary _cache = new Dictionary(StringComparer.OrdinalIgnoreCase); internal string ImagesDirectory => _imagesDirectory; internal int ExpectedCount { get; private set; } internal int LoadedCount { get; private set; } internal int MissingCount { get; private set; } internal ImageLoader(string imagesDirectory, ManualLogSource logger) { _imagesDirectory = imagesDirectory; _logger = logger; _logger.LogInfo((object)("[MonsterGuide] Image path: " + _imagesDirectory)); } internal void Preload(IReadOnlyList monsters) { ExpectedCount = monsters.Count; LoadedCount = 0; MissingCount = 0; foreach (MonsterRecord monster in monsters) { if ((Object)(object)GetTexture(monster) != (Object)null) { LoadedCount++; } else { MissingCount++; } } _logger.LogInfo((object)$"[MonsterGuide] Loaded images: {LoadedCount} / {ExpectedCount}"); if (MissingCount > 0) { _logger.LogWarning((object)$"[MonsterGuide] Missing images: {MissingCount} / {ExpectedCount}"); } } internal Texture2D? GetTexture(MonsterRecord monster) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0114: Expected O, but got Unknown string text = (string.IsNullOrWhiteSpace(monster.image) ? (monster.id + ".png") : monster.image); if (!IsSafeFileName(text)) { _logger.LogWarning((object)("Ignoring unsafe MonsterGuide image filename '" + text + "' for " + monster.id + ".")); return null; } string text2 = Path.Combine(_imagesDirectory, text); if (_cache.TryGetValue(text2, out Texture2D value)) { return value; } _logger.LogInfo((object)("[MonsterGuide] Trying image for " + monster.name + ": " + text2)); if (!File.Exists(text2)) { _cache[text2] = null; _logger.LogWarning((object)("[MonsterGuide] Missing image for " + monster.name + ": " + text)); return null; } try { byte[] array = File.ReadAllBytes(text2); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = "MonsterGuide_" + monster.id, hideFlags = (HideFlags)61 }; if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); _cache[text2] = null; _logger.LogWarning((object)("[MonsterGuide] Could not decode image for " + monster.name + ": " + text)); return null; } _cache[text2] = val; _logger.LogInfo((object)("[MonsterGuide] Loaded image for " + monster.name + ": " + text)); return val; } catch (Exception ex) { _cache[text2] = null; _logger.LogWarning((object)("[MonsterGuide] Could not load image for " + monster.name + " from " + text2 + ": " + ex.Message)); return null; } } internal void DestroyAll() { foreach (Texture2D value in _cache.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } _cache.Clear(); } private static bool IsSafeFileName(string fileName) { if (!string.IsNullOrWhiteSpace(fileName) && fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 && !fileName.Contains("..")) { if (!fileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase) && !fileName.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) { return fileName.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase); } return true; } return false; } } internal static class InputBlocker { private static readonly HashSet PatchedMethods = new HashSet(); private static Harmony? _harmony; private static ManualLogSource? _logger; internal static void Init(ManualLogSource logger) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown _logger = logger; if (_harmony == null) { _harmony = new Harmony("mechgaming13.MonsterGuide.InputBlocker"); } } internal static void PatchAvailableHotkeyReaders() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (_harmony == null) { return; } HarmonyMethod val = new HarmonyMethod(typeof(InputBlocker), "BlockExternalHotkeyPostfix", (Type[])null); int num = 0; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly == typeof(InputBlocker).Assembly) { continue; } foreach (Type safeType in GetSafeTypes(assembly)) { if (!string.Equals(safeType.Name, "HotkeyInput", StringComparison.Ordinal)) { continue; } MethodInfo method = safeType.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(KeyCode) }, null); if (method == null || method.ReturnType != typeof(bool) || PatchedMethods.Contains(method)) { continue; } try { _harmony.Patch((MethodBase)method, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); PatchedMethods.Add(method); num++; ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)("[MonsterGuide] Blocking external hotkeys while open: " + safeType.FullName + "." + method.Name)); } } catch (Exception ex) { ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogDebug((object)("[MonsterGuide] Could not patch hotkey reader " + safeType.FullName + ": " + ex.Message)); } } } } if (num > 0) { ManualLogSource? logger3 = _logger; if (logger3 != null) { logger3.LogInfo((object)$"[MonsterGuide] Patched {num} external hotkey reader(s)."); } } } internal static void Unpatch() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } PatchedMethods.Clear(); } private static void BlockExternalHotkeyPostfix(ref bool __result) { if (Plugin.GuideOpen) { __result = false; } } private static IEnumerable GetSafeTypes(Assembly assembly) { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.WhereNotNull(); } catch { return Array.Empty(); } } } internal static class TypeEnumerableExtensions { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private Type <>2__current; private int <>l__initialThreadId; private IEnumerable types; public IEnumerable <>3__types; private IEnumerator <>7__wrap1; Type IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = types.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { Type current = <>7__wrap1.Current; if (current != null) { <>2__current = current; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.types = <>3__types; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] internal static IEnumerable WhereNotNull(this IEnumerable types) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2) { <>3__types = types }; } } [Serializable] internal sealed class MonsterGuideData { public SourceInfo source = new SourceInfo(); public SpawningData spawning = new SpawningData(); public List monsters = new List(); } [Serializable] internal sealed class SourceInfo { public string name = string.Empty; public string url = string.Empty; public string license = string.Empty; public string lastReviewedUtc = string.Empty; } [Serializable] internal sealed class SpawningData { public string summary = string.Empty; public string level3ReplacementChance = string.Empty; public List rows = new List(); public List replacementPacks = new List(); } [Serializable] internal sealed class SpawningRow { public string level = string.Empty; public int level1Monsters; public int level2Monsters; public int level3Monsters; } [Serializable] internal sealed class ReplacementPack { public string monsterId = string.Empty; public string name = string.Empty; public int count; } [Serializable] internal sealed class MonsterRecord { public string id = string.Empty; public string name = string.Empty; public string appearance = string.Empty; public string dangerLevel = string.Empty; public string health = string.Empty; public string damage = string.Empty; public string detection = string.Empty; public string strengthBreakpoint = string.Empty; public string strengthBreakpointStunned = string.Empty; public string attacksCrouchedPlayers = string.Empty; public string orbSize = string.Empty; public string image = string.Empty; } internal sealed class MonsterDataLoader { private readonly string _dataPath; private readonly string _preferredDataPath; private readonly ManualLogSource _logger; internal MonsterDataLoader(string pluginDirectory, ManualLogSource logger) { _dataPath = Path.Combine(pluginDirectory, "Data", "monsters.json"); _preferredDataPath = _dataPath; _logger = logger; } internal MonsterGuideData Load() { string text = ResolveDataPath(); bool flag = File.Exists(text); _logger.LogInfo((object)("[MonsterGuide] Data path: " + text)); _logger.LogInfo((object)$"[MonsterGuide] monsters.json exists: {flag}"); if (!flag) { _logger.LogWarning((object)("[MonsterGuide] Monster data file not found: " + text)); MonsterGuideData monsterGuideData = LoadEmbeddedFallback("Monster data file missing. Embedded defaults loaded."); TryWriteEmbeddedDefault(_preferredDataPath); LogLoadedCounts(monsterGuideData); return monsterGuideData; } try { MonsterGuideData monsterGuideData2 = JsonConvert.DeserializeObject(File.ReadAllText(text)); if (monsterGuideData2 == null) { _logger.LogWarning((object)"[MonsterGuide] Monster data JSON loaded as null. Embedded defaults loaded."); MonsterGuideData monsterGuideData3 = LoadEmbeddedFallback("Monster data could not be parsed. Embedded defaults loaded."); LogLoadedCounts(monsterGuideData3); return monsterGuideData3; } Normalize(monsterGuideData2); if (monsterGuideData2.monsters.Count == 0 || monsterGuideData2.spawning.rows.Count == 0) { _logger.LogWarning((object)"[MonsterGuide] Monster data parsed but contained no monsters or spawn rows. Embedded defaults loaded."); MonsterGuideData monsterGuideData4 = LoadEmbeddedFallback("Monster data was empty. Embedded defaults loaded."); LogLoadedCounts(monsterGuideData4); return monsterGuideData4; } LogLoadedCounts(monsterGuideData2); return monsterGuideData2; } catch (Exception arg) { _logger.LogWarning((object)$"[MonsterGuide] Could not parse MonsterGuide data from {text}: {arg}"); MonsterGuideData monsterGuideData5 = LoadEmbeddedFallback("Monster data is malformed. Embedded defaults loaded. Check BepInEx logs for details."); LogLoadedCounts(monsterGuideData5); return monsterGuideData5; } } private string ResolveDataPath() { if (File.Exists(_dataPath)) { return _dataPath; } string text = Path.Combine(Paths.PluginPath, "MonsterGuide", "Data", "monsters.json"); if (File.Exists(text)) { return text; } return _dataPath; } private static void Normalize(MonsterGuideData data) { MonsterGuideData monsterGuideData = data; if (monsterGuideData.source == null) { monsterGuideData.source = new SourceInfo(); } monsterGuideData = data; if (monsterGuideData.spawning == null) { monsterGuideData.spawning = new SpawningData(); } SpawningData spawning = data.spawning; if (spawning.rows == null) { spawning.rows = new List(); } spawning = data.spawning; if (spawning.replacementPacks == null) { spawning.replacementPacks = new List(); } monsterGuideData = data; if (monsterGuideData.monsters == null) { monsterGuideData.monsters = new List(); } data.monsters.RemoveAll((MonsterRecord monster) => monster == null || string.IsNullOrWhiteSpace(monster.id)); foreach (MonsterRecord monster in data.monsters) { monster.name = FirstNonEmpty(monster.name, monster.id); monster.image = FirstNonEmpty(monster.image, monster.id + ".png"); } } private MonsterGuideData LoadEmbeddedFallback(string message) { try { MonsterGuideData monsterGuideData = JsonConvert.DeserializeObject(ReadEmbeddedDefaultJson()); if (monsterGuideData != null) { Normalize(monsterGuideData); if (monsterGuideData.monsters.Count > 0 && monsterGuideData.spawning.rows.Count > 0) { return monsterGuideData; } } _logger.LogWarning((object)"[MonsterGuide] Embedded monsters.json was empty or unreadable."); } catch (Exception arg) { _logger.LogWarning((object)$"[MonsterGuide] Could not load embedded monsters.json fallback: {arg}"); } return CreateFallbackData(message); } private static string ReadEmbeddedDefaultJson() { using Stream stream = typeof(MonsterDataLoader).Assembly.GetManifestResourceStream("MonsterGuide.Data.monsters.json"); if (stream == null) { throw new FileNotFoundException("Embedded resource MonsterGuide.Data.monsters.json was not found."); } using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); return streamReader.ReadToEnd(); } private void TryWriteEmbeddedDefault(string destinationPath) { try { string directoryName = Path.GetDirectoryName(destinationPath); if (!string.IsNullOrWhiteSpace(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(destinationPath, ReadEmbeddedDefaultJson(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); _logger.LogInfo((object)("[MonsterGuide] Wrote default monsters.json to " + destinationPath)); } catch (Exception ex) { _logger.LogWarning((object)("[MonsterGuide] Could not write default monsters.json to " + destinationPath + ": " + ex.Message)); } } private void LogLoadedCounts(MonsterGuideData data) { _logger.LogInfo((object)$"[MonsterGuide] Loaded monsters: {data.monsters.Count}"); _logger.LogInfo((object)$"[MonsterGuide] Loaded spawn rows: {data.spawning.rows.Count}"); _logger.LogInfo((object)$"[MonsterGuide] Loaded replacement packs: {data.spawning.replacementPacks.Count}"); } private static MonsterGuideData CreateFallbackData(string message) { return new MonsterGuideData { source = new SourceInfo { name = "Fallback", url = string.Empty, license = string.Empty, lastReviewedUtc = string.Empty }, spawning = new SpawningData { summary = message, level3ReplacementChance = "Unavailable until Data/monsters.json is restored.", rows = new List { new SpawningRow { level = "1-2", level1Monsters = 1, level2Monsters = 0, level3Monsters = 1 }, new SpawningRow { level = "3-5", level1Monsters = 1, level2Monsters = 1, level3Monsters = 1 }, new SpawningRow { level = "6-8", level1Monsters = 2, level2Monsters = 2, level3Monsters = 2 }, new SpawningRow { level = "9", level1Monsters = 2, level2Monsters = 3, level3Monsters = 2 }, new SpawningRow { level = "10-19", level1Monsters = 2, level2Monsters = 3, level3Monsters = 3 }, new SpawningRow { level = "20+", level1Monsters = 3, level2Monsters = 4, level3Monsters = 4 } }, replacementPacks = new List() }, monsters = new List() }; } private static string FirstNonEmpty(string value, string fallback) { if (!string.IsNullOrWhiteSpace(value)) { return value; } return fallback; } } internal enum GuideTab { Spawning, Monsters, Notes } internal sealed class MonsterGuideUI { private const float DefaultWidth = 1120f; private const float DefaultHeight = 760f; private const float OuterPadding = 14f; private const string MonsterSearchControl = "MonsterGuideTextInputMonsterSearch"; private const string NotesSearchControl = "MonsterGuideTextInputNotesSearch"; private const string NotesTextControl = "MonsterGuideTextInputNotes"; private readonly MonsterGuideData _data; private readonly NotesManager _notes; private readonly ImageLoader _images; private readonly ManualLogSource _logger; private readonly Action _closeAction; private readonly Func _toggleKey; private readonly Dictionary _monsterById; private Rect _windowRect; private GuideTab _tab = GuideTab.Monsters; private Vector2 _monsterListScroll; private Vector2 _detailScroll; private Vector2 _spawningScroll; private Vector2 _notesListScroll; private Vector2 _notesDetailScroll; private string _monsterSearch = string.Empty; private string _notesSearch = string.Empty; private string _selectedMonsterId = string.Empty; private string _editingNotesMonsterId = string.Empty; private string _notesText = string.Empty; private bool _notesDirty; private float _nextNotesSaveTime; internal bool TextInputFocused { get; private set; } internal MonsterGuideUI(MonsterGuideData data, NotesManager notes, ImageLoader images, ManualLogSource logger, Action closeAction, Func toggleKey) { _data = data; _notes = notes; _images = images; _logger = logger; _closeAction = closeAction; _toggleKey = toggleKey; _monsterById = data.monsters.ToDictionary((MonsterRecord monster) => monster.id, (MonsterRecord monster) => monster, StringComparer.OrdinalIgnoreCase); _selectedMonsterId = ((data.monsters.Count > 0) ? data.monsters[0].id : string.Empty); } internal void OnOpened() { EnsureWindowRect(); if (string.IsNullOrWhiteSpace(_selectedMonsterId) && _data.monsters.Count > 0) { SelectMonster(_data.monsters[0].id); } } internal void Update() { if (_notesDirty && Time.unscaledTime >= _nextNotesSaveTime) { FlushNotes(); } } internal void Draw() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) MonsterGuideStyles.Ensure(); EnsureWindowRect(); DrawBackdrop(); _windowRect = ClampWindow(GUI.Window(781312, _windowRect, new WindowFunction(DrawWindow), GUIContent.none, MonsterGuideStyles.Window)); string nameOfFocusedControl = GUI.GetNameOfFocusedControl(); TextInputFocused = !string.IsNullOrWhiteSpace(nameOfFocusedControl) && nameOfFocusedControl.StartsWith("MonsterGuideTextInput", StringComparison.Ordinal); } internal void FlushNotes() { if (_notesDirty) { if (!string.IsNullOrWhiteSpace(_editingNotesMonsterId)) { _notes.SetNote(_editingNotesMonsterId, _notesText); _notes.Save(); } _notesDirty = false; } } private void DrawWindow(int windowId) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty()); DrawHeader(); DrawTabs(); GUILayout.Space(10f); switch (_tab) { case GuideTab.Spawning: DrawSpawningTab(); break; case GuideTab.Monsters: DrawMonstersTab(); break; case GuideTab.Notes: DrawNotesTab(); break; } GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 48f)); } private void DrawHeader() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(((Rect)(ref _windowRect)).width - 2f, 52f); MonsterGuideStyles.DrawRect(rect, new Color(0.04f, 0.07f, 0.08f, 0.98f)); MonsterGuideStyles.DrawRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - 2f, ((Rect)(ref rect)).width, 2f), new Color(0.26f, 0.72f, 0.62f, 1f)); GUI.Label(new Rect(((Rect)(ref rect)).x + 16f, ((Rect)(ref rect)).y + 8f, 320f, 30f), "MonsterGuide", MonsterGuideStyles.Title); GUI.Label(new Rect(((Rect)(ref rect)).x + 17f, ((Rect)(ref rect)).y + 32f, 440f, 18f), BuildHeaderHint(), MonsterGuideStyles.MicroLabel); GUI.Label(new Rect(((Rect)(ref rect)).x + 440f, ((Rect)(ref rect)).y + 8f, ((Rect)(ref rect)).width - 570f, 18f), FirstNonEmpty(_data.source.name, "Local monster data"), MonsterGuideStyles.SourceLabel); GUI.Label(new Rect(((Rect)(ref rect)).x + 440f, ((Rect)(ref rect)).y + 28f, ((Rect)(ref rect)).width - 570f, 18f), $"Loaded {_data.monsters.Count} monsters | {_data.spawning.rows.Count} spawn rows | {_images.LoadedCount} images", MonsterGuideStyles.SourceLabel); if (GUI.Button(new Rect(((Rect)(ref rect)).xMax - 96f, ((Rect)(ref rect)).y + 12f, 78f, 30f), "Close", MonsterGuideStyles.CloseButton)) { _closeAction(); } } private string BuildHeaderHint() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return $"Toggle {_toggleKey()} | Esc closes"; } private void DrawTabs() { GUILayout.BeginHorizontal(Array.Empty()); DrawTabButton(GuideTab.Spawning, "Spawning"); DrawTabButton(GuideTab.Monsters, "Monsters"); DrawTabButton(GuideTab.Notes, "Notes / My Notes"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void DrawTabButton(GuideTab tab, string label) { GUIStyle val = ((_tab == tab) ? MonsterGuideStyles.TabSelected : MonsterGuideStyles.Tab); if (GUILayout.Button(label, val, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width((tab == GuideTab.Notes) ? 190f : 130f), GUILayout.Height(34f) }) && _tab != tab) { _tab = tab; GUI.FocusControl(string.Empty); TextInputFocused = false; } } private void DrawSpawningTab() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) _spawningScroll = GUILayout.BeginScrollView(_spawningScroll, false, true, Array.Empty()); GUILayout.BeginVertical(MonsterGuideStyles.Panel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.Label("Spawning Table", MonsterGuideStyles.SectionTitle, Array.Empty()); GUILayout.Label(FirstNonEmpty(_data.spawning.summary, "Monster picks are grouped by danger tier and current map level."), MonsterGuideStyles.BodyLabel, Array.Empty()); GUILayout.Space(10f); DrawSpawningTable(); GUILayout.Space(14f); GUILayout.Label("Level 3 Replacement Chance", MonsterGuideStyles.SectionTitle, Array.Empty()); GUILayout.Label(FirstNonEmpty(_data.spawning.level3ReplacementChance, "No replacement chance data bundled."), MonsterGuideStyles.BodyLabel, Array.Empty()); GUILayout.Space(8f); DrawReplacementPacks(); GUILayout.Space(16f); if (!string.IsNullOrWhiteSpace(_data.source.url)) { GUILayout.Label("Source: " + _data.source.url, MonsterGuideStyles.MicroLabel, Array.Empty()); } if (!string.IsNullOrWhiteSpace(_data.source.license)) { GUILayout.Label("Attribution: " + _data.source.license, MonsterGuideStyles.MicroLabel, Array.Empty()); } GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void DrawSpawningTable() { GUILayout.BeginVertical(MonsterGuideStyles.Table, Array.Empty()); DrawSpawningRow("Level", "Lvl. 1 Monsters", "Lvl. 2 Monsters", "Lvl. 3 Monsters", MonsterGuideStyles.TableHeader); foreach (SpawningRow row in _data.spawning.rows) { DrawSpawningRow(row.level, row.level1Monsters.ToString(), row.level2Monsters.ToString(), row.level3Monsters.ToString(), MonsterGuideStyles.TableCell); } GUILayout.EndVertical(); } private static void DrawSpawningRow(string level, string levelOne, string levelTwo, string levelThree, GUIStyle style) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(level, style, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(170f), GUILayout.Height(32f) }); GUILayout.Label(levelOne, style, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(190f), GUILayout.Height(32f) }); GUILayout.Label(levelTwo, style, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(190f), GUILayout.Height(32f) }); GUILayout.Label(levelThree, style, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(190f), GUILayout.Height(32f) }); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void DrawReplacementPacks() { if (_data.spawning.replacementPacks.Count == 0) { GUILayout.Label("No replacement pack records are bundled.", MonsterGuideStyles.BodyLabel, Array.Empty()); return; } for (int i = 0; i < _data.spawning.replacementPacks.Count; i += 3) { GUILayout.BeginHorizontal(Array.Empty()); for (int j = 0; j < 3 && i + j < _data.spawning.replacementPacks.Count; j++) { ReplacementPack replacementPack = _data.spawning.replacementPacks[i + j]; GUILayout.Label($"{replacementPack.count}x {replacementPack.name}", MonsterGuideStyles.Pill, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(250f), GUILayout.Height(28f) }); } GUILayout.EndHorizontal(); GUILayout.Space(4f); } } private void DrawMonstersTab() { GUILayout.BeginHorizontal(Array.Empty()); DrawMonsterSidebar(); GUILayout.Space(10f); DrawMonsterDetailPanel(); GUILayout.EndHorizontal(); } private void DrawMonsterSidebar() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(MonsterGuideStyles.Sidebar, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(292f), GUILayout.ExpandHeight(true) }); GUILayout.Label("Monster Index", MonsterGuideStyles.SectionTitle, Array.Empty()); GUI.SetNextControlName("MonsterGuideTextInputMonsterSearch"); _monsterSearch = GUILayout.TextField(_monsterSearch, MonsterGuideStyles.SearchField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(8f); List filteredMonsters = GetFilteredMonsters(_monsterSearch); _monsterListScroll = GUILayout.BeginScrollView(_monsterListScroll, false, true, Array.Empty()); foreach (MonsterRecord item in filteredMonsters) { GUIStyle val = (string.Equals(item.id, _selectedMonsterId, StringComparison.OrdinalIgnoreCase) ? MonsterGuideStyles.MonsterButtonSelected : MonsterGuideStyles.MonsterButton); if (GUILayout.Button(item.name + " L" + item.dangerLevel, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(31f) })) { SelectMonster(item.id); } } if (filteredMonsters.Count == 0) { GUILayout.Label("No matching monsters.", MonsterGuideStyles.EmptyLabel, Array.Empty()); } GUILayout.EndScrollView(); GUILayout.EndVertical(); } private List GetFilteredMonsters(string search) { string search2 = search; IEnumerable source = _data.monsters; if (!string.IsNullOrWhiteSpace(search2)) { source = source.Where((MonsterRecord monster) => monster.name.IndexOf(search2, StringComparison.OrdinalIgnoreCase) >= 0); } return source.ToList(); } private void DrawMonsterDetailPanel() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(MonsterGuideStyles.Panel, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true) }); MonsterRecord selectedMonster = GetSelectedMonster(); if (selectedMonster == null) { GUILayout.Label("No monster selected.", MonsterGuideStyles.EmptyLabel, Array.Empty()); GUILayout.EndVertical(); return; } _detailScroll = GUILayout.BeginScrollView(_detailScroll, false, true, Array.Empty()); GUILayout.Label(selectedMonster.name, MonsterGuideStyles.MonsterTitle, Array.Empty()); DrawMonsterImage(selectedMonster, 180f); GUILayout.Space(10f); DrawStats(selectedMonster); GUILayout.Space(12f); DrawNotesEditor(selectedMonster.id, 142f); GUILayout.EndScrollView(); GUILayout.EndVertical(); } private void DrawStats(MonsterRecord monster) { DrawStatRow("Appearance", monster.appearance); DrawStatRow("Danger Level", monster.dangerLevel); DrawStatRow("Health", monster.health); DrawStatRow("Damage", monster.damage); DrawStatRow("Detection", monster.detection); DrawStatRow("Strength Breakpoint", monster.strengthBreakpoint); DrawStatRow("Strength Breakpoint (Stunned)", monster.strengthBreakpointStunned); DrawStatRow("Attacks Crouched Players", monster.attacksCrouchedPlayers); DrawStatRow("Orb Size", monster.orbSize); } private static void DrawStatRow(string label, string value) { GUILayout.BeginHorizontal(MonsterGuideStyles.StatRow, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(34f) }); GUILayout.Label(label, MonsterGuideStyles.StatLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); GUILayout.Label(FirstNonEmpty(value, "Unknown"), MonsterGuideStyles.StatValue, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); GUILayout.Space(4f); } private void DrawMonsterImage(MonsterRecord monster, float height) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(1f, height, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); MonsterGuideStyles.DrawRect(rect, new Color(0.03f, 0.045f, 0.05f, 0.96f)); MonsterGuideStyles.DrawRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - 1f, ((Rect)(ref rect)).width, 1f), new Color(0.24f, 0.48f, 0.44f, 1f)); Texture2D texture = _images.GetTexture(monster); if ((Object)(object)texture == (Object)null) { GUI.Label(rect, "No image available", MonsterGuideStyles.PlaceholderLabel); } else { GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 8f, ((Rect)(ref rect)).width - 16f, ((Rect)(ref rect)).height - 16f), (Texture)(object)texture, (ScaleMode)2, true); } } private void DrawNotesTab() { GUILayout.BeginHorizontal(Array.Empty()); DrawNotesSidebar(); GUILayout.Space(10f); DrawNotesDetail(); GUILayout.EndHorizontal(); } private void DrawNotesSidebar() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(MonsterGuideStyles.Sidebar, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(292f), GUILayout.ExpandHeight(true) }); GUILayout.Label("My Notes", MonsterGuideStyles.SectionTitle, Array.Empty()); GUI.SetNextControlName("MonsterGuideTextInputNotesSearch"); _notesSearch = GUILayout.TextField(_notesSearch, MonsterGuideStyles.SearchField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(8f); List noteMonsterIds = GetNoteMonsterIds(); _notesListScroll = GUILayout.BeginScrollView(_notesListScroll, false, true, Array.Empty()); foreach (string item in noteMonsterIds) { string displayName = GetDisplayName(item); if (string.IsNullOrWhiteSpace(_notesSearch) || displayName.IndexOf(_notesSearch, StringComparison.OrdinalIgnoreCase) >= 0 || item.IndexOf(_notesSearch, StringComparison.OrdinalIgnoreCase) >= 0) { bool num = string.Equals(item, _selectedMonsterId, StringComparison.OrdinalIgnoreCase); bool flag = _notes.HasNote(item); GUIStyle val = (num ? MonsterGuideStyles.MonsterButtonSelected : MonsterGuideStyles.MonsterButton); if (GUILayout.Button(flag ? (displayName + " *") : displayName, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(31f) })) { SelectMonster(item); } } } GUILayout.EndScrollView(); GUILayout.EndVertical(); } private List GetNoteMonsterIds() { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (MonsterRecord monster in _data.monsters) { hashSet.Add(monster.id); } foreach (string knownMonsterId in _notes.GetKnownMonsterIds()) { hashSet.Add(knownMonsterId); } List list = hashSet.ToList(); list.Sort((string left, string right) => string.Compare(GetDisplayName(left), GetDisplayName(right), StringComparison.OrdinalIgnoreCase)); return list; } private void DrawNotesDetail() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(MonsterGuideStyles.Panel, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true) }); if (string.IsNullOrWhiteSpace(_selectedMonsterId)) { List noteMonsterIds = GetNoteMonsterIds(); if (noteMonsterIds.Count > 0) { SelectMonster(noteMonsterIds[0]); } } _notesDetailScroll = GUILayout.BeginScrollView(_notesDetailScroll, false, true, Array.Empty()); MonsterRecord selectedMonster = GetSelectedMonster(); GUILayout.Label(GetDisplayName(_selectedMonsterId), MonsterGuideStyles.MonsterTitle, Array.Empty()); if (selectedMonster != null) { DrawMonsterImage(selectedMonster, 130f); GUILayout.Space(8f); GUILayout.Label("Danger " + selectedMonster.dangerLevel + " | HP " + selectedMonster.health + " | Orb " + selectedMonster.orbSize, MonsterGuideStyles.BodyLabel, Array.Empty()); } else { GUILayout.Label("This note belongs to a monster id that is not in the current data file. It is kept here so edits to monsters.json do not delete player notes.", MonsterGuideStyles.WarningLabel, Array.Empty()); } GUILayout.Space(12f); DrawNotesEditor(_selectedMonsterId, 330f); GUILayout.EndScrollView(); GUILayout.EndVertical(); } private void DrawNotesEditor(string monsterId, float height) { if (string.IsNullOrWhiteSpace(monsterId)) { GUILayout.Label("Select a monster to write notes.", MonsterGuideStyles.EmptyLabel, Array.Empty()); return; } BeginEditingNotes(monsterId); GUILayout.Label("Player Notes", MonsterGuideStyles.SectionTitle, Array.Empty()); GUI.SetNextControlName("MonsterGuideTextInputNotes"); string text = GUILayout.TextArea(_notesText, MonsterGuideStyles.NotesArea, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinHeight(height), GUILayout.ExpandWidth(true) }); if (!string.Equals(text, _notesText, StringComparison.Ordinal)) { _notesText = text; _notes.SetNote(_editingNotesMonsterId, _notesText); _notesDirty = true; _nextNotesSaveTime = Time.unscaledTime + 0.6f; } GUILayout.Label(_notesDirty ? "Autosave pending..." : "Notes saved locally.", MonsterGuideStyles.MicroLabel, Array.Empty()); } private void SelectMonster(string monsterId) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (string.Equals(monsterId, _selectedMonsterId, StringComparison.OrdinalIgnoreCase)) { BeginEditingNotes(monsterId); return; } FlushNotes(); _selectedMonsterId = monsterId; _detailScroll = Vector2.zero; _notesDetailScroll = Vector2.zero; BeginEditingNotes(monsterId); } private void BeginEditingNotes(string monsterId) { if (!string.Equals(monsterId, _editingNotesMonsterId, StringComparison.OrdinalIgnoreCase)) { FlushNotes(); _editingNotesMonsterId = monsterId; _notesText = _notes.GetNote(monsterId); _notesDirty = false; } } private MonsterRecord? GetSelectedMonster() { if (!string.IsNullOrWhiteSpace(_selectedMonsterId) && _monsterById.TryGetValue(_selectedMonsterId, out MonsterRecord value)) { return value; } return null; } private string GetDisplayName(string monsterId) { if (string.IsNullOrWhiteSpace(monsterId)) { return "No monster selected"; } if (!_monsterById.TryGetValue(monsterId, out MonsterRecord value)) { return monsterId + " (missing data)"; } return value.name; } private void EnsureWindowRect() { //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_00aa: 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_00b4: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(1120f, Mathf.Max(360f, (float)Screen.width - 28f)); float num2 = Mathf.Min(760f, Mathf.Max(320f, (float)Screen.height - 28f)); if (((Rect)(ref _windowRect)).width <= 0f || ((Rect)(ref _windowRect)).height <= 0f) { _windowRect = new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2); return; } ((Rect)(ref _windowRect)).width = num; ((Rect)(ref _windowRect)).height = num2; _windowRect = ClampWindow(_windowRect); } private static Rect ClampWindow(Rect rect) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) ((Rect)(ref rect)).x = Mathf.Clamp(((Rect)(ref rect)).x, 14f, Mathf.Max(14f, (float)Screen.width - ((Rect)(ref rect)).width - 14f)); ((Rect)(ref rect)).y = Mathf.Clamp(((Rect)(ref rect)).y, 14f, Mathf.Max(14f, (float)Screen.height - ((Rect)(ref rect)).height - 14f)); return rect; } private static void DrawBackdrop() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) MonsterGuideStyles.DrawRect(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), new Color(0f, 0f, 0f, 0.58f)); } private static string FirstNonEmpty(string value, string fallback) { if (!string.IsNullOrWhiteSpace(value)) { return value; } return fallback; } } internal static class MonsterGuideStyles { internal static GUIStyle Window; internal static GUIStyle Title; internal static GUIStyle SourceLabel; internal static GUIStyle MicroLabel; internal static GUIStyle SectionTitle; internal static GUIStyle BodyLabel; internal static GUIStyle WarningLabel; internal static GUIStyle EmptyLabel; internal static GUIStyle Tab; internal static GUIStyle TabSelected; internal static GUIStyle CloseButton; internal static GUIStyle Sidebar; internal static GUIStyle Panel; internal static GUIStyle SearchField; internal static GUIStyle MonsterButton; internal static GUIStyle MonsterButtonSelected; internal static GUIStyle MonsterTitle; internal static GUIStyle StatRow; internal static GUIStyle StatLabel; internal static GUIStyle StatValue; internal static GUIStyle PlaceholderLabel; internal static GUIStyle NotesArea; internal static GUIStyle Table; internal static GUIStyle TableHeader; internal static GUIStyle TableCell; internal static GUIStyle Pill; private static bool _initialized; internal static void Ensure() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0061: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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) //IL_00cc: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_0135: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: 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_01f2: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Expected O, but got Unknown //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Expected O, but got Unknown //IL_0448: 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_0461: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Expected O, but got Unknown //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_04a2: Expected O, but got Unknown //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Expected O, but got Unknown //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Expected O, but got Unknown //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_0509: 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_051a: Expected O, but got Unknown //IL_051a: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Expected O, but got Unknown //IL_058f: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: 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_05cb: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Expected O, but got Unknown //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0632: Expected O, but got Unknown //IL_0650: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_0673: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_0692: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06bb: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Expected O, but got Unknown //IL_06d9: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_06fa: Unknown result type (might be due to invalid IL or missing references) //IL_0701: Unknown result type (might be due to invalid IL or missing references) //IL_070d: Expected O, but got Unknown //IL_072b: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_074b: Unknown result type (might be due to invalid IL or missing references) //IL_0755: Expected O, but got Unknown //IL_0755: Unknown result type (might be due to invalid IL or missing references) //IL_076f: Unknown result type (might be due to invalid IL or missing references) //IL_0783: Expected O, but got Unknown //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_0792: Unknown result type (might be due to invalid IL or missing references) //IL_079a: Unknown result type (might be due to invalid IL or missing references) //IL_07a1: Unknown result type (might be due to invalid IL or missing references) //IL_07ad: Expected O, but got Unknown //IL_07cb: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_07e4: Unknown result type (might be due to invalid IL or missing references) //IL_07ec: Unknown result type (might be due to invalid IL or missing references) //IL_07f8: Expected O, but got Unknown //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_082a: Unknown result type (might be due to invalid IL or missing references) //IL_082f: Unknown result type (might be due to invalid IL or missing references) //IL_0837: Unknown result type (might be due to invalid IL or missing references) //IL_083e: Unknown result type (might be due to invalid IL or missing references) //IL_084a: Expected O, but got Unknown //IL_0868: Unknown result type (might be due to invalid IL or missing references) //IL_087c: Unknown result type (might be due to invalid IL or missing references) //IL_0881: Unknown result type (might be due to invalid IL or missing references) //IL_0889: Unknown result type (might be due to invalid IL or missing references) //IL_0890: Unknown result type (might be due to invalid IL or missing references) //IL_0897: Unknown result type (might be due to invalid IL or missing references) //IL_08a1: Expected O, but got Unknown //IL_08a1: Unknown result type (might be due to invalid IL or missing references) //IL_08bb: Unknown result type (might be due to invalid IL or missing references) //IL_08ca: Unknown result type (might be due to invalid IL or missing references) //IL_08e4: Unknown result type (might be due to invalid IL or missing references) //IL_08f8: Expected O, but got Unknown //IL_0916: Unknown result type (might be due to invalid IL or missing references) //IL_092a: Unknown result type (might be due to invalid IL or missing references) //IL_093e: Unknown result type (might be due to invalid IL or missing references) //IL_0943: Unknown result type (might be due to invalid IL or missing references) //IL_0948: Unknown result type (might be due to invalid IL or missing references) //IL_0952: Expected O, but got Unknown //IL_0952: Unknown result type (might be due to invalid IL or missing references) //IL_096c: Unknown result type (might be due to invalid IL or missing references) //IL_0980: Expected O, but got Unknown //IL_098a: Unknown result type (might be due to invalid IL or missing references) //IL_098f: Unknown result type (might be due to invalid IL or missing references) //IL_0996: Unknown result type (might be due to invalid IL or missing references) //IL_099d: Unknown result type (might be due to invalid IL or missing references) //IL_09b7: Unknown result type (might be due to invalid IL or missing references) //IL_09cb: Expected O, but got Unknown //IL_09d5: Unknown result type (might be due to invalid IL or missing references) //IL_09e9: Unknown result type (might be due to invalid IL or missing references) //IL_09ee: Unknown result type (might be due to invalid IL or missing references) //IL_09f5: Unknown result type (might be due to invalid IL or missing references) //IL_0a0f: Unknown result type (might be due to invalid IL or missing references) //IL_0a23: Expected O, but got Unknown //IL_0a41: Unknown result type (might be due to invalid IL or missing references) //IL_0a55: Unknown result type (might be due to invalid IL or missing references) //IL_0a5a: Unknown result type (might be due to invalid IL or missing references) //IL_0a61: Unknown result type (might be due to invalid IL or missing references) //IL_0a68: Unknown result type (might be due to invalid IL or missing references) //IL_0a82: Unknown result type (might be due to invalid IL or missing references) //IL_0a96: Expected O, but got Unknown //IL_0ab4: Unknown result type (might be due to invalid IL or missing references) if (!_initialized) { GUIStyle val = new GUIStyle(GUI.skin.window) { padding = new RectOffset(12, 12, 8, 12) }; val.normal.background = MakeTexture(new Color(0.055f, 0.075f, 0.078f, 0.98f)); Window = val; Title = new GUIStyle(GUI.skin.label) { fontSize = 26, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; Title.normal.textColor = new Color(0.86f, 1f, 0.94f, 1f); SourceLabel = new GUIStyle(GUI.skin.label) { fontSize = 12, alignment = (TextAnchor)5 }; SourceLabel.normal.textColor = new Color(0.63f, 0.78f, 0.75f, 1f); MicroLabel = new GUIStyle(GUI.skin.label) { fontSize = 11, wordWrap = true }; MicroLabel.normal.textColor = new Color(0.6f, 0.7f, 0.68f, 1f); SectionTitle = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, wordWrap = true }; SectionTitle.normal.textColor = new Color(0.87f, 0.98f, 0.92f, 1f); BodyLabel = new GUIStyle(GUI.skin.label) { fontSize = 13, wordWrap = true }; BodyLabel.normal.textColor = new Color(0.84f, 0.89f, 0.86f, 1f); WarningLabel = new GUIStyle(BodyLabel) { fontStyle = (FontStyle)1 }; WarningLabel.normal.textColor = new Color(1f, 0.78f, 0.45f, 1f); EmptyLabel = new GUIStyle(BodyLabel) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1 }; EmptyLabel.normal.textColor = new Color(0.74f, 0.82f, 0.79f, 1f); GUIStyle val2 = new GUIStyle(GUI.skin.button) { fontSize = 13, fontStyle = (FontStyle)1, margin = new RectOffset(0, 6, 8, 0) }; val2.normal.background = MakeTexture(new Color(0.1f, 0.14f, 0.15f, 1f)); val2.hover.background = MakeTexture(new Color(0.13f, 0.19f, 0.2f, 1f)); val2.active.background = MakeTexture(new Color(0.16f, 0.24f, 0.23f, 1f)); Tab = val2; Tab.normal.textColor = new Color(0.7f, 0.84f, 0.8f, 1f); Tab.hover.textColor = Color.white; GUIStyle val3 = new GUIStyle(Tab); val3.normal.background = MakeTexture(new Color(0.18f, 0.39f, 0.34f, 1f)); val3.hover.background = MakeTexture(new Color(0.2f, 0.46f, 0.4f, 1f)); TabSelected = val3; TabSelected.normal.textColor = Color.white; GUIStyle val4 = new GUIStyle(GUI.skin.button) { fontStyle = (FontStyle)1 }; val4.normal.background = MakeTexture(new Color(0.22f, 0.12f, 0.12f, 1f)); val4.hover.background = MakeTexture(new Color(0.36f, 0.14f, 0.14f, 1f)); CloseButton = val4; CloseButton.normal.textColor = new Color(1f, 0.88f, 0.84f, 1f); GUIStyle val5 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(12, 12, 12, 12) }; val5.normal.background = MakeTexture(new Color(0.075f, 0.095f, 0.105f, 0.96f)); Sidebar = val5; GUIStyle val6 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(14, 14, 14, 14) }; val6.normal.background = MakeTexture(new Color(0.075f, 0.105f, 0.105f, 0.94f)); Panel = val6; GUIStyle val7 = new GUIStyle(GUI.skin.textField) { fontSize = 13, padding = new RectOffset(9, 9, 6, 6) }; val7.normal.background = MakeTexture(new Color(0.02f, 0.03f, 0.032f, 1f)); val7.focused.background = MakeTexture(new Color(0.035f, 0.065f, 0.06f, 1f)); SearchField = val7; SearchField.normal.textColor = new Color(0.9f, 1f, 0.96f, 1f); SearchField.focused.textColor = Color.white; GUIStyle val8 = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)3, fontSize = 12, padding = new RectOffset(10, 8, 4, 4) }; val8.normal.background = MakeTexture(new Color(0.08f, 0.105f, 0.11f, 1f)); val8.hover.background = MakeTexture(new Color(0.11f, 0.16f, 0.16f, 1f)); MonsterButton = val8; MonsterButton.normal.textColor = new Color(0.82f, 0.9f, 0.86f, 1f); MonsterButton.hover.textColor = Color.white; GUIStyle val9 = new GUIStyle(MonsterButton); val9.normal.background = MakeTexture(new Color(0.19f, 0.39f, 0.34f, 1f)); val9.hover.background = MakeTexture(new Color(0.22f, 0.46f, 0.4f, 1f)); MonsterButtonSelected = val9; MonsterButtonSelected.normal.textColor = Color.white; MonsterTitle = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)1, wordWrap = true }; MonsterTitle.normal.textColor = new Color(0.96f, 1f, 0.91f, 1f); GUIStyle val10 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(10, 10, 7, 7) }; val10.normal.background = MakeTexture(new Color(0.045f, 0.062f, 0.065f, 1f)); StatRow = val10; StatLabel = new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = (FontStyle)1, wordWrap = true }; StatLabel.normal.textColor = new Color(0.47f, 0.77f, 0.68f, 1f); StatValue = new GUIStyle(GUI.skin.label) { fontSize = 13, wordWrap = true }; StatValue.normal.textColor = new Color(0.9f, 0.94f, 0.9f, 1f); PlaceholderLabel = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; PlaceholderLabel.normal.textColor = new Color(0.52f, 0.64f, 0.61f, 1f); GUIStyle val11 = new GUIStyle(GUI.skin.textArea) { fontSize = 13, wordWrap = true, padding = new RectOffset(10, 10, 8, 8) }; val11.normal.background = MakeTexture(new Color(0.02f, 0.028f, 0.03f, 1f)); val11.focused.background = MakeTexture(new Color(0.03f, 0.055f, 0.05f, 1f)); NotesArea = val11; NotesArea.normal.textColor = new Color(0.9f, 0.96f, 0.9f, 1f); NotesArea.focused.textColor = Color.white; GUIStyle val12 = new GUIStyle(GUI.skin.box) { padding = new RectOffset(8, 8, 8, 8) }; val12.normal.background = MakeTexture(new Color(0.035f, 0.052f, 0.055f, 1f)); Table = val12; GUIStyle val13 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1 }; val13.normal.background = MakeTexture(new Color(0.17f, 0.32f, 0.3f, 1f)); TableHeader = val13; TableHeader.normal.textColor = Color.white; GUIStyle val14 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4 }; val14.normal.background = MakeTexture(new Color(0.065f, 0.092f, 0.095f, 1f)); TableCell = val14; TableCell.normal.textColor = new Color(0.88f, 0.93f, 0.9f, 1f); GUIStyle val15 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1 }; val15.normal.background = MakeTexture(new Color(0.09f, 0.16f, 0.17f, 1f)); Pill = val15; Pill.normal.textColor = new Color(0.82f, 0.98f, 0.9f, 1f); _initialized = true; } } internal static void DrawRect(Rect rect, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; } private static Texture2D MakeTexture(Color color) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, color); val.Apply(); return val; } } internal sealed class NotesManager { [Serializable] private sealed class NotesFile { public List notes = new List(); } [Serializable] private sealed class MonsterNoteEntry { public string monsterId = string.Empty; public string text = string.Empty; } private readonly string _notesPath; private readonly ManualLogSource _logger; private readonly Dictionary _notesByMonster = new Dictionary(StringComparer.OrdinalIgnoreCase); internal string NotesPath => _notesPath; internal NotesManager(string notesPath, ManualLogSource logger) { _notesPath = notesPath; _logger = logger; } internal void Load() { _notesByMonster.Clear(); if (!File.Exists(_notesPath)) { return; } try { NotesFile notesFile = JsonConvert.DeserializeObject(File.ReadAllText(_notesPath)); if (notesFile?.notes == null) { return; } foreach (MonsterNoteEntry note in notesFile.notes) { if (note != null && !string.IsNullOrWhiteSpace(note.monsterId)) { _notesByMonster[note.monsterId] = note.text ?? string.Empty; } } _logger.LogInfo((object)$"Loaded MonsterGuide notes for {_notesByMonster.Count} monsters."); } catch (Exception ex) { _logger.LogWarning((object)("Could not load MonsterGuide notes from " + _notesPath + ": " + ex.Message)); } } internal string GetNote(string monsterId) { if (!_notesByMonster.TryGetValue(monsterId, out string value)) { return string.Empty; } return value; } internal void SetNote(string monsterId, string text) { if (!string.IsNullOrWhiteSpace(monsterId)) { if (string.IsNullOrEmpty(text)) { _notesByMonster.Remove(monsterId); } else { _notesByMonster[monsterId] = text; } } } internal IReadOnlyList GetKnownMonsterIds() { return _notesByMonster.Keys.OrderBy((string id) => id, StringComparer.OrdinalIgnoreCase).ToList(); } internal bool HasNote(string monsterId) { if (_notesByMonster.TryGetValue(monsterId, out string value)) { return !string.IsNullOrWhiteSpace(value); } return false; } internal void Save() { try { string directoryName = Path.GetDirectoryName(_notesPath); if (!string.IsNullOrWhiteSpace(directoryName)) { Directory.CreateDirectory(directoryName); } string contents = JsonConvert.SerializeObject((object)new NotesFile { notes = (from pair in _notesByMonster.OrderBy, string>((KeyValuePair pair) => pair.Key, StringComparer.OrdinalIgnoreCase) select new MonsterNoteEntry { monsterId = pair.Key, text = pair.Value }).ToList() }, (Formatting)1); File.WriteAllText(_notesPath, contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } catch (Exception ex) { _logger.LogWarning((object)("Could not save MonsterGuide notes to " + _notesPath + ": " + ex.Message)); } } } [BepInPlugin("mechgaming13.MonsterGuide", "MonsterGuide", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "mechgaming13.MonsterGuide"; public const string PluginName = "MonsterGuide"; public const string PluginVersion = "1.0.0"; private ConfigEntry _toggleKey; private ConfigEntry _resetInputWhileOpen; private ConfigEntry _restoreCursorOnClose; private MonsterGuideUI _ui; private NotesManager _notes; private ImageLoader _images; private bool _guideOpen; private bool _storedCursorVisible; private CursorLockMode _storedCursorLockMode; internal static bool GuideOpen { get; private set; } private void Awake() { _toggleKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ToggleKey", (KeyCode)286, "Key used to open or close MonsterGuide."); _resetInputWhileOpen = ((BaseUnityPlugin)this).Config.Bind("Input", "ResetInputWhileOpen", true, "Best-effort input quieting while the guide is open."); _restoreCursorOnClose = ((BaseUnityPlugin)this).Config.Bind("Input", "RestoreCursorOnClose", true, "Restore the cursor visibility and lock state that were active before opening the guide."); string text = Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? Paths.PluginPath; MonsterGuideData monsterGuideData = new MonsterDataLoader(text, ((BaseUnityPlugin)this).Logger).Load(); _notes = new NotesManager(Path.Combine(Paths.ConfigPath, "MonsterGuide", "notes.json"), ((BaseUnityPlugin)this).Logger); _notes.Load(); _images = new ImageLoader(Path.Combine(text, "Images"), ((BaseUnityPlugin)this).Logger); _images.Preload(monsterGuideData.monsters); _ui = new MonsterGuideUI(monsterGuideData, _notes, _images, ((BaseUnityPlugin)this).Logger, delegate { SetGuideOpen(open: false); }, () => _toggleKey.Value); InputBlocker.Init(((BaseUnityPlugin)this).Logger); InputBlocker.PatchAvailableHotkeyReaders(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("MonsterGuide 1.0.0 loaded. Data path: " + Path.Combine(text, "Data", "monsters.json"))); } private void Update() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (_guideOpen) { InputBlocker.PatchAvailableHotkeyReaders(); if (HotkeyInput.GetKeyDown(_toggleKey.Value) || HotkeyInput.GetKeyDown((KeyCode)27)) { SetGuideOpen(open: false); return; } _ui.Update(); ResetInputIfConfigured(); } else if (HotkeyInput.GetKeyDown(_toggleKey.Value) && HotkeyInput.NoTextInputActive()) { SetGuideOpen(open: true); } } private void LateUpdate() { if (_guideOpen) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } } private void OnGUI() { if (_guideOpen) { _ui.Draw(); ConsumeKeyboardEvent(); } } private void OnDestroy() { SetGuideOpen(open: false); _ui?.FlushNotes(); _images?.DestroyAll(); InputBlocker.Unpatch(); GuideOpen = false; } private void SetGuideOpen(bool open) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) if (_guideOpen == open) { return; } _guideOpen = open; GuideOpen = open; ((BaseUnityPlugin)this).Logger.LogInfo((object)("MonsterGuide " + (open ? "opened" : "closed") + ".")); if (open) { InputBlocker.PatchAvailableHotkeyReaders(); _storedCursorVisible = Cursor.visible; _storedCursorLockMode = Cursor.lockState; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; _ui.OnOpened(); } else { _ui.FlushNotes(); if (_restoreCursorOnClose.Value) { Cursor.visible = _storedCursorVisible; Cursor.lockState = _storedCursorLockMode; } } } private static void ConsumeKeyboardEvent() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 Event current = Event.current; if (current != null && ((int)current.type == 4 || (int)current.type == 5)) { current.Use(); } } private void ResetInputIfConfigured() { if (!_resetInputWhileOpen.Value) { return; } try { Input.ResetInputAxes(); } catch { } } } }