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 RambosValheimModGuide v2.0.0
BepInEx/plugins/RambosValheimModGuide.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using Microsoft.CodeAnalysis; 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: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 RambosValheimModGuide { [BepInPlugin("rambos.valheim.modguide", "Rambo's Valheim Mod Guide", "2.0.0")] public class ModGuide : BaseUnityPlugin { private class ModInfo { public string Name; public string Guid; public string Version; public string Description; public bool IsSelf; public int KeybindCount; } private class KeyBindInfo { public string Key; public string ModName; public string Action; public string Section; } private Rect window = new Rect(70f, 45f, 980f, 700f); private bool visible; private Vector2 scroll; private GUIStyle title; private GUIStyle subtitle; private GUIStyle tab; private GUIStyle tabActive; private GUIStyle heading; private GUIStyle normal; private GUIStyle small; private GUIStyle modName; private GUIStyle keyStyle; private GUIStyle badge; private GUIStyle panel; private GUIStyle closeStyle; private bool stylesReady; private int tabIndex; private readonly List<ModInfo> mods = new List<ModInfo>(); private readonly List<KeyBindInfo> keybinds = new List<KeyBindInfo>(); private readonly Dictionary<string, string> knownDescriptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "Epic Loot", "Adds RPG-style magical weapons, armour, enchantments, rarities and loot progression." }, { "StarLevelSystem", "Adds progressive enemy star levels and scaling difficulty as you explore and progress." }, { "InventorySlots", "Adds extra inventory and quick slots, plus hotbar switching and container restocking." }, { "AzuCraftyBoxes", "Lets you craft and manage resources using nearby storage and adds contextual resource actions." }, { "MassFarming", "Adds faster farming actions so planting and harvesting large areas takes less time." }, { "KeepInventoryOnDeath", "Keeps your inventory when you die instead of requiring a corpse recovery trip." }, { "Forsaken Powers Plus Remastered", "Expands and improves the Forsaken Powers system with additional power options." }, { "SwmarlyValheimQOL", "Adds a collection of quality-of-life improvements for movement, stamina, building and survival." }, { "PlantEverything", "Expands farming and planting options, allowing more plants and cultivation choices." }, { "InstantMonsterLootDrop", "Makes monster loot appear immediately instead of requiring the normal pickup/drop delay." }, { "TargetPortal", "Improves portal travel with target-based portal linking and easier destination selection." } }; private static readonly string[] HiddenTokens = new string[9] { "jotunn", "jsondotnet", "newtonsoft", "yaml", "bepinexpack", "bepinex", "harmony", "monomod", "0harmony" }; private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rambo's Valheim Mod Guide 2.0.0 loaded. Press F10 to scan and open the guide."); } private void EnsureStyles() { //IL_000e: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_01c0: Unknown result type (might be due to invalid IL or missing references) if (!stylesReady) { title = MakeStyle(25, (FontStyle)1, Color.white); subtitle = MakeStyle(14, (FontStyle)0, new Color(0.78f, 0.8f, 0.84f)); tab = MakeStyle(15, (FontStyle)1, new Color(0.82f, 0.84f, 0.88f)); tabActive = MakeStyle(15, (FontStyle)1, new Color(1f, 0.78f, 0.32f)); heading = MakeStyle(19, (FontStyle)1, new Color(1f, 0.78f, 0.32f)); normal = MakeStyle(15, (FontStyle)0, new Color(0.91f, 0.92f, 0.94f)); small = MakeStyle(12, (FontStyle)0, new Color(0.68f, 0.7f, 0.74f)); modName = MakeStyle(17, (FontStyle)1, Color.white); keyStyle = MakeStyle(15, (FontStyle)1, new Color(1f, 0.83f, 0.45f)); badge = MakeStyle(12, (FontStyle)1, new Color(0.78f, 0.84f, 0.9f)); panel = new GUIStyle(GUI.skin.box); panel.normal.background = MakeTexture(1, 1, new Color(0.055f, 0.065f, 0.075f, 0.96f)); panel.border = new RectOffset(8, 8, 8, 8); panel.padding = new RectOffset(14, 14, 10, 10); closeStyle = MakeStyle(14, (FontStyle)1, Color.white); stylesReady = true; } } private GUIStyle MakeStyle(int size, FontStyle fontStyle, Color color) { //IL_000a: 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_0016: 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_001d: 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_0029: 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_0038: Expected O, but got Unknown GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = size, fontStyle = fontStyle }; val.normal.textColor = color; val.wordWrap = true; val.richText = false; return val; } private Texture2D MakeTexture(int width, int height, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0017: Expected O, but got Unknown Texture2D val = new Texture2D(width, height); val.SetPixel(0, 0, color); val.Apply(); return val; } private void OnGUI() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0069: 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_008a: Expected O, but got Unknown //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 EnsureStyles(); if (Event.current != null && (int)Event.current.type == 4 && (int)Event.current.keyCode == 291) { visible = !visible; if (visible) { ScanPlugins(); } Event.current.Use(); } if (visible) { GUI.depth = -100; window = GUI.Window(741080, window, new WindowFunction(DrawWindow), GUIContent.none, panel); } } private void ScanPlugins() { mods.Clear(); keybinds.Clear(); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { try { PluginInfo value = pluginInfo.Value; if (value == null || value.Metadata == null) { continue; } string name = value.Metadata.Name ?? pluginInfo.Key; string text = value.Metadata.GUID ?? pluginInfo.Key; if (ShouldHide(name, text)) { continue; } ModInfo modInfo = new ModInfo { Name = name, Guid = text, Version = value.Metadata.Version.ToString(), Description = FindDescription(name, text), IsSelf = text.Equals("rambos.valheim.modguide", StringComparison.OrdinalIgnoreCase) }; if (!modInfo.IsSelf) { if ((Object)(object)value.Instance != (Object)null) { ScanConfig(value.Instance.Config, modInfo); } mods.Add(modInfo); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Mod scan skipped a plugin: " + ex.Message)); } } mods.Sort((ModInfo a, ModInfo b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); keybinds.Sort((KeyBindInfo a, KeyBindInfo b) => string.Compare(a.Key, b.Key, StringComparison.OrdinalIgnoreCase)); } private void ScanConfig(ConfigFile config, ModInfo mod) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (config == null) { return; } foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item2 in config) { try { if (item2.Value == null || item2.Value.SettingType != typeof(KeyboardShortcut)) { continue; } KeyboardShortcut shortcut = (KeyboardShortcut)item2.Value.BoxedValue; if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0) { string key = FormatShortcut(shortcut); string value = ((item2.Value.Description != null) ? item2.Value.Description.Description : ""); if (string.IsNullOrWhiteSpace(value)) { value = item2.Key.Key; } KeyBindInfo item = new KeyBindInfo { Key = key, ModName = mod.Name, Action = CleanDescription(value), Section = item2.Key.Section }; keybinds.Add(item); mod.KeybindCount++; } } catch { } } } private string FormatShortcut(KeyboardShortcut shortcut) { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if ((int)modifier != 0) { list.Add(PrettyKey(modifier)); } } list.Add(PrettyKey(((KeyboardShortcut)(ref shortcut)).MainKey)); return string.Join(" + ", list); } private unsafe string PrettyKey(KeyCode key) { string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); text = text.Replace("Alpha", ""); text = text.Replace("Keypad", "Num"); text = text.Replace("Left", "L-"); text = text.Replace("Right", "R-"); return text switch { "BackQuote" => "`", "Mouse0" => "Mouse1", "Mouse1" => "Mouse2", "Mouse2" => "Mouse3", _ => text, }; } private string FindDescription(string name, string guid) { foreach (KeyValuePair<string, string> knownDescription in knownDescriptions) { if (name.IndexOf(knownDescription.Key, StringComparison.OrdinalIgnoreCase) >= 0) { return knownDescription.Value; } } return "Gameplay or quality-of-life plugin detected in your current BepInEx installation."; } private bool ShouldHide(string name, string guid) { string text = (name + " " + guid).ToLowerInvariant(); string[] hiddenTokens = HiddenTokens; foreach (string value in hiddenTokens) { if (text.Contains(value)) { return true; } } return false; } private string CleanDescription(string value) { value = (value ?? "").Replace("\r", " ").Replace("\n", " ").Trim(); while (value.Contains(" ")) { value = value.Replace(" ", " "); } return value; } private void DrawWindow(int id) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("RAMBO'S VALHEIM MOD GUIDE", title, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button("X", closeStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(34f), GUILayout.Height(30f) })) { visible = false; } GUILayout.EndHorizontal(); GUILayout.Label("Automatic scan of loaded BepInEx plugins • F10 to close", subtitle, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); DrawTab("MODS", 0); DrawTab("KEYBINDS", 1); DrawTab("CONFLICTS", 2); GUILayout.FlexibleSpace(); if (GUILayout.Button("Rescan", tab, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(80f), GUILayout.Height(30f) })) { ScanPlugins(); } GUILayout.EndHorizontal(); GUILayout.Space(8f); scroll = GUILayout.BeginScrollView(scroll, false, true, Array.Empty<GUILayoutOption>()); if (tabIndex == 0) { DrawMods(); } else if (tabIndex == 1) { DrawKeybinds(); } else { DrawConflicts(); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 34f)); } private void DrawTab(string text, int index) { if (GUILayout.Button(text, (index == tabIndex) ? tabActive : tab, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(115f), GUILayout.Height(30f) })) { tabIndex = index; } } private void DrawMods() { GUILayout.Label("GAMEPLAY & PLAYER MODS", heading, Array.Empty<GUILayoutOption>()); GUILayout.Label(mods.Count + " user-facing mods detected. Framework/dependency plugins are hidden automatically.", small, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); foreach (ModInfo mod in mods) { GUILayout.BeginVertical(panel, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(mod.Name, modName, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.Label("v" + mod.Version, badge, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); GUILayout.EndHorizontal(); GUILayout.Label(mod.Description, normal, Array.Empty<GUILayoutOption>()); if (mod.KeybindCount > 0) { GUILayout.Label(mod.KeybindCount + " keybind" + ((mod.KeybindCount == 1) ? "" : "s") + " detected — see KEYBINDS", keyStyle, Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); GUILayout.Space(7f); } if (mods.Count == 0) { GUILayout.Label("No user-facing plugins were detected yet. Press Rescan after the game has finished loading.", normal, Array.Empty<GUILayoutOption>()); } } private void DrawKeybinds() { GUILayout.Label("DETECTED KEYBINDS", heading, Array.Empty<GUILayoutOption>()); GUILayout.Label(keybinds.Count + " configurable keyboard shortcut" + ((keybinds.Count == 1) ? "" : "s") + " detected.", small, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); if (keybinds.Count == 0) { GUILayout.Label("No BepInEx KeyboardShortcut settings were detected. Some mods use hard-coded keys and cannot be discovered automatically.", normal, Array.Empty<GUILayoutOption>()); return; } string text = null; foreach (KeyBindInfo keybind in keybinds) { if (text != null && text != keybind.Key) { GUILayout.Space(3f); } GUILayout.BeginVertical(panel, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(keybind.Key, keyStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) }); GUILayout.Label(keybind.ModName, modName, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Label(keybind.Action, normal, Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); GUILayout.Space(6f); text = keybind.Key; } } private void DrawConflicts() { GUILayout.Label("KEY CONFLICTS / SHARED KEYS", heading, Array.Empty<GUILayoutOption>()); List<IGrouping<string, KeyBindInfo>> list = (from g in keybinds.GroupBy<KeyBindInfo, string>((KeyBindInfo x) => x.Key, StringComparer.OrdinalIgnoreCase) where g.Count() > 1 select g).ToList(); if (list.Count == 0) { GUILayout.Label("No shared configurable keybinds detected.", normal, Array.Empty<GUILayoutOption>()); return; } GUILayout.Label(list.Count + " shared key" + ((list.Count == 1) ? "" : "s") + " detected. Shared keys are not necessarily a problem if their actions are contextual.", small, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); foreach (IGrouping<string, KeyBindInfo> item in list) { GUILayout.BeginVertical(panel, Array.Empty<GUILayoutOption>()); GUILayout.Label(item.Key, keyStyle, Array.Empty<GUILayoutOption>()); foreach (KeyBindInfo item2 in item) { GUILayout.Label("• " + item2.ModName + " — " + item2.Action, normal, Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); GUILayout.Space(7f); } } } }