Decompiled source of Staurolite v1.0.1

Staurolite.dll

Decompiled 6 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Staurolite")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4b9345e2a16503d35124df4709a857e0b60801c5")]
[assembly: AssemblyProduct("Staurolite")]
[assembly: AssemblyTitle("Staurolite")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 Eirshy.DSP.Staurolite
{
	internal class Config
	{
		public static bool Spile { get; set; }

		public static bool SpileAlways4 { get; set; }

		public static void Load(ConfigFile cf)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			Spile = cf.Bind<bool>("Staurolite.Spiling", "Spile", false, new ConfigDescription("Whether splitters with boxes on top of them should pile their outputs when possible.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
			SpileAlways4 = cf.Bind<bool>("Staurolite.Spiling", "SpileAlways4", false, new ConfigDescription("If Spiling is enabled, whether we should always pile to 4 if possible.\nIf this option is disabled, we will use the Station Piling research level instead.", (AcceptableValueBase)null, Array.Empty<object>())).Value;
		}
	}
	[BepInPlugin("eirshy.dsp.Staurolite", "Staurolite", "1.0.0")]
	public class Staurolite : BaseUnityPlugin
	{
		public const string MODID = "Staurolite";

		public const string ROOT = "eirshy.dsp.";

		public const string GUID = "eirshy.dsp.Staurolite";

		public const string VERSION = "1.0.0";

		public const string NAME = "Staurolite";

		private static readonly Lazy<Harmony> _harmony = new Lazy<Harmony>((Func<Harmony>)(() => new Harmony("eirshy.dsp.Staurolite")));

		internal static Harmony Harmony => _harmony.Value;

		internal static ManualLogSource Logs { get; private set; }

		private void Awake()
		{
			Logs = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogMessage((object)"Staurolite injectors green, splitters primed!");
			Config.Load(((BaseUnityPlugin)this).Config);
			Harmony.PatchAll(typeof(StauroliteJet));
		}
	}
	internal class StauroliteJet
	{
		private struct Splinput
		{
			public int Splindex;

			public CargoPath Path;

			public int CargoID;

			public Cargo Cargo;

			public bool Picked;

			public Splinput(int splindex, CargoPath path, int cargoID, in Cargo cargo)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				Splindex = splindex;
				Path = path;
				CargoID = cargoID;
				Cargo = cargo;
				Picked = false;
			}
		}

		private struct Sploutput
		{
			public int Splindex;

			public CargoPath Path;

			public int Blank;

			public bool Picked;

			public Sploutput(int splindex, CargoPath path, int blank)
			{
				Splindex = splindex;
				Path = path;
				Blank = blank;
				Picked = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CargoTraffic), "SplitterGameTick")]
		private static void SplitterGameTick(long time, ref CargoTraffic __instance, ref bool __runOriginal)
		{
			if (!__runOriginal)
			{
				return;
			}
			__runOriginal = false;
			PerformanceMonitor.BeginSample((ECpuWorkEntry)11);
			Splinput[] splins = new Splinput[4];
			int num = 0;
			Sploutput[] splouts = new Sploutput[4];
			int num2 = 0;
			bool flag = false;
			int piling = ((!Config.Spile) ? 1 : (Config.SpileAlways4 ? 4 : GameMain.history.stationPilerLevel));
			int[] array = new int[4];
			_ = new int[4];
			bool[] array2 = new bool[4];
			int splitterCursor = __instance.splitterCursor;
			while (splitterCursor-- > 1)
			{
				ref SplitterComponent reference = ref __instance.splitterPool[splitterCursor];
				if (reference.id != splitterCursor)
				{
					continue;
				}
				((SplitterComponent)(ref reference)).CheckPriorityPreset();
				int num3 = ((reference.input0 > 0) ? ((reference.input1 <= 0) ? 1 : ((reference.input2 <= 0) ? 2 : ((reference.input3 <= 0) ? 3 : 4))) : 0);
				int num4 = ((reference.output0 > 0) ? ((reference.output1 <= 0) ? 1 : ((reference.output2 <= 0) ? 2 : ((reference.output3 <= 0) ? 3 : 4))) : 0);
				bool flag2 = reference.topId != 0;
				if ((num3 | num4) == 0 || (!flag2 && (num3 == 0 || num4 == 0)))
				{
					continue;
				}
				num = 0;
				switch (num3)
				{
				case 4:
				{
					int splindex = 3;
					_spltr_loadRear_inline(in splindex, in reference.input3, in splins, in __instance, ref num);
					goto case 3;
				}
				case 3:
				{
					int splindex = 2;
					_spltr_loadRear_inline(in splindex, in reference.input2, in splins, in __instance, ref num);
					goto case 2;
				}
				case 2:
				{
					int splindex = 1;
					_spltr_loadRear_inline(in splindex, in reference.input1, in splins, in __instance, ref num);
					goto case 1;
				}
				case 1:
				{
					int splindex = 0;
					_spltr_loadRear_inline(in splindex, in reference.input0, in splins, in __instance, ref num);
					break;
				}
				}
				if (!flag2 && num == 0)
				{
					continue;
				}
				num2 = 0;
				switch (num4)
				{
				case 4:
				{
					int splindex = 3;
					_spltr_loadBlank_inline(in splindex, in reference.output3, in splouts, in __instance, ref num2);
					goto case 3;
				}
				case 3:
				{
					int splindex = 2;
					_spltr_loadBlank_inline(in splindex, in reference.output2, in splouts, in __instance, ref num2);
					goto case 2;
				}
				case 2:
				{
					int splindex = 1;
					_spltr_loadBlank_inline(in splindex, in reference.output1, in splouts, in __instance, ref num2);
					goto case 1;
				}
				case 1:
				{
					int splindex = 0;
					flag = _spltr_loadBlank_inline(in splindex, in reference.output0, in splouts, in __instance, ref num2);
					break;
				}
				}
				if (flag && reference.outFilter <= 0)
				{
					flag = false;
				}
				bool cycleInputs = false;
				bool cycleOutputs = false;
				if (!flag2)
				{
					if (num2 == 0)
					{
						continue;
					}
					int num5 = num2 - 1;
					ref Sploutput reference2 = ref splouts[num5];
					if (flag)
					{
						switch (num)
						{
						case 3:
						{
							ref Splinput reference3 = ref splins[2];
							if (reference3.Cargo.item == reference.outFilter)
							{
								_spltr_moveCargo_inline(ref reference3, ref reference2);
								cycleInputs = true;
								break;
							}
							goto case 2;
						}
						case 2:
						{
							ref Splinput reference5 = ref splins[1];
							if (reference5.Cargo.item == reference.outFilter)
							{
								_spltr_moveCargo_inline(ref reference5, ref reference2);
								cycleInputs = true;
								break;
							}
							goto case 1;
						}
						case 1:
						{
							ref Splinput reference4 = ref splins[0];
							if (reference4.Cargo.item == reference.outFilter)
							{
								_spltr_moveCargo_inline(ref reference4, ref reference2);
								cycleInputs = true;
							}
							break;
						}
						}
						if (num5 > 0)
						{
							reference2 = ref splouts[--num5];
						}
						else
						{
							reference2.Picked = true;
						}
					}
					if (!reference2.Picked)
					{
						switch (num)
						{
						case 3:
						{
							ref Splinput reference6 = ref splins[2];
							if (!reference6.Picked)
							{
								_spltr_moveCargo_inline(ref reference6, ref reference2);
								cycleInputs = true;
								cycleOutputs = true;
								if (num5 <= 0)
								{
									break;
								}
								reference2 = ref splouts[--num5];
							}
							goto case 2;
						}
						case 2:
						{
							ref Splinput reference7 = ref splins[1];
							if (!reference7.Picked)
							{
								_spltr_moveCargo_inline(ref reference7, ref reference2);
								cycleInputs = true;
								cycleOutputs = true;
								if (num5 <= 0)
								{
									break;
								}
								reference2 = ref splouts[--num5];
							}
							goto case 1;
						}
						case 1:
						{
							ref Splinput reference8 = ref splins[0];
							if (!reference8.Picked)
							{
								_spltr_moveCargo_inline(ref reference8, ref reference2);
								cycleInputs = true;
								cycleOutputs = true;
							}
							break;
						}
						}
					}
				}
				else
				{
					switch (num)
					{
					case 4:
						_spltr_buffered_inline(in reference, ref splins[3], in __instance, ref cycleInputs);
						goto case 3;
					case 3:
						_spltr_buffered_inline(in reference, ref splins[2], in __instance, ref cycleInputs);
						goto case 2;
					case 2:
						_spltr_buffered_inline(in reference, ref splins[1], in __instance, ref cycleInputs);
						goto case 1;
					case 1:
						_spltr_buffered_inline(in reference, ref splins[0], in __instance, ref cycleInputs);
						break;
					}
					int num6 = num2;
					if (flag)
					{
						int filter = reference.outFilter;
						ref Sploutput splout = ref splouts[--num6];
						bool cycleOutputs2 = false;
						_spltr_buffered_inline(in reference, ref splout, ref filter, in piling, in __instance, ref cycleOutputs2);
					}
					switch (num6)
					{
					case 4:
					{
						int filter = -reference.outFilter;
						if (!_spltr_buffered_inline(in reference, ref splouts[3], ref filter, in piling, in __instance, ref cycleOutputs))
						{
							break;
						}
						goto case 3;
					}
					case 3:
					{
						int filter = -reference.outFilter;
						if (!_spltr_buffered_inline(in reference, ref splouts[2], ref filter, in piling, in __instance, ref cycleOutputs))
						{
							break;
						}
						goto case 2;
					}
					case 2:
					{
						int filter = -reference.outFilter;
						if (!_spltr_buffered_inline(in reference, ref splouts[1], ref filter, in piling, in __instance, ref cycleOutputs))
						{
							break;
						}
						goto case 1;
					}
					case 1:
					{
						int filter = -reference.outFilter;
						_spltr_buffered_inline(in reference, ref splouts[0], ref filter, in piling, in __instance, ref cycleOutputs);
						break;
					}
					}
				}
				if (cycleInputs)
				{
					int num7 = 0;
					int num8 = 0;
					int num9 = 0;
					Array.Clear(array2, 0, 4);
					switch (num)
					{
					case 4:
					{
						ref Splinput reference9 = ref splins[3];
						if (reference9.Picked)
						{
							num8++;
							if (!reference.inPriority || reference9.Splindex != 0)
							{
								array2[reference9.Splindex] = true;
								num9++;
							}
						}
						goto case 3;
					}
					case 3:
					{
						ref Splinput reference10 = ref splins[2];
						if (reference10.Picked)
						{
							num8++;
							if (!reference.inPriority || reference10.Splindex != 0)
							{
								array2[reference10.Splindex] = true;
								num9++;
							}
						}
						goto case 2;
					}
					case 2:
					{
						ref Splinput reference12 = ref splins[1];
						if (reference12.Picked)
						{
							num8++;
							if (!reference.inPriority || reference12.Splindex != 0)
							{
								array2[reference12.Splindex] = true;
								num9++;
							}
						}
						goto case 1;
					}
					case 1:
					{
						ref Splinput reference11 = ref splins[0];
						if (reference11.Picked)
						{
							num8++;
							if (!reference.inPriority || reference11.Splindex != 0)
							{
								array2[reference11.Splindex] = true;
								num9++;
							}
						}
						break;
					}
					}
					if (num9 > 0 && num8 <= num3)
					{
						int num10 = num3 - num9 - 1;
						switch (num3)
						{
						case 4:
							if (!array2[3])
							{
								array[num10 - num7++] = reference.input3;
							}
							goto case 3;
						case 3:
							if (!array2[2])
							{
								array[num10 - num7++] = reference.input2;
							}
							goto case 2;
						case 2:
							if (!array2[1])
							{
								array[num10 - num7++] = reference.input1;
							}
							goto case 1;
						case 1:
							if (!array2[0])
							{
								array[num10 - num7++] = reference.input0;
							}
							break;
						}
						switch (num3)
						{
						case 4:
							if (array2[3])
							{
								array[num7++] = reference.input3;
							}
							goto case 3;
						case 3:
							if (array2[2])
							{
								array[num7++] = reference.input2;
							}
							goto case 2;
						case 2:
							if (array2[1])
							{
								array[num7++] = reference.input1;
							}
							goto case 1;
						case 1:
							if (array2[0])
							{
								array[num7++] = reference.input0;
							}
							break;
						}
						switch (num7)
						{
						case 4:
							reference.input3 = array[3];
							goto case 3;
						case 3:
							reference.input2 = array[2];
							goto case 2;
						case 2:
							reference.input1 = array[1];
							goto case 1;
						case 1:
							reference.input0 = array[0];
							break;
						}
					}
				}
				if (!cycleOutputs)
				{
					continue;
				}
				int num11 = 0;
				int num12 = 0;
				int num13 = 0;
				Array.Clear(array2, 0, 4);
				switch (num2)
				{
				case 4:
				{
					ref Sploutput reference13 = ref splouts[3];
					if (reference13.Picked)
					{
						num12++;
						if (!reference.outPriority || reference13.Splindex != 0)
						{
							array2[reference13.Splindex] = true;
							num13++;
						}
					}
					goto case 3;
				}
				case 3:
				{
					ref Sploutput reference14 = ref splouts[2];
					if (reference14.Picked)
					{
						num12++;
						if (!reference.outPriority || reference14.Splindex != 0)
						{
							array2[reference14.Splindex] = true;
							num13++;
						}
					}
					goto case 2;
				}
				case 2:
				{
					ref Sploutput reference16 = ref splouts[1];
					if (reference16.Picked)
					{
						num12++;
						if (!reference.outPriority || reference16.Splindex != 0)
						{
							array2[reference16.Splindex] = true;
							num13++;
						}
					}
					goto case 1;
				}
				case 1:
				{
					ref Sploutput reference15 = ref splouts[0];
					if (reference15.Picked)
					{
						num12++;
						if (!reference.outPriority || reference15.Splindex != 0)
						{
							array2[reference15.Splindex] = true;
							num13++;
						}
					}
					break;
				}
				}
				if (num13 <= 0 || num12 > num4)
				{
					continue;
				}
				int num14 = num4 - num13 - 1;
				switch (num4)
				{
				case 4:
					if (!array2[3])
					{
						array[num14 - num11++] = reference.output3;
					}
					goto case 3;
				case 3:
					if (!array2[2])
					{
						array[num14 - num11++] = reference.output2;
					}
					goto case 2;
				case 2:
					if (!array2[1])
					{
						array[num14 - num11++] = reference.output1;
					}
					goto case 1;
				case 1:
					if (!array2[0])
					{
						array[num14 - num11++] = reference.output0;
					}
					break;
				}
				switch (num4)
				{
				case 4:
					if (array2[3])
					{
						array[num11++] = reference.output3;
					}
					goto case 3;
				case 3:
					if (array2[2])
					{
						array[num11++] = reference.output2;
					}
					goto case 2;
				case 2:
					if (array2[1])
					{
						array[num11++] = reference.output1;
					}
					goto case 1;
				case 1:
					if (array2[0])
					{
						array[num11++] = reference.output0;
					}
					break;
				}
				switch (num11)
				{
				case 4:
					reference.output3 = array[3];
					goto case 3;
				case 3:
					reference.output2 = array[2];
					goto case 2;
				case 2:
					reference.output1 = array[1];
					break;
				case 1:
					break;
				default:
					continue;
				}
				reference.output0 = array[0];
			}
			PerformanceMonitor.EndSample((ECpuWorkEntry)11);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static void _spltr_loadRear_inline(in int splindex, in int pathID, in Splinput[] splins, in CargoTraffic traffic, ref int tail)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			CargoPath cargoPath = traffic.GetCargoPath(traffic.beltPool[pathID].segPathId);
			int cargoIdAtRear = cargoPath.GetCargoIdAtRear();
			if (cargoIdAtRear != -1)
			{
				ref Splinput reference = ref splins[tail];
				reference.Splindex = splindex;
				reference.Path = cargoPath;
				reference.CargoID = cargoIdAtRear;
				reference.Cargo = traffic.container.cargoPool[cargoIdAtRear];
				reference.Picked = false;
				tail++;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool _spltr_loadBlank_inline(in int splindex, in int pathID, in Sploutput[] splouts, in CargoTraffic traffic, ref int tail)
		{
			CargoPath cargoPath = traffic.GetCargoPath(traffic.beltPool[pathID].segPathId);
			int num = cargoPath.TestBlankAtHead();
			if (cargoPath.pathLength > 10 && num >= 0)
			{
				ref Sploutput reference = ref splouts[tail];
				reference.Splindex = splindex;
				reference.Path = cargoPath;
				reference.Blank = num;
				reference.Picked = false;
				tail++;
				return true;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static void _spltr_moveCargo_inline(ref Splinput splin, ref Sploutput splout)
		{
			int num = splin.Path.TryPickCargoAtEnd();
			splout.Path.InsertCargoAtHeadDirect(num, splout.Blank);
			splin.Picked = true;
			splout.Picked = true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static void _spltr_buffered_inline(in SplitterComponent sp, ref Splinput splin, in CargoTraffic traffic, ref bool cycleInputs)
		{
			if (traffic.factory.InsertCargoIntoStorage(sp.topId, ref traffic.container.cargoPool[splin.CargoID], true))
			{
				int num = splin.Path.TryPickCargoAtEnd();
				traffic.container.RemoveCargo(num);
				splin.Picked = true;
				cycleInputs = true;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool _spltr_buffered_inline(in SplitterComponent sp, ref Sploutput splout, ref int filter, in int piling, in CargoTraffic traffic, ref bool cycleOutputs)
		{
			int num = default(int);
			int num2 = traffic.factory.PickFromStorageFiltered(sp.topId, ref filter, piling, ref num);
			if (num2 <= 0)
			{
				return false;
			}
			int num3 = traffic.container.AddCargo((short)filter, (byte)num2, (byte)num);
			splout.Path.InsertCargoAtHeadDirect(num3, splout.Blank);
			splout.Picked = true;
			cycleOutputs = true;
			return true;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Staurolite";

		public const string PLUGIN_NAME = "Staurolite";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}