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 MonsterGuide v1.0.0
BepInEx\plugins\MonsterGuide\MonsterGuide.dll
Decompiled a month agousing 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<KeyCode, bool> PreviousStates = new Dictionary<KeyCode, bool>(); 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<string, Texture2D?> _cache = new Dictionary<string, Texture2D>(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<MonsterRecord> 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<MethodBase> PatchedMethods = new HashSet<MethodBase>(); 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<Type> GetSafeTypes(Assembly assembly) { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.WhereNotNull(); } catch { return Array.Empty<Type>(); } } } internal static class TypeEnumerableExtensions { [CompilerGenerated] private sealed class <WhereNotNull>d__0 : IEnumerable<Type>, IEnumerable, IEnumerator<Type>, IEnumerator, IDisposable { private int <>1__state; private Type <>2__current; private int <>l__initialThreadId; private IEnumerable<Type?> types; public IEnumerable<Type?> <>3__types; private IEnumerator<Type?> <>7__wrap1; Type IEnumerator<Type>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WhereNotNull>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<Type> IEnumerable<Type>.GetEnumerator() { <WhereNotNull>d__0 <WhereNotNull>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <WhereNotNull>d__ = this; } else { <WhereNotNull>d__ = new <WhereNotNull>d__0(0); } <WhereNotNull>d__.types = <>3__types; return <WhereNotNull>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Type>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<WhereNotNull>d__0))] internal static IEnumerable<Type> WhereNotNull(this IEnumerable<Type?> types) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WhereNotNull>d__0(-2) { <>3__types = types }; } } [Serializable] internal sealed class MonsterGuideData { public SourceInfo source = new SourceInfo(); public SpawningData spawning = new SpawningData(); public List<MonsterRecord> monsters = new List<MonsterRecord>(); } [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<SpawningRow> rows = new List<SpawningRow>(); public List<ReplacementPack> replacementPacks = new List<ReplacementPack>(); } [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<MonsterGuideData>(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<SpawningRow>(); } spawning = data.spawning; if (spawning.replacementPacks == null) { spawning.replacementPacks = new List<ReplacementPack>(); } monsterGuideData = data; if (monsterGuideData.monsters == null) { monsterGuideData.monsters = new List<MonsterRecord>(); } 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<MonsterGuideData>(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<SpawningRow> { 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<ReplacementPack>() }, monsters = new List<MonsterRecord>() }; } 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<KeyCode> _toggleKey; private readonly Dictionary<string, MonsterRecord> _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<KeyCode> toggleKey) { _data = data; _notes = notes; _images = images; _logger = logger; _closeAction = closeAction; _toggleKey = toggleKey; _monsterById = data.monsters.ToDictionary<MonsterRecord, string, MonsterRecord>((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<GUILayoutOption>()); 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<GUILayoutOption>()); 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<GUILayoutOption>()); GUILayout.BeginVertical(MonsterGuideStyles.Panel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.Label("Spawning Table", MonsterGuideStyles.SectionTitle, Array.Empty<GUILayoutOption>()); GUILayout.Label(FirstNonEmpty(_data.spawning.summary, "Monster picks are grouped by danger tier and current map level."), MonsterGuideStyles.BodyLabel, Array.Empty<GUILayoutOption>()); GUILayout.Space(10f); DrawSpawningTable(); GUILayout.Space(14f); GUILayout.Label("Level 3 Replacement Chance", MonsterGuideStyles.SectionTitle, Array.Empty<GUILayoutOption>()); GUILayout.Label(FirstNonEmpty(_data.spawning.level3ReplacementChance, "No replacement chance data bundled."), MonsterGuideStyles.BodyLabel, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); DrawReplacementPacks(); GUILayout.Space(16f); if (!string.IsNullOrWhiteSpace(_data.source.url)) { GUILayout.Label("Source: " + _data.source.url, MonsterGuideStyles.MicroLabel, Array.Empty<GUILayoutOption>()); } if (!string.IsNullOrWhiteSpace(_data.source.license)) { GUILayout.Label("Attribution: " + _data.source.license, MonsterGuideStyles.MicroLabel, Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void DrawSpawningTable() { GUILayout.BeginVertical(MonsterGuideStyles.Table, Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); 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<GUILayoutOption>()); return; } for (int i = 0; i < _data.spawning.replacementPacks.Count; i += 3) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); 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<GUILayoutOption>()); GUI.SetNextControlName("MonsterGuideTextInputMonsterSearch"); _monsterSearch = GUILayout.TextField(_monsterSearch, MonsterGuideStyles.SearchField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(8f); List<MonsterRecord> filteredMonsters = GetFilteredMonsters(_monsterSearch); _monsterListScroll = GUILayout.BeginScrollView(_monsterListScroll, false, true, Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); } GUILayout.EndScrollView(); GUILayout.EndVertical(); } private List<MonsterRecord> GetFilteredMonsters(string search) { string search2 = search; IEnumerable<MonsterRecord> 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<GUILayoutOption>()); GUILayout.EndVertical(); return; } _detailScroll = GUILayout.BeginScrollView(_detailScroll, false, true, Array.Empty<GUILayoutOption>()); GUILayout.Label(selectedMonster.name, MonsterGuideStyles.MonsterTitle, Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); 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<GUILayoutOption>()); GUI.SetNextControlName("MonsterGuideTextInputNotesSearch"); _notesSearch = GUILayout.TextField(_notesSearch, MonsterGuideStyles.SearchField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.Space(8f); List<string> noteMonsterIds = GetNoteMonsterIds(); _notesListScroll = GUILayout.BeginScrollView(_notesListScroll, false, true, Array.Empty<GUILayoutOption>()); 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<string> GetNoteMonsterIds() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (MonsterRecord monster in _data.monsters) { hashSet.Add(monster.id); } foreach (string knownMonsterId in _notes.GetKnownMonsterIds()) { hashSet.Add(knownMonsterId); } List<string> 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<string> noteMonsterIds = GetNoteMonsterIds(); if (noteMonsterIds.Count > 0) { SelectMonster(noteMonsterIds[0]); } } _notesDetailScroll = GUILayout.BeginScrollView(_notesDetailScroll, false, true, Array.Empty<GUILayoutOption>()); MonsterRecord selectedMonster = GetSelectedMonster(); GUILayout.Label(GetDisplayName(_selectedMonsterId), MonsterGuideStyles.MonsterTitle, Array.Empty<GUILayoutOption>()); if (selectedMonster != null) { DrawMonsterImage(selectedMonster, 130f); GUILayout.Space(8f); GUILayout.Label("Danger " + selectedMonster.dangerLevel + " | HP " + selectedMonster.health + " | Orb " + selectedMonster.orbSize, MonsterGuideStyles.BodyLabel, Array.Empty<GUILayoutOption>()); } 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<GUILayoutOption>()); } 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<GUILayoutOption>()); return; } BeginEditingNotes(monsterId); GUILayout.Label("Player Notes", MonsterGuideStyles.SectionTitle, Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); } 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<MonsterNoteEntry> notes = new List<MonsterNoteEntry>(); } [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<string, string> _notesByMonster = new Dictionary<string, string>(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<NotesFile>(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<string> GetKnownMonsterIds() { return _notesByMonster.Keys.OrderBy<string, string>((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<KeyValuePair<string, string>, string>((KeyValuePair<string, string> 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<KeyCode> _toggleKey; private ConfigEntry<bool> _resetInputWhileOpen; private ConfigEntry<bool> _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<KeyCode>("Controls", "ToggleKey", (KeyCode)286, "Key used to open or close MonsterGuide."); _resetInputWhileOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("Input", "ResetInputWhileOpen", true, "Best-effort input quieting while the guide is open."); _restoreCursorOnClose = ((BaseUnityPlugin)this).Config.Bind<bool>("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 { } } } }