Decompiled source of Recycle N Reclaim v1.3.5
Recycle_N_Reclaim.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using Auga; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jewelcrafting; using LocalizationManager; using Microsoft.CodeAnalysis; using Recycle_N_Reclaim.GamePatches.MarkAsTrash; using Recycle_N_Reclaim.GamePatches.Recycling; using Recycle_N_Reclaim.GamePatches.UI; using Recycle_N_Reclaim.YAMLStuff; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: AssemblyDescription("")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyProduct("Recycle_N_Reclaim")] [assembly: AssemblyCompany("Azumatt")] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyConfiguration("")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyTitle("Recycle_N_Reclaim")] [assembly: AssemblyFileVersion("1.3.5")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.5.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [<59ee7180-282a-4211-9143-92bdb4a1f8d1>Embedded] [CompilerGenerated] internal sealed class <59ee7180-282a-4211-9143-92bdb4a1f8d1>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<59ee7180-282a-4211-9143-92bdb4a1f8d1>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <3f607022-9496-490a-85e6-01cde9ffb3e4>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <3f607022-9496-490a-85e6-01cde9ffb3e4>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <3f607022-9496-490a-85e6-01cde9ffb3e4>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<59ee7180-282a-4211-9143-92bdb4a1f8d1>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContextAttribute : Attribute { public readonly byte Flag; public <607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace LocalizationManager { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [PublicAPI] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(2)] private static BaseUnityPlugin _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null) { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (object _, EventArgs _) => { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static void Load() { LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.ContainsKey(language)) { text2 = File.ReadAllText(dictionary[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text2 = Encoding.UTF8.GetString(array2); } } } if (text2 == null && dictionary.ContainsKey("English")) { text2 = File.ReadAllText(dictionary["English"]); } if (text2 != null) { foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair<string, string> item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string> { ".json", ".yml" }; new Harmony("org.bepinex.helpers.LocalizationManager").Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [return: <3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(2)] private static byte[] LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(2)] public static byte[] ReadEmbeddedFileBytes([<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(1)] string resourceFileName, Assembly containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Recycle_N_Reclaim { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [BepInPlugin("Azumatt.Recycle_N_Reclaim", "Recycle_N_Reclaim", "1.3.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Recycle_N_ReclaimPlugin : BaseUnityPlugin { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] public enum Toggle { On = 1, Off = 0 } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string Category; [UsedImplicitly] public Action<ConfigEntryBase> CustomDrawer; } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } internal const string ModName = "Recycle_N_Reclaim"; internal const string ModVersion = "1.3.5"; internal const string Author = "Azumatt"; private const string ModGUID = "Azumatt.Recycle_N_Reclaim"; private static string ConfigFileName = "Azumatt.Recycle_N_Reclaim.cfg"; private static string ConfigFileFullPath; [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(2)] internal static Assembly epicLootAssembly; internal static string ConnectionError; public static bool HasAuga; private ContainerRecyclingButtonHolder _containerRecyclingButton; private readonly Harmony _harmony = new Harmony("Azumatt.Recycle_N_Reclaim"); public static readonly ManualLogSource Recycle_N_ReclaimLogger; internal static readonly ConfigSync ConfigSyncVar; internal static readonly string yamlFileName; internal static readonly string yamlPath; internal static readonly CustomSyncedValue<string> RNRExcludeListData; internal static Root yamlData; internal static Dictionary<string, HashSet<string>> predefinedGroups; private static ConfigEntry<Toggle> _serverConfigLocked; public static ConfigEntry<KeyboardShortcut> hotKey; public static ConfigEntry<Toggle> discardInvEnabled; public static ConfigEntry<Toggle> lockToAdmin; public static ConfigEntry<Toggle> returnUnknownResources; public static ConfigEntry<Toggle> returnEnchantedResources; public static ConfigEntry<float> returnResources; private ConfigEntry<string> _stationFilterListString; public static List<string> StationFilterList; public static ConfigEntry<Toggle> StationFilterEnabled; public static ConfigEntry<Toggle> EnableExperimentalCraftingTabUI; public static ConfigEntry<Toggle> NotifyOnSalvagingImpediments; public static ConfigEntry<Toggle> PreventZeroResourceYields; public static ConfigEntry<Toggle> UnstackableItemsAlwaysReturnAtLeastOneResource; public static ConfigEntry<float> RecyclingRate; public static ConfigEntry<Toggle> ContainerRecyclingEnabled; public static ConfigEntry<Toggle> IgnoreItemsOnHotbar; public static ConfigEntry<Vector3> ContainerRecyclingButtonPositionJsonString; public static ConfigEntry<Toggle> AllowRecyclingUnknownRecipes; public static ConfigEntry<Toggle> DebugAlwaysDumpAnalysisContext; public static ConfigEntry<Toggle> DebugAllowSpammyLogs; public static ConfigEntry<Toggle> HideEquippedItemsInRecyclingTab; public static ConfigEntry<Toggle> RequireExactCraftingStationForRecycling; public static ConfigEntry<Toggle> returnEnchantedResourcesReclaiming; public static ConfigEntry<Color> BorderColorTrashedItem; public static ConfigEntry<Color> BorderColorTrashedSlot; public static ConfigEntry<bool> DisplayTooltipHint; public static ConfigEntry<KeyboardShortcut> TrashingModifierKeybind1; public static ConfigEntry<KeyboardShortcut> TrashingKeybind; public static ConfigEntry<string> TrashedSlotTooltip; public static StationRecyclingTabHolder RecyclingTabButtonHolder { get; private set; } private ConfigEntry<string> StationFilterListString { get { return _stationFilterListString; } set { _stationFilterListString = value; value.SettingChanged += [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (object sender, EventArgs args) => { SplitNewValueAndSetProperty(); }; SplitNewValueAndSetProperty(); void SplitNewValueAndSetProperty() { StationFilterList = (from entry in value.Value.Split(new char[1] { ',' }) select entry.Trim()).ToList(); } } } public void Awake() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) Game.isModded = true; Localizer.Load(); _serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); ConfigSyncVar.AddLockingConfigEntry<Toggle>(_serverConfigLocked); string group = "2 - Inventory Recycle"; discardInvEnabled = config(group, "Enabled", Toggle.On, new ConfigDescription("If on, you'll be able to discard things inside of the player inventory.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); lockToAdmin = config(group, "Lock to Admin", Toggle.On, new ConfigDescription("If on, only admin's can use this feature.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); hotKey = config<KeyboardShortcut>(group, "DiscardHotkey(s)", new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()), new ConfigDescription("The hotkey to discard an item or regain resources. Must be enabled", (AcceptableValueBase)(object)new AcceptableShortcuts(), Array.Empty<object>()), synchronizedSetting: false); returnUnknownResources = config(group, "ReturnUnknownResources", Toggle.Off, "If on, discarding an item in the inventory will return resources if recipe is unknown"); returnEnchantedResources = config(group, "ReturnEnchantedResources", Toggle.On, "If on and Epic Loot or Jewelcrafting is installed, discarding an item in the inventory will return resources for Epic Loot enchantments or Jewelcrafting gems"); returnResources = config(group, "ReturnResources", 1f, "Fraction of resources to return (0.0 - 1.0). This setting is forced to be between 0 and 1. Any higher or lower values will be set to 0 or 1 respectively."); returnResources.SettingChanged += [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (object sender, EventArgs args) => { if (returnResources.Value > 1f) { returnResources.Value = 1f; } if (returnResources.Value < 0f) { returnResources.Value = 0f; } }; string text = "While this & right click are held, hovering over items marks them for trashing. Releasing this will cancel trashing for all items."; BorderColorTrashedSlot = config<Color>(group, "BorderColorTrashedItem", new Color(1f, 0f, 0f), "Color of the border for slots containing Trashed items.", synchronizedSetting: false); DisplayTooltipHint = config(group, "DisplayTooltipHint", value: true, "Whether to add additional info the item tooltip of a Trashed or trash flagged item.", synchronizedSetting: false); TrashingKeybind = config<KeyboardShortcut>(group, "TrashingKeybind", new KeyboardShortcut((KeyCode)325, Array.Empty<KeyCode>()), "Key(s) that when pressed while holding your modifier key will trash all items marked as trash. Default setting is middle mouse click", synchronizedSetting: false); TrashingModifierKeybind1 = config<KeyboardShortcut>(group, "TrashingModifierKeybind1", new KeyboardShortcut((KeyCode)120, Array.Empty<KeyCode>()), text + ".", synchronizedSetting: false); TrashedSlotTooltip = config(group, "TrashedSlotTooltip", "Slot is Trashed and will be a part of the bulk delete", string.Empty, synchronizedSetting: false); RecyclingRate = config("3 - Reclaiming", "RecyclingRate", 0.5f, "Rate at which the resources are recycled. Value must be between 0 and 1.\nThe mod always rolls *down*, so if you were supposed to get 2.5 items, you would only receive 2. If the recycling rate is 0.5 (50%), the player will receive half of the resources they would usually need to craft the item, assuming a single item in a stack and the item is of quality level 1. If the item is of higher quality, the resulting yield would be higher as well."); RecyclingRate.SettingChanged += [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (object sender, EventArgs args) => { if (RecyclingRate.Value > 1f) { RecyclingRate.Value = 1f; } if (RecyclingRate.Value < 0f) { RecyclingRate.Value = 0f; } }; UnstackableItemsAlwaysReturnAtLeastOneResource = config("3 - Reclaiming", "UnstackableItemsAlwaysReturnAtLeastOneResource", Toggle.On, "If enabled and recycling a specific _unstackable_ item would yield 0 of a material,\ninstead you will receive 1. If disabled, you get nothing."); RequireExactCraftingStationForRecycling = config("3 - Reclaiming", "RequireExactCraftingStationForRecycling", Toggle.On, "If enabled, recycling will also check for the required crafting station type and level.\nIf disabled, will ignore all crafting station requirements altogether.\nEnabled by default, to keep things close to how Valheim operates."); returnEnchantedResourcesReclaiming = config("3 - Reclaiming", "ReturnEnchantedResources", Toggle.On, "If on and Epic Loot or Jewelcrafting is installed, discarding an item in the inventory will return resources for Epic Loot enchantments or Jewelcrafting gems"); PreventZeroResourceYields = config("3 - Reclaiming", "PreventZeroResourceYields", Toggle.On, "If enabled and recycling an item that would yield 0 of any material,\ninstead you will receive 1. If disabled, you get nothing."); AllowRecyclingUnknownRecipes = config("3 - Reclaiming", "AllowRecyclingUnknownRecipes", Toggle.Off, "If enabled, it will allow you to recycle items that you do not know the recipe for yet.\nDisabled by default as this can be cheaty, but sometimes required due to people losing progress."); ContainerRecyclingButtonPositionJsonString = config<Vector3>("4 - UI", "ContainerButtonPosition", new Vector3(496f, -374f, -1f), "The last saved recycling button position stored in JSON"); ContainerRecyclingEnabled = config("4 - UI", "ContainerRecyclingEnabled", Toggle.On, "If enabled, the mod will display the container recycling button"); NotifyOnSalvagingImpediments = config("4 - UI", "NotifyOnSalvagingImpediments", Toggle.On, "If enabled and recycling a specific item runs into any issues, the mod will print a message\nin the center of the screen (native Valheim notification). At the time of implementation,\nthis happens in the following cases:\n - not enough free slots in the inventory to place the resulting resources\n - player does not know the recipe for the item\n - if enabled, cases when `PreventZeroResourceYields` kicks in and prevent the crafting"); EnableExperimentalCraftingTabUI = config("4 - UI", "EnableExperimentalCraftingTabUI", Toggle.On, "If enabled, will display the experimental work in progress crafting tab UI\nEnabled by default."); HideEquippedItemsInRecyclingTab = config("4 - UI", "HideRecipesForEquippedItems", Toggle.On, "If enabled, it will hide equipped items in the crafting tab.\nThis does not make the item recyclable and only influences whether or not it's shown.\nEnabled by default."); IgnoreItemsOnHotbar = config("4 - UI", "IgnoreItemsOnHotbar", Toggle.On, "If enabled, it will hide hotbar items in the crafting tab.\nEnabled by default."); StationFilterEnabled = config("4 - UI", "StationFilterEnabled", Toggle.On, "If enabled, will filter all recycling recipes based on the crafting station\nused to produce said item. Main purpose of this is to prevent showing food\nas a recyclable item, but can be extended further if needed.\nEnabled by default"); StationFilterListString = config("4 - UI", "StationFilterList", "piece_cauldron", "Comma separated list of crafting stations (by their \"prefab name\")\nrecipes from which should be ignored in regards to recycling.\nMain purpose of this is to prevent showing food as a recyclable item,\nbut can be extended further if needed.\n\nFull list of stations used in recipes as of 0.216.9:\n- identifier: `forge` in game name: Forge\n- identifier: `blackforge` in game name: Black Forge\n- identifier: `piece_workbench` in game name: Workbench\n- identifier: `piece_cauldron` in game name: Cauldron\n- identifier: `piece_stonecutter` in game name: Stonecutter\n- identifier: `piece_artisanstation` in game name: Artisan table\n- identifier: `piece_magetable` in game name: Galdr table\n"); DebugAlwaysDumpAnalysisContext = config("zDebug", "DebugAlwaysDumpAnalysisContext", Toggle.Off, "If enabled will dump a complete detailed recycling report every time. This is taxing in terms\nof performance and should only be used when debugging issues. "); DebugAllowSpammyLogs = config("zDebug", "DebugAllowSpammyLogs", Toggle.Off, "If enabled, will spam recycling checks to the console.\nVERY. VERY. SPAMMY. Influences performance. "); if (!File.Exists(yamlPath)) { YAMLUtils.WriteConfigFileFromResource(yamlPath); } RNRExcludeListData.ValueChanged += OnValChangedUpdate; RNRExcludeListData.AssignLocalValue(File.ReadAllText(yamlPath)); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); } private void Start() { InventoryGridUpdateGuiPatch.border = loadSprite("trashingborder.png"); AutoDoc(); HasAuga = Auga.API.IsLoaded(); _containerRecyclingButton = ((Component)this).gameObject.AddComponent<ContainerRecyclingButtonHolder>(); _containerRecyclingButton.OnRecycleAllTriggered += ContainerRecyclingTriggered; RecyclingTabButtonHolder = ((Component)this).gameObject.AddComponent<StationRecyclingTabHolder>(); if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot")) { epicLootAssembly = ((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType().Assembly; Recycle_N_ReclaimLogger.LogDebug((object)"Epic Loot found, providing compatibility"); } } internal static Sprite loadSprite(string name) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = loadTexture(name); if ((Object)(object)val != (Object)null) { return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), Vector2.zero); } return null; } private static Texture2D loadTexture(string name) { //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_001d: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("Assets." + name)); return val; } private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream); return memoryStream.ToArray(); } private void AutoDoc() { } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; FileSystemWatcher fileSystemWatcher2 = new FileSystemWatcher(Paths.ConfigPath, yamlFileName); fileSystemWatcher2.Changed += ReadYamlFiles; fileSystemWatcher2.Created += ReadYamlFiles; fileSystemWatcher2.Renamed += ReadYamlFiles; fileSystemWatcher2.IncludeSubdirectories = true; fileSystemWatcher2.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher2.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { Recycle_N_ReclaimLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { Recycle_N_ReclaimLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); Recycle_N_ReclaimLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private void ReadYamlFiles(object sender, FileSystemEventArgs e) { if (!File.Exists(yamlPath)) { return; } try { Recycle_N_ReclaimLogger.LogDebug((object)"ReadConfigValues called"); RNRExcludeListData.AssignLocalValue(File.ReadAllText(yamlPath)); } catch { Recycle_N_ReclaimLogger.LogError((object)("There was an issue loading your " + yamlFileName)); Recycle_N_ReclaimLogger.LogError((object)"Please check your entries for spelling and format!"); } } private static void OnValChangedUpdate() { Recycle_N_ReclaimLogger.LogDebug((object)"OnValChanged called"); try { YAMLUtils.ReadYaml(RNRExcludeListData.Value); } catch (Exception arg) { Recycle_N_ReclaimLogger.LogError((object)$"Failed to deserialize {yamlFileName}: {arg}"); } } public static string Localize(string text) { return Localization.instance.Localize(text); } public static string Localize(string text, params string[] words) { return Localization.instance.Localize(text, words); } private void ContainerRecyclingTriggered() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; Container val = (Container)AccessTools.Field(typeof(InventoryGui), "m_currentContainer").GetValue(InventoryGui.instance); if (!((Object)(object)val == (Object)null)) { Recycle_N_ReclaimLogger.LogDebug((object)("Player " + localPlayer.GetPlayerName() + " triggered recycling")); Reclaimer.RecycleInventoryForAllRecipes(val.GetInventory(), GroupUtils.GetPrefabName(((Object)((Component)val).transform).name), localPlayer); } } private ConfigEntry<T> config<[<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val); ConfigSyncVar.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedSetting; return val2; } private ConfigEntry<T> config<[<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } static Recycle_N_ReclaimPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; Recycle_N_ReclaimLogger = Logger.CreateLogSource("Recycle_N_Reclaim"); ConfigSyncVar = new ConfigSync("Azumatt.Recycle_N_Reclaim") { DisplayName = "Recycle_N_Reclaim", CurrentVersion = "1.3.5", MinimumRequiredVersion = "1.3.5" }; yamlFileName = "Azumatt.Recycle_N_Reclaim_ExcludeLists.yml"; string configPath2 = Paths.ConfigPath; directorySeparatorChar = Path.DirectorySeparatorChar; yamlPath = configPath2 + directorySeparatorChar + yamlFileName; RNRExcludeListData = new CustomSyncedValue<string>(ConfigSyncVar, "RNR_YamlData", ""); yamlData = new Root(); predefinedGroups = new Dictionary<string, HashSet<string>>(); _serverConfigLocked = null; hotKey = null; discardInvEnabled = null; lockToAdmin = null; returnUnknownResources = null; returnEnchantedResources = null; returnResources = null; StationFilterList = new List<string>(); StationFilterEnabled = null; EnableExperimentalCraftingTabUI = null; NotifyOnSalvagingImpediments = null; PreventZeroResourceYields = null; UnstackableItemsAlwaysReturnAtLeastOneResource = null; RecyclingRate = null; ContainerRecyclingEnabled = null; IgnoreItemsOnHotbar = null; ContainerRecyclingButtonPositionJsonString = null; AllowRecyclingUnknownRecipes = null; DebugAlwaysDumpAnalysisContext = null; DebugAllowSpammyLogs = null; HideEquippedItemsInRecyclingTab = null; RequireExactCraftingStationForRecycling = null; returnEnchantedResourcesReclaiming = null; BorderColorTrashedItem = null; BorderColorTrashedSlot = null; DisplayTooltipHint = null; TrashingModifierKeybind1 = null; TrashingKeybind = null; TrashedSlotTooltip = null; } } public static class KeyboardExtensions { public static bool IsKeyDown(this KeyboardShortcut shortcut) { //IL_0002: 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) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } return false; } public static bool IsKeyHeld(this KeyboardShortcut shortcut) { //IL_0002: 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) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } return false; } } } namespace Recycle_N_Reclaim.YAMLStuff { [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPriority(0)] internal static class PredefinedGroupGrab { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] private static void Postfix(ObjectDB __instance) { if (Object.op_Implicit((Object)(object)ZNetScene.instance)) { GroupUtils.CreatePredefinedGroups(__instance); } } } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public class GroupUtils { public static List<string> GetExcludedGroups(string container) { if (Recycle_N_ReclaimPlugin.yamlData.Containers.TryGetValue(container, out var value)) { return value.Exclude.Where([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (string excludeItem) => Recycle_N_ReclaimPlugin.yamlData.Groups.ContainsKey(excludeItem)).ToList(); } return new List<string>(); } public static bool IsGroupDefined(string groupName) { return Recycle_N_ReclaimPlugin.yamlData.Groups.ContainsKey(groupName); } public static bool GroupExists(string groupName) { return Recycle_N_ReclaimPlugin.yamlData.Groups.ContainsKey(groupName); } public static List<string> GetAllGroups() { return Recycle_N_ReclaimPlugin.yamlData.Groups.Keys.ToList(); } public static List<string> GetItemsInGroup(string groupName) { if (Recycle_N_ReclaimPlugin.yamlData.Groups.TryGetValue(groupName, out var value)) { return value.ToList(); } return new List<string>(); } public static string GetPrefabName(string name) { char[] anyOf = new char[2] { '(', ' ' }; int num = name.IndexOfAny(anyOf); if (num >= 0) { return name.Substring(0, num); } return name; } [return: <3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(2)] internal static GameObject GetItemPrefabFromGameObject(ItemDrop itemDropComponent, GameObject inputGameObject) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(GetPrefabName(((Object)inputGameObject).name)); itemDropComponent.m_itemData.m_dropPrefab = itemPrefab; if (!((Object)(object)itemPrefab != (Object)null)) { return null; } return itemPrefab; } internal static bool CheckItemDropIntegrity(ItemDrop itemDropComp) { if (itemDropComp.m_itemData == null) { return false; } return itemDropComp.m_itemData.m_shared != null; } internal static void CreatePredefinedGroups(ObjectDB __instance) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Invalid comparison between Unknown and I4 //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected I4, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected I4, but got Unknown foreach (GameObject item in __instance.m_items.Where([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (GameObject x) => (Object)(object)x.GetComponentInChildren<ItemDrop>() != (Object)null)) { ItemDrop componentInChildren = item.GetComponentInChildren<ItemDrop>(); if (!CheckItemDropIntegrity(componentInChildren)) { continue; } GameObject itemPrefabFromGameObject = GetItemPrefabFromGameObject(componentInChildren, item); componentInChildren.m_itemData.m_dropPrefab = ((Component)componentInChildren).gameObject; if (!((Object)(object)itemPrefabFromGameObject != (Object)null)) { continue; } SharedData sharedData = componentInChildren.m_itemData.m_shared; string text = ""; if ((double)sharedData.m_food > 0.0 && (double)sharedData.m_foodStamina > 0.0) { text = "Food"; } if ((double)sharedData.m_food > 0.0 && (double)sharedData.m_foodStamina == 0.0) { text = "Potion"; } else if ((int)sharedData.m_itemType == 21) { text = "Fish"; } ItemType itemType = sharedData.m_itemType; switch (itemType - 1) { case 2: case 3: case 13: case 21: { SkillType skillType = sharedData.m_skillType; switch (skillType - 1) { case 0: text = "Swords"; break; case 7: text = "Bows"; break; case 13: text = "Crossbows"; break; case 6: text = "Axes"; break; case 2: text = "Clubs"; break; case 1: text = "Knives"; break; case 11: text = "Pickaxes"; break; case 3: text = "Polearms"; break; case 4: text = "Spears"; break; } break; } case 14: text = "Equipment"; break; case 12: text = (new string[6] { "eikthyr", "elder", "bonemass", "dragonqueen", "goblinking", "SeekerQueen" }.Any(sharedData.m_name.EndsWith) ? "Boss Trophy" : "Trophy"); break; case 0: { GameObject val = ((IEnumerable<GameObject>)ObjectDB.instance.GetItemPrefab("Cultivator").GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces.m_pieces).FirstOrDefault((Func<GameObject, bool>)([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (GameObject p) => { Requirement[] resources = p.GetComponent<Piece>().m_resources; return resources.Length == 1 && resources[0].m_resItem.m_itemData.m_shared.m_name == sharedData.m_name; })); if (val != null) { Plant component = val.GetComponent<Plant>(); text = ((component != null && component.m_grownPrefabs[0].GetComponent<Pickable>()?.m_amount > 1) ? "Crops" : "Seeds"); } if (ZNetScene.instance.GetPrefab("smelter").GetComponent<Smelter>().m_conversion.Any([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemConversion c) => c.m_from.m_itemData.m_shared.m_name == sharedData.m_name)) { text = "Ores"; } if (ZNetScene.instance.GetPrefab("smelter").GetComponent<Smelter>().m_conversion.Any([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemConversion c) => c.m_to.m_itemData.m_shared.m_name == sharedData.m_name)) { text = "Metals"; } if (ZNetScene.instance.GetPrefab("blastfurnace").GetComponent<Smelter>().m_conversion.Any([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemConversion c) => c.m_from.m_itemData.m_shared.m_name == sharedData.m_name)) { text = "Ores"; } if (ZNetScene.instance.GetPrefab("blastfurnace").GetComponent<Smelter>().m_conversion.Any([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemConversion c) => c.m_to.m_itemData.m_shared.m_name == sharedData.m_name)) { text = "Metals"; } if (ZNetScene.instance.GetPrefab("charcoal_kiln").GetComponent<Smelter>().m_conversion.Any([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemConversion c) => c.m_from.m_itemData.m_shared.m_name == sharedData.m_name)) { text = "Woods"; } if (sharedData.m_name == "$item_elderbark") { text = "Woods"; } break; } case 5: text = "Helmets"; break; case 6: case 10: case 11: case 16: text = "Armor"; break; case 8: case 22: text = "Ammunition"; break; case 17: text = "Utilities"; break; case 18: text = "Tools"; break; case 15: text = "Miscellaneous"; break; case 9: text = "Customizations"; break; } if (!string.IsNullOrEmpty(text)) { AddItemToGroup(text, componentInChildren); } if (sharedData != null) { text = "All"; AddItemToGroup(text, componentInChildren); } } } private static void AddItemToGroup(string groupName, ItemDrop itemDrop) { if (!GroupExists(groupName)) { Recycle_N_ReclaimPlugin.yamlData.Groups[groupName] = new List<string>(); Recycle_N_ReclaimPlugin.predefinedGroups[groupName] = new HashSet<string>(); } string prefabName = Utils.GetPrefabName(itemDrop.m_itemData.m_dropPrefab); if (!Recycle_N_ReclaimPlugin.yamlData.Groups[groupName].Contains(prefabName)) { Recycle_N_ReclaimPlugin.yamlData.Groups[groupName].Add(prefabName); Recycle_N_ReclaimPlugin.predefinedGroups[groupName].Add(prefabName); } } public static bool IsPrefabExcludedInReclaiming(string prefabName) { return IsPrefabExcludedInEntity(Recycle_N_ReclaimPlugin.yamlData.Reclaiming, prefabName); } public static bool IsPrefabExcludedInInventory(string prefabName) { return IsPrefabExcludedInEntity(Recycle_N_ReclaimPlugin.yamlData.Inventory, prefabName); } public static bool IsPrefabExcludedInContainer(string containerName, string prefabName) { if (Recycle_N_ReclaimPlugin.yamlData.Containers.TryGetValue(containerName, out var value)) { return IsPrefabExcludedInEntity(value, prefabName); } return false; } private static bool IsPrefabExcludedInEntity(object entity, string prefabName) { bool flag = ((entity is excludeContainer || entity is Reclaiming || entity is Inventory) ? true : false); if (!flag) { throw new ArgumentException("The entity type is not supported."); } List<string> list = null; List<string> list2 = null; if (!(entity is excludeContainer excludeContainer2)) { if (!(entity is Reclaiming reclaiming)) { if (entity is Inventory inventory) { list2 = inventory.Exclude; list = inventory.IncludeOverride; } } else { list = reclaiming.IncludeOverride; list2 = reclaiming.Exclude; } } else { list = excludeContainer2.IncludeOverride; list2 = excludeContainer2.Exclude; } if (list != null) { foreach (string item in list) { if (item == prefabName) { flag = false; } else { if (!Recycle_N_ReclaimPlugin.yamlData.Groups.TryGetValue(item, out var value) || !value.Contains(prefabName)) { continue; } flag = false; } goto IL_014b; } } if (list2 != null) { foreach (string item2 in list2) { if (item2 == prefabName) { flag = true; } else { if (!Recycle_N_ReclaimPlugin.yamlData.Groups.TryGetValue(item2, out var value2) || !value2.Contains(prefabName)) { continue; } flag = true; } goto IL_014b; } } return false; IL_014b: return flag; } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public class Root { [YamlMember(Alias = "groups")] public Dictionary<string, List<string>> Groups { get; set; } [YamlMember(Alias = "containers")] public Dictionary<string, excludeContainer> Containers { get; set; } [YamlMember(Alias = "reclaiming")] public Reclaiming Reclaiming { get; set; } [YamlMember(Alias = "inventory")] public Inventory Inventory { get; set; } } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public class excludeContainer { [YamlMember(Alias = "exclude")] public List<string> Exclude { get; set; } [YamlMember(Alias = "includeOverride")] public List<string> IncludeOverride { get; set; } } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public class Reclaiming { [YamlMember(Alias = "exclude")] public List<string> Exclude { get; set; } [YamlMember(Alias = "includeOverride")] public List<string> IncludeOverride { get; set; } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public class Inventory { [YamlMember(Alias = "exclude")] public List<string> Exclude { get; set; } [YamlMember(Alias = "includeOverride")] public List<string> IncludeOverride { get; set; } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public class YAMLUtils { internal static void WriteConfigFileFromResource(string configFilePath) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = "Recycle_N_Reclaim.YAMLStuff.Example.yml"; using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { throw new FileNotFoundException("Resource '" + text + "' not found in the assembly."); } using StreamReader streamReader = new StreamReader(stream); string contents = streamReader.ReadToEnd(); File.WriteAllText(configFilePath, contents); } internal static void ReadYaml(string yamlInput) { Recycle_N_ReclaimPlugin.yamlData = new DeserializerBuilder().Build().Deserialize<Root>(yamlInput); Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)("yamlData:\n" + yamlInput)); foreach (KeyValuePair<string, HashSet<string>> predefinedGroup in Recycle_N_ReclaimPlugin.predefinedGroups) { Recycle_N_ReclaimPlugin.yamlData.Groups[predefinedGroup.Key] = predefinedGroup.Value.ToList(); } } internal static void ParseGroups() { if (Recycle_N_ReclaimPlugin.yamlData == null) { Recycle_N_ReclaimPlugin.yamlData.Groups = new Dictionary<string, List<string>>(); } if (!Recycle_N_ReclaimPlugin.yamlData.Groups.Any()) { return; } foreach (KeyValuePair<string, List<string>> group in Recycle_N_ReclaimPlugin.yamlData.Groups) { string key = group.Key; List<string> value = group.Value; if (value == null) { continue; } List<string> list = new List<string>(); foreach (string item in value) { list.Add(item); } Recycle_N_ReclaimPlugin.yamlData.Groups[key] = list; } } public static void WriteYaml(string filePath) { ISerializer serializer = new SerializerBuilder().Build(); using StreamWriter writer = new StreamWriter(filePath); serializer.Serialize(writer, Recycle_N_ReclaimPlugin.yamlData); string contents = serializer.Serialize(Recycle_N_ReclaimPlugin.yamlData); File.AppendAllText(filePath, contents); } } } namespace Recycle_N_Reclaim.GamePatches { [HarmonyPatch(typeof(InventoryGui), "UpdateItemDrag")] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(2)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public static class UpdateItemDragPatch { internal static readonly Type epicLootType = Recycle_N_ReclaimPlugin.epicLootAssembly?.GetType("EpicLoot.ItemDataExtensions"); internal static readonly MethodInfo isMagicMethod = epicLootType?.GetMethod("IsMagic", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); internal static readonly MethodInfo getRarityMethod = epicLootType?.GetMethod("GetRarity", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); internal static readonly Type enchantTabControllerType = Recycle_N_ReclaimPlugin.epicLootAssembly?.GetType("EpicLoot.Crafting.EnchantHelper"); internal static readonly MethodInfo getEnchantCostsMethod = enchantTabControllerType?.GetMethod("GetEnchantCosts", BindingFlags.Static | BindingFlags.Public); [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] private static void Postfix(InventoryGui __instance, ItemData ___m_dragItem, Inventory ___m_dragInventory, int ___m_dragAmount, ref GameObject ___m_dragGo) { //IL_002b: 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) if ((Recycle_N_ReclaimPlugin.lockToAdmin.Value != Recycle_N_ReclaimPlugin.Toggle.On || Recycle_N_ReclaimPlugin.ConfigSyncVar.IsAdmin) && Recycle_N_ReclaimPlugin.discardInvEnabled.Value != 0) { KeyboardShortcut value = Recycle_N_ReclaimPlugin.hotKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && ___m_dragItem != null && ___m_dragInventory.ContainsItem(___m_dragItem)) { Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)$"Discarding {___m_dragAmount}/{___m_dragItem.m_stack} {((Object)___m_dragItem.m_dropPrefab).name}"); Utils.InventoryRecycleItem(___m_dragItem, ___m_dragAmount, ___m_dragInventory, __instance, ___m_dragGo); Object.Destroy((Object)(object)___m_dragGo); ___m_dragGo = null; __instance.UpdateCraftingPanel(false); } } } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public class ObjectDumper { private readonly List<int> _hashListOfFoundElements; private readonly int _indentSize; private readonly StringBuilder _stringBuilder; private int _level; private ObjectDumper(int indentSize) { _indentSize = indentSize; _stringBuilder = new StringBuilder(); _hashListOfFoundElements = new List<int>(); } public static string Dump(object element, int indentSize = 2) { return new ObjectDumper(indentSize).DumpElement(element); } private string GetTypeName(Type type) { if (!IsAnonymousType(type)) { return type.Name; } return "AnonymousType"; } private string DumpElement(object element) { if ((element == null || element is ValueType || element is string) ? true : false) { Write(FormatValue(element)); } else { Type type = element.GetType(); if (!typeof(IEnumerable).IsAssignableFrom(type)) { Write("{{{0}}}", GetTypeName(type)); _hashListOfFoundElements.Add(element.GetHashCode()); _level++; } if (element is IEnumerable enumerable) { foreach (object item in enumerable) { if (item is IEnumerable enumerable2 && !(enumerable2 is string)) { _level++; DumpElement(item); _level--; } else if (!AlreadyTouched(item)) { DumpElement(item); } else { Write("{{{0}}} <-- bidirectional reference found", GetTypeName(item.GetType())); } } } else { MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public); foreach (MemberInfo memberInfo in members) { FieldInfo fieldInfo = memberInfo as FieldInfo; PropertyInfo propertyInfo = memberInfo as PropertyInfo; if (fieldInfo == null && propertyInfo == null) { continue; } Type type2 = ((fieldInfo != null) ? fieldInfo.FieldType : propertyInfo.PropertyType); object obj = ((fieldInfo != null) ? fieldInfo.GetValue(element) : propertyInfo.GetValue(element, null)); if (type2.IsValueType || type2 == typeof(string)) { Write("{0}: {1}", memberInfo.Name, FormatValue(obj)); continue; } bool flag = typeof(IEnumerable).IsAssignableFrom(type2); Write("{0}: {1}", memberInfo.Name, flag ? "..." : "{ }"); bool num = !flag && AlreadyTouched(obj); _level++; if (!num) { DumpElement(obj); } else { Write("{{{0}}} <-- bidirectional reference found", GetTypeName(obj.GetType())); } _level--; } } if (!typeof(IEnumerable).IsAssignableFrom(type)) { _level--; } } return _stringBuilder.ToString(); } private bool AlreadyTouched(object value) { if (value == null) { return false; } int hashCode = value.GetHashCode(); for (int i = 0; i < _hashListOfFoundElements.Count; i++) { if (_hashListOfFoundElements[i] == hashCode) { return true; } } return false; } private void Write(string value, params object[] args) { string text = new string(' ', _level * _indentSize); if (args != null) { value = string.Format(value, args); } _stringBuilder.AppendLine(text + value); } private string FormatValue(object o) { if (o != null) { if (!(o is DateTime dateTime)) { if (!(o is string)) { if (o is char) { if ((char)o == '\0') { return string.Empty; } } else if (!(o is ValueType)) { if (o is IEnumerable) { return "..."; } return "{ }"; } return o.ToString(); } return $"\"{o}\""; } return dateTime.ToShortDateString(); } return "null"; } private static bool IsAnonymousType(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), inherit: false) && type.IsGenericType && type.Name.Contains("AnonymousType") && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))) { return type.Attributes.HasFlag(TypeAttributes.NotPublic); } return false; } } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public static class Utils { public static Texture2D LoadTextureFromResources(string pathName, string folderName = "Assets") { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Stream manifestResourceStream = typeof(Recycle_N_ReclaimPlugin).Assembly.GetManifestResourceStream(typeof(Recycle_N_ReclaimPlugin).Namespace + "." + folderName + "." + pathName); Texture2D val = new Texture2D(2, 2); Texture2D result = new Texture2D(2, 2); if (manifestResourceStream == null) { return result; } byte[] array; using (BinaryReader binaryReader = new BinaryReader(manifestResourceStream)) { array = binaryReader.ReadBytes((int)manifestResourceStream.Length); } if (!ImageConversion.LoadImage(val, array)) { return result; } return val; } public static void InventoryRecycleItem(ItemData ___m_dragItem, int ___m_dragAmount, Inventory ___m_dragInventory, InventoryGui __instance, GameObject ___m_dragGo) { //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Expected O, but got Unknown //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_0591: Unknown result type (might be due to invalid IL or missing references) //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Expected O, but got Unknown if (Recycle_N_ReclaimPlugin.returnResources.Value > 0f) { Recipe recipe = ObjectDB.instance.GetRecipe(___m_dragItem); if ((Object)(object)recipe != (Object)null && (Recycle_N_ReclaimPlugin.returnUnknownResources.Value == Recycle_N_ReclaimPlugin.Toggle.On || Player.m_localPlayer.IsRecipeKnown(___m_dragItem.m_shared.m_name))) { Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)$"Recipe stack: {recipe.m_amount} num of stacks: {___m_dragAmount / recipe.m_amount}"); List<Requirement> list = recipe.m_resources.ToList(); bool flag = false; bool flag2 = false; if (Recycle_N_ReclaimPlugin.epicLootAssembly != null && Recycle_N_ReclaimPlugin.returnEnchantedResources.Value == Recycle_N_ReclaimPlugin.Toggle.On) { MethodInfo isMagicMethod = UpdateItemDragPatch.isMagicMethod; object obj; if ((object)isMagicMethod == null) { obj = null; } else { object[] parameters = (object[])(object)new ItemData[1] { ___m_dragItem }; obj = isMagicMethod.Invoke(null, parameters); } flag = (bool)obj; } if (flag) { MethodInfo getRarityMethod = UpdateItemDragPatch.getRarityMethod; object obj2; if ((object)getRarityMethod == null) { obj2 = null; } else { object[] parameters = (object[])(object)new ItemData[1] { ___m_dragItem }; obj2 = getRarityMethod.Invoke(null, parameters); } int num = (int)obj2; foreach (KeyValuePair<ItemDrop, int> item in (List<KeyValuePair<ItemDrop, int>>)(UpdateItemDragPatch.getEnchantCostsMethod?.Invoke(null, new object[2] { ___m_dragItem, num }))) { Recipe recipe2 = ObjectDB.instance.GetRecipe(item.Key.m_itemData); bool flag3 = (Object)(object)recipe2 != (Object)null && Player.m_localPlayer.IsRecipeKnown(item.Key.m_itemData.m_shared.m_name); bool flag4 = Player.m_localPlayer.m_knownMaterial.Contains(item.Key.m_itemData.m_shared.m_name); if (Recycle_N_ReclaimPlugin.returnUnknownResources.Value == Recycle_N_ReclaimPlugin.Toggle.Off && (!flag3 || !flag4)) { ((Character)Player.m_localPlayer).Message((MessageType)2, Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_no_material_recipes"), 0, (Sprite)null); return; } list.Add(new Requirement { m_amount = (((Object)(object)recipe2 != (Object)null) ? recipe2.m_amount : item.Value), m_resItem = item.Key }); } } if (Jewelcrafting.API.IsLoaded() && Recycle_N_ReclaimPlugin.returnEnchantedResources.Value == Recycle_N_ReclaimPlugin.Toggle.On && Jewelcrafting.API.GetGems(___m_dragItem).Any()) { foreach (KeyValuePair<ItemDrop, ItemData> item2 in (from gem in Jewelcrafting.API.GetGems(___m_dragItem) where gem != null select ObjectDB.instance.GetItemPrefab(gem.gemPrefab).GetComponent<ItemDrop>() into itemDrop where (Object)(object)itemDrop != (Object)null select itemDrop).ToDictionary([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemDrop itemDrop) => itemDrop, [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (ItemDrop itemDrop) => itemDrop.m_itemData)) { Recipe recipe3 = ObjectDB.instance.GetRecipe(item2.Value); bool flag5 = (Object)(object)recipe3 != (Object)null && Player.m_localPlayer.IsRecipeKnown(item2.Value.m_shared.m_name); bool flag6 = Player.m_localPlayer.m_knownMaterial.Contains(item2.Value.m_shared.m_name); if (Recycle_N_ReclaimPlugin.returnUnknownResources.Value == Recycle_N_ReclaimPlugin.Toggle.Off && (!flag5 || !flag6)) { ((Character)Player.m_localPlayer).Message((MessageType)2, Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_no_material_recipes"), 0, (Sprite)null); return; } list.Add(new Requirement { m_amount = (((Object)(object)recipe3 != (Object)null) ? recipe3.m_amount : item2.Value.m_stack), m_resItem = item2.Key }); } } if (!flag2 && ___m_dragAmount / recipe.m_amount > 0) { for (int i = 0; i < ___m_dragAmount / recipe.m_amount; i++) { foreach (Requirement req in list) { for (int num2 = ___m_dragItem.m_quality; num2 > 0; num2--) { GameObject val = ((IEnumerable<GameObject>)ObjectDB.instance.m_items).FirstOrDefault((Func<GameObject, bool>)([<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] (GameObject item) => item.GetComponent<ItemDrop>().m_itemData.m_shared.m_name == req.m_resItem.m_itemData.m_shared.m_name)); ItemData itemData = val.GetComponent<ItemDrop>().m_itemData.Clone(); int num3 = Mathf.RoundToInt((float)req.GetAmount(num2) * Recycle_N_ReclaimPlugin.returnResources.Value); Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)$"Returning {num3}/{req.GetAmount(num2)} {((Object)val).name}"); while (num3 > 0) { int num4 = Mathf.Min(req.m_resItem.m_itemData.m_shared.m_maxStackSize, num3); num3 -= num4; if (!GroupUtils.IsPrefabExcludedInInventory(Utils.GetPrefabName(val)) && ((Humanoid)Player.m_localPlayer).GetInventory().AddItem(((Object)val).name, num4, req.m_resItem.m_itemData.m_quality, req.m_resItem.m_itemData.m_variant, 0L, "", false) == null) { Transform transform; ItemDrop component = Object.Instantiate<GameObject>(val, (transform = ((Component)Player.m_localPlayer).transform).position + transform.forward + transform.up, transform.rotation).GetComponent<ItemDrop>(); component.m_itemData = itemData; component.m_itemData.m_dropPrefab = val; component.m_itemData.m_stack = num4; component.Save(); } } } } } } } } if (___m_dragAmount == ___m_dragItem.m_stack) { ((Humanoid)Player.m_localPlayer).RemoveEquipAction(___m_dragItem); ((Humanoid)Player.m_localPlayer).UnequipItem(___m_dragItem, false); ___m_dragInventory.RemoveItem(___m_dragItem); } else { ___m_dragInventory.RemoveItem(___m_dragItem, ___m_dragAmount); } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterAndCheckVersion { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] private static void Prefix(ZNetPeer peer, ref ZNet __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)"Registering version RPC handler"); peer.m_rpc.Register<ZPackage>("Recycle_N_Reclaim_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_Recycle_N_Reclaim_Version); Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogInfo((object)"Invoking version check"); ZPackage val = new ZPackage(); val.Write("1.3.5"); val.Write(RpcHandlers.ComputeHashForMod().Replace("-", "")); peer.m_rpc.Invoke("Recycle_N_Reclaim_VersionCheck", new object[1] { val }); } } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public static class VerifyClient { private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance) { if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc)) { return true; } Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting")); rpc.Invoke("Error", new object[1] { 3 }); return false; } private static void Postfix(ZNet __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "Recycle_N_ReclaimRequestAdminSync", new object[1] { (object)new ZPackage() }); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] public class ShowConnectionError { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] private static void Postfix(FejdStartup __instance) { if (__instance.m_connectionFailedPanel.activeSelf) { __instance.m_connectionFailedError.fontSizeMax = 25f; __instance.m_connectionFailedError.fontSizeMin = 15f; TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + Recycle_N_ReclaimPlugin.ConnectionError; } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] public static class RemoveDisconnectedPeerFromVerified { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] private static void Prefix(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list")); RpcHandlers.ValidatedPeers.Remove(peer.m_rpc); } } } [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public static class RpcHandlers { public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>(); public static void RPC_Recycle_N_Reclaim_Version(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = ComputeHashForMod().Replace("-", ""); Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogInfo((object)("Hash/Version check, local: 1.3.5 " + text3 + " remote: " + text + " " + text2)); if (text2 != text3 || text != "1.3.5") { Recycle_N_ReclaimPlugin.ConnectionError = "Recycle_N_Reclaim Installed: 1.3.5 " + text3 + "\n Needed: " + text + " " + text2; if (ZNet.instance.IsServer()) { Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...")); rpc.Invoke("Error", new object[1] { 3 }); } } else if (!ZNet.instance.IsServer()) { Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogInfo((object)"Received same version from server!"); } else { Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list")); ValidatedPeers.Add(rpc); } } public static string ComputeHashForMod() { using SHA256 sHA = SHA256.Create(); byte[] array = sHA.ComputeHash(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location)); StringBuilder stringBuilder = new StringBuilder(); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("X2")); } return stringBuilder.ToString(); } } } namespace Recycle_N_Reclaim.GamePatches.UI { [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] public class ContainerRecyclingButtonHolder : MonoBehaviour { [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(0)] public delegate void RecycleAllHandler(); private Button _recycleAllButton; private bool _prefired; private TMP_Text _textComponent; private Image _imageComponent; public event RecycleAllHandler OnRecycleAllTriggered; private void Start() { ((MonoBehaviour)this).InvokeRepeating("EnsureRecyclingButtonExistsIfPossible", 0f, 5f); } private void EnsureRecyclingButtonExistsIfPossible() { if (!((Object)(object)InventoryGui.instance == (Object)null)) { if ((Object)(object)_recycleAllButton == (Object)null) { SetupButton(); } ((Component)_recycleAllButton).gameObject.SetActive(Recycle_N_ReclaimPlugin.ContainerRecyclingEnabled.Value == Recycle_N_ReclaimPlugin.Toggle.On); } } private void OnDestroy() { try { Object.Destroy((Object)(object)((Component)_recycleAllButton).gameObject); } catch { } } private void FixedUpdate() { if (Recycle_N_ReclaimPlugin.ContainerRecyclingEnabled.Value != 0 && !((Object)(object)_recycleAllButton == (Object)null) && !InventoryGui.instance.IsContainerOpen() && _prefired) { SetButtonState(showPrefire: false); } } private void SetupButton() { //IL_0038: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown if (!((Object)(object)_recycleAllButton != (Object)null)) { if (Recycle_N_ReclaimPlugin.HasAuga) { _recycleAllButton = ((Component)((Transform)InventoryGui.instance.m_container).Find("RecycleAll")).GetComponent<Button>(); } else { Vector3 savedButtonPosition = GetSavedButtonPosition(); _recycleAllButton = Object.Instantiate<Button>(InventoryGui.instance.m_takeAllButton, ((Component)InventoryGui.instance.m_takeAllButton).transform); ((Component)_recycleAllButton).transform.SetParent(((Component)InventoryGui.instance.m_takeAllButton).transform.parent); ((Component)_recycleAllButton).transform.localPosition = savedButtonPosition; } _recycleAllButton.onClick = new ButtonClickedEvent(); ((UnityEvent)_recycleAllButton.onClick).AddListener(new UnityAction(OnRecycleAllPressed)); _textComponent = ((Component)_recycleAllButton).GetComponentInChildren<TMP_Text>(); _imageComponent = ((Component)_recycleAllButton).GetComponentInChildren<Image>(); ((Component)_recycleAllButton).gameObject.AddComponent<UIDragger>().OnUIDropped += delegate(object source, Vector3 position) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Recycle_N_ReclaimPlugin.ContainerRecyclingButtonPositionJsonString.Value = position; }; SetButtonState(showPrefire: false); } } private Vector3 GetSavedButtonPosition() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Recycle_N_ReclaimPlugin.ContainerRecyclingButtonPositionJsonString.Value; } private void SetButtonState(bool showPrefire) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (showPrefire) { _prefired = true; _textComponent.text = Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_confirm"); ((Graphic)_imageComponent).color = new Color(1f, 0.5f, 0.5f); } else { _prefired = false; _textComponent.text = Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_reclaim_all"); ((Graphic)_imageComponent).color = new Color(0.5f, 1f, 0.5f); } } private void OnRecycleAllPressed() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { if (!_prefired) { SetButtonState(showPrefire: true); return; } SetButtonState(showPrefire: false); this.OnRecycleAllTriggered?.Invoke(); } } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public static class InventoryGuiExtensions { public static float get_m_recipeListBaseSize(this InventoryGui instance) { return instance.m_recipeListBaseSize; } public static List<RecipeDataPair> get_m_recipeList(this InventoryGui instance) { return instance.m_availableRecipes; } public static List<RecipeDataPair> get_m_availableRecipes(this InventoryGui instance) { return instance.m_availableRecipes; } public static RecipeDataPair get_m_selectedRecipe(this InventoryGui instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return instance.m_selectedRecipe; } public static void set_m_selectedRecipe(this InventoryGui instance, RecipeDataPair value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) instance.m_selectedRecipe = value; } public static int get_m_selectedVariant(this InventoryGui instance) { return instance.m_selectedVariant; } public static void set_m_selectedVariant(this InventoryGui instance, int value) { instance.m_selectedVariant = value; } public static float get_m_craftTimer(this InventoryGui instance) { return instance.m_craftTimer; } public static void set_m_craftTimer(this InventoryGui instance, float value) { instance.m_craftTimer = value; } public static Color get_m_minStationLevelBasecolor(this InventoryGui instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return instance.m_minStationLevelBasecolor; } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] [HarmonyPatch] public static class InventoryGuiPatches { [HarmonyPriority(600)] [HarmonyPatch(typeof(InventoryGui), "OnTabCraftPressed")] [HarmonyPrefix] [HarmonyPatch(typeof(InventoryGui), "OnTabUpgradePressed")] private static void OnTabCraftPressedAlsoEnableRecycling1(InventoryGui __instance) { Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.SetInteractable(interactable: true); __instance.UpdateCraftingPanel(false); } [HarmonyPrefix] [HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")] private static bool UpdateCraftingPanelDetourOnRecyclingTab(InventoryGui __instance) { if (Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.InRecycleTab()) { return false; } return true; } [HarmonyPatch(typeof(InventoryGui), "Hide")] [HarmonyPrefix] private static void OnHideSetToCraftingTab(InventoryGui __instance) { if (!((Object)(object)Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder == (Object)null) && Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.InRecycleTab()) { InventoryGui.instance.OnTabCraftPressed(); Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.SetActive(active: false); } } [HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")] [HarmonyPostfix] private static void UpdateCraftingPanelDetourOnOtherTabsEnableRecyclingButton(InventoryGui __instance) { if (!Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.InRecycleTab()) { Player localPlayer = Player.m_localPlayer; Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.SetInteractable(interactable: true); if (!Object.op_Implicit((Object)(object)localPlayer.GetCurrentCraftingStation()) && !localPlayer.NoCostCheat()) { Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.SetActive(active: false); } else { Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.SetActive(active: true); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe", new Type[] { typeof(Player), typeof(float) })] [HarmonyPrefix] private static bool UpdateRecipeOnRecyclingTab(InventoryGui __instance, Player player, float dt) { if (!Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.InRecycleTab()) { return true; } Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.UpdateRecipe(player, dt); return false; } [HarmonyPatch(typeof(Inventory), "Changed")] [HarmonyPostfix] private static void InventorySave(Inventory __instance) { if (!((Object)(object)Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder == (Object)null) && Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.InRecycleTab() && __instance == ((Humanoid)Player.m_localPlayer).GetInventory()) { Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.UpdateRecyclingList(); InventoryGui.instance.SetRecipe(-1, false); } } [HarmonyPostfix] [HarmonyPatch(typeof(Humanoid), "EquipItem", new Type[] { typeof(ItemData), typeof(bool) })] [HarmonyPatch(typeof(Humanoid), "UnequipItem", new Type[] { typeof(ItemData), typeof(bool) })] private static void HumanoidEquip(Humanoid __instance) { if (!((Object)(object)Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.InRecycleTab() && __instance.GetInventory() == ((Humanoid)Player.m_localPlayer).GetInventory()) { Recycle_N_ReclaimPlugin.RecyclingTabButtonHolder.UpdateRecyclingList(); InventoryGui.instance.SetRecipe(-1, false); } } } [<607bf95e-59f1-4e63-ab42-7b11f8515926>NullableContext(1)] [<3f607022-9496-490a-85e6-01cde9ffb3e4>Nullable(0)] public class StationRecyclingTabHolder : MonoBehaviour { private GameObject _recyclingTabButtonGameObject; private Button _recyclingTabButtonComponent; private List<RecyclingAnalysisContext> _recyclingAnalysisContexts = new List<RecyclingAnalysisContext>(); private WorkbenchTabData _augaTabData; private GameObject _itemInfoGo; private GameObject _descriptionBoxGo; private void Start() { ((MonoBehaviour)this).InvokeRepeating("EnsureRecyclingTabExists", 5f, 5f); } private void EnsureRecyclingTabExists() { if (!((Object)(object)InventoryGui.instance == (Object)null) && (Object)(object)_recyclingTabButtonComponent == (Object)null) { SetupTabButton(); } } private void OnDestroy() { try { Object.Destroy((Object)(object)_recyclingTabButtonGameObject.gameObject); } catch { } } private void SetupTabButton() { //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_005f: 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) if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)"Creating Workbench Tab"); if (Recycle_N_ReclaimPlugin.HasAuga) { if (!Auga.API.Workbench_HasWorkbenchTab("Reclaim")) { Texture2D val = Utils.LoadTextureFromResources("RecyclingPanel.png"); Sprite tabIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0f, 0f), 100f); if (Recycle_N_ReclaimPlugin.epicLootAssembly != null) { _augaTabData = Auga.API.Workbench_AddWorkbenchTab("Reclaim", tabIcon, "Recycle_N_Reclaim".Replace("_", "-"), delegate { OnRecycleClick(); }); } else { _augaTabData = Auga.API.Workbench_AddVanillaWorkbenchTab("Reclaim", tabIcon, "Recycle_N_Reclaim".Replace("_", "-"), delegate { OnRecycleClick(); }); } _recyclingTabButtonComponent = (_recyclingTabButtonGameObject = _augaTabData.TabButtonGO).GetComponent<Button>(); _itemInfoGo = _augaTabData.ItemInfoGO; Auga.API.ComplexTooltip_AddDivider(_itemInfoGo); _descriptionBoxGo = Auga.API.ComplexTooltip_AddTwoColumnTextBox(_itemInfoGo); Auga.API.ComplexTooltip_EnableDescription(_itemInfoGo, enabled: false); } } else { Transform transform = ((Component)InventoryGui.instance.m_tabUpgrade).transform; _recyclingTabButtonGameObject = Object.Instantiate<GameObject>(((Component)InventoryGui.instance.m_tabUpgrade).gameObject, transform.position, transform.rotation, transform.parent); ((Object)_recyclingTabButtonGameObject).name = "RECLAIM"; _recyclingTabButtonGameObject.transform.parent.Find("TabBorder").SetAsLastSibling(); _recyclingTabButtonGameObject.transform.localPosition = new Vector3(-45f, -94f, 0f); _recyclingTabButtonComponent = _recyclingTabButtonGameObject.GetComponent<Button>(); ((Selectable)_recyclingTabButtonComponent).interactable = true; _recyclingTabButtonComponent.onClick = new ButtonClickedEvent(); ((UnityEvent)_recyclingTabButtonComponent.onClick).AddListener(new UnityAction(OnRecycleClick)); TMP_Text componentInChildren = _recyclingTabButtonGameObject.GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_reclaim_tab"); } } bool active = (Object)(object)Player.m_localPlayer.GetCurrentCraftingStation() != (Object)null; _recyclingTabButtonGameObject.SetActive(active); } private void OnRecycleClick() { ((Selectable)_recyclingTabButtonComponent).interactable = false; ((Selectable)InventoryGui.instance.m_tabCraft).interactable = true; ((Selectable)InventoryGui.instance.m_tabUpgrade).interactable = true; Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)"OnRecycleClick"); UpdateCraftingPanel(); } public void UpdateCraftingPanel() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //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_00de: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer.GetCurrentCraftingStation() == (Object)null && !localPlayer.NoCostCheat()) { ((Selectable)instance.m_tabCraft).interactable = false; ((Selectable)instance.m_tabUpgrade).interactable = true; ((Component)instance.m_tabUpgrade).gameObject.SetActive(false); ((Selectable)_recyclingTabButtonComponent).interactable = true; ((Component)_recyclingTabButtonComponent).gameObject.SetActive(false); } else { ((Component)instance.m_tabUpgrade).gameObject.SetActive(true); } UpdateRecyclingList(); RecipeDataPair val; if (instance.m_availableRecipes.Count > 0) { val = instance.get_m_selectedRecipe(); if ((Object)(object)((RecipeDataPair)(ref val)).Recipe != (Object)null) { instance.SetRecipe(instance.GetSelectedRecipeIndex(false), true); } else { instance.SetRecipe(0, true); } } else { InventoryGui.instance.SetRecipe(-1, true); } if (Recycle_N_ReclaimPlugin.HasAuga) { GameObject itemInfoGo = _itemInfoGo; val = instance.get_m_selectedRecipe(); Auga.API.ComplexTooltip_SetItem(itemInfoGo, ((RecipeDataPair)(ref val)).ItemData); } } public void UpdateRecyclingList() { //IL_003e: 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) Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; List<RecipeDataPair> list = instance.get_m_recipeList(); Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)$"Old recipe list had {list.Count} entries. Cleaning up"); foreach (RecipeDataPair item in list) { RecipeDataPair current = item; Object.Destroy((Object)(object)((RecipeDataPair)(ref current)).InterfaceElement); } list.Clear(); _recyclingAnalysisContexts.Clear(); IEnumerable<RecyclingAnalysisContext> collection = from context in Reclaimer.GetRecyclingAnalysisForInventory(((Humanoid)localPlayer).GetInventory(), localPlayer) where (Object)(object)context.Recipe != (Object)null && context.DisplayImpediments.Count == 0 select context; _recyclingAnalysisContexts.AddRange(collection); foreach (RecyclingAnalysisContext recyclingAnalysisContext in _recyclingAnalysisContexts) { if (!((Object)(object)recyclingAnalysisContext.Recipe == (Object)null)) { AddRecipeToList(recyclingAnalysisContext, list); } } Recycle_N_ReclaimPlugin.Recycle_N_ReclaimLogger.LogDebug((object)$"Added {list.Count} entries"); instance.m_recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(instance.get_m_recipeListBaseSize(), (float)list.Count * instance.m_recipeListSpace)); } private void AddRecipeToList(RecyclingAnalysisContext context, List<RecipeDataPair> m_recipeList) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown //IL_02d6: Unknown result type (might be due to invalid IL or missing references) int count = m_recipeList.Count; InventoryGui igui = InventoryGui.instance; RectTransform recipeListRoot = igui.m_recipeListRoot; GameObject element = Object.Instantiate<GameObject>(igui.m_recipeElementPrefab, (Transform)(object)recipeListRoot); element.SetActive(true); ((RectTransform)element.transform).anchoredPosition = new Vector2(0f, (float)count * (0f - igui.m_recipeListSpace)); Image component = ((Component)element.transform.Find("icon")).GetComponent<Image>(); component.sprite = context.Item.GetIcon(); ((Graphic)component).color = (Color)((context.RecyclingImpediments.Count == 0) ? Color.white : new Color(1f, 0f, 1f, 0f)); TMP_Text component2 = ((Component)element.transform.Find("name")).GetComponent<TMP_Text>(); string text = Recycle_N_ReclaimPlugin.Localize(context.Item.m_shared.m_name); if (context.Item.m_stack > 1 && context.Item.m_shared.m_maxStackSize > 1) { text = $"{text} x{context.Item.m_stack}"; } component2.text = text; ((Graphic)component2).color = (Color)((context.RecyclingImpediments.Count == 0) ? Color.white : new Color(0.66f, 0.66f, 0.66f, 1f)); GuiBar component3 = ((Component)element.transform.Find("Durability")).GetComponent<GuiBar>(); if (context.Item.m_shared.m_useDurability && (double)context.Item.m_durability < (double)context.Item.GetMaxDurability()) { ((Component)component3).gameObject.SetActive(true); component3.SetValue(context.Item.GetDurabilityPercentage()); } else { ((Component)component3).gameObject.SetActive(false); } TMP_Text component4 = ((Component)element.transform.Find("QualityLevel")).GetComponent<TMP_Text>(); ((Component)component4).gameObject.SetActive(true); component4.text = context.Item.m_quality.ToString(); ((UnityEvent)element.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { igui.OnSelectedRecipe(element); }); bool globalKey = ZoneSystem.instance.GetGlobalKey((GlobalKeys)19); bool flag = (igui.InCraftTab() ? (Player.m_localPlayer.HaveRequirements(context.Recipe, false, 1, 1) || globalKey) : (context.Item.m_quality < context.Item.m_shared.m_maxQuality && (Player.m_localPlayer.HaveRequirements(context.Recipe, false, context.Item.m_quality + 1, 1) || globalKey))); m_recipeList.Add(new RecipeDataPair(context.Recipe, context.Item, element, flag)); } public bool InRecycleTab() { if ((Object)(object)_recyclingTabButtonComponent == (Object)null) { return false; } return !((Selectable)_recyclingTabButtonComponent).interactable; } public void SetInteractable(bool interactable) { EnsureRecyclingTabExists(); ((Selectable)_recyclingTabButtonComponent).interactable = interactable; } public void SetActive(bool active) { if (Recycle_N_ReclaimPlugin.EnableExperimentalCraftingTabUI.Value != 0) { _recyclingTabButtonGameObject.SetActive(active); } } public void UpdateRecipe(Player player, float dt) { //IL_001e: 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) InventoryGui instance = InventoryGui.instance; int selectedRecipeIndex = instance.GetSelectedRecipeIndex(false); UpdateRecyclingAnalysisContexts(selectedRecipeIndex, player); UpdateCraftingStationUI(player); RecipeDataPair val = instance.get_m_selectedRecipe(); if (Object.op_Implicit((Object)(object)((RecipeDataPair)(ref val)).Recipe)) { UpdateRecipeUI(selectedRecipeIndex, instance); } else { ClearRecipeUI(instance); } UpdateCraftingTimer(dt, selectedRecipeIndex, player, instance); } private void UpdateRecyclingAnalysisContexts(int selectedRecipeIndex, Player player) { if (selectedRecipeIndex > -1 && _recyclingAnalysisContexts.Count > 0 && selectedRecipeIndex < _recyclingAnalysisContexts.Count) { RecyclingAnalysisContext recyclingAnalysisContext = new RecyclingAnalysisContext(_recyclingAnalysisContexts[selectedRecipeIndex].Item); Reclaimer.TryAnalyzeOneItem(recyclingAnalysisContext, ((Humanoid)player).GetInventory(), player); _recyclingAnalysisContexts[selectedRecipeIndex] = recyclingAnalysisContext; } } private void UpdateCraftingStationUI(Player player) { InventoryGui instance = InventoryGui.instance; CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); if (Object.op_Implicit((Object)(object)currentCraftingStation)) { SetActive(((Component)instance.m_craftingStationIcon).gameObject, isActive: true); SetActive(((Component)instance.m_craftingStationLevelRoot).gameObject, isActive: true); instance.m_craftingStationName.text = Recycle_N_ReclaimPlugin.Localize(currentCraftingStation.m_name); instance.m_craftingStationIcon.sprite = currentCraftingStation.m_icon; instance.m_craftingStationLevel.text = currentCraftingStation.GetLevel(true).ToString(); } else { SetActive(((Component)instance.m_craftingStationIcon).gameObject, isActive: false); SetActive(((Component)instance.m_craftingStationLevelRoot).gameObject, isActive: false); instance.m_craftingStationName.text = Recycle_N_ReclaimPlugin.Localize("$hud_crafting"); } } private void UpdateRecipeUI(int selectedRecipeIndex, InventoryGui igui) { //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) //IL_0051: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) RecyclingAnalysisContext recyclingAnalysisContext = _recyclingAnalysisContexts[selectedRecipeIndex]; RecipeDataPair val = igui.get_m_selectedRecipe(); ItemData itemData = ((RecipeDataPair)(ref val)).ItemData; _ = itemData?.m_quality; ((Behaviour)igui.m_recipeIcon).enabled = true; ((Behaviour)igui.m_recipeName).enabled = true; ((Behaviour)igui.m_recipeDecription).enabled = true; Image recipeIcon = igui.m_recipeIcon; val = igui.get_m_selectedRecipe(); recipeIcon.sprite = ((RecipeDataPair)(ref val)).Recipe.m_item.m_itemData.m_shared.m_icons[itemData?.m_variant ?? igui.get_m_selectedVariant()]; val = igui.get_m_selectedRecipe(); string text = Recycle_N_ReclaimPlugin.Localize(((RecipeDataPair)(ref val)).Recipe.m_item.m_itemData.m_shared.m_name); if (recyclingAnalysisContext.Item.m_stack > 1) { text = text + " x" + recyclingAnalysisContext.Item.m_stack; } igui.m_recipeName.text = text; if (recyclingAnalysisContext.RecyclingImpediments.Count == 0) { igui.m_recipeDecription.text = "\n" + Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_requirements_fulfilled"); } else { igui.m_recipeDecription.text = "\n" + Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_requirements_blocked") + ":\n\n<size=15>" + string.Join("\n", recyclingAnalysisContext.RecyclingImpediments) + "</size>"; } if (itemData != null) { SetActive(((Component)igui.m_itemCraftType).gameObject, isActive: true); igui.m_itemCraftType.text = Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_reclaim_item_level", Recycle_N_ReclaimPlugin.Localize(itemData.m_shared.m_name), itemData.m_quality.ToString()); } else { SetActive(((Component)igui.m_itemCraftType).gameObject, isActive: false); } if (Recycle_N_ReclaimPlugin.HasAuga) { if ((Object)(object)_descriptionBoxGo == (Object)null) { _descriptionBoxGo = Auga.API.ComplexTooltip_AddTwoColumnTextBox(_augaTabData.ItemInfoGO); } Auga.API.TooltipTextBox_AddLine(_descriptionBoxGo, (object)igui.m_recipeDecription.text, localize: true, overwrite: true); } GameObject gameObject = ((Component)igui.m_variantButton).gameObject; val = igui.get_m_selectedRecipe(); int isActive; if (((RecipeDataPair)(ref val)).Recipe.m_item.m_itemData.m_shared.m_variants > 1) { val = igui.get_m_selectedRecipe(); isActive = ((((RecipeDataPair)(ref val)).ItemData == null) ? 1 : 0); } else { isActive = 0; } SetActive(gameObject, (byte)isActive != 0); if (Recycle_N_ReclaimPlugin.epicLootAssembly == null) { SetupRequirementList(recyclingAnalysisContext); } else { SetupRequirementListEpicLoot(recyclingAnalysisContext); } SetActive(((Component)igui.m_minStationLevelIcon).gameObject, isActive: false); ((Selectable)igui.m_craftButton).interactable = recyclingAnalysisContext.RecyclingImpediments.Count == 0; ((Component)igui.m_craftButton).GetComponentInChildren<TMP_Text>().text = Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_reclaim_button"); ((Component)igui.m_craftButton).GetComponent<UITooltip>().m_text = ((recyclingAnalysisContext.RecyclingImpediments.Count == 0) ? "" : Recycle_N_ReclaimPlugin.Localize("$msg_missingrequirement")); } private void ClearRecipeUI(InventoryGui igui) { ((Behaviour)igui.m_recipeIcon).enabled = false; ((Behaviour)igui.m_recipeName).enabled = false; ((Behaviour)igui.m_recipeDecription).enabled = false; SetActive(((Component)igui.m_qualityPanel).gameObject, isActive: false); SetActive(((Component)igui.m_minStationLevelIcon).gameObject, isActive: false); ((Component)igui.m_craftButton).GetComponent<UITooltip>().m_text = ""; SetActive(((Component)igui.m_variantButton).gameObject, isActive: false); ((Component)igui.m_craftButton).GetComponentInChildren<TMP_Text>().text = Recycle_N_ReclaimPlugin.Localize("$azumatt_recycle_n_reclaim_reclaim_button"); SetActive(((Component)igui.m_itemCraftType).gameObject, isActive: false); for (int i = 0; i < igui.m_recipeRequirementList.Length; i++) { InventoryGui.HideRequirement(igui.m_recipeRequirementList[i].transform); } ((Selectable)igui.m_craftButton).interactable = false; } private void UpdateCraftingTimer(float dt, int selectedRecipeIndex, Player player, InventoryGui igui) { if ((double)igui.get_m_craftTimer() < 0.0) { SetActive(((Component)igui.m_craftProgressPanel).gameObject, isActive: false); SetActive(((Component)igui.m_craftButton).gameObject, isActive: true); return; } SetActive(((Component)igui.m_craftButton).gameObject, isActive: false); SetActive(((Component)igui.m_craftProgressPanel).gameObject, isActive: true); igui.m_craftProgressBar.SetMaxValue(igui.m_craftDuration); igui.m_craftProgressBar.SetValue(igui.get_m_craftTimer()); igui.set_m_craftTimer(igui.get_m_craftTimer() + dt); if ((double)igui.get_m_craftTimer() >= (double)igui.m_craftDuration) { Reclaimer.DoInventoryChanges(_recyclingAnalysisContexts[selectedRecipeIndex], ((Humanoid)player).GetInventory(), player); igui.set_m_craftTimer(-1f); igui.SetRecipe(-1, false); UpdateCraftingPanel(); } } private void SetActive(GameObject gameObject, bool isActive) { if (Object.op_Implicit((Object)(object)gameObject)) { gameObject.SetActive(isActive); } } private void SetupRequirementListEpicLoot(RecyclingAnalysisContext analysisContexts) { InventoryGui instance = InventoryGui.instance; List<RecyclingAnalysisContext.ReclaimingYieldEntry> list = analysisContexts.Entries.Where((RecyclingAnalysisContext.ReclaimingYieldEntry entry) => entry.Amount != 0).ToList(); for (int i = 0; i < instance.m_recipeRequirementList.Length; i++) { Transform transform = instance.m_recipeRequirementList[i].transform; if (i < list.Count) { if (analysisContexts.Entries[i].Amount == 0) { InventoryGui.HideRequirement(transform); } else { SetupRequirementEpicLoot(transform, list[i]); } } else { InventoryGui.HideRequirement(transform); } } } public static void SetupRequirem