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 SeneaL Recycle v1.0.0
plugins/SeneaL-Recycle/SeneaL-Recycle.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using SeneaLUI.Core; using SeneaLUI.Inv; using SeneaLUI.Mods; using SeneaLUI.Net; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [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 SeneaLUI.Recycle { public sealed class NativeRecycler : Recycler { private readonly List<KeyValuePair<ItemDrop, int>> _scratch = new List<KeyValuePair<ItemDrop, int>>(8); public override bool On { get { if (RecyclePlugin.On != null && RecyclePlugin.On.Value) { return Policy.CanRecycle; } return false; } } public override void List(Player player, List<Recipe> recipes, List<ItemData> items, List<bool> can, Dictionary<ItemData, string> why) { ObjectDB instance = ObjectDB.instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } List<ItemData> allItems = ((Humanoid)player).GetInventory().GetAllItems(); CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); for (int i = 0; i < allItems.Count; i++) { ItemData val = allItems[i]; if (val.m_equipped || Raw(val)) { continue; } Recipe recipe = instance.GetRecipe(val); if (Object.op_Implicit((Object)(object)recipe) && recipe.m_enabled && Object.op_Implicit((Object)(object)recipe.m_item) && recipe.m_resources != null && recipe.m_resources.Length != 0 && (player.IsRecipeKnown(recipe.m_item.m_itemData.m_shared.m_name) || (RecyclePlugin.Unknown.Value && Policy.CanRecycleUnknown))) { string text = null; if ((RecyclePlugin.Station.Value || Policy.RecycleOwnStation) && Object.op_Implicit((Object)(object)recipe.m_craftingStation) && (!Object.op_Implicit((Object)(object)currentCraftingStation) || currentCraftingStation.m_name != recipe.m_craftingStation.m_name)) { text = string.Format(Loc.T("Recycle.NeedStation"), Localization.instance.Localize(recipe.m_craftingStation.m_name)); } _scratch.Clear(); ((Recycler)this).Gains(val, recipe, _scratch); if (text == null && _scratch.Count == 0) { text = ((Batches(val, recipe) == 0) ? string.Format(Loc.T("Recycle.NeedStack"), recipe.m_amount) : Loc.T("Recycle.Nothing")); } recipes.Add(recipe); items.Add(val); can.Add(text == null); if (text != null) { why[val] = text; } } } } public override void Gains(ItemData item, Recipe recipe, List<KeyValuePair<ItemDrop, int>> into) { int num = Batches(item, recipe); if (num <= 0) { return; } float num2 = Mathf.Min(Mathf.Clamp01(RecyclePlugin.Rate.Value), Policy.MaxRecycleRate); Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (Object.op_Implicit((Object)(object)val.m_resItem) && val.m_recover && !val.m_upgraderResource) { int num3 = 0; for (int j = 1; j <= Mathf.Max(1, item.m_quality); j++) { num3 += val.GetAmount(j); } int num4 = Mathf.FloorToInt((float)(num3 * num) * num2); if (num4 > 0) { into.Add(new KeyValuePair<ItemDrop, int>(val.m_resItem, num4)); } } } } public override bool Take(Player player, ItemData item, Recipe recipe) { _scratch.Clear(); ((Recycler)this).Gains(item, recipe, _scratch); if (_scratch.Count == 0) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (item.m_shared.m_maxStackSize > 1) { inventory.RemoveItem(item, Batches(item, recipe) * Mathf.Max(1, recipe.m_amount)); } else { inventory.RemoveItem(item); } for (int i = 0; i < _scratch.Count; i++) { Recycling.Give(player, inventory, _scratch[i].Key, _scratch[i].Value); } return true; } private static bool Raw(ItemData item) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 SharedData shared = item.m_shared; if ((int)shared.m_itemType != 1 && (int)shared.m_itemType != 13) { if ((int)shared.m_itemType == 16) { return shared.m_maxStackSize > 1; } return false; } return true; } private static int Batches(ItemData item, Recipe recipe) { if (item.m_shared.m_maxStackSize <= 1) { return 1; } return item.m_stack / Mathf.Max(1, recipe.m_amount); } } [BepInPlugin("seneaL.valheim.ui.recycle", "SeneaL Recycle", "1.0.0")] [BepInDependency("seneaL.valheim.ui", "1.2.0")] public sealed class RecyclePlugin : BaseUnityPlugin { public const string Guid = "seneaL.valheim.ui.recycle"; public const string Name = "SeneaL Recycle"; public const string Version = "1.0.0"; private const string Texts = "SeneaLUI.Recycle.Languages."; private readonly NativeRecycler _recycler = new NativeRecycler(); public static ConfigEntry<bool> On { get; private set; } public static ConfigEntry<float> Rate { get; private set; } public static ConfigEntry<bool> Station { get; private set; } public static ConfigEntry<bool> Unknown { get; private set; } private void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown On = ((BaseUnityPlugin)this).Config.Bind<bool>("Recycle", "Enabled", true, "A Recycle tab at crafting stations that takes a crafted item apart into part of its materials. Ignored while Valheim Recycle or Recycle N Reclaim is installed: their recycling fills the same tab instead."); Rate = ((BaseUnityPlugin)this).Config.Bind<float>("Recycle", "Rate", 0.5f, new ConfigDescription("Share of the materials that comes back, counting every quality level of the item (rounded down).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); Station = ((BaseUnityPlugin)this).Config.Bind<bool>("Recycle", "OwnStation", true, "An item is recycled only at the station it is crafted at."); Unknown = ((BaseUnityPlugin)this).Config.Bind<bool>("Recycle", "UnknownRecipes", false, "Also list items whose recipe you do not know yet."); LoadTexts(); Recycling.Register((Recycler)(object)_recycler); Func<bool> free = () => !Recycle.On && !Rnr.On; Func<bool> active = () => On.Value && free() && Policy.CanRecycle; Func<string> why = () => (!free() || Policy.CanRecycle) ? ((!free()) ? string.Format(Loc.T("Recycle.WhyMod"), Rnr.On ? "Recycle N Reclaim" : "Valheim Recycle") : string.Format(Loc.T("Recycle.WhyOn"), Loc.T("Recycle.Enabled"))) : Loc.T("Recycle.WhyServer"); Addon obj = Addons.Register("seneaL.valheim.ui.recycle", "SeneaL Recycle", (Func<string>)null, (string)null, (string)null); obj.Switch((Func<string>)(() => Loc.T("Recycle.Enabled")), On, free, why); obj.Slider((Func<string>)(() => Loc.T("Recycle.Rate")), Rate, 0f, 1f, (Func<float, string>)((float v) => Mathf.RoundToInt(v * 100f) + "%"), active, (Func<float>)(() => Policy.MaxRecycleRate), why); obj.Switch((Func<string>)(() => Loc.T("Recycle.Station")), Station, (Func<bool>)(() => active() && !Policy.RecycleOwnStation), (Func<string>)(() => (!Policy.RecycleOwnStation) ? why() : Loc.T("Recycle.WhyServer"))); obj.Switch((Func<string>)(() => Loc.T("Recycle.Unknown")), Unknown, (Func<bool>)(() => active() && Policy.CanRecycleUnknown), (Func<string>)(() => Policy.CanRecycleUnknown ? why() : Loc.T("Recycle.WhyServer"))); } private void OnDestroy() { Recycling.Unregister((Recycler)(object)_recycler); } private static void LoadTexts() { Assembly assembly = typeof(RecyclePlugin).Assembly; string[] manifestResourceNames = assembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (!text.StartsWith("SeneaLUI.Recycle.Languages.") || !text.EndsWith(".txt")) { continue; } using Stream stream = assembly.GetManifestResourceStream(text); using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8); Loc.Extend(text.Substring("SeneaLUI.Recycle.Languages.".Length, text.Length - "SeneaLUI.Recycle.Languages.".Length - 4), streamReader.ReadToEnd()); } } } }