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 FoodStats v1.0.0
plugins/FoodStats.dll
Decompiled 2 weeks agousing System; using System.Collections; 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.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [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("FoodStats")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FoodStats")] [assembly: AssemblyTitle("FoodStats")] [assembly: AssemblyVersion("1.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 FoodStats { internal sealed class ConfigurationManagerAttributes { public int? Order; public bool? HideDefaultButton; public Action<ConfigEntryBase> CustomDrawer; } public enum FoodSort { Default, Health, Stamina, Eitr, Total } internal static class FoodInfo { private const string HealthColor = "#ff8080"; private const string StaminaColor = "#ffff80"; private const string EitrColor = "#9090ff"; public static SharedData Displayed(SharedData shared) { ItemDrop val = shared?.m_appendToolTip; if (!((Object)(object)val != (Object)null) || !IsFood(val.m_itemData.m_shared)) { return shared; } return val.m_itemData.m_shared; } public static bool IsFood(SharedData shared) { if (shared != null) { if (!(shared.m_food > 0f) && !(shared.m_foodStamina > 0f)) { return shared.m_foodEitr > 0f; } return true; } return false; } public static string StatsText(SharedData shared) { List<string> list = new List<string>(); if (shared.m_food > 0f) { list.Add(Colored(shared.m_food, "#ff8080")); } if (shared.m_foodStamina > 0f) { list.Add(Colored(shared.m_foodStamina, "#ffff80")); } if (shared.m_foodEitr > 0f) { list.Add(Colored(shared.m_foodEitr, "#9090ff")); } return string.Join(" ", list); } public static float SortKey(SharedData shared, FoodSort mode) { if (!IsFood(shared)) { return 0f; } return mode switch { FoodSort.Health => shared.m_food, FoodSort.Stamina => shared.m_foodStamina, FoodSort.Eitr => shared.m_foodEitr, FoodSort.Total => shared.m_food + shared.m_foodStamina + shared.m_foodEitr, _ => 0f, }; } private static string Colored(float value, string color) { return $"<color={color}>{Mathf.RoundToInt(value)}</color>"; } } [BepInPlugin("batera.FoodStats", "FoodStats", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "batera.FoodStats"; public const string PluginName = "FoodStats"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<FoodSort> SortMode; private Harmony _harmony; private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BindConfig(); _harmony = new Harmony("batera.FoodStats"); _harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"FoodStats 1.0.0 loaded"); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void BindConfig() { Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, Desc("Show food stats in the crafting list and the sort button.", 2)); SortMode = ((BaseUnityPlugin)this).Config.Bind<FoodSort>("1 - General", "SortMode", FoodSort.Default, Desc("How food recipes are sorted. The sort button next to the crafting tabs changes this too.", 1)); } private static ConfigDescription Desc(string text, int order) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new ConfigDescription(text, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = order } }); } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] internal static class RecipeListPatch { private const string StatsObjectName = "foodstats"; private static readonly FieldInfo AvailableRecipesField = AccessTools.Field(typeof(InventoryGui), "m_availableRecipes"); private static readonly Type PairType = AccessTools.Inner(typeof(InventoryGui), "RecipeDataPair"); private static readonly PropertyInfo PairRecipe = AccessTools.Property(PairType, "Recipe"); private static readonly PropertyInfo PairElement = AccessTools.Property(PairType, "InterfaceElement"); private static void Postfix(InventoryGui __instance) { if (!(AvailableRecipesField.GetValue(__instance) is IList list)) { return; } bool flag = false; if (Plugin.Enabled.Value) { foreach (object item in list) { SharedData shared = Shared(item); if (FoodInfo.IsFood(shared)) { flag = true; AddStats(Element(item), shared); } } } bool flag2 = flag && __instance.InCraftTab(); SortButton.Refresh(__instance, flag2); if (flag2 && Plugin.SortMode.Value != FoodSort.Default) { Sort(__instance, list, Plugin.SortMode.Value); } } private static void AddStats(GameObject element, SharedData shared) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) object obj; if (!((Object)(object)element != (Object)null)) { obj = null; } else { Transform obj2 = element.transform.Find("name"); obj = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null); } TMP_Text val = (TMP_Text)obj; if (!((Object)(object)val == (Object)null) && !((Object)(object)element.transform.Find("foodstats") != (Object)null)) { float num = (val.enableAutoSizing ? val.fontSizeMax : val.fontSize); GameObject obj3 = Object.Instantiate<GameObject>(((Component)val).gameObject, val.transform.parent); ((Object)obj3).name = "foodstats"; TMP_Text component = obj3.GetComponent<TMP_Text>(); component.text = FoodInfo.StatsText(shared); ((Graphic)component).color = Color.white; component.enableAutoSizing = false; component.fontSize = num * 0.72f; component.alignment = (TextAlignmentOptions)4100; component.textWrappingMode = (TextWrappingModes)0; component.overflowMode = (TextOverflowModes)0; ((Graphic)component).raycastTarget = false; float x = component.GetPreferredValues(component.text).x; val.enableAutoSizing = false; val.fontSize = num * 0.8f; val.textWrappingMode = (TextWrappingModes)0; val.overflowMode = (TextOverflowModes)1; RectTransform rectTransform = val.rectTransform; rectTransform.offsetMax = new Vector2(rectTransform.offsetMax.x - x - 8f, rectTransform.offsetMax.y); } } private static void Sort(InventoryGui gui, IList rows, FoodSort mode) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) List<object> list = (from object row in rows orderby FoodInfo.SortKey(Shared(row), mode) descending select row).ToList(); rows.Clear(); foreach (object item in list) { rows.Add(item); } for (int num = 0; num < list.Count; num++) { GameObject obj = Element(list[num]); Transform obj2 = ((obj != null) ? obj.transform : null); RectTransform val = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); if (val != null) { val.anchoredPosition = new Vector2(0f, (float)num * (0f - gui.m_recipeListSpace)); } } } private static SharedData Shared(object row) { object? value = PairRecipe.GetValue(row); Recipe val = (Recipe)((value is Recipe) ? value : null); if (!((Object)(object)val != (Object)null) || !((Object)(object)val.m_item != (Object)null)) { return null; } return FoodInfo.Displayed(val.m_item.m_itemData.m_shared); } private static GameObject Element(object row) { object? value = PairElement.GetValue(row); return (GameObject)((value is GameObject) ? value : null); } } internal static class SortButton { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnClick; } private static readonly MethodInfo UpdateCraftingPanel = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null); private static Button s_button; private static TMP_Text s_label; public static void Refresh(InventoryGui gui, bool visible) { if ((Object)(object)s_button == (Object)null) { Create(gui); } if (!((Object)(object)s_button == (Object)null)) { ((Component)s_button).gameObject.SetActive(visible); if (visible && (Object)(object)s_label != (Object)null) { s_label.text = Texts.SortLabel(Plugin.SortMode.Value); } } } private static void Create(InventoryGui gui) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_010f: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown Button tabUpgrade = gui.m_tabUpgrade; if ((Object)(object)tabUpgrade == (Object)null) { return; } GameObject val = Object.Instantiate<GameObject>(((Component)tabUpgrade).gameObject, ((Component)tabUpgrade).transform.parent); ((Object)val).name = "FoodStats_SortButton"; Component[] componentsInChildren = val.GetComponentsInChildren<Component>(true); foreach (Component val2 in componentsInChildren) { string name = ((object)val2).GetType().Name; if (name == "Localize" || name == "UIGamePad") { Object.Destroy((Object)(object)val2); } } s_button = val.GetComponent<Button>(); s_button.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = s_button.onClick; object obj = <>O.<0>__OnClick; if (obj == null) { UnityAction val3 = OnClick; <>O.<0>__OnClick = val3; obj = (object)val3; } ((UnityEvent)onClick).AddListener((UnityAction)obj); ((Selectable)s_button).interactable = true; RectTransform val4 = (RectTransform)val.transform; RectTransform val5 = (RectTransform)((Component)tabUpgrade).transform; Vector2 anchoredPosition = val5.anchoredPosition; Rect rect = val5.rect; val4.anchoredPosition = anchoredPosition + new Vector2(((Rect)(ref rect)).width + 10f, 0f); s_label = val.GetComponentInChildren<TMP_Text>(true); } private static void OnClick() { int length = Enum.GetValues(typeof(FoodSort)).Length; Plugin.SortMode.Value = (FoodSort)((int)(Plugin.SortMode.Value + 1) % length); InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance != (Object)null) { UpdateCraftingPanel.Invoke(instance, new object[1] { false }); } } } internal static class Texts { private static bool Pt { get { if (Localization.instance != null) { return Localization.instance.GetSelectedLanguage().StartsWith("Portuguese", StringComparison.OrdinalIgnoreCase); } return false; } } public static string SortLabel(FoodSort mode) { return (Pt ? "Ordem: " : "Sort: ") + ModeName(mode); } private static string ModeName(FoodSort mode) { switch (mode) { case FoodSort.Health: if (!Pt) { return "Health"; } return "Vida"; case FoodSort.Stamina: return "Stamina"; case FoodSort.Eitr: return "Eitr"; case FoodSort.Total: return "Total"; default: if (!Pt) { return "Default"; } return "Padrão"; } } } }