Decompiled source of BigBatch v0.2.1

plugins/Jarki-BigBatch/BigBatch.dll

Decompiled 6 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
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("BigBatch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyInformationalVersion("0.2.1+ee8ceb92e1cd92072b3d330a2ec1258da41d6c33")]
[assembly: AssemblyProduct("BigBatch")]
[assembly: AssemblyTitle("BigBatch")]
[assembly: AssemblyVersion("0.2.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BigBatch
{
	internal sealed class PendingLoad
	{
		internal const float Lifetime = 5f;

		private bool initialized;

		private long owner;

		private int observedOre;

		private float observedFuel;

		private int ore;

		private float fuel;

		private float oreDeadline;

		private float fuelDeadline;

		internal void Observe(long currentOwner, int actualOre, float actualFuel, float now)
		{
			if (!initialized || currentOwner != owner)
			{
				initialized = true;
				owner = currentOwner;
				ore = 0;
				fuel = 0f;
			}
			else
			{
				ore -= Math.Min(ore, Math.Max(0, actualOre - observedOre));
				fuel -= Math.Min(fuel, Math.Max(0f, actualFuel - observedFuel));
			}
			if (now >= oreDeadline)
			{
				ore = 0;
			}
			if (now >= fuelDeadline)
			{
				fuel = 0f;
			}
			observedOre = actualOre;
			observedFuel = actualFuel;
		}

		internal void SentOre(float now)
		{
			ore++;
			oreDeadline = now + 5f;
		}

		internal void SentFuel(float now)
		{
			fuel += 1f;
			fuelDeadline = now + 5f;
		}

		internal int PredictOre(int actual)
		{
			if (actual <= int.MaxValue - ore)
			{
				return actual + ore;
			}
			return int.MaxValue;
		}

		internal float PredictFuel(float actual)
		{
			return actual + fuel;
		}
	}
	[BepInPlugin("jarki.bigbatch", "BigBatch", "0.2.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private static int inputCapacity;

		private static int smelterInputCapacity;

		private static int fuelCapacity;

		private static readonly ConditionalWeakTable<ZNetView, PendingLoad> pending = new ConditionalWeakTable<ZNetView, PendingLoad>();

		[ThreadStatic]
		private static ZNetView loadingView;

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			inputCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Capacity", "InputCapacity", 100, new ConfigDescription("Minimum input capacity for non-coal processors, including charcoal kilns. Restart to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>())).Value;
			smelterInputCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Capacity", "SmelterInputCapacity", 50, new ConfigDescription("Minimum input capacity for coal-burning smelters and blast furnaces. Restart to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>())).Value;
			fuelCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Capacity", "FuelCapacity", 100, new ConfigDescription("Minimum fuel capacity for processors that use fuel. Restart to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>())).Value;
			new Harmony("jarki.bigbatch").PatchAll(typeof(Plugin));
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"BigBatch loaded: input {inputCapacity}, smelter input {smelterInputCapacity}, fuel {fuelCapacity}; pending-load prediction and owner-side overflow returns enabled.");
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Smelter), "Awake")]
		private static void ApplyCapacity(Smelter __instance)
		{
			if (__instance.m_maxOre > 0)
			{
				bool flag = Object.op_Implicit((Object)(object)__instance.m_fuelItem) && ((Object)((Component)__instance.m_fuelItem).gameObject).name == "Coal";
				__instance.m_maxOre = Math.Max(__instance.m_maxOre, flag ? smelterInputCapacity : inputCapacity);
			}
			if (__instance.m_maxFuel > 0)
			{
				__instance.m_maxFuel = Math.Max(__instance.m_maxFuel, fuelCapacity);
			}
		}

		private static ZNetView BeginLoading(ZNetView view)
		{
			ZNetView result = loadingView;
			loadingView = view;
			if (Object.op_Implicit((Object)(object)view) && view.IsOwner())
			{
				pending.Remove(view);
			}
			return result;
		}

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyPatch(typeof(Smelter), "OnAddOre")]
		private static void BeginOre(ZNetView ___m_nview, out ZNetView __state)
		{
			__state = BeginLoading(___m_nview);
		}

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
		private static void BeginFuel(ZNetView ___m_nview, out ZNetView __state)
		{
			__state = BeginLoading(___m_nview);
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(Smelter), "OnAddOre")]
		private static void EndOre(ZNetView __state)
		{
			loadingView = __state;
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
		private static void EndFuel(ZNetView __state)
		{
			loadingView = __state;
		}

		private static PendingLoad Observe(ZNetView view)
		{
			ZDO zDO = view.GetZDO();
			PendingLoad orCreateValue = pending.GetOrCreateValue(view);
			orCreateValue.Observe(zDO.GetOwner(), zDO.GetInt(ZDOVars.s_queued, 0), zDO.GetFloat(ZDOVars.s_fuel, 0f), Time.unscaledTime);
			return orCreateValue;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Smelter), "GetQueueSize")]
		private static void PredictOre(ZNetView ___m_nview, ref int __result)
		{
			if (loadingView == ___m_nview && Object.op_Implicit((Object)(object)___m_nview) && ___m_nview.IsValid() && !___m_nview.IsOwner())
			{
				__result = Observe(___m_nview).PredictOre(__result);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Smelter), "GetFuel")]
		private static void PredictFuel(ZNetView ___m_nview, ref float __result)
		{
			if (loadingView == ___m_nview && Object.op_Implicit((Object)(object)___m_nview) && ___m_nview.IsValid() && !___m_nview.IsOwner())
			{
				__result = Observe(___m_nview).PredictFuel(__result);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ZNetView), "InvokeRPC", new Type[]
		{
			typeof(string),
			typeof(object[])
		})]
		private static void TrackOutgoing(ZNetView __instance, string method)
		{
			if (loadingView == __instance && __instance.IsValid() && !__instance.IsOwner())
			{
				if (method == "RPC_AddOre")
				{
					Observe(__instance).SentOre(Time.unscaledTime);
				}
				else if (method == "RPC_AddFuel")
				{
					Observe(__instance).SentFuel(Time.unscaledTime);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(Smelter), "RPC_AddOre")]
		private static bool GuardOre(Smelter __instance, ZNetView ___m_nview, string name, bool cheated)
		{
			if (!Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsValid() || !___m_nview.IsOwner() || __instance.m_maxOre <= 0 || ___m_nview.GetZDO().GetInt(ZDOVars.s_queued, 0) < __instance.m_maxOre)
			{
				return true;
			}
			foreach (ItemConversion item in __instance.m_conversion)
			{
				if (Object.op_Implicit((Object)(object)item.m_from) && ((Object)((Component)item.m_from).gameObject).name == name)
				{
					ReturnItem(__instance, item.m_from, cheated);
					return false;
				}
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(Smelter), "RPC_AddFuel")]
		private static bool GuardFuel(Smelter __instance, ZNetView ___m_nview)
		{
			if (!Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsValid() || !___m_nview.IsOwner() || __instance.m_maxFuel <= 0 || !Object.op_Implicit((Object)(object)__instance.m_fuelItem) || ___m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) <= (float)(__instance.m_maxFuel - 1))
			{
				return true;
			}
			ReturnItem(__instance, __instance.m_fuelItem, cheated: false);
			return false;
		}

		private static void ReturnItem(Smelter machine, ItemDrop prefab, bool cheated)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			Transform val = (Object.op_Implicit((Object)(object)machine.m_outputPoint) ? machine.m_outputPoint : ((Component)machine).transform);
			ItemDrop component = Object.Instantiate<GameObject>(((Component)prefab).gameObject, val.position + Vector3.up * 0.5f, val.rotation).GetComponent<ItemDrop>();
			ItemDrop.OnCreateNew(component, cheated && !PlayerProfile.s_bypassCheatChecks);
			component.SetStack(1);
		}
	}
}