Decompiled source of FactoryOverclock v3.0.0

FactoryOverclock.dll

Decompiled 5 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using CommonAPI.Systems;
using CommonAPI.Systems.ModLocalization;
using DysonSphereMods.Shared;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Valoneu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyDescription("FactoryOverclock")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: AssemblyInformationalVersion("3.0.0+31b1750490d034965cde15adfc56e59a7ba9b23f")]
[assembly: AssemblyProduct("DysonSphereMods")]
[assembly: AssemblyTitle("FactoryOverclock")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DysonSphereMods.Shared
{
	public static class Log
	{
		private static ManualLogSource _logger;

		public static void Init(ManualLogSource logger)
		{
			_logger = logger;
		}

		public static void Debug(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogDebug(data);
			}
		}

		public static void Info(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogInfo(data);
			}
		}

		public static void Warning(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogWarning(data);
			}
		}

		public static void Error(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError(data);
			}
		}

		public static void Fatal(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogFatal(data);
			}
		}

		public static void Message(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogMessage(data);
			}
		}

		public static void LogOnce(string msg, ref bool flag, params object[] args)
		{
			if (flag)
			{
				return;
			}
			flag = true;
			try
			{
				string[] array = ((args == null) ? Array.Empty<string>() : args.Select((object arg) => (arg != null) ? ((!(arg is int) && !(arg is string) && !arg.GetType().IsPrimitive) ? JsonUtility.ToJson(arg) : arg.ToString()) : "null").ToArray());
				object[] args2 = array;
				Info(string.Format(msg, args2));
			}
			catch (Exception arg2)
			{
				Warning($"LogOnce failed to format message: {msg}. Exception: {arg2}");
			}
		}
	}
	public static class MultiplierService
	{
		private static readonly Dictionary<string, float> _multipliers = new Dictionary<string, float>();

		private static bool _isDirty;

		public static event Action OnMultipliersChanged;

		public static void SetMultiplier(string key, float value)
		{
			if (!_multipliers.TryGetValue(key, out var value2) || Math.Abs(value2 - value) > 0.0001f)
			{
				_multipliers[key] = value;
				_isDirty = true;
			}
		}

		public static float GetMultiplier(string key, float defaultValue = 1f)
		{
			if (!_multipliers.TryGetValue(key, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public static void CommitChanges()
		{
			if (_isDirty)
			{
				_isDirty = false;
				MultiplierService.OnMultipliersChanged?.Invoke();
			}
		}
	}
	public static class TickManager
	{
		private static long _lastSlowTick = -1L;

		private static long _lastLazyTick = -1L;

		private static bool _patched = false;

		public static event Action OnSlowTick;

		public static event Action OnLazyTick;

		public static void Patch(Harmony harmony)
		{
			if (!_patched)
			{
				_patched = true;
				harmony.PatchAll(typeof(TickManager));
			}
		}

		[HarmonyPatch(typeof(GameMain), "Begin")]
		[HarmonyPostfix]
		public static void Init()
		{
			_lastSlowTick = -1L;
			_lastLazyTick = -1L;
		}

		[HarmonyPatch(typeof(GameLogic), "LogicFrame")]
		[HarmonyPostfix]
		public static void GameTick()
		{
			long gameTick = GameMain.gameTick;
			if (gameTick / 60 > _lastSlowTick)
			{
				_lastSlowTick = gameTick / 60;
				TickManager.OnSlowTick?.Invoke();
			}
			if (gameTick / 600 > _lastLazyTick)
			{
				_lastLazyTick = gameTick / 600;
				TickManager.OnLazyTick?.Invoke();
			}
		}
	}
	public abstract class WindowBase
	{
		public Rect WindowRect;

		protected Vector2 ScrollPos;

		private bool _isResizing;

		private Rect _resizeRect = new Rect(0f, 0f, 15f, 15f);

		public Vector2 MinSize = new Vector2(300f, 200f);

		public int WindowId { get; protected set; }

		public string Title { get; set; }

		public bool IsVisible { get; set; }

		protected WindowBase(int windowId, string title, Rect defaultRect)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			WindowId = windowId;
			Title = title;
			WindowRect = defaultRect;
		}

		public virtual void OnGUI()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0050: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (IsVisible)
			{
				GUI.backgroundColor = new Color(0.08f, 0.12f, 0.22f, 0.95f);
				WindowRect = GUILayout.Window(WindowId, WindowRect, new WindowFunction(DrawWindowInternal), Title, Array.Empty<GUILayoutOption>());
				GUI.backgroundColor = Color.white;
				((Rect)(ref WindowRect)).x = Mathf.Clamp(((Rect)(ref WindowRect)).x, 0f - ((Rect)(ref WindowRect)).width + 50f, (float)(Screen.width - 50));
				((Rect)(ref WindowRect)).y = Mathf.Clamp(((Rect)(ref WindowRect)).y, -20f, (float)(Screen.height - 50));
			}
		}

		private void DrawWindowInternal(int id)
		{
			//IL_0008: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00dd: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Invalid comparison between Unknown and I4
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Invalid comparison between Unknown and I4
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			DrawWindowHeader();
			ScrollPos = GUILayout.BeginScrollView(ScrollPos, Array.Empty<GUILayoutOption>());
			DrawWindowContent();
			GUILayout.EndScrollView();
			DrawWindowFooter();
			((Rect)(ref _resizeRect)).x = ((Rect)(ref WindowRect)).width - 20f;
			((Rect)(ref _resizeRect)).y = ((Rect)(ref WindowRect)).height - 20f;
			((Rect)(ref _resizeRect)).width = 20f;
			((Rect)(ref _resizeRect)).height = 20f;
			GUI.Label(_resizeRect, "↘", new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 20,
				normal = new GUIStyleState
				{
					textColor = new Color(0.6f, 0.6f, 0.6f, 0.8f)
				}
			});
			Event current = Event.current;
			bool flag = false;
			if ((int)current.type == 0 && ((Rect)(ref _resizeRect)).Contains(current.mousePosition))
			{
				_isResizing = true;
				flag = true;
				current.Use();
			}
			else if ((int)current.type == 1)
			{
				_isResizing = false;
			}
			else if ((int)current.type == 3 && _isResizing)
			{
				ref Rect windowRect = ref WindowRect;
				((Rect)(ref windowRect)).width = ((Rect)(ref windowRect)).width + current.delta.x;
				ref Rect windowRect2 = ref WindowRect;
				((Rect)(ref windowRect2)).height = ((Rect)(ref windowRect2)).height + current.delta.y;
				((Rect)(ref WindowRect)).width = Mathf.Max(MinSize.x, ((Rect)(ref WindowRect)).width);
				((Rect)(ref WindowRect)).height = Mathf.Max(MinSize.y, ((Rect)(ref WindowRect)).height);
				current.Use();
			}
			if ((int)current.type == 0 && !flag)
			{
				GUIUtility.keyboardControl = 0;
			}
			GUI.DragWindow();
		}

		protected virtual void DrawWindowHeader()
		{
		}

		protected abstract void DrawWindowContent();

		protected virtual void DrawWindowFooter()
		{
		}

		public virtual void Toggle()
		{
			IsVisible = !IsVisible;
		}
	}
}
namespace FactoryOverclock
{
	[BepInPlugin("com.Valoneu.FactoryOverclock", "FactoryOverclock", "3.0.0")]
	[BepInProcess("DSPGAME.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[CommonAPISubmoduleDependency(new string[] { "ProtoRegistry", "CustomKeyBindSystem", "LocalizationModule" })]
	public class MultiplierPlugin : BaseUnityPlugin
	{
		public const string GUID = "com.Valoneu.FactoryOverclock";

		public const string NAME = "FactoryOverclock";

		public const string VERSION = "3.0.0";

		private Harmony _harmony;

		public static int BattlefieldAnalysisBaseProtoId = 3009;

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Log.Init(((BaseUnityPlugin)this).Logger);
			PluginConfig.InitConfig(((BaseUnityPlugin)this).Config);
			InitKeyBinds();
			_harmony = new Harmony("com.Valoneu.FactoryOverclock");
			_harmony.PatchAll(typeof(PowerConsumptionPatcher));
			_harmony.PatchAll(typeof(PowerGenerationPatcher));
			_harmony.PatchAll(typeof(FactorySystemPatcher));
			_harmony.PatchAll(typeof(StationPatcher));
			_harmony.PatchAll(typeof(BeltPatcher));
			_harmony.PatchAll(typeof(BuildingPatcher));
			_harmony.PatchAll(typeof(TurretPatcher));
			_harmony.PatchAll(typeof(MultiplierPlugin));
			if (Chainloader.PluginInfos.ContainsKey("jinxOAO.MoreMegaStructure"))
			{
				Log.Info("MoreMegaStructure detected, applying compatibility patches.");
				_harmony.PatchAll(typeof(StationPatcher.MoreMegaStructureCompat));
			}
			Log.Info("FactoryOverclock 3.0.0 loaded.");
		}

		private void Update()
		{
			bool flag = PluginConfig.keyTestMode.Value && VFInput.alt && Input.GetKeyDown((KeyCode)49);
			if (CustomKeyBindSystem.GetKeyBind("ToggleOverclock").keyValue || flag)
			{
				PluginConfig.multiplierEnabled.Value = !PluginConfig.multiplierEnabled.Value;
				if (!PluginConfig.multiplierEnabled.Value)
				{
					Log.Info("Reverting factory to normal speed.");
					UIRealtimeTip.Popup("Reverting factory to normal", true, 0);
				}
				else
				{
					Log.Info($"Applying multipliers. Asm={PluginConfig.assembleMultiplier.Value}, Mine={PluginConfig.miningMultiplier.Value}, Smelt={PluginConfig.smeltMultiplier.Value}");
					UIRealtimeTip.Popup("Applying multipliers to factory", true, 0);
				}
				RefreshAllSystems();
			}
		}

		public void RefreshAllSystems()
		{
			if (GameMain.data?.factories == null)
			{
				return;
			}
			Log.Info("Refreshing all factory systems...");
			PlanetFactory[] factories = GameMain.data.factories;
			foreach (PlanetFactory val in factories)
			{
				if (val != null)
				{
					if (val.powerSystem != null)
					{
						PowerGenerationPatcher.SyncGenerators(val.powerSystem);
						PowerConsumptionPatcher.SyncPowerSystems(val.powerSystem);
					}
					if (val.factorySystem != null)
					{
						FactorySystemPatcher.SyncAll(val.factorySystem);
					}
					if (val.cargoTraffic != null)
					{
						BeltPatcher.SyncBelts(val);
					}
				}
			}
		}

		private void InitKeyBinds()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected I4, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!CustomKeyBindSystem.HasKeyBind("ToggleOverclock"))
			{
				BuiltinKey val = default(BuiltinKey);
				val.id = 1214;
				KeyboardShortcut value = PluginConfig.toggleOverclockKey.Value;
				val.key = new CombineKey((int)((KeyboardShortcut)(ref value)).MainKey, (byte)0, (ECombineKeyAction)0, false);
				val.conflictGroup = 2052;
				val.name = "ToggleOverclock";
				val.canOverride = true;
				CustomKeyBindSystem.RegisterKeyBind<PressKeyBind>(val);
			}
			LocalizationModule.RegisterTranslation("KEYToggleOverclock", "Enable/disable factory OverClock");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameMain), "Begin")]
		private static void GameBegin_Postfix()
		{
			Object.FindObjectOfType<MultiplierPlugin>()?.RefreshAllSystems();
		}
	}
	public static class PluginConfig
	{
		public static ConfigEntry<int> smeltMultiplier;

		public static ConfigEntry<int> chemicalMultiplier;

		public static ConfigEntry<int> refineMultiplier;

		public static ConfigEntry<int> assembleMultiplier;

		public static ConfigEntry<int> particleMultiplier;

		public static ConfigEntry<int> miningMultiplier;

		private static ConfigEntry<int> _labMultiplier;

		private static ConfigEntry<int> _fractionatorMultiplier;

		private static ConfigEntry<int> _ejectorMultiplier;

		private static ConfigEntry<int> _siloMultiplier;

		public static ConfigEntry<int> gammaMultiplier;

		private static ConfigEntry<int> _inserterMultiplier;

		private static ConfigEntry<int> _turretMultiplier;

		private static ConfigEntry<int> _beltMultiplier;

		public static ConfigEntry<double> drawMultiplier;

		private static ConfigEntry<int> _genWindMultiplier;

		private static ConfigEntry<int> _genSolarMultiplier;

		private static ConfigEntry<int> _genGeoMultiplier;

		private static ConfigEntry<int> _genThermalMultiplier;

		private static ConfigEntry<int> _genFusionMultiplier;

		private static ConfigEntry<int> _genStarMultiplier;

		private static ConfigEntry<int> _genExchMultiplier;

		public static ConfigEntry<bool> keyTestMode;

		public static ConfigEntry<KeyboardShortcut> toggleOverclockKey;

		public static ConfigEntry<bool> multiplierEnabled;

		public static ConfigEntry<bool> enableAssemblerPopupLogMessage;

		public static int genWindMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genWindMultiplier.Value;
			}
		}

		public static int genSolarMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genSolarMultiplier.Value;
			}
		}

		public static int genGeoMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genGeoMultiplier.Value;
			}
		}

		public static int genThermalMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genThermalMultiplier.Value;
			}
		}

		public static int genFusionMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genFusionMultiplier.Value;
			}
		}

		public static int genStarMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genStarMultiplier.Value;
			}
		}

		public static int genExchMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _genExchMultiplier.Value;
			}
		}

		public static int siloMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _siloMultiplier.Value;
			}
		}

		public static int inserterMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _inserterMultiplier.Value;
			}
		}

		public static int beltMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _beltMultiplier.Value;
			}
		}

		public static int ejectorMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _ejectorMultiplier.Value;
			}
		}

		public static int fractionatorMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _fractionatorMultiplier.Value;
			}
		}

		public static int labMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _labMultiplier.Value;
			}
		}

		public static int turretMultiplier
		{
			get
			{
				if (!multiplierEnabled.Value)
				{
					return 1;
				}
				return _turretMultiplier.Value;
			}
		}

		public static void InitConfig(ConfigFile confFile)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Expected O, but got Unknown
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Expected O, but got Unknown
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Expected O, but got Unknown
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Expected O, but got Unknown
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Expected O, but got Unknown
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Expected O, but got Unknown
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Expected O, but got Unknown
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			smeltMultiplier = confFile.Bind<int>("1. Factory", "smeltMultiplier", 2, new ConfigDescription("Multiplies speed of smelters", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			chemicalMultiplier = confFile.Bind<int>("1. Factory", "chemicalMultiplier", 2, new ConfigDescription("Multiplies speed of chemical plants", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			refineMultiplier = confFile.Bind<int>("1. Factory", "refineMultiplier", 2, new ConfigDescription("Multiplies speed of refineries", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			assembleMultiplier = confFile.Bind<int>("1. Factory", "assembleMultiplier", 2, new ConfigDescription("Multiplies speed of assemblers", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			particleMultiplier = confFile.Bind<int>("1. Factory", "particleMultiplier", 2, new ConfigDescription("Multiplies speed of particle colliders", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			_labMultiplier = confFile.Bind<int>("1. Factory", "labMultiplier", 2, new ConfigDescription("Multiplies speed of laboratories", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			_fractionatorMultiplier = confFile.Bind<int>("1. Factory", "fractionateMultiplier", 2, new ConfigDescription("Multiplies % of fractionators", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			_ejectorMultiplier = confFile.Bind<int>("1. Factory", "ejectorMultiplier", 2, new ConfigDescription("Multiplies speed of EM rail ejectors", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_siloMultiplier = confFile.Bind<int>("1. Factory", "siloMultiplier", 2, new ConfigDescription("Multiplies speed of silos", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			gammaMultiplier = confFile.Bind<int>("1. Factory", "gammaMultiplier", 2, new ConfigDescription("Multiplies speed of ray recievers", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>()));
			miningMultiplier = confFile.Bind<int>("1. Factory", "miningMultiplier", 2, new ConfigDescription("Multiplies speed of mining machines", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			_inserterMultiplier = confFile.Bind<int>("1. Factory", "sorterMultiplier", 2, new ConfigDescription("Multiplies speed of sorter", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[4] { 1, 2, 4, 8 }), Array.Empty<object>()));
			_turretMultiplier = confFile.Bind<int>("1. Factory", "turretMultiplier", 2, new ConfigDescription("Multiplies speed of turrets", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			_beltMultiplier = confFile.Bind<int>("1. Factory", "beltMultiplier", 1, new ConfigDescription("Multiplies speed of belts (max 2x)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 2), Array.Empty<object>()));
			drawMultiplier = confFile.Bind<double>("1. Factory", "drawMultipler", 1.0, new ConfigDescription("Multiplies how much your factory will draw on top of your normal overclock", (AcceptableValueBase)(object)new AcceptableValueRange<double>(0.1, 10.0), Array.Empty<object>()));
			_genWindMultiplier = confFile.Bind<int>("2. Generator", "generatorWindMultiplier", 2, new ConfigDescription("Multiplies speed of wind turbines", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_genSolarMultiplier = confFile.Bind<int>("2. Generator", "generatorSolarMultiplier", 2, new ConfigDescription("Multiplies speed of solar panels", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_genGeoMultiplier = confFile.Bind<int>("2. Generator", "generatorGeothermalMultiplier", 2, new ConfigDescription("Multiplies speed of geothermal plants", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_genThermalMultiplier = confFile.Bind<int>("2. Generator", "generatorThermalMultiplier", 2, new ConfigDescription("Multiplies speed of thermal plants", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_genFusionMultiplier = confFile.Bind<int>("2. Generator", "generatorFusionMultiplier", 2, new ConfigDescription("Multiplies speed of fusion power plants", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_genStarMultiplier = confFile.Bind<int>("2. Generator", "generatorArtificialStarMultiplier", 2, new ConfigDescription("Multiplies speed of artificial stars", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			_genExchMultiplier = confFile.Bind<int>("2. Generator", "generatorExchangerMultiplier", 2, new ConfigDescription("Multiplies speed of energy exchangers", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			keyTestMode = confFile.Bind<bool>("3. Advanced", "keyTestMode", false, "Uses alt+1 as keybind for scriptengine support");
			toggleOverclockKey = confFile.Bind<KeyboardShortcut>("3. Advanced", "toggleOverclockKey", new KeyboardShortcut((KeyCode)269, Array.Empty<KeyCode>()), "Key to toggle overclock");
			multiplierEnabled = confFile.Bind<bool>("3. Advanced", "multiplierEnabled", true, "Determine whether we are currently multiplying values");
			enableAssemblerPopupLogMessage = confFile.Bind<bool>("3. Advanced", "enableAssemblerPopupLogMessage", false, "Ignore - For debugging, log message when UI window is opened");
		}

		public static int GetMultiplierByRecipe(ERecipeType eRecipeType)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected I4, but got Unknown
			if (!multiplierEnabled.Value)
			{
				return 1;
			}
			return (eRecipeType - 1) switch
			{
				3 => assembleMultiplier.Value, 
				1 => chemicalMultiplier.Value, 
				5 => 1, 
				7 => fractionatorMultiplier, 
				4 => particleMultiplier.Value, 
				2 => refineMultiplier.Value, 
				14 => labMultiplier, 
				0 => smeltMultiplier.Value, 
				6 => gammaMultiplier.Value, 
				_ => 1, 
			};
		}
	}
	public static class ItemUtil
	{
		private static readonly ERecipeType[] _recipeByProtoId = (ERecipeType[])(object)new ERecipeType[15000];

		private static readonly bool[] _recipeCacheInit = new bool[15000];

		private static readonly bool[] _rayPhotonReceiverProtosArray = new bool[15000];

		private static bool _rayPhotonReceiverProtosInit = false;

		private static int _ejectorChargeFrame = -1;

		private static int _siloChargeFrame = -1;

		public static int EjectorChargeFrame
		{
			get
			{
				if (_ejectorChargeFrame == -1)
				{
					_ejectorChargeFrame = (((IEnumerable<ItemProto>)((ProtoSet<ItemProto>)(object)LDB.items).dataArray).FirstOrDefault((Func<ItemProto, bool>)((ItemProto i) => i.prefabDesc.isEjector))?.prefabDesc?.ejectorChargeFrame).GetValueOrDefault();
				}
				return _ejectorChargeFrame;
			}
		}

		public static int SiloChargeFrame
		{
			get
			{
				if (_siloChargeFrame == -1)
				{
					_siloChargeFrame = (((IEnumerable<ItemProto>)((ProtoSet<ItemProto>)(object)LDB.items).dataArray).FirstOrDefault((Func<ItemProto, bool>)((ItemProto i) => i.prefabDesc.isSilo))?.prefabDesc?.siloChargeFrame).GetValueOrDefault();
				}
				return _siloChargeFrame;
			}
		}

		public static ERecipeType GetRecipeByProtoId(int protoId)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected I4, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (protoId < 0 || protoId >= 15000)
			{
				return (ERecipeType)0;
			}
			if (_recipeCacheInit[protoId])
			{
				return _recipeByProtoId[protoId];
			}
			ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId);
			if (val?.prefabDesc != null)
			{
				ERecipeType assemblerRecipeType = val.prefabDesc.assemblerRecipeType;
				_recipeByProtoId[protoId] = (ERecipeType)(int)assemblerRecipeType;
				_recipeCacheInit[protoId] = true;
				return assemblerRecipeType;
			}
			return (ERecipeType)0;
		}

		public static bool IsPhotonRayReceiver(int protoId)
		{
			if (protoId < 0 || protoId >= 15000)
			{
				return false;
			}
			if (!_rayPhotonReceiverProtosInit)
			{
				ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
				foreach (ItemProto val in dataArray)
				{
					if (val.prefabDesc.gammaRayReceiver && ((Proto)val).ID >= 0 && ((Proto)val).ID < 15000)
					{
						_rayPhotonReceiverProtosArray[((Proto)val).ID] = true;
					}
				}
				_rayPhotonReceiverProtosInit = true;
			}
			return _rayPhotonReceiverProtosArray[protoId];
		}
	}
	public static class BeltPatcher
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(CargoTraffic), "NewBeltComponent")]
		[HarmonyPatch(typeof(CargoTraffic), "UpgradeBeltComponent")]
		public static void Belt_Prefix(ref int speed)
		{
			speed *= PluginConfig.beltMultiplier;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(CargoTraffic), "UpdateSplitter")]
		public static void CallOriginalUpdateSplitter(CargoTraffic instance, ref SplitterComponent sp)
		{
			throw new NotImplementedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(PilerComponent), "InternalUpdate")]
		public static void CallOriginalPilerUpdate(ref PilerComponent instance, CargoTraffic _traffic, AnimData[] _animPool)
		{
			throw new NotImplementedException();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CargoTraffic), "UpdateSplitter")]
		public static void UpdateSplitter_Postfix(ref SplitterComponent sp, CargoTraffic __instance)
		{
			if (PluginConfig.multiplierEnabled.Value && PluginConfig.beltMultiplier > 1)
			{
				for (int i = 0; i < PluginConfig.beltMultiplier - 1; i++)
				{
					CallOriginalUpdateSplitter(__instance, ref sp);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PilerComponent), "InternalUpdate")]
		public static void Piler_InternalUpdate_Postfix(ref PilerComponent __instance, CargoTraffic _traffic, AnimData[] _animPool)
		{
			if (PluginConfig.multiplierEnabled.Value && PluginConfig.beltMultiplier > 1)
			{
				__instance.cacheCdTick = 0;
				if (__instance.timeSpend < 10000)
				{
					__instance.timeSpend = 10000;
				}
				for (int i = 0; i < PluginConfig.beltMultiplier - 1; i++)
				{
					CallOriginalPilerUpdate(ref __instance, _traffic, _animPool);
					__instance.cacheCdTick = 0;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(FractionatorComponent), "InternalUpdate")]
		public static void Fractionator_InternalUpdate_Prefix(ref FractionatorComponent __instance, PlanetFactory factory)
		{
			if (!PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
			{
				return;
			}
			int beltMultiplier = PluginConfig.beltMultiplier;
			CargoTraffic cargoTraffic = factory.cargoTraffic;
			byte b = default(byte);
			byte b2 = default(byte);
			byte b3 = default(byte);
			byte b4 = default(byte);
			byte b5 = default(byte);
			byte b6 = default(byte);
			for (int i = 0; i < beltMultiplier - 1; i++)
			{
				if (__instance.fluidInputCount >= __instance.fluidInputMax)
				{
					break;
				}
				if (__instance.belt1 > 0 && !__instance.isOutput1)
				{
					if (__instance.fluidId > 0)
					{
						if (cargoTraffic.TryPickItemAtRear(__instance.belt1, __instance.fluidId, (int[])null, ref b, ref b2) > 0)
						{
							__instance.fluidInputCount += b;
							__instance.fluidInputInc += b2;
							__instance.fluidInputCargoCount += 1f;
						}
					}
					else
					{
						int num = cargoTraffic.TryPickItemAtRear(__instance.belt1, 0, RecipeProto.fractionatorNeeds, ref b3, ref b4);
						if (num > 0)
						{
							__instance.fluidInputCount += b3;
							__instance.fluidInputInc += b4;
							__instance.fluidInputCargoCount += 1f;
							((FractionatorComponent)(ref __instance)).SetRecipe(num, factory.entitySignPool);
						}
					}
				}
				if (__instance.belt2 > 0 && !__instance.isOutput2 && __instance.fluidInputCount < __instance.fluidInputMax && __instance.fluidId > 0 && cargoTraffic.TryPickItemAtRear(__instance.belt2, __instance.fluidId, (int[])null, ref b5, ref b6) > 0)
				{
					__instance.fluidInputCount += b5;
					__instance.fluidInputInc += b6;
					__instance.fluidInputCargoCount += 1f;
				}
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(FractionatorComponent), "InternalUpdate")]
		public static IEnumerable<CodeInstruction> Fractionator_InternalUpdate_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R8 && (double)list[i].operand == 30.0)
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = AccessTools.Method(typeof(BeltPatcher), "GetFractionatorLimit", (Type[])null, (Type[])null);
				}
				if (list[i].opcode == OpCodes.Ldc_I4_1 && i + 2 < list.Count && list[i + 1].opcode == OpCodes.Ldc_I4_0 && list[i + 2].opcode == OpCodes.Callvirt && list[i + 2].operand.ToString().Contains("TryInsertItemAtHead"))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = AccessTools.Method(typeof(BeltPatcher), "GetBeltMultiplier", (Type[])null, (Type[])null);
				}
				if (list[i].opcode == OpCodes.Ldc_I4_1 && i + 2 < list.Count && list[i + 2].opcode == OpCodes.Callvirt && list[i + 2].operand.ToString().Contains("TryUpdateItemAtHeadAndFillBlank"))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = AccessTools.Method(typeof(BeltPatcher), "GetBeltMultiplier", (Type[])null, (Type[])null);
				}
			}
			return list;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FractionatorComponent), "InternalUpdate")]
		public static void Fractionator_InternalUpdate_Postfix(ref FractionatorComponent __instance, PlanetFactory factory)
		{
			if (!PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
			{
				return;
			}
			CargoTraffic cargoTraffic = factory.cargoTraffic;
			int beltMultiplier = PluginConfig.beltMultiplier;
			for (int i = 0; i < beltMultiplier - 1; i++)
			{
				if (__instance.productOutputCount <= 0)
				{
					break;
				}
				if (__instance.belt0 <= 0)
				{
					break;
				}
				if (!__instance.isOutput0)
				{
					break;
				}
				if (!cargoTraffic.TryInsertItemAtHead(__instance.belt0, __instance.productId, (byte)1, (byte)0))
				{
					break;
				}
				__instance.productOutputCount--;
			}
			for (int j = 0; j < beltMultiplier - 1; j++)
			{
				if (__instance.fluidOutputCount <= 0)
				{
					break;
				}
				int num = ((__instance.belt1 > 0 && __instance.isOutput1) ? __instance.belt1 : ((__instance.belt2 > 0 && __instance.isOutput2) ? __instance.belt2 : 0));
				if (num != 0)
				{
					CargoPath cargoPath = cargoTraffic.GetCargoPath(cargoTraffic.beltPool[num].segPathId);
					if (cargoPath != null)
					{
						int num2 = __instance.fluidOutputInc / __instance.fluidOutputCount;
						if (cargoPath.TryUpdateItemAtHeadAndFillBlank(__instance.fluidId, 4, (byte)1, (byte)num2))
						{
							__instance.fluidOutputCount--;
							__instance.fluidOutputInc -= num2;
							continue;
						}
						break;
					}
					break;
				}
				break;
			}
		}

		public static double GetFractionatorLimit()
		{
			if (!PluginConfig.multiplierEnabled.Value)
			{
				return 30.0;
			}
			return (double)PluginConfig.beltMultiplier * 30.0;
		}

		public static int GetBeltMultiplier()
		{
			if (!PluginConfig.multiplierEnabled.Value)
			{
				return 1;
			}
			return PluginConfig.beltMultiplier;
		}

		public static void SyncBelts(PlanetFactory factory)
		{
			CargoTraffic cargoTraffic = factory.cargoTraffic;
			if (cargoTraffic == null)
			{
				return;
			}
			int beltMultiplier = PluginConfig.beltMultiplier;
			for (int i = 1; i < cargoTraffic.beltCursor; i++)
			{
				if (cargoTraffic.beltPool[i].id != i)
				{
					continue;
				}
				int entityId = cargoTraffic.beltPool[i].entityId;
				int protoId = factory.entityPool[entityId].protoId;
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId);
				if (val != null)
				{
					int num = val.prefabDesc.beltSpeed * beltMultiplier;
					if (num > 10)
					{
						num = 10;
					}
					cargoTraffic.beltPool[i].speed = num;
				}
			}
			for (int j = 1; j < cargoTraffic.pathCursor; j++)
			{
				CargoPath val2 = cargoTraffic.pathPool[j];
				if (val2 == null || val2.id != j || val2.chunks == null)
				{
					continue;
				}
				for (int k = 0; k < val2.chunkCount && k * 3 + 2 < val2.chunks.Length; k++)
				{
					int num2 = val2.chunks[k * 3];
					int num3 = 1;
					if (val2.belts != null)
					{
						int num4 = -1;
						foreach (int belt in val2.belts)
						{
							if (belt > 0 && belt < cargoTraffic.beltCursor)
							{
								ref BeltComponent reference = ref cargoTraffic.beltPool[belt];
								if (reference.id == belt && reference.segIndex <= num2 && reference.segIndex > num4)
								{
									num4 = reference.segIndex;
									num3 = reference.speed;
								}
							}
						}
					}
					val2.chunks[k * 3 + 2] = num3;
				}
			}
		}
	}
	public static class BuildingPatcher
	{
		private static readonly ConcurrentDictionary<int, int> _inserterDelayByProtoId = new ConcurrentDictionary<int, int>();

		[HarmonyPrefix]
		[HarmonyPatch(typeof(EjectorComponent), "InternalUpdate")]
		public static void Ejector_Prefix(ref EjectorComponent __instance, ref float power)
		{
			int ejectorMultiplier = PluginConfig.ejectorMultiplier;
			if (ejectorMultiplier > 1)
			{
				power *= ejectorMultiplier;
				int ejectorChargeFrame = ItemUtil.EjectorChargeFrame;
				if (ejectorChargeFrame > 0)
				{
					__instance.chargeSpend = ejectorChargeFrame * 10000 / ejectorMultiplier;
					__instance.coldSpend = ejectorChargeFrame * 10000 / ejectorMultiplier;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SiloComponent), "InternalUpdate")]
		public static void Silo_Prefix(ref SiloComponent __instance, ref float power)
		{
			int siloMultiplier = PluginConfig.siloMultiplier;
			if (siloMultiplier > 1)
			{
				power *= siloMultiplier;
				int siloChargeFrame = ItemUtil.SiloChargeFrame;
				if (siloChargeFrame > 0)
				{
					__instance.chargeSpend = siloChargeFrame * 10000 / siloMultiplier;
					__instance.coldSpend = siloChargeFrame * 10000 / siloMultiplier;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InserterComponent), "InternalUpdate")]
		[HarmonyPatch(typeof(InserterComponent), "InternalUpdateNoAnim")]
		[HarmonyPatch(typeof(InserterComponent), "InternalUpdate_Bidirectional")]
		public static void Inserter_InternalUpdate_Prefix(ref InserterComponent __instance, ref float power, PlanetFactory factory)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.id == 0 || __instance.entityId == 0)
			{
				return;
			}
			int inserterMultiplier = PluginConfig.inserterMultiplier;
			if (inserterMultiplier > 1)
			{
				power *= inserterMultiplier;
				int protoId = factory.entityPool[__instance.entityId].protoId;
				if (!_inserterDelayByProtoId.TryGetValue(protoId, out var value))
				{
					ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId);
					int num = (_inserterDelayByProtoId[protoId] = (val?.prefabDesc?.inserterDelay).GetValueOrDefault());
					value = num;
				}
				if (value > 0)
				{
					__instance.delay = value / inserterMultiplier;
				}
				if (!__instance.bidirectional && (int)__instance.stage == 0 && __instance.itemId > 0)
				{
					__instance.time += 10000 * (inserterMultiplier - 1);
				}
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(InserterComponent), "InternalUpdate_Bidirectional")]
		public static IEnumerable<CodeInstruction> Inserter_Bidirectional_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_I4_1 && i + 1 < list.Count && (list[i + 1].opcode == OpCodes.Stloc_0 || list[i + 1].opcode == OpCodes.Stloc_1 || list[i + 1].opcode == OpCodes.Stloc_2 || list[i + 1].opcode == OpCodes.Stloc_3))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = AccessTools.PropertyGetter(typeof(PluginConfig), "inserterMultiplier");
				}
			}
			return list;
		}
	}
	public static class FactorySystemPatcher
	{
		private static readonly ConcurrentDictionary<int, int> _baseSpeedByProtoId = new ConcurrentDictionary<int, int>();

		private static readonly ConcurrentDictionary<int, int> _labBaseSpeedByProtoId = new ConcurrentDictionary<int, int>();

		private static readonly ConcurrentDictionary<int, int> _minerBaseSpeedByProtoId = new ConcurrentDictionary<int, int>();

		public static void SyncAll(FactorySystem factorySystem)
		{
			SyncAssemblers(factorySystem);
			SyncLabs(factorySystem);
			SyncMiners(factorySystem);
		}

		public static void SyncMiners(FactorySystem factorySystem)
		{
			for (int i = 1; i < factorySystem.minerCursor; i++)
			{
				if (factorySystem.minerPool[i].id == i)
				{
					SyncMiner(ref factorySystem.minerPool[i], factorySystem.factory);
				}
			}
		}

		public static void SyncMiner(ref MinerComponent miner, PlanetFactory factory)
		{
			int protoId = factory.entityPool[miner.entityId].protoId;
			int value = PluginConfig.miningMultiplier.Value;
			if (!_minerBaseSpeedByProtoId.TryGetValue(protoId, out var value2))
			{
				value2 = 10000;
				_minerBaseSpeedByProtoId[protoId] = value2;
			}
			miner.speed = value * value2;
		}

		public static void SyncLabs(FactorySystem factorySystem)
		{
			for (int i = 1; i < factorySystem.labCursor; i++)
			{
				if (factorySystem.labPool[i].id == i)
				{
					SyncLab(ref factorySystem.labPool[i], factorySystem.factory);
				}
			}
		}

		public static void SyncLab(ref LabComponent lab, PlanetFactory factory)
		{
			int protoId = factory.entityPool[lab.entityId].protoId;
			int labMultiplier = PluginConfig.labMultiplier;
			if (!_labBaseSpeedByProtoId.TryGetValue(protoId, out var value))
			{
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId);
				int num = (_labBaseSpeedByProtoId[protoId] = (val?.prefabDesc?.labAssembleSpeed).GetValueOrDefault(10000));
				value = num;
			}
			if (lab.replicating && lab.speed > 0)
			{
				double num2 = (double)lab.speedOverride / (double)lab.speed;
				lab.speedOverride = (int)(num2 * (double)labMultiplier * (double)value);
			}
			lab.speed = labMultiplier * value;
		}

		public static void SyncAssemblers(FactorySystem factorySystem)
		{
			for (int i = 1; i < factorySystem.assemblerCursor; i++)
			{
				if (factorySystem.assemblerPool[i].id == i)
				{
					SyncAssembler(ref factorySystem.assemblerPool[i], factorySystem.factory);
				}
			}
		}

		public static void SyncAssembler(ref AssemblerComponent assembler, PlanetFactory factory)
		{
			//IL_0092: 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)
			int protoId = factory.entityPool[assembler.entityId].protoId;
			if (!_baseSpeedByProtoId.TryGetValue(protoId, out var value))
			{
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId);
				int num = (_baseSpeedByProtoId[protoId] = (val?.prefabDesc?.assemblerSpeed).GetValueOrDefault(10000));
				value = num;
			}
			int multiplierByRecipe = PluginConfig.GetMultiplierByRecipe((assembler.recipeId > 0) ? assembler.recipeType : ItemUtil.GetRecipeByProtoId(protoId));
			if (assembler.replicating && assembler.speed > 0)
			{
				double num2 = (double)assembler.speedOverride / (double)assembler.speed;
				assembler.speedOverride = (int)(num2 * (double)multiplierByRecipe * (double)value);
			}
			assembler.speed = multiplierByRecipe * value;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FactorySystem), "NewAssemblerComponent")]
		public static void NewAssemblerComponent_Postfix(FactorySystem __instance, int __result)
		{
			if (__result > 0)
			{
				SyncAssembler(ref __instance.assemblerPool[__result], __instance.factory);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FactorySystem), "NewLabComponent")]
		public static void NewLabComponent_Postfix(FactorySystem __instance, int __result)
		{
			if (__result > 0)
			{
				SyncLab(ref __instance.labPool[__result], __instance.factory);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FactorySystem), "NewMinerComponent")]
		public static void NewMinerComponent_Postfix(FactorySystem __instance, int __result)
		{
			if (__result > 0)
			{
				SyncMiner(ref __instance.minerPool[__result], __instance.factory);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LabComponent), "InternalUpdateResearch")]
		private static void MultiplyLabResearch(ref float research_speed)
		{
			if (PluginConfig.multiplierEnabled.Value && PluginConfig.labMultiplier > 1)
			{
				research_speed *= PluginConfig.labMultiplier;
			}
		}
	}
	public static class PowerConsumptionPatcher
	{
		public static void SyncPowerSystems(PowerSystem powerSystem)
		{
			for (int i = 1; i < powerSystem.consumerCursor; i++)
			{
				if (powerSystem.consumerPool[i].id == i)
				{
					SyncConsumer(ref powerSystem.consumerPool[i], powerSystem.factory);
				}
			}
		}

		public static void SyncConsumer(ref PowerConsumerComponent consumer, PlanetFactory factory)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			int entityId = consumer.entityId;
			if (entityId <= 0)
			{
				return;
			}
			ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select((int)factory.entityPool[entityId].protoId);
			if (val == null)
			{
				return;
			}
			PrefabDesc prefabDesc = val.prefabDesc;
			if ((int)val.Type != 5 && !prefabDesc.isStation && !prefabDesc.isPowerExchanger && ((Proto)val).ID != MultiplierPlugin.BattlefieldAnalysisBaseProtoId)
			{
				int num = 1;
				if (prefabDesc.isAssembler)
				{
					num = PluginConfig.GetMultiplierByRecipe(ItemUtil.GetRecipeByProtoId(((Proto)val).ID));
				}
				else if (prefabDesc.isLab)
				{
					num = PluginConfig.labMultiplier;
				}
				else if ((int)prefabDesc.minerType != 0)
				{
					num = PluginConfig.miningMultiplier.Value;
				}
				else if (prefabDesc.isTurret)
				{
					num = PluginConfig.turretMultiplier;
				}
				else if (prefabDesc.isSilo)
				{
					num = PluginConfig.siloMultiplier;
				}
				else if (prefabDesc.isFractionator)
				{
					num = PluginConfig.fractionatorMultiplier;
				}
				else if (prefabDesc.isEjector)
				{
					num = PluginConfig.ejectorMultiplier;
				}
				consumer.workEnergyPerTick = (long)(PluginConfig.drawMultiplier.Value * (double)num * (double)prefabDesc.workEnergyPerTick);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PowerSystem), "NewConsumerComponent")]
		public static void NewConsumerComponent_Postfix(PowerSystem __instance, int __result)
		{
			if (__result > 0)
			{
				SyncConsumer(ref __instance.consumerPool[__result], __instance.factory);
			}
		}
	}
	public static class PowerGenerationPatcher
	{
		public static void SyncGenerators(PowerSystem powerSystem)
		{
			for (int i = 1; i < powerSystem.genCursor; i++)
			{
				if (powerSystem.genPool[i].id == i)
				{
					SyncGenerator(ref powerSystem.genPool[i], powerSystem.factory);
				}
			}
			for (int j = 1; j < powerSystem.excCursor; j++)
			{
				if (powerSystem.excPool[j].id == j)
				{
					ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select((int)powerSystem.factory.entityPool[powerSystem.excPool[j].entityId].protoId);
					if (val != null)
					{
						powerSystem.excPool[j].energyPerTick = val.prefabDesc.exchangeEnergyPerTick * PluginConfig.genExchMultiplier;
					}
				}
			}
		}

		public static void SyncGenerator(ref PowerGeneratorComponent gen, PlanetFactory factory)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select((int)factory.entityPool[gen.entityId].protoId);
			if (val == null)
			{
				return;
			}
			if (gen.photovoltaic)
			{
				gen.genEnergyPerTick = val.prefabDesc.genEnergyPerTick * PluginConfig.genSolarMultiplier;
			}
			else if (gen.wind)
			{
				gen.genEnergyPerTick = val.prefabDesc.genEnergyPerTick * PluginConfig.genWindMultiplier;
			}
			else if (gen.geothermal)
			{
				gen.genEnergyPerTick = val.prefabDesc.genEnergyPerTick * PluginConfig.genGeoMultiplier;
			}
			else if (gen.gamma)
			{
				gen.genEnergyPerTick = val.prefabDesc.genEnergyPerTick * PluginConfig.gammaMultiplier.Value;
			}
			else if (IsFuelConsumer(gen))
			{
				int num = 1;
				if (((uint)gen.fuelMask & (true ? 1u : 0u)) != 0)
				{
					num = PluginConfig.genThermalMultiplier;
				}
				else if (((uint)gen.fuelMask & 2u) != 0)
				{
					num = PluginConfig.genFusionMultiplier;
				}
				else if (((uint)gen.fuelMask & 4u) != 0)
				{
					num = PluginConfig.genStarMultiplier;
				}
				gen.genEnergyPerTick = val.prefabDesc.genEnergyPerTick * num;
				gen.useFuelPerTick = val.prefabDesc.useFuelPerTick * num;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PowerSystem), "NewGeneratorComponent")]
		public static void NewGeneratorComponent_Postfix(PowerSystem __instance, int __result)
		{
			if (__result > 0)
			{
				SyncGenerator(ref __instance.genPool[__result], __instance.factory);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PowerSystem), "NewExchangerComponent")]
		public static void NewExchangerComponent_Postfix(PowerSystem __instance, int __result)
		{
			if (__result > 0)
			{
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select((int)__instance.factory.entityPool[__instance.excPool[__result].entityId].protoId);
				if (val != null)
				{
					__instance.excPool[__result].energyPerTick = val.prefabDesc.exchangeEnergyPerTick * PluginConfig.genExchMultiplier;
				}
			}
		}

		private static bool IsFuelConsumer(PowerGeneratorComponent gen)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			int[] array = ItemProto.fuelNeeds[gen.fuelMask];
			if (array != null)
			{
				return array.Length != 0;
			}
			return false;
		}
	}
	public static class StationPatcher
	{
		public static class MoreMegaStructureCompat
		{
			private static FastInvokeHandler _updateOutputSlotsHandler;

			private static FastInvokeHandler _updateInputSlotsHandler;

			private static bool _handlersInitialized;

			private static void InitHandlers(object instance)
			{
				if (!_handlersInitialized)
				{
					Type type = instance.GetType();
					MethodInfo method = type.GetMethod("UpdateOutputSlots");
					if (method != null)
					{
						_updateOutputSlotsHandler = MethodInvoker.GetHandler(method, false);
					}
					MethodInfo method2 = type.GetMethod("UpdateInputSlots");
					if (method2 != null)
					{
						_updateInputSlotsHandler = MethodInvoker.GetHandler(method2, false);
					}
					_handlersInitialized = true;
				}
			}

			[HarmonyPrefix]
			[HarmonyPatch("MoreMegaStructure.ExchangeStationComponent", "UpdateOutputSlots")]
			public static bool ExchangeStation_UpdateOutputSlots_Prefix(object __instance, CargoTraffic traffic, SignData[] signPool, int maxPilerCount, bool active)
			{
				if (_isLooping || !PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
				{
					return true;
				}
				_isLooping = true;
				InitHandlers(__instance);
				try
				{
					if (_updateOutputSlotsHandler != null)
					{
						object[] array = new object[4] { traffic, signPool, maxPilerCount, active };
						for (int i = 0; i < PluginConfig.beltMultiplier; i++)
						{
							_updateOutputSlotsHandler.Invoke(__instance, array);
						}
					}
				}
				finally
				{
					_isLooping = false;
				}
				return false;
			}

			[HarmonyPrefix]
			[HarmonyPatch("MoreMegaStructure.ExchangeStationComponent", "UpdateInputSlots")]
			public static bool ExchangeStation_UpdateInputSlots_Prefix(object __instance, CargoTraffic traffic, SignData[] signPool, int maxPilerCount, bool active)
			{
				if (_isLooping || !PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
				{
					return true;
				}
				_isLooping = true;
				InitHandlers(__instance);
				try
				{
					if (_updateInputSlotsHandler != null)
					{
						object[] array = new object[4] { traffic, signPool, maxPilerCount, active };
						for (int i = 0; i < PluginConfig.beltMultiplier; i++)
						{
							_updateInputSlotsHandler.Invoke(__instance, array);
						}
					}
				}
				finally
				{
					_isLooping = false;
				}
				return false;
			}

			[HarmonyTranspiler]
			[HarmonyPatch("MoreMegaStructure.ExchangeStationComponent", "UpdateOutputSlots")]
			[HarmonyPatch("MoreMegaStructure.ExchangeStationComponent", "UpdateInputSlots")]
			[HarmonyPatch("MoreMegaStructure.ExchangeStationComponent", "UpdateSlots")]
			public static IEnumerable<CodeInstruction> MoreMegaStructure_UpdateSlots_Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return StationComponent_UpdateSlots_Transpiler(instructions);
			}
		}

		[ThreadStatic]
		private static bool _isLooping;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StationComponent), "UpdateOutputSlots")]
		public static bool UpdateOutputSlots_Prefix(StationComponent __instance, CargoTraffic traffic, SignData[] signPool, int maxPilerCount, bool active)
		{
			if (_isLooping || !PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
			{
				return true;
			}
			_isLooping = true;
			try
			{
				int beltMultiplier = PluginConfig.beltMultiplier;
				for (int i = 0; i < beltMultiplier; i++)
				{
					__instance.UpdateOutputSlots(traffic, signPool, maxPilerCount, active);
				}
			}
			finally
			{
				_isLooping = false;
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StationComponent), "UpdateInputSlots")]
		public static void UpdateInputSlots_Postfix(StationComponent __instance, CargoTraffic traffic, SignData[] signPool, bool active)
		{
			if (_isLooping || !PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
			{
				return;
			}
			_isLooping = true;
			try
			{
				int beltMultiplier = PluginConfig.beltMultiplier;
				for (int i = 0; i < beltMultiplier - 1; i++)
				{
					__instance.UpdateInputSlots(traffic, signPool, active);
				}
			}
			finally
			{
				_isLooping = false;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(StationComponent), "UpdateOutputSlots")]
		[HarmonyPatch(typeof(StationComponent), "UpdateInputSlots")]
		public static IEnumerable<CodeInstruction> StationComponent_UpdateSlots_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_I4_1 && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Stfld && list[i + 1].operand.ToString().Contains("counter"))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = AccessTools.Method(typeof(StationPatcher), "GetSlotCounterValue", (Type[])null, (Type[])null);
				}
			}
			return list;
		}

		public static int GetSlotCounterValue()
		{
			if (!PluginConfig.multiplierEnabled.Value || PluginConfig.beltMultiplier <= 1)
			{
				return 1;
			}
			return 0;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StationComponent), "UpdateCollection")]
		public static void UpdateCollection_Prefix(StationComponent __instance, ref float collectSpeedRate)
		{
			if (!PluginConfig.multiplierEnabled.Value)
			{
				return;
			}
			float num = ((collectSpeedRate < 0f) ? 0f : collectSpeedRate);
			float num2 = PluginConfig.beltMultiplier;
			float num3 = num * num2;
			if (__instance.isCollector && __instance.collectionPerTick != null)
			{
				float num4 = 0f;
				for (int i = 0; i < __instance.collectionPerTick.Length; i++)
				{
					if (__instance.collectionPerTick[i] > num4)
					{
						num4 = __instance.collectionPerTick[i];
					}
				}
				if (num4 > 0.0001f)
				{
					float num5 = 1000f / num4;
					if (num3 > num5)
					{
						num3 = Math.Max(num, num5);
					}
				}
			}
			if (num3 > 1000000f)
			{
				num3 = 1000000f;
			}
			collectSpeedRate = num3;
		}
	}
	[HarmonyPatch(typeof(TurretComponent))]
	public static class TurretPatcher
	{
		[HarmonyPrefix]
		[HarmonyPatch("InternalUpdate")]
		[HarmonyPatch("Aim")]
		[HarmonyPatch("Shoot")]
		public static void Turret_Prefix(ref float power)
		{
			if (PluginConfig.multiplierEnabled.Value)
			{
				power *= PluginConfig.turretMultiplier;
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.Valoneu.FactoryOverclock";

		public const string PLUGIN_NAME = "FactoryOverclock";

		public const string PLUGIN_VERSION = "3.0.0";
	}
}