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 WhatsMyWorkbenchMissing v0.1.0
BepInEx/plugins/WhatsMyWorkbenchMissing.dll
Decompiled 5 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("WhatsMyWorkbenchMissing")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+d5a8ee4882e3122994c9bdaae89ebc5453618d37")] [assembly: AssemblyProduct("WhatsMyWorkbenchMissing")] [assembly: AssemblyTitle("WhatsMyWorkbenchMissing")] [assembly: AssemblyVersion("0.1.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 WhatsMyWorkbenchMissing { [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] internal static class LevelTooltip { private const float RefreshInterval = 0.5f; private static UITooltip _tooltip; private static bool _warnedNoPrefab; private static CraftingStation _lastStation; private static int _lastLevel = -1; private static float _nextRefresh; private static void Postfix(InventoryGui __instance, Player player) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) RectTransform craftingStationLevelRoot = __instance.m_craftingStationLevelRoot; if ((Object)(object)craftingStationLevelRoot == (Object)null || (Object)(object)player == (Object)null) { return; } CraftingStation val = (WhatsMyWorkbenchMissingMod.ModEnabled.Value ? player.GetCurrentCraftingStation() : null); if ((Object)(object)val == (Object)null) { if ((Object)(object)_tooltip != (Object)null) { _tooltip.Set("", "", (RectTransform)null, default(Vector2)); } _lastStation = null; _lastLevel = -1; return; } if ((Object)(object)_tooltip == (Object)null || (Object)(object)((Component)_tooltip).gameObject != (Object)(object)((Component)craftingStationLevelRoot).gameObject) { _tooltip = Attach(__instance, craftingStationLevelRoot); } if (!((Object)(object)_tooltip == (Object)null)) { int level = val.GetLevel(true); if (!((Object)(object)val == (Object)(object)_lastStation) || level != _lastLevel || !(Time.unscaledTime < _nextRefresh)) { _lastStation = val; _lastLevel = level; _nextRefresh = Time.unscaledTime + 0.5f; UpgradeReport.Build(val, player, out var topic, out var text); _tooltip.Set(topic, text, (RectTransform)null, default(Vector2)); } } } private static UITooltip Attach(InventoryGui gui, RectTransform root) { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) UITooltip component = ((Component)root).GetComponent<UITooltip>(); if ((Object)(object)component != (Object)null) { return component; } GameObject val = null; UITooltip val2 = (((Object)(object)gui.m_craftButton != (Object)null) ? ((Component)gui.m_craftButton).GetComponent<UITooltip>() : null); if ((Object)(object)val2 != (Object)null) { val = val2.m_tooltipPrefab; } if ((Object)(object)val == (Object)null) { UITooltip[] componentsInChildren = ((Component)gui).GetComponentsInChildren<UITooltip>(true); foreach (UITooltip val3 in componentsInChildren) { if ((Object)(object)val3.m_tooltipPrefab != (Object)null) { val = val3.m_tooltipPrefab; break; } } } if ((Object)(object)val == (Object)null) { if (!_warnedNoPrefab) { _warnedNoPrefab = true; WhatsMyWorkbenchMissingMod.Log.LogWarning((object)"No tooltip prefab found in the inventory panel; the level tooltip is off."); } return null; } bool flag = false; Graphic[] componentsInChildren2 = ((Component)root).GetComponentsInChildren<Graphic>(true); foreach (Graphic obj in componentsInChildren2) { obj.raycastTarget = true; if ((Object)(object)((Component)obj).gameObject == (Object)(object)((Component)root).gameObject) { flag = true; } } if (!flag) { Image obj2 = ((Component)root).gameObject.AddComponent<Image>(); ((Graphic)obj2).color = Color.clear; ((Graphic)obj2).raycastTarget = true; } UITooltip obj3 = ((Component)root).gameObject.AddComponent<UITooltip>(); obj3.m_tooltipPrefab = val; WhatsMyWorkbenchMissingMod.Log.LogInfo((object)"Level tooltip attached to the crafting panel."); return obj3; } } internal static class UpgradeReport { private const string ColorReady = "#9be27a"; private const string ColorKnown = "#ffb866"; private const string ColorShort = "#ff5e5e"; private const string ColorDim = "#9a9a9a"; private static Dictionary<string, List<Piece>> _byStation; private static ObjectDB _indexedDb; private static int _indexedItemCount = -1; private static readonly List<StationExtension> _attached = new List<StationExtension>(); private static readonly HashSet<string> _builtNames = new HashSet<string>(); private static readonly List<Piece> _ready = new List<Piece>(); private static readonly List<Piece> _known = new List<Piece>(); private static readonly List<Piece> _built = new List<Piece>(); internal static void Build(CraftingStation station, Player player, out string topic, out string text) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) int level = station.GetLevel(true); topic = $"{station.m_name} level {level}"; Dictionary<string, List<Piece>> dictionary = Index(); List<Piece> value = null; dictionary?.TryGetValue(station.m_name, out value); if (value == null || value.Count == 0) { text = "This station has no upgrades."; return; } _attached.Clear(); StationExtension.FindExtensions(station, ((Component)station).transform.position, _attached); _builtNames.Clear(); foreach (StationExtension item in _attached) { Piece val = (Object.op_Implicit((Object)(object)item) ? ((Component)item).GetComponent<Piece>() : null); if ((Object)(object)val != (Object)null) { _builtNames.Add(val.m_name); } } _ready.Clear(); _known.Clear(); _built.Clear(); int num = 0; foreach (Piece item2 in value) { if (_builtNames.Contains(item2.m_name)) { _built.Add(item2); } else if (item2.m_enabled) { if (!IsKnown(item2, player)) { num++; } else if (player.HaveRequirements(item2, (RequirementMode)0)) { _ready.Add(item2); } else { _known.Add(item2); } } } Inventory inventory = ((Humanoid)player).GetInventory(); StringBuilder stringBuilder = new StringBuilder(); if (_ready.Count > 0) { stringBuilder.Append("<color=").Append("#9be27a").Append(">Ready to build:</color>\n"); foreach (Piece item3 in _ready) { AppendPiece(stringBuilder, item3, inventory, "#9be27a"); } } if (_known.Count > 0) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append("<color=").Append("#ffb866").Append(">Missing materials:</color>\n"); foreach (Piece item4 in _known) { AppendPiece(stringBuilder, item4, inventory, "#ffb866"); } } if (_ready.Count == 0 && _known.Count == 0) { if (num == 0) { stringBuilder.Append("Fully upgraded.\n"); } else if (_built.Count == 0) { stringBuilder.Append("No upgrades discovered yet.\n"); } else { stringBuilder.Append("Every upgrade you know is built.\n"); } } if (WhatsMyWorkbenchMissingMod.ShowUndiscovered.Value && num > 0) { stringBuilder.Append("<color=").Append("#9a9a9a").Append('>') .Append(num) .Append((num == 1) ? " more upgrade" : " more upgrades") .Append(" not yet discovered.</color>\n"); } if (WhatsMyWorkbenchMissingMod.ShowBuilt.Value && _built.Count > 0) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append("<color=").Append("#9a9a9a").Append(">Built:\n"); foreach (Piece item5 in _built) { stringBuilder.Append(" ").Append(item5.m_name).Append('\n'); } stringBuilder.Append("</color>"); } text = stringBuilder.ToString().TrimEnd(new char[1] { '\n' }); } private static bool IsKnown(Piece piece, Player player) { if (player.NoCostCheat()) { return true; } if (player.IsRecipeKnown(piece.m_name)) { return player.HaveRequirements(piece, (RequirementMode)1); } return false; } private static void AppendPiece(StringBuilder sb, Piece piece, Inventory inventory, string nameColor) { sb.Append(" <color=").Append(nameColor).Append('>') .Append(piece.m_name) .Append("</color>"); if (WhatsMyWorkbenchMissingMod.ShowMaterials.Value) { bool flag = true; Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; int num = ((inventory != null) ? inventory.CountItems(name, -1, true) : 0); sb.Append(flag ? " " : ", "); flag = false; if (num >= val.m_amount) { sb.Append(val.m_amount).Append(' ').Append(name); } else { sb.Append("<color=").Append("#ff5e5e").Append('>') .Append(num) .Append('/') .Append(val.m_amount) .Append(' ') .Append(name) .Append("</color>"); } } } } sb.Append('\n'); } private static Dictionary<string, List<Piece>> Index() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return null; } if (_byStation != null && (Object)(object)_indexedDb == (Object)(object)instance && _indexedItemCount == instance.m_items.Count) { return _byStation; } Dictionary<string, List<Piece>> dictionary = new Dictionary<string, List<Piece>>(); HashSet<GameObject> hashSet = new HashSet<GameObject>(); HashSet<string> hashSet2 = new HashSet<string>(); foreach (GameObject item in instance.m_items) { PieceTable val = (Object.op_Implicit((Object)(object)item) ? item.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val == (Object)null) { continue; } foreach (GameObject piece in val.m_pieces) { if ((Object)(object)piece == (Object)null || !hashSet.Add(piece)) { continue; } StationExtension component = piece.GetComponent<StationExtension>(); if ((Object)(object)component == (Object)null || (Object)(object)component.m_craftingStation == (Object)null) { continue; } Piece component2 = piece.GetComponent<Piece>(); if (!((Object)(object)component2 == (Object)null) && hashSet2.Add(component.m_craftingStation.m_name + "\n" + component2.m_name)) { if (!dictionary.TryGetValue(component.m_craftingStation.m_name, out var value)) { value = new List<Piece>(); dictionary[component.m_craftingStation.m_name] = value; } value.Add(component2); } } } _byStation = dictionary; _indexedDb = instance; _indexedItemCount = instance.m_items.Count; int num = 0; foreach (List<Piece> value2 in dictionary.Values) { num += value2.Count; } WhatsMyWorkbenchMissingMod.Log.LogInfo((object)$"Indexed {num} station upgrades for {dictionary.Count} stations."); return dictionary; } } [BepInPlugin("DeathMonger.WhatsMyWorkbenchMissing", "What's My Workbench Missing", "0.1.0")] [BepInProcess("valheim.exe")] public class WhatsMyWorkbenchMissingMod : BaseUnityPlugin { public const string ModGuid = "DeathMonger.WhatsMyWorkbenchMissing"; public const string ModName = "What's My Workbench Missing"; public const string ModVersion = "0.1.0"; internal static ConfigEntry<bool> ModEnabled; internal static ConfigEntry<bool> ShowMaterials; internal static ConfigEntry<bool> ShowUndiscovered; internal static ConfigEntry<bool> ShowBuilt; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Mod Enabled", true, "Master switch. Off means the level number shows no tooltip. Takes effect immediately."); ShowMaterials = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Materials", true, "List each upgrade's materials after its name. Amounts you are short of are red and show how many you carry, as in 4/10 Flint."); ShowUndiscovered = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Undiscovered Count", true, "Add a line counting the upgrades you have not discovered yet, without naming them. Off leaves the undiscovered ones out entirely."); ShowBuilt = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Built", false, "Also list the upgrades already attached to the station, dimmed, so the tooltip shows the whole picture."); _harmony = new Harmony("DeathMonger.WhatsMyWorkbenchMissing"); _harmony.PatchAll(); Log.LogInfo((object)"What's My Workbench Missing 0.1.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }