Decompiled source of InPlaceUpgrade v0.1.0

InPlaceUpgrade.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Rewired;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InPlaceUpgrade")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BeltUpgrade")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("64443039-edc2-4adb-8193-a459b7477663")]
[assembly: AssemblyFileVersion("0.0.4.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.4.0")]
namespace InPlaceUpgrade;

[BepInPlugin("inplaceupgrade.nhickling.co.uk", "InPlaceUpgrade", "0.1.0")]
public class InPlaceUpgrade : BaseUnityPlugin
{
	private class ModSystemMessage : SystemMessageInfo
	{
		public override MessageType type => (MessageType)5;

		public ModSystemMessage(string message)
			: base(message)
		{
		}
	}

	private class PendingBuildRequest
	{
		public BuildMachineAction BuildAction { get; set; }

		public GridInfo BuildGrid { get; set; }

		public int BuildAttempts { get; set; } = 5;

	}

	private const int TicksBetweenBuilds = 5;

	public const string pluginGuid = "inplaceupgrade.nhickling.co.uk";

	public const string pluginName = "InPlaceUpgrade";

	public const string pluginShort = "IPU";

	public const string pluginVersion = "0.1.0";

	public static ConfigEntry<bool> UseAggressiveBeltFinder;

	public static ConfigEntry<bool> EnableLogging;

	public static ConfigEntry<bool> EnableSameBeltTriggering;

	public static bool loggingEnabled;

	public static ConfigEntry<int> TraverseLimit;

	public static ConfigEntry<int> ReplaceCount;

	private Stopwatch heavyLoggingTimer = Stopwatch.StartNew();

	private static ManualLogSource modLogger;

	private static GameObject hostObject;

	private int capturedBuildMask = 2097512;

	private Player playerReference;

	private int ticksTillNextbuild = 2;

	private Queue<PendingBuildRequest> queuedBuildActions = new Queue<PendingBuildRequest>();

	private float raycastRange = 15f;

	private int notificationCycle = 50;

	private int notificationTimer = 50;

	public void Awake()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected O, but got Unknown
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Expected O, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Expected O, but got Unknown
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Expected O, but got Unknown
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Expected O, but got Unknown
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Expected O, but got Unknown
		modLogger = ((BaseUnityPlugin)this).Logger;
		modLogger.LogInfo((object)"Moved to persistant scene");
		((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
		modLogger.LogInfo((object)"Started DevBuild 4");
		UseAggressiveBeltFinder = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Aggressive", false, new ConfigDescription("Search for belts indirectly.", (AcceptableValueBase)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		EnableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Logging", false, new ConfigDescription("Enable disagnostic logging. Can cause lag. (Value is ONLY loaded at startup, changes after WILL be ignored for performance reasons)", (AcceptableValueBase)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		EnableSameBeltTriggering = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSameBeltTriggering", true, new ConfigDescription("Enable starting an in-place-upgrade of belts when looking at the same type of belt.", (AcceptableValueBase)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		loggingEnabled = EnableLogging.Value;
		ReplaceCount = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "ReplaceCount", 50, new ConfigDescription("How many belts is the mod allowed to replace at once. High values can cause a stutter when starting replacement.", (AcceptableValueBase)new AcceptableValueRange<int>(25, 100), Array.Empty<object>()));
		TraverseLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "TraverseLimit", 50, new ConfigDescription("How many belts is the mod allowed to scan at once. (Used when Aggresive ssearch is enabled)", (AcceptableValueBase)new AcceptableValueRange<int>(25, 100), Array.Empty<object>()));
		modLogger.LogInfo((object)$"Loaded settings from config. Aggressive:{UseAggressiveBeltFinder.Value}. Logging {EnableLogging.Value}. Depth {TraverseLimit.Value}. Count {ReplaceCount.Value}");
	}

	public void FixedUpdate()
	{
		if (notificationTimer > 0)
		{
			notificationTimer--;
		}
		if (playerReference != null)
		{
			DoGameLoop();
			return;
		}
		try
		{
			if (ReInput.isReady && playerReference == null)
			{
				playerReference = ReInput.players.GetPlayer(0);
				TryDetailLog("Attached to player controllers");
			}
		}
		catch
		{
			if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
			{
				TryDetailLog("Waiting for ReInput.");
				heavyLoggingTimer.Restart();
			}
		}
	}

	private void DoGameLoop()
	{
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Invalid comparison between Unknown and I4
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_044b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Unknown result type (might be due to invalid IL or missing references)
		//IL_0456: Unknown result type (might be due to invalid IL or missing references)
		//IL_0468: Expected O, but got Unknown
		//IL_046d: Expected O, but got Unknown
		GridManager val = null;
		Player val2 = null;
		try
		{
			val = GridManager.instance;
			val2 = Player.instance;
		}
		catch (Exception)
		{
			if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
			{
				TryDetailLog("Error getting manager instances");
				heavyLoggingTimer.Restart();
			}
		}
		if ((Object)(object)val2 == (Object)null || (Object)(object)val == (Object)null)
		{
			if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
			{
				TryDetailLog("Waiting for manager instances.");
				heavyLoggingTimer.Restart();
			}
		}
		else if (queuedBuildActions.Count > 0)
		{
			if (--ticksTillNextbuild == 0)
			{
				ticksTillNextbuild = 5;
				PendingBuildRequest pendingBuildRequest = queuedBuildActions.Peek();
				TryDetailLog(" Sending build event");
				if (val.CheckBuildableIncludingVoxelsAt(pendingBuildRequest.BuildGrid))
				{
					TryDetailLog(" Sending build event");
					pendingBuildRequest = queuedBuildActions.Dequeue();
					NetworkMessageRelay.instance.SendNetworkAction((NetworkAction)(object)pendingBuildRequest.BuildAction);
				}
				else
				{
					ticksTillNextbuild = 5;
					TryShowNotification("IPU: Rebuild is currently blocked, skipping for now");
					PendingBuildRequest pendingBuildRequest2 = pendingBuildRequest;
					int buildAttempts = pendingBuildRequest2.BuildAttempts - 1;
					pendingBuildRequest2.BuildAttempts = buildAttempts;
					if (pendingBuildRequest.BuildAttempts == 0)
					{
						queuedBuildActions.Dequeue();
						queuedBuildActions.Enqueue(new PendingBuildRequest
						{
							BuildAction = pendingBuildRequest.BuildAction,
							BuildGrid = pendingBuildRequest.BuildGrid
						});
					}
				}
			}
			if (playerReference.GetButton(109))
			{
				TryShowNotification("IPU: Rebuild is currently busy!");
				if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
				{
					TryDetailLog("Input recieved while busy.");
					heavyLoggingTimer.Restart();
				}
			}
		}
		else
		{
			if (!playerReference.GetButton(109))
			{
				return;
			}
			TryDetailLog(" Input captured");
			if (!((Object)(object)val2 != (Object)null))
			{
				return;
			}
			Vector3 forward = ((Component)val2.cam).transform.forward;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(((Component)val2.cam).transform.position, forward, ref val3, raycastRange, capturedBuildMask, (QueryTriggerInteraction)1))
			{
				TryDetailLog(" Raycast hit!");
				Vector3Int voxel = FHG_Utils.GetVoxel(((RaycastHit)(ref val3)).point);
				GenericMachineInstanceRef val4 = default(GenericMachineInstanceRef);
				val.TryGetMachine(ref voxel, ref val4);
				MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref val4)).typeIndex;
				TryDetailLog(" Raycast found machine of type " + ((object)(MachineTypeEnum)(ref typeIndex)).ToString());
				if (!CanReplace(val4))
				{
					return;
				}
				TryDetailLog(" Machine is replacable.");
				if (!val2.toolbar.selectedInfo.buildable)
				{
					return;
				}
				BuilderInfo selectedBuildableInfo = val2.toolbar.selectedBuildableInfo;
				if (selectedBuildableInfo.GetInstanceType() != ((GenericMachineInstanceRef)(ref val4)).typeIndex)
				{
					return;
				}
				bool flag = ((UniqueIdScriptableObject)selectedBuildableInfo).uniqueId != ((GenericMachineInstanceRef)(ref val4)).ResId;
				bool flag2 = EnableSameBeltTriggering.Value && (int)((GenericMachineInstanceRef)(ref val4)).typeIndex == 4;
				TryDetailLog($" Matching item type, checking for item difference. {flag}/{flag2}");
				if (flag || flag2)
				{
					ResourceInfo selectedInfo = val2.toolbar.selectedInfo;
					int resourceCount = ((InventoryWrapper)val2.inventory).GetResourceCount(((UniqueIdScriptableObject)selectedInfo).uniqueId, false);
					List<GenericMachineInstanceRef> replacableItems = GetReplacableItems(val4, selectedBuildableInfo);
					TryDetailLog($" Need to replace {replacableItems.Count} items.");
					TryDetailLog($" Found {resourceCount} items in inventory.");
					if (replacableItems.Count == 0)
					{
						TryShowNotification("IPU: Nothing to replace found.");
					}
					else if (replacableItems.Count <= resourceCount)
					{
						TryDetailLog(" Found enough items");
						TryShowNotification(string.Format("{0}: Replacing {1} items.", "IPU", replacableItems.Count));
						List<uint> list = new List<uint>();
						foreach (GenericMachineInstanceRef item in replacableItems)
						{
							GenericMachineInstanceRef current = item;
							list.Add(((GenericMachineInstanceRef)(ref current)).instanceId);
						}
						List<PendingBuildRequest> rebuildAction = GetRebuildAction(val4, ((UniqueIdScriptableObject)selectedBuildableInfo).uniqueId, replacableItems);
						if (rebuildAction.Count <= 1 || replacableItems.Count * 2 < resourceCount)
						{
							TryDetailLog(" Sending deconstruction");
							notificationTimer = notificationCycle;
							NetworkMessageRelay.instance.SendNetworkAction((NetworkAction)new EraseMachineAction
							{
								info = new EraseMachineInfo
								{
									machineIDs = list.ToArray()
								}
							});
							TryDetailLog(" Queing construction");
							{
								foreach (PendingBuildRequest item2 in rebuildAction)
								{
									queuedBuildActions.Enqueue(item2);
								}
								return;
							}
						}
						TryShowNotification(string.Format("{0}: Rebuild protection. More items needed. ({1} of {2})", "IPU", resourceCount, replacableItems.Count * 2));
					}
					else
					{
						TryDetailLog(" Not enough items.");
						TryShowNotification(string.Format("{0}: Not enough items ({1} of {2})", "IPU", resourceCount, replacableItems.Count));
					}
				}
				else
				{
					TryDetailLog(" Can't self replace.");
					TryShowNotification("IPU: Can't replace with the same type.");
				}
			}
			else
			{
				TryDetailLog(" Raycast did not hit anything");
			}
		}
	}

	internal static void TryDetailLog(string log)
	{
		if (loggingEnabled)
		{
			modLogger.LogInfo((object)("InPlaceUpgrade: " + log));
		}
	}

	private void TryShowNotification(string message)
	{
		if (notificationTimer == 0)
		{
			SystemLogUI systemLog = UIManager.instance.systemLog;
			ModSystemMessage modSystemMessage = new ModSystemMessage(message);
			systemLog.FlashMessage((SystemMessageInfo)(object)modSystemMessage);
			notificationTimer = notificationCycle;
		}
	}

	private List<PendingBuildRequest> GetRebuildAction(GenericMachineInstanceRef sourceMachine, int selectedItem, List<GenericMachineInstanceRef> toReplace)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//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_0032: Expected I4, but got Unknown
		//IL_003d: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Invalid comparison between Unknown and I4
		List<PendingBuildRequest> result = new List<PendingBuildRequest>();
		MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref sourceMachine)).typeIndex;
		switch (typeIndex - 1)
		{
		default:
			if ((int)typeIndex != 16 && (int)typeIndex != 19)
			{
				break;
			}
			goto case 0;
		case 0:
		case 4:
		case 6:
			AppendSimpleBuildAction(sourceMachine, selectedItem, ref result);
			break;
		case 3:
			AppendConveyorBuildAction(((GenericMachineInstanceRef)(ref sourceMachine)).typeIndex, selectedItem, ref result, toReplace);
			break;
		case 1:
		case 2:
		case 5:
			break;
		}
		return result;
	}

	private void AppendConveyorBuildAction(MachineTypeEnum machineType, int selectedItem, ref List<PendingBuildRequest> result, List<GenericMachineInstanceRef> toReplace)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Invalid comparison between Unknown and I4
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Expected O, but got Unknown
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Expected O, but got Unknown
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		TryDetailLog(" Building conveyor replaceaction");
		List<ChainData> list = new List<ChainData>();
		ConveyorMachineList val = (ConveyorMachineList)FactorySimManager.instance.machineManager.GetMachineList<ConveyorInstance, ConveyorDefinition>((MachineTypeEnum)4);
		TryDetailLog($" Got machineList: {val == null}");
		bool flag = false;
		foreach (GenericMachineInstanceRef item in toReplace)
		{
			GenericMachineInstanceRef current = item;
			TryDetailLog(" Adding conveyor segment");
			ConveyorInstance val2 = ((MachineInstanceList<ConveyorInstance, ConveyorDefinition>)(object)val).myArray[((GenericMachineInstanceRef)(ref current)).index];
			flag = val2.buildBackwards;
			Vector3Int voxel = FHG_Utils.GetVoxel(((GridInfo)(ref ((GenericMachineInstanceRef)(ref current)).MyGridInfo)).Center);
			if ((int)val2.beltShape == 3 || (int)val2.beltShape == 4)
			{
				((Vector3Int)(ref voxel)).y = ((Vector3Int)(ref voxel)).y - 1;
			}
			list.Add(new ChainData
			{
				count = 1,
				shape = val2.beltShape,
				rotation = val2.gridInfo.yawRot,
				start = voxel
			});
			ConveyorBuildInfo val3 = new ConveyorBuildInfo();
			((NetworkBuildInfo)val3).machineType = selectedItem;
			val3.chainData = list;
			val3.isReversed = flag;
			((MultiBuildInfo)val3).machineIds = new List<uint>();
			((NetworkActionInfo)val3).tick = ((NetworkActionInfo)val3).tick + 5;
			ConveyorBuildAction val4 = new ConveyorBuildAction();
			val4.info = (ConveyorBuildInfo)((NetworkBuildInfo)val3).Clone();
			((BuildMachineAction)val4).resourceCostAmount = val3.chainData.Count;
			((BuildMachineAction)val4).resourceCostID = selectedItem;
			result.Add(new PendingBuildRequest
			{
				BuildAction = (BuildMachineAction)(object)val4,
				BuildGrid = ((GenericMachineInstanceRef)(ref current)).MyGridInfo
			});
		}
		TryDetailLog(" Finalising action");
	}

	private void AppendSimpleBuildAction(GenericMachineInstanceRef machineRef, int selectedItem, ref List<PendingBuildRequest> result)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_005c: 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)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		TryDetailLog(" Building simple replace action");
		FactorySimManager instance = FactorySimManager.instance;
		TryDetailLog($" Got factory reference: {(Object)(object)instance == (Object)null}");
		TryDetailLog(" Adding conveyor segment");
		SimpleBuildInfo val = new SimpleBuildInfo();
		((NetworkBuildInfo)val).machineType = selectedItem;
		val.rotation = ((GridInfo)(ref ((GenericMachineInstanceRef)(ref machineRef)).MyGridInfo)).YawRotation;
		val.minGridPos = ((GenericMachineInstanceRef)(ref machineRef)).MyGridInfo.minPos;
		((NetworkActionInfo)val).tick = ((NetworkActionInfo)val).tick + 5;
		SimpleBuildAction val2 = new SimpleBuildAction();
		val2.info = (SimpleBuildInfo)((NetworkBuildInfo)val).Clone();
		((BuildMachineAction)val2).resourceCostAmount = 1;
		((BuildMachineAction)val2).resourceCostID = selectedItem;
		result.Add(new PendingBuildRequest
		{
			BuildAction = (BuildMachineAction)(object)val2,
			BuildGrid = ((GenericMachineInstanceRef)(ref machineRef)).MyGridInfo
		});
		TryDetailLog(" Finalising action");
	}

	private bool CanReplace(GenericMachineInstanceRef foundMachine)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Invalid comparison between Unknown and I4
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Invalid comparison between Unknown and I4
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Invalid comparison between Unknown and I4
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Invalid comparison between Unknown and I4
		MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref foundMachine)).typeIndex;
		if ((int)typeIndex <= 7)
		{
			if (typeIndex - 4 <= 1 || (int)typeIndex == 7)
			{
				goto IL_0022;
			}
		}
		else if ((int)typeIndex == 16 || (int)typeIndex == 19)
		{
			goto IL_0022;
		}
		return false;
		IL_0022:
		return true;
	}

	private List<GenericMachineInstanceRef> GetReplacableItems(GenericMachineInstanceRef foundMachine, BuilderInfo inventoryRef)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_004a: Expected I4, but got Unknown
		//IL_0059: 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)
		//IL_004d: Invalid comparison between Unknown and I4
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Invalid comparison between Unknown and I4
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		List<GenericMachineInstanceRef> list = new List<GenericMachineInstanceRef>();
		MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref foundMachine)).typeIndex;
		switch (typeIndex - 1)
		{
		default:
			if ((int)typeIndex != 16 && (int)typeIndex != 19)
			{
				break;
			}
			goto case 0;
		case 0:
		case 4:
		case 6:
			list.Add(foundMachine);
			break;
		case 3:
			try
			{
				TryDetailLog(" Trying to cast");
				ConveyorInstance typed = MachineManager.instance.GetTyped<ConveyorInstance>(foundMachine);
				TryDetailLog(" Traversing");
				List<ConveyorInstance> list2 = TraverseConveyor(typed);
				TryDetailLog($" Found {list2.Count} linked conveyors");
				list2 = list2.Where((ConveyorInstance linked) => ((UniqueIdScriptableObject)linked._myDef).uniqueId != ((UniqueIdScriptableObject)inventoryRef).uniqueId).ToList();
				TryDetailLog($" Found {list2.Count} conveyors to replace");
				TryDetailLog(" Sorting by distance");
				list2 = list2.OrderBy((ConveyorInstance linked) => (int)Vector3Int.Distance(linked.gridInfo.minPos, ((GenericMachineInstanceRef)(ref foundMachine)).MyGridInfo.minPos)).ToList();
				TryDetailLog(" Sorted");
				foreach (ConveyorInstance item in list2)
				{
					if (!list.Contains(item.gridInfo.myRef))
					{
						if (list.Count < ReplaceCount.Value)
						{
							list.Add(item.gridInfo.myRef);
						}
						else
						{
							TryDetailLog($"Maximum replace count hit. {ReplaceCount.Value}");
						}
					}
				}
			}
			catch (Exception ex)
			{
				TryDetailLog(" Failure to traverse! " + ex.Message);
			}
			TryDetailLog($" {list.Count} items found");
			break;
		case 1:
		case 2:
		case 5:
			break;
		}
		return list;
	}

	private List<ConveyorInstance> TraverseConveyor(ConveyorInstance sourcePoint)
	{
		//IL_0045: 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)
		List<ConveyorInstance> foundConveyors = new List<ConveyorInstance>();
		Queue<ConveyorInstance> conveyorsToScan = new Queue<ConveyorInstance>();
		Action<ConveyorInstance> action = ((!UseAggressiveBeltFinder.Value) ? ((Action<ConveyorInstance>)delegate(ConveyorInstance conv)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			if (!foundConveyors.Any((ConveyorInstance traversed) => ((GenericMachineInstanceRef)(ref traversed.gridInfo.myRef)).instanceId == ((GenericMachineInstanceRef)(ref conv.gridInfo.myRef)).instanceId))
			{
				foundConveyors.Add(conv);
				((ConveyorInstance)(ref conv)).RefreshShape(true);
				if (((ConveyorInstance)(ref conv)).isHub)
				{
					TryDetailLog($" Found hub, adding {conv.numHubConns} cons");
					for (int i = 0; i < conv.numHubConns; i++)
					{
						conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(conv.hubConns[i].machineRef));
					}
				}
				else if (conv.canUseOutputRef)
				{
					TryDetailLog(" adding output reference");
					conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(conv.mainOutputRef.machineRef));
				}
				else if (conv.canUseInputRef)
				{
					TryDetailLog(" adding input reference");
					conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(conv.mainInputRef.machineRef));
				}
			}
		}) : ((Action<ConveyorInstance>)delegate(ConveyorInstance conv)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (foundConveyors.Any((ConveyorInstance traversed) => ((GenericMachineInstanceRef)(ref traversed.gridInfo.myRef)).instanceId == ((GenericMachineInstanceRef)(ref conv.gridInfo.myRef)).instanceId))
			{
				return;
			}
			foundConveyors.Add(conv);
			foreach (GenericMachineInstanceRef neighbor in conv.gridInfo.neighbors)
			{
				GenericMachineInstanceRef current = neighbor;
				if ((int)((GenericMachineInstanceRef)(ref current)).typeIndex == 4)
				{
					conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(current));
				}
			}
		}));
		action(sourcePoint);
		int value = TraverseLimit.Value;
		while (true)
		{
			TryDetailLog($" Traverse run state - CurCount:{foundConveyors.Count} Queue:{conveyorsToScan.Count} ");
			if (conveyorsToScan.Count() > 0)
			{
				action(conveyorsToScan.Dequeue());
			}
			if (foundConveyors.Count() > value)
			{
				TryDetailLog($" Traverse limit hit. Found {foundConveyors.Count()} limit {value}");
				break;
			}
			if (conveyorsToScan.Count() == 0)
			{
				TryDetailLog($" no more belts. Found {foundConveyors.Count()}.");
				break;
			}
		}
		return foundConveyors;
	}

	private static void TryAdd(ref List<ConveyorInstance> traversedConveyors, ConveyorInstance instance)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		if (!traversedConveyors.Contains(instance))
		{
			traversedConveyors.Add(instance);
		}
	}
}

plugins/InPlaceUpgrade/InPlaceUpgrade.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Rewired;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InPlaceUpgrade")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BeltUpgrade")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("64443039-edc2-4adb-8193-a459b7477663")]
[assembly: AssemblyFileVersion("0.0.4.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.4.0")]
namespace InPlaceUpgrade;

[BepInPlugin("inplaceupgrade.nhickling.co.uk", "InPlaceUpgrade", "0.1.0")]
public class InPlaceUpgrade : BaseUnityPlugin
{
	private class ModSystemMessage : SystemMessageInfo
	{
		public override MessageType type => (MessageType)5;

		public ModSystemMessage(string message)
			: base(message)
		{
		}
	}

	private class PendingBuildRequest
	{
		public BuildMachineAction BuildAction { get; set; }

		public GridInfo BuildGrid { get; set; }

		public int BuildAttempts { get; set; } = 5;

	}

	private const int TicksBetweenBuilds = 5;

	public const string pluginGuid = "inplaceupgrade.nhickling.co.uk";

	public const string pluginName = "InPlaceUpgrade";

	public const string pluginShort = "IPU";

	public const string pluginVersion = "0.1.0";

	public static ConfigEntry<bool> UseAggressiveBeltFinder;

	public static ConfigEntry<bool> EnableLogging;

	public static ConfigEntry<bool> EnableSameBeltTriggering;

	public static bool loggingEnabled;

	public static ConfigEntry<int> TraverseLimit;

	public static ConfigEntry<int> ReplaceCount;

	private Stopwatch heavyLoggingTimer = Stopwatch.StartNew();

	private static ManualLogSource modLogger;

	private static GameObject hostObject;

	private int capturedBuildMask = 2097512;

	private Player playerReference;

	private int ticksTillNextbuild = 2;

	private Queue<PendingBuildRequest> queuedBuildActions = new Queue<PendingBuildRequest>();

	private float raycastRange = 15f;

	private int notificationCycle = 50;

	private int notificationTimer = 50;

	public void Awake()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected O, but got Unknown
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Expected O, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Expected O, but got Unknown
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Expected O, but got Unknown
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Expected O, but got Unknown
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Expected O, but got Unknown
		modLogger = ((BaseUnityPlugin)this).Logger;
		modLogger.LogInfo((object)"Moved to persistant scene");
		((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
		modLogger.LogInfo((object)"Started DevBuild 4");
		UseAggressiveBeltFinder = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Aggressive", false, new ConfigDescription("Search for belts indirectly.", (AcceptableValueBase)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		EnableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Logging", false, new ConfigDescription("Enable disagnostic logging. Can cause lag. (Value is ONLY loaded at startup, changes after WILL be ignored for performance reasons)", (AcceptableValueBase)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		EnableSameBeltTriggering = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSameBeltTriggering", true, new ConfigDescription("Enable starting an in-place-upgrade of belts when looking at the same type of belt.", (AcceptableValueBase)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		loggingEnabled = EnableLogging.Value;
		ReplaceCount = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "ReplaceCount", 50, new ConfigDescription("How many belts is the mod allowed to replace at once. High values can cause a stutter when starting replacement.", (AcceptableValueBase)new AcceptableValueRange<int>(25, 100), Array.Empty<object>()));
		TraverseLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "TraverseLimit", 50, new ConfigDescription("How many belts is the mod allowed to scan at once. (Used when Aggresive ssearch is enabled)", (AcceptableValueBase)new AcceptableValueRange<int>(25, 100), Array.Empty<object>()));
		modLogger.LogInfo((object)$"Loaded settings from config. Aggressive:{UseAggressiveBeltFinder.Value}. Logging {EnableLogging.Value}. Depth {TraverseLimit.Value}. Count {ReplaceCount.Value}");
	}

	public void FixedUpdate()
	{
		if (notificationTimer > 0)
		{
			notificationTimer--;
		}
		if (playerReference != null)
		{
			DoGameLoop();
			return;
		}
		try
		{
			if (ReInput.isReady && playerReference == null)
			{
				playerReference = ReInput.players.GetPlayer(0);
				TryDetailLog("Attached to player controllers");
			}
		}
		catch
		{
			if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
			{
				TryDetailLog("Waiting for ReInput.");
				heavyLoggingTimer.Restart();
			}
		}
	}

	private void DoGameLoop()
	{
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Invalid comparison between Unknown and I4
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_044b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Unknown result type (might be due to invalid IL or missing references)
		//IL_0456: Unknown result type (might be due to invalid IL or missing references)
		//IL_0468: Expected O, but got Unknown
		//IL_046d: Expected O, but got Unknown
		GridManager val = null;
		Player val2 = null;
		try
		{
			val = GridManager.instance;
			val2 = Player.instance;
		}
		catch (Exception)
		{
			if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
			{
				TryDetailLog("Error getting manager instances");
				heavyLoggingTimer.Restart();
			}
		}
		if ((Object)(object)val2 == (Object)null || (Object)(object)val == (Object)null)
		{
			if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
			{
				TryDetailLog("Waiting for manager instances.");
				heavyLoggingTimer.Restart();
			}
		}
		else if (queuedBuildActions.Count > 0)
		{
			if (--ticksTillNextbuild == 0)
			{
				ticksTillNextbuild = 5;
				PendingBuildRequest pendingBuildRequest = queuedBuildActions.Peek();
				TryDetailLog(" Sending build event");
				if (val.CheckBuildableIncludingVoxelsAt(pendingBuildRequest.BuildGrid))
				{
					TryDetailLog(" Sending build event");
					pendingBuildRequest = queuedBuildActions.Dequeue();
					NetworkMessageRelay.instance.SendNetworkAction((NetworkAction)(object)pendingBuildRequest.BuildAction);
				}
				else
				{
					ticksTillNextbuild = 5;
					TryShowNotification("IPU: Rebuild is currently blocked, skipping for now");
					PendingBuildRequest pendingBuildRequest2 = pendingBuildRequest;
					int buildAttempts = pendingBuildRequest2.BuildAttempts - 1;
					pendingBuildRequest2.BuildAttempts = buildAttempts;
					if (pendingBuildRequest.BuildAttempts == 0)
					{
						queuedBuildActions.Dequeue();
						queuedBuildActions.Enqueue(new PendingBuildRequest
						{
							BuildAction = pendingBuildRequest.BuildAction,
							BuildGrid = pendingBuildRequest.BuildGrid
						});
					}
				}
			}
			if (playerReference.GetButton(109))
			{
				TryShowNotification("IPU: Rebuild is currently busy!");
				if (heavyLoggingTimer.ElapsedMilliseconds > 2000)
				{
					TryDetailLog("Input recieved while busy.");
					heavyLoggingTimer.Restart();
				}
			}
		}
		else
		{
			if (!playerReference.GetButton(109))
			{
				return;
			}
			TryDetailLog(" Input captured");
			if (!((Object)(object)val2 != (Object)null))
			{
				return;
			}
			Vector3 forward = ((Component)val2.cam).transform.forward;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(((Component)val2.cam).transform.position, forward, ref val3, raycastRange, capturedBuildMask, (QueryTriggerInteraction)1))
			{
				TryDetailLog(" Raycast hit!");
				Vector3Int voxel = FHG_Utils.GetVoxel(((RaycastHit)(ref val3)).point);
				GenericMachineInstanceRef val4 = default(GenericMachineInstanceRef);
				val.TryGetMachine(ref voxel, ref val4);
				MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref val4)).typeIndex;
				TryDetailLog(" Raycast found machine of type " + ((object)(MachineTypeEnum)(ref typeIndex)).ToString());
				if (!CanReplace(val4))
				{
					return;
				}
				TryDetailLog(" Machine is replacable.");
				if (!val2.toolbar.selectedInfo.buildable)
				{
					return;
				}
				BuilderInfo selectedBuildableInfo = val2.toolbar.selectedBuildableInfo;
				if (selectedBuildableInfo.GetInstanceType() != ((GenericMachineInstanceRef)(ref val4)).typeIndex)
				{
					return;
				}
				bool flag = ((UniqueIdScriptableObject)selectedBuildableInfo).uniqueId != ((GenericMachineInstanceRef)(ref val4)).ResId;
				bool flag2 = EnableSameBeltTriggering.Value && (int)((GenericMachineInstanceRef)(ref val4)).typeIndex == 4;
				TryDetailLog($" Matching item type, checking for item difference. {flag}/{flag2}");
				if (flag || flag2)
				{
					ResourceInfo selectedInfo = val2.toolbar.selectedInfo;
					int resourceCount = ((InventoryWrapper)val2.inventory).GetResourceCount(((UniqueIdScriptableObject)selectedInfo).uniqueId, false);
					List<GenericMachineInstanceRef> replacableItems = GetReplacableItems(val4, selectedBuildableInfo);
					TryDetailLog($" Need to replace {replacableItems.Count} items.");
					TryDetailLog($" Found {resourceCount} items in inventory.");
					if (replacableItems.Count == 0)
					{
						TryShowNotification("IPU: Nothing to replace found.");
					}
					else if (replacableItems.Count <= resourceCount)
					{
						TryDetailLog(" Found enough items");
						TryShowNotification(string.Format("{0}: Replacing {1} items.", "IPU", replacableItems.Count));
						List<uint> list = new List<uint>();
						foreach (GenericMachineInstanceRef item in replacableItems)
						{
							GenericMachineInstanceRef current = item;
							list.Add(((GenericMachineInstanceRef)(ref current)).instanceId);
						}
						List<PendingBuildRequest> rebuildAction = GetRebuildAction(val4, ((UniqueIdScriptableObject)selectedBuildableInfo).uniqueId, replacableItems);
						if (rebuildAction.Count <= 1 || replacableItems.Count * 2 < resourceCount)
						{
							TryDetailLog(" Sending deconstruction");
							notificationTimer = notificationCycle;
							NetworkMessageRelay.instance.SendNetworkAction((NetworkAction)new EraseMachineAction
							{
								info = new EraseMachineInfo
								{
									machineIDs = list.ToArray()
								}
							});
							TryDetailLog(" Queing construction");
							{
								foreach (PendingBuildRequest item2 in rebuildAction)
								{
									queuedBuildActions.Enqueue(item2);
								}
								return;
							}
						}
						TryShowNotification(string.Format("{0}: Rebuild protection. More items needed. ({1} of {2})", "IPU", resourceCount, replacableItems.Count * 2));
					}
					else
					{
						TryDetailLog(" Not enough items.");
						TryShowNotification(string.Format("{0}: Not enough items ({1} of {2})", "IPU", resourceCount, replacableItems.Count));
					}
				}
				else
				{
					TryDetailLog(" Can't self replace.");
					TryShowNotification("IPU: Can't replace with the same type.");
				}
			}
			else
			{
				TryDetailLog(" Raycast did not hit anything");
			}
		}
	}

	internal static void TryDetailLog(string log)
	{
		if (loggingEnabled)
		{
			modLogger.LogInfo((object)("InPlaceUpgrade: " + log));
		}
	}

	private void TryShowNotification(string message)
	{
		if (notificationTimer == 0)
		{
			SystemLogUI systemLog = UIManager.instance.systemLog;
			ModSystemMessage modSystemMessage = new ModSystemMessage(message);
			systemLog.FlashMessage((SystemMessageInfo)(object)modSystemMessage);
			notificationTimer = notificationCycle;
		}
	}

	private List<PendingBuildRequest> GetRebuildAction(GenericMachineInstanceRef sourceMachine, int selectedItem, List<GenericMachineInstanceRef> toReplace)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//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_0032: Expected I4, but got Unknown
		//IL_003d: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Invalid comparison between Unknown and I4
		List<PendingBuildRequest> result = new List<PendingBuildRequest>();
		MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref sourceMachine)).typeIndex;
		switch (typeIndex - 1)
		{
		default:
			if ((int)typeIndex != 16 && (int)typeIndex != 19)
			{
				break;
			}
			goto case 0;
		case 0:
		case 4:
		case 6:
			AppendSimpleBuildAction(sourceMachine, selectedItem, ref result);
			break;
		case 3:
			AppendConveyorBuildAction(((GenericMachineInstanceRef)(ref sourceMachine)).typeIndex, selectedItem, ref result, toReplace);
			break;
		case 1:
		case 2:
		case 5:
			break;
		}
		return result;
	}

	private void AppendConveyorBuildAction(MachineTypeEnum machineType, int selectedItem, ref List<PendingBuildRequest> result, List<GenericMachineInstanceRef> toReplace)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Invalid comparison between Unknown and I4
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Expected O, but got Unknown
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Expected O, but got Unknown
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		TryDetailLog(" Building conveyor replaceaction");
		List<ChainData> list = new List<ChainData>();
		ConveyorMachineList val = (ConveyorMachineList)FactorySimManager.instance.machineManager.GetMachineList<ConveyorInstance, ConveyorDefinition>((MachineTypeEnum)4);
		TryDetailLog($" Got machineList: {val == null}");
		bool flag = false;
		foreach (GenericMachineInstanceRef item in toReplace)
		{
			GenericMachineInstanceRef current = item;
			TryDetailLog(" Adding conveyor segment");
			ConveyorInstance val2 = ((MachineInstanceList<ConveyorInstance, ConveyorDefinition>)(object)val).myArray[((GenericMachineInstanceRef)(ref current)).index];
			flag = val2.buildBackwards;
			Vector3Int voxel = FHG_Utils.GetVoxel(((GridInfo)(ref ((GenericMachineInstanceRef)(ref current)).MyGridInfo)).Center);
			if ((int)val2.beltShape == 3 || (int)val2.beltShape == 4)
			{
				((Vector3Int)(ref voxel)).y = ((Vector3Int)(ref voxel)).y - 1;
			}
			list.Add(new ChainData
			{
				count = 1,
				shape = val2.beltShape,
				rotation = val2.gridInfo.yawRot,
				start = voxel
			});
			ConveyorBuildInfo val3 = new ConveyorBuildInfo();
			((NetworkBuildInfo)val3).machineType = selectedItem;
			val3.chainData = list;
			val3.isReversed = flag;
			((MultiBuildInfo)val3).machineIds = new List<uint>();
			((NetworkActionInfo)val3).tick = ((NetworkActionInfo)val3).tick + 5;
			ConveyorBuildAction val4 = new ConveyorBuildAction();
			val4.info = (ConveyorBuildInfo)((NetworkBuildInfo)val3).Clone();
			((BuildMachineAction)val4).resourceCostAmount = val3.chainData.Count;
			((BuildMachineAction)val4).resourceCostID = selectedItem;
			result.Add(new PendingBuildRequest
			{
				BuildAction = (BuildMachineAction)(object)val4,
				BuildGrid = ((GenericMachineInstanceRef)(ref current)).MyGridInfo
			});
		}
		TryDetailLog(" Finalising action");
	}

	private void AppendSimpleBuildAction(GenericMachineInstanceRef machineRef, int selectedItem, ref List<PendingBuildRequest> result)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_005c: 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)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		TryDetailLog(" Building simple replace action");
		FactorySimManager instance = FactorySimManager.instance;
		TryDetailLog($" Got factory reference: {(Object)(object)instance == (Object)null}");
		TryDetailLog(" Adding conveyor segment");
		SimpleBuildInfo val = new SimpleBuildInfo();
		((NetworkBuildInfo)val).machineType = selectedItem;
		val.rotation = ((GridInfo)(ref ((GenericMachineInstanceRef)(ref machineRef)).MyGridInfo)).YawRotation;
		val.minGridPos = ((GenericMachineInstanceRef)(ref machineRef)).MyGridInfo.minPos;
		((NetworkActionInfo)val).tick = ((NetworkActionInfo)val).tick + 5;
		SimpleBuildAction val2 = new SimpleBuildAction();
		val2.info = (SimpleBuildInfo)((NetworkBuildInfo)val).Clone();
		((BuildMachineAction)val2).resourceCostAmount = 1;
		((BuildMachineAction)val2).resourceCostID = selectedItem;
		result.Add(new PendingBuildRequest
		{
			BuildAction = (BuildMachineAction)(object)val2,
			BuildGrid = ((GenericMachineInstanceRef)(ref machineRef)).MyGridInfo
		});
		TryDetailLog(" Finalising action");
	}

	private bool CanReplace(GenericMachineInstanceRef foundMachine)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Invalid comparison between Unknown and I4
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Invalid comparison between Unknown and I4
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Invalid comparison between Unknown and I4
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Invalid comparison between Unknown and I4
		MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref foundMachine)).typeIndex;
		if ((int)typeIndex <= 7)
		{
			if (typeIndex - 4 <= 1 || (int)typeIndex == 7)
			{
				goto IL_0022;
			}
		}
		else if ((int)typeIndex == 16 || (int)typeIndex == 19)
		{
			goto IL_0022;
		}
		return false;
		IL_0022:
		return true;
	}

	private List<GenericMachineInstanceRef> GetReplacableItems(GenericMachineInstanceRef foundMachine, BuilderInfo inventoryRef)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_004a: Expected I4, but got Unknown
		//IL_0059: 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)
		//IL_004d: Invalid comparison between Unknown and I4
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Invalid comparison between Unknown and I4
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		List<GenericMachineInstanceRef> list = new List<GenericMachineInstanceRef>();
		MachineTypeEnum typeIndex = ((GenericMachineInstanceRef)(ref foundMachine)).typeIndex;
		switch (typeIndex - 1)
		{
		default:
			if ((int)typeIndex != 16 && (int)typeIndex != 19)
			{
				break;
			}
			goto case 0;
		case 0:
		case 4:
		case 6:
			list.Add(foundMachine);
			break;
		case 3:
			try
			{
				TryDetailLog(" Trying to cast");
				ConveyorInstance typed = MachineManager.instance.GetTyped<ConveyorInstance>(foundMachine);
				TryDetailLog(" Traversing");
				List<ConveyorInstance> list2 = TraverseConveyor(typed);
				TryDetailLog($" Found {list2.Count} linked conveyors");
				list2 = list2.Where((ConveyorInstance linked) => ((UniqueIdScriptableObject)linked._myDef).uniqueId != ((UniqueIdScriptableObject)inventoryRef).uniqueId).ToList();
				TryDetailLog($" Found {list2.Count} conveyors to replace");
				TryDetailLog(" Sorting by distance");
				list2 = list2.OrderBy((ConveyorInstance linked) => (int)Vector3Int.Distance(linked.gridInfo.minPos, ((GenericMachineInstanceRef)(ref foundMachine)).MyGridInfo.minPos)).ToList();
				TryDetailLog(" Sorted");
				foreach (ConveyorInstance item in list2)
				{
					if (!list.Contains(item.gridInfo.myRef))
					{
						if (list.Count < ReplaceCount.Value)
						{
							list.Add(item.gridInfo.myRef);
						}
						else
						{
							TryDetailLog($"Maximum replace count hit. {ReplaceCount.Value}");
						}
					}
				}
			}
			catch (Exception ex)
			{
				TryDetailLog(" Failure to traverse! " + ex.Message);
			}
			TryDetailLog($" {list.Count} items found");
			break;
		case 1:
		case 2:
		case 5:
			break;
		}
		return list;
	}

	private List<ConveyorInstance> TraverseConveyor(ConveyorInstance sourcePoint)
	{
		//IL_0045: 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)
		List<ConveyorInstance> foundConveyors = new List<ConveyorInstance>();
		Queue<ConveyorInstance> conveyorsToScan = new Queue<ConveyorInstance>();
		Action<ConveyorInstance> action = ((!UseAggressiveBeltFinder.Value) ? ((Action<ConveyorInstance>)delegate(ConveyorInstance conv)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			if (!foundConveyors.Any((ConveyorInstance traversed) => ((GenericMachineInstanceRef)(ref traversed.gridInfo.myRef)).instanceId == ((GenericMachineInstanceRef)(ref conv.gridInfo.myRef)).instanceId))
			{
				foundConveyors.Add(conv);
				((ConveyorInstance)(ref conv)).RefreshShape(true);
				if (((ConveyorInstance)(ref conv)).isHub)
				{
					TryDetailLog($" Found hub, adding {conv.numHubConns} cons");
					for (int i = 0; i < conv.numHubConns; i++)
					{
						conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(conv.hubConns[i].machineRef));
					}
				}
				else if (conv.canUseOutputRef)
				{
					TryDetailLog(" adding output reference");
					conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(conv.mainOutputRef.machineRef));
				}
				else if (conv.canUseInputRef)
				{
					TryDetailLog(" adding input reference");
					conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(conv.mainInputRef.machineRef));
				}
			}
		}) : ((Action<ConveyorInstance>)delegate(ConveyorInstance conv)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (foundConveyors.Any((ConveyorInstance traversed) => ((GenericMachineInstanceRef)(ref traversed.gridInfo.myRef)).instanceId == ((GenericMachineInstanceRef)(ref conv.gridInfo.myRef)).instanceId))
			{
				return;
			}
			foundConveyors.Add(conv);
			foreach (GenericMachineInstanceRef neighbor in conv.gridInfo.neighbors)
			{
				GenericMachineInstanceRef current = neighbor;
				if ((int)((GenericMachineInstanceRef)(ref current)).typeIndex == 4)
				{
					conveyorsToScan.Enqueue(MachineManager.instance.GetTyped<ConveyorInstance>(current));
				}
			}
		}));
		action(sourcePoint);
		int value = TraverseLimit.Value;
		while (true)
		{
			TryDetailLog($" Traverse run state - CurCount:{foundConveyors.Count} Queue:{conveyorsToScan.Count} ");
			if (conveyorsToScan.Count() > 0)
			{
				action(conveyorsToScan.Dequeue());
			}
			if (foundConveyors.Count() > value)
			{
				TryDetailLog($" Traverse limit hit. Found {foundConveyors.Count()} limit {value}");
				break;
			}
			if (conveyorsToScan.Count() == 0)
			{
				TryDetailLog($" no more belts. Found {foundConveyors.Count()}.");
				break;
			}
		}
		return foundConveyors;
	}

	private static void TryAdd(ref List<ConveyorInstance> traversedConveyors, ConveyorInstance instance)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		if (!traversedConveyors.Contains(instance))
		{
			traversedConveyors.Add(instance);
		}
	}
}