Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of QuickMachineFill v1.4.0
QuickMachineFill.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("QuickMachineFill")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("QuickMachineFill")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a96c08d8-db3c-49d0-8cd0-9dc9abc6677e")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("com.ezat.quickmachinefill", "Quick Machine Fill", "1.4.0")] public class QuickMachineFillPlugin : BaseUnityPlugin { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyboardShortcut> FillShortcut; internal static ConfigEntry<string> Language; internal static ConfigEntry<bool> DebugLog; private Harmony harmony; private void Awake() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable Quick Machine Fill."); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Debug Log", false, "Write detailed fill information to the BepInEx log."); FillShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keyboard", "Keyboard Shortcut", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Keyboard shortcut for filling a machine completely."); Language = ((BaseUnityPlugin)this).Config.Bind<string>("Language", "Language", "English", new ConfigDescription("Language used for the in-game tooltip.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[12] { "English", "Deutsch", "Français", "Español", "Italiano", "Português", "Русский", "Polski", "Türkçe", "简体中文", "日本語", "한국어" }), Array.Empty<object>())); harmony = new Harmony("com.ezat.quickmachinefill"); harmony.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Quick Machine Fill loaded."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Mod enabled: " + Enabled.Value)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Keyboard shortcut: " + GetShortcutText())); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Language: " + Language.Value)); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } } internal static void Log(string message) { if (DebugLog != null && DebugLog.Value) { Debug.Log((object)("[Quick Machine Fill] " + message)); } } internal static string GetShortcutText() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_001b: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected I4, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) if (FillShortcut != null) { KeyboardShortcut value = FillShortcut.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0) { KeyboardShortcut value2 = FillShortcut.Value; string text = ""; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value2)).Modifiers) { KeyCode val = modifier; KeyCode val2 = val; switch (val2 - 303) { case 0: case 1: if (!text.Contains("Shift")) { text += "Shift + "; } break; case 2: case 3: if (!text.Contains("Ctrl")) { text += "Ctrl + "; } break; case 4: case 5: if (!text.Contains("Alt")) { text += "Alt + "; } break; } } return text + ((object)((KeyboardShortcut)(ref value2)).MainKey/*cast due to .constrained prefix*/).ToString(); } } return ""; } internal static string GetHintText() { if (Enabled == null || !Enabled.Value) { return ""; } string shortcutText = GetShortcutText(); if (string.IsNullOrEmpty(shortcutText)) { return GetTranslation("Keine Taste zugewiesen", "No key assigned", "Aucune touche assignée", "Ninguna tecla asignada", "Nessun tasto assegnato", "Nenhuma tecla atribuída", "Клавиша не назначена", "Nie przypisano klawisza", "Tuş atanmamış", "未分配按键", "キーが割り当てられていません", "키가 지정되지 않았습니다"); } return "[<color=yellow>" + shortcutText + "</color>] " + GetTranslation("Alles auffüllen", "Fill completely", "Tout remplir", "Llenar todo", "Riempi tutto", "Encher tudo", "Заполнить полностью", "Wypełnij do pełna", "Tümünü doldur", "全部填满", "すべて補充", "모두 채우기"); } private static string GetTranslation(string de, string en, string fr, string es, string it, string pt, string ru, string pl, string tr, string zh, string ja, string ko) { string text = ((Language != null) ? Language.Value : "English"); return text.ToLowerInvariant() switch { "deutsch" => de, "français" => fr, "español" => es, "italiano" => it, "português" => pt, "русский" => ru, "polski" => pl, "türkçe" => tr, "简体中文" => zh, "日本語" => ja, "한국어" => ko, _ => en, }; } } internal static class QuickMachineFillLogic { private sealed class MachineState { public int OreExpected; public float OreUntil; public int OreLastFrame = -1; public float FuelExpected; public float FuelUntil; public int FuelLastFrame = -1; } private const int MaxIterations = 100; private const float PendingSeconds = 5f; private static bool isInternalFill; private static readonly Dictionary<int, MachineState> states = new Dictionary<int, MachineState>(); private static readonly MethodInfo queueMethod = AccessTools.Method(typeof(Smelter), "GetQueueSize", (Type[])null, (Type[])null); private static readonly MethodInfo fuelMethod = AccessTools.Method(typeof(Smelter), "GetFuel", (Type[])null, (Type[])null); private static readonly MethodInfo addOreMethod = AccessTools.Method(typeof(Smelter), "OnAddOre", (Type[])null, (Type[])null); private static readonly MethodInfo addFuelMethod = AccessTools.Method(typeof(Smelter), "OnAddFuel", (Type[])null, (Type[])null); internal static bool IsInternalFill => isInternalFill; internal static bool ShouldHandleShortcut(Humanoid user) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) int result; if (!isInternalFill && (Object)(object)user != (Object)null && (Object)(object)user == (Object)(object)Player.m_localPlayer && QuickMachineFillPlugin.Enabled != null && QuickMachineFillPlugin.Enabled.Value && QuickMachineFillPlugin.FillShortcut != null) { KeyboardShortcut value = QuickMachineFillPlugin.FillShortcut.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0) { value = QuickMachineFillPlugin.FillShortcut.Value; result = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0); goto IL_0061; } } result = 0; goto IL_0061; IL_0061: return (byte)result != 0; } private static MachineState GetState(Smelter smelter) { int instanceID = ((Object)smelter).GetInstanceID(); if (!states.TryGetValue(instanceID, out var value)) { if (states.Count > 64) { CleanupStates(); } value = new MachineState(); states[instanceID] = value; } return value; } private static void CleanupStates() { float realtimeSinceStartup = Time.realtimeSinceStartup; List<int> list = new List<int>(); foreach (KeyValuePair<int, MachineState> state in states) { if (state.Value.OreUntil < realtimeSinceStartup && state.Value.FuelUntil < realtimeSinceStartup) { list.Add(state.Key); } } foreach (int item in list) { states.Remove(item); } } internal static bool FillOre(Smelter smelter, Switch sw, Humanoid user) { if ((Object)(object)smelter == (Object)null || (Object)(object)sw == (Object)null || (Object)(object)user == (Object)null || queueMethod == null || addOreMethod == null) { return false; } MachineState state = GetState(smelter); if (state.OreLastFrame == Time.frameCount) { return false; } state.OreLastFrame = Time.frameCount; int num; try { num = Convert.ToInt32(queueMethod.Invoke(smelter, null)); } catch (Exception ex) { Debug.LogError((object)("[Quick Machine Fill] Could not read ore queue: " + ex)); return false; } float realtimeSinceStartup = Time.realtimeSinceStartup; int num2 = num; if (state.OreUntil > realtimeSinceStartup && num < state.OreExpected) { num2 = state.OreExpected; } int num3 = smelter.m_maxOre - num2; QuickMachineFillPlugin.Log("Ore: actual=" + num + ", effective=" + num2 + ", max=" + smelter.m_maxOre + ", slots=" + num3); if (num3 <= 0) { return CallVanillaOnce(addOreMethod, smelter, sw, user); } num3 = Math.Min(num3, 100); int num4 = 0; isInternalFill = true; try { for (int i = 0; i < num3; i++) { object obj; try { obj = addOreMethod.Invoke(smelter, new object[3] { sw, user, null }); } catch (Exception ex2) { Debug.LogError((object)("[Quick Machine Fill] Adding ore failed: " + ex2)); break; } if (obj is bool && !(bool)obj) { QuickMachineFillPlugin.Log("Ore: vanilla refused after " + num4 + " items."); break; } num4++; } } finally { isInternalFill = false; } if (num4 > 0) { state.OreExpected = num2 + num4; state.OreUntil = Time.realtimeSinceStartup + 5f; } QuickMachineFillPlugin.Log("Ore: added " + num4 + ", expected now " + (num2 + num4)); return num4 > 0; } internal static bool FillFuel(Smelter smelter, Switch sw, Humanoid user) { if ((Object)(object)smelter == (Object)null || (Object)(object)sw == (Object)null || (Object)(object)user == (Object)null || fuelMethod == null || addFuelMethod == null) { return false; } MachineState state = GetState(smelter); if (state.FuelLastFrame == Time.frameCount) { return false; } state.FuelLastFrame = Time.frameCount; float num; try { num = Convert.ToSingle(fuelMethod.Invoke(smelter, null)); } catch (Exception ex) { Debug.LogError((object)("[Quick Machine Fill] Could not read fuel level: " + ex)); return false; } float realtimeSinceStartup = Time.realtimeSinceStartup; float num2 = num; if (state.FuelUntil > realtimeSinceStartup && num < state.FuelExpected - 0.5f) { num2 = state.FuelExpected; } int num3 = Math.Max(0, Mathf.FloorToInt((float)smelter.m_maxFuel - num2 + 0.0001f)); QuickMachineFillPlugin.Log("Fuel: actual=" + num + ", effective=" + num2 + ", max=" + smelter.m_maxFuel + ", slots=" + num3); if (num3 <= 0) { return CallVanillaOnce(addFuelMethod, smelter, sw, user); } num3 = Math.Min(num3, 100); int num4 = 0; isInternalFill = true; try { for (int i = 0; i < num3; i++) { object obj; try { obj = addFuelMethod.Invoke(smelter, new object[3] { sw, user, null }); } catch (Exception ex2) { Debug.LogError((object)("[Quick Machine Fill] Adding fuel failed: " + ex2)); break; } if (obj is bool && !(bool)obj) { QuickMachineFillPlugin.Log("Fuel: vanilla refused after " + num4 + " items."); break; } num4++; } } finally { isInternalFill = false; } if (num4 > 0) { state.FuelExpected = num2 + (float)num4; state.FuelUntil = Time.realtimeSinceStartup + 5f; } QuickMachineFillPlugin.Log("Fuel: added " + num4 + ", expected now " + (num2 + (float)num4)); return num4 > 0; } private static bool CallVanillaOnce(MethodInfo method, Smelter smelter, Switch sw, Humanoid user) { return false; } } [HarmonyPatch(typeof(Smelter), "OnAddOre")] internal static class QuickMachineFillOreInputPatch { [HarmonyPrefix] private static bool Prefix(Smelter __instance, Switch sw, Humanoid user, ItemData item, ref bool __result) { if (QuickMachineFillLogic.IsInternalFill || !QuickMachineFillLogic.ShouldHandleShortcut(user)) { return true; } __result = QuickMachineFillLogic.FillOre(__instance, sw, user); return false; } } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] internal static class QuickMachineFillFuelInputPatch { [HarmonyPrefix] private static bool Prefix(Smelter __instance, Switch sw, Humanoid user, ItemData item, ref bool __result) { if (QuickMachineFillLogic.IsInternalFill || !QuickMachineFillLogic.ShouldHandleShortcut(user)) { return true; } __result = QuickMachineFillLogic.FillFuel(__instance, sw, user); return false; } } [HarmonyPatch(typeof(Smelter), "OnHoverAddOre")] internal static class QuickMachineFillOreHintPatch { private static void Postfix(ref string __result) { string hintText = QuickMachineFillPlugin.GetHintText(); if (!string.IsNullOrEmpty(hintText)) { __result = __result + "\n" + hintText; } } } [HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")] internal static class QuickMachineFillFuelHintPatch { private static void Postfix(ref string __result) { string hintText = QuickMachineFillPlugin.GetHintText(); if (!string.IsNullOrEmpty(hintText)) { __result = __result + "\n" + hintText; } } }