Decompiled source of FullRecycle v1.0.0

BepInEx/plugins/FullRecycle/FullRecycle.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FullRecycle.Configuration;
using FullRecycle.Localization;
using FullRecycle.Runtime;
using Fusion;
using HarmonyLib;
using ModSettingsMenu.Api;
using SunkenlandLocalizationAPI.Api;
using UnityEngine;
using cfg;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("FullRecycle")]
[assembly: AssemblyDescription("Full recycle mod for Sunkenland by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("FullRecycle")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("5f7cdd9d-21b1-4bb2-9bcb-8c44f9f7629a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FullRecycle
{
	[BepInPlugin("IceBoxStudio.Sunkenland.FullRecycle", "FullRecycle", "1.0.0")]
	[BepInDependency("IceBoxStudio.Sunkenland.ModSettingsMenu", "1.2.0")]
	[BepInDependency("IceBoxStudio.Sunkenland.LocalizationAPI", "1.1.0")]
	public sealed class FullRecycle : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			LocalizationApi.LanguageChanged += OnLanguageChanged;
			try
			{
				Log.LogInfo((object)"=============================================");
				Log.LogInfo((object)("FullRecycle " + I18n.Text("plugin.initializing")));
				Log.LogInfo((object)(I18n.Text("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				ConfigManager.Bind(((BaseUnityPlugin)this).Config);
				RegisterSettings();
				_harmony = new Harmony("IceBoxStudio.Sunkenland.FullRecycle");
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				Log.LogInfo((object)("FullRecycle " + I18n.Text("plugin.initialized")));
				Log.LogInfo((object)"=============================================");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to initialize Full Recycle: {arg}");
			}
		}

		private static void RegisterSettings()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			ModSettingsRegistry.Register("IceBoxStudio.Sunkenland.FullRecycle", new ModSettingsModOptions
			{
				Name = "Full Recycle",
				LocalizedName = () => I18n.Text("mod.name"),
				Description = I18n.Text("mod.description"),
				Author = "Ice Box Studio",
				Version = "1.0.0",
				NexusModsId = 83,
				ThunderstoreTeam = "Ice_Box_Studio_Sunkenland",
				ThunderstoreModName = "FullRecycle"
			});
		}

		private static void OnLanguageChanged(string language)
		{
			RegisterSettings();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.Sunkenland.FullRecycle";

		public const string PLUGIN_NAME = "FullRecycle";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace FullRecycle.Runtime
{
	internal static class RecoveryCalculator
	{
		internal static int GetCraftingRecoveryDivisor()
		{
			if (!ConfigManager.Enabled)
			{
				return 2;
			}
			return 1;
		}
	}
	internal static class RecycleChanceRuntime
	{
		internal static float GetProbabilityDenominator()
		{
			if (!RecycleContext.IsActive || !ConfigManager.Enabled)
			{
				return 10000f;
			}
			return 0.0001f;
		}
	}
	internal static class RecycleContext
	{
		[ThreadStatic]
		private static int _depth;

		internal static bool IsActive => _depth > 0;

		internal static bool Enter(bool pass, int itemId)
		{
			if (!pass || !ConfigManager.Enabled || (Object)(object)RM.code == (Object)null || RM.code.ItemDictionary == null)
			{
				return false;
			}
			if (!RM.code.ItemDictionary.TryGetValue(itemId, out var value) || value == (Item)null || value.RecyclingDropID == 0)
			{
				return false;
			}
			_depth++;
			return true;
		}

		internal static void Exit()
		{
			if (_depth > 0)
			{
				_depth--;
			}
		}
	}
}
namespace FullRecycle.Patches
{
	[HarmonyPatch(typeof(DecomposeTable), "RPC_OnConfirmTakeItem", new Type[]
	{
		typeof(PlayerRef),
		typeof(bool),
		typeof(int),
		typeof(int),
		typeof(int[])
	})]
	internal static class DecomposeTableFullRecoveryPatch
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			FieldInfo fieldInfo = AccessTools.Field(typeof(CraftingItemRequirement), "amount");
			MethodInfo methodInfo = AccessTools.Method(typeof(RecoveryCalculator), "GetCraftingRecoveryDivisor", (Type[])null, (Type[])null);
			if (fieldInfo == null || methodInfo == null)
			{
				throw new InvalidOperationException("FullRecycle could not resolve the crafting recovery patch members.");
			}
			int num = 0;
			for (int i = 0; i < list.Count - 2; i++)
			{
				if (!(list[i].opcode != OpCodes.Ldfld) && object.Equals(list[i].operand, fieldInfo) && !(list[i + 1].opcode != OpCodes.Ldc_I4_2) && (!(list[i + 2].opcode != OpCodes.Div) || !(list[i + 2].opcode != OpCodes.Div_Un)))
				{
					list[i + 1].opcode = OpCodes.Call;
					list[i + 1].operand = methodInfo;
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException($"FullRecycle expected one crafting recovery division, found {num}.");
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(DecomposeTable), "RPC_OnConfirmTakeItem", new Type[]
	{
		typeof(PlayerRef),
		typeof(bool),
		typeof(int),
		typeof(int),
		typeof(int[])
	})]
	internal static class DecomposeTableRecycleScopePatch
	{
		[HarmonyPrefix]
		private static void Prefix(bool __1, int __2, out bool __state)
		{
			__state = RecycleContext.Enter(__1, __2);
		}

		[HarmonyFinalizer]
		private static Exception Finalizer(Exception __exception, bool __state)
		{
			if (__state)
			{
				RecycleContext.Exit();
			}
			return __exception;
		}
	}
	internal static class DropChancePatchHelper
	{
		internal static IEnumerable<CodeInstruction> ReplaceDenominator(IEnumerable<CodeInstruction> instructions, string target)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(RecycleChanceRuntime), "GetProbabilityDenominator", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new InvalidOperationException("FullRecycle could not resolve the recycle chance helper.");
			}
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if (!(item.opcode != OpCodes.Ldc_R4) && item.operand is float num2 && !(Math.Abs(num2 - 10000f) > 0.001f))
				{
					item.opcode = OpCodes.Call;
					item.operand = methodInfo;
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException($"FullRecycle expected one recycle chance denominator in {target}, found {num}.");
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(DropManager), "GetDroppedItems", new Type[] { typeof(int) })]
	internal static class DropManagerGroupChancePatch
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return DropChancePatchHelper.ReplaceDenominator(instructions, "DropManager.GetDroppedItems");
		}
	}
	[HarmonyPatch(typeof(DropManager), "GetDropPoolDataByID", new Type[]
	{
		typeof(Tables),
		typeof(int)
	})]
	internal static class DropManagerPoolChancePatch
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return DropChancePatchHelper.ReplaceDenominator(instructions, "DropManager.GetDropPoolDataByID");
		}
	}
}
namespace FullRecycle.Localization
{
	internal static class I18n
	{
		private const string FileName = "FullRecycle.Localization.json";

		private static readonly ModLocalizer _localizer = Load();

		internal static ModLocalizer Localizer => _localizer;

		internal static string Text(string key, params object[] args)
		{
			return _localizer.GetLocalizedText(key, args);
		}

		private static ModLocalizer Load()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ModLocalizer obj = LocalizationApi.For("IceBoxStudio.Sunkenland.FullRecycle");
			obj.RegisterJson(Path.Combine(directoryName, "FullRecycle.Localization.json"));
			return obj;
		}
	}
}
namespace FullRecycle.Configuration
{
	internal static class ConfigManager
	{
		private const string Section = "Full Recycle";

		private static ConfigEntry<bool> _enabled;

		internal static bool Enabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		internal static void Bind(ConfigFile config)
		{
			_enabled = config.Bind<bool>("Full Recycle", "EnableFullRecycle", true, I18n.Localizer.Config("config.enabled", 10, "Full Recycle", "config.section", 10, (AcceptableValueBase)null));
		}
	}
}