Decompiled source of BigTower v1.2.0

BigTower.dll

Decompiled 4 hours 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;
using UnityEngine;

[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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
internal static class PluginInfo
{
	public const string PLUGIN_GUID = "com.yummi.dsp.bigtower";

	public const string PLUGIN_NAME = "BigTower";

	public const string PLUGIN_VERSION = "1.2.0";
}
namespace BigTower
{
	[BepInPlugin("com.yummi.dsp.bigtower", "大塔 (Big Tower)", "1.2.0")]
	public class BigTower : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.yummi.dsp.bigtower";

		public const string PLUGIN_NAME = "大塔 (Big Tower)";

		public const string PLUGIN_VERSION = "1.2.0";

		private static readonly Harmony harmony = new Harmony("com.yummi.dsp.bigtower");

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExpansionMode", "max", new ConfigDescription("max: planetary stations 8 slots, interstellar 9. safe: all stations 6 slots (best vanilla compatibility after uninstall).\nmax:行星内运输塔 8 格、星际 9 格。safe:全部 6 格(卸载后原版兼容性最好)。", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "max", "safe" }), Array.Empty<object>()));
			StationExpandPatch.UseSafeMode = val.Value.Equals("safe", StringComparison.OrdinalIgnoreCase);
			harmony.PatchAll(typeof(StationExpandPatch));
			harmony.PatchAll(typeof(StationWindowPatch));
			harmony.PatchAll(typeof(StationLogicPatch));
			Log.LogInfo((object)("大塔 (Big Tower) v1.2.0 已加载 (ExpansionMode=" + val.Value + ")"));
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}
	}
	[HarmonyPatch]
	public static class StationExpandPatch
	{
		internal const int SafeSlots = 6;

		internal const int PlanetaryMaxSlots = 8;

		internal const int StellarMaxSlots = 9;

		internal static bool UseSafeMode;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StationComponent), "Init")]
		public static void StationComponent_Init_Postfix(StationComponent __instance)
		{
			Expand(__instance);
		}

		internal static int GetTargetSlots(StationComponent station)
		{
			if (UseSafeMode)
			{
				return 6;
			}
			if (!station.isStellar)
			{
				return 8;
			}
			return 9;
		}

		internal static void Expand(StationComponent station)
		{
			if (station.isCollector || station.isVeinCollector || station.storage == null)
			{
				return;
			}
			int targetSlots = GetTargetSlots(station);
			if (station.storage.Length >= targetSlots)
			{
				return;
			}
			lock (station.storage)
			{
				StationStore[] array = (StationStore[])(object)new StationStore[targetSlots];
				Array.Copy(station.storage, array, station.storage.Length);
				StationPriorityLock[] array2 = (StationPriorityLock[])(object)new StationPriorityLock[targetSlots];
				if (station.priorityLocks != null)
				{
					Array.Copy(station.priorityLocks, array2, Math.Min(station.priorityLocks.Length, targetSlots));
				}
				station.priorityLocks = array2;
				station.storage = array;
			}
		}
	}
	[HarmonyPatch]
	public static class StationLogicPatch
	{
		private const int VanillaNeedsLength = 6;

		private const int WarperItemId = 1210;

		[ThreadStatic]
		private static int[] needsChunk;

		private static int[] GetNeedsChunk(int[] needs, int start)
		{
			int[] array = needsChunk ?? (needsChunk = new int[6]);
			bool flag = false;
			for (int i = 0; i < 6; i++)
			{
				int num = start + i;
				array[i] = ((num < needs.Length) ? needs[num] : 0);
				flag |= array[i] > 0;
			}
			if (!flag)
			{
				return null;
			}
			return array;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StationComponent), "UpdateNeeds")]
		public static void UpdateNeeds_Postfix(StationComponent __instance)
		{
			StationStore[] storage = __instance.storage;
			int num = storage.Length;
			if (num <= 5)
			{
				return;
			}
			lock (storage)
			{
				int[] array = __instance.needs;
				if (array == null || array.Length != num + 1)
				{
					array = new int[num + 1];
				}
				bool flag = false;
				bool flag2 = false;
				for (int i = 0; i < num; i++)
				{
					array[i] = ((storage[i].count < storage[i].max) ? storage[i].itemId : 0);
				}
				array[num] = ((__instance.isStellar && __instance.warperCount < __instance.warperMaxCount) ? 1210 : 0);
				for (int j = 0; j < array.Length; j++)
				{
					if (array[j] != 0)
					{
						if (j < 6)
						{
							flag = true;
						}
						else
						{
							flag2 = true;
						}
					}
				}
				if (!flag && flag2)
				{
					array[0] = -1;
				}
				__instance.needs = array;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StationComponent), "UpdateInputSlots")]
		public static void UpdateInputSlots_Prefix(StationComponent __instance, out long __state)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			__state = 0L;
			if (__instance.needs == null || __instance.needs.Length <= 6)
			{
				return;
			}
			SlotData[] slots = __instance.slots;
			for (int i = 0; i < slots.Length && i < 64; i++)
			{
				if ((int)slots[i].dir == 2 && slots[i].counter == 0 && slots[i].beltId != 0)
				{
					__state |= 1L << i;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StationComponent), "UpdateInputSlots")]
		public static void UpdateInputSlots_Postfix(StationComponent __instance, CargoTraffic traffic, long __state)
		{
			if (__state == 0L)
			{
				return;
			}
			int[] needs = __instance.needs;
			SlotData[] slots = __instance.slots;
			BeltComponent[] beltPool = traffic.beltPool;
			int num2 = default(int);
			byte b = default(byte);
			byte b2 = default(byte);
			for (int i = 0; i < slots.Length && i < 64; i++)
			{
				if ((__state & (1L << i)) == 0L)
				{
					continue;
				}
				ref SlotData reference = ref slots[i];
				if (reference.counter != 0 || reference.beltId == 0)
				{
					continue;
				}
				CargoPath cargoPath = traffic.GetCargoPath(beltPool[reference.beltId].segPathId);
				if (cargoPath == null)
				{
					continue;
				}
				for (int j = 6; j < needs.Length; j += 6)
				{
					int[] array = GetNeedsChunk(needs, j);
					if (array != null)
					{
						int num = cargoPath.TryPickItemAtRear(array, ref num2, ref b, ref b2);
						if (num2 >= 0)
						{
							__instance.InputItem(num, j + num2, (int)b, (int)b2);
							reference.storageIdx = j + num2 + 1;
							reference.counter = 1;
							break;
						}
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void PickFrom_Entity_Postfix(PlanetFactory __instance, ref int __result, int entityId, int offset, int filter, int[] needs, ref byte stack, ref byte inc)
		{
			if (__result != 0 || needs == null || needs.Length <= 6)
			{
				return;
			}
			for (int i = 6; i < needs.Length; i += 6)
			{
				int[] array = GetNeedsChunk(needs, i);
				if (array != null)
				{
					__result = __instance.PickFrom(entityId, offset, filter, array, ref stack, ref inc);
					if (__result != 0)
					{
						break;
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void PickFrom_Typed_Postfix(PlanetFactory __instance, ref int __result, uint ioTargetTypedId, int offset, int filter, int[] needs, ref byte stack, ref byte inc)
		{
			if (__result != 0 || needs == null || needs.Length <= 6)
			{
				return;
			}
			for (int i = 6; i < needs.Length; i += 6)
			{
				int[] array = GetNeedsChunk(needs, i);
				if (array != null)
				{
					__result = __instance.PickFrom(ioTargetTypedId, offset, filter, array, ref stack, ref inc);
					if (__result != 0)
					{
						break;
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StationComponent), "AddItem")]
		public static void AddItem_Postfix(StationComponent __instance, ref int __result, int itemId, int count, int inc)
		{
			StationStore[] storage = __instance.storage;
			if (__result != 0 || itemId <= 0 || storage.Length <= 6)
			{
				return;
			}
			lock (storage)
			{
				for (int i = 6; i < storage.Length; i++)
				{
					if (storage[i].itemId == itemId)
					{
						storage[i].count += count;
						storage[i].inc += inc;
						__result = count;
						break;
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StationComponent), "UpdateKeepMode")]
		public static void UpdateKeepMode_Postfix(StationComponent __instance)
		{
			StationStore[] storage = __instance.storage;
			if (storage.Length <= 5)
			{
				return;
			}
			lock (storage)
			{
				for (int i = 5; i < storage.Length; i++)
				{
					ref StationStore reference = ref storage[i];
					if (reference.keepMode > 0 && reference.itemId > 0)
					{
						reference.count = ((reference.keepMode <= 2) ? (reference.max / reference.keepMode) : 0);
						reference.inc = ((reference.keepMode <= 2) ? ((int)((float)reference.count * reference.keepIncRatio + 1E-05f)) : 0);
					}
				}
			}
		}
	}
	[HarmonyPatch]
	public static class StationWindowPatch
	{
		private const int RowTop = -90;

		private const int RowHeight = 76;

		private const float ScreenMargin = 80f;

		private static readonly FieldRef<UIStationWindow, UIStationStorage[]> storageUIsRef = AccessTools.FieldRefAccess<UIStationWindow, UIStationStorage[]>("storageUIs");

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UIStationWindow), "OnStationIdChange")]
		public static void OnStationIdChange_Prefix(UIStationWindow __instance)
		{
			if (((ManualBehaviour)__instance).active && __instance.transport != null && __instance.stationId > 0)
			{
				StationComponent val = __instance.transport.stationPool[__instance.stationId];
				if (val != null && val.id == __instance.stationId && val.storage != null)
				{
					StationExpandPatch.Expand(val);
					EnsureRows(__instance, val.storage.Length);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIStationWindow), "OnStationIdChange")]
		public static void OnStationIdChange_Postfix(UIStationWindow __instance)
		{
			FitToScreen(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIStationWindow), "RefreshTrans")]
		public static void RefreshTrans_Postfix(UIStationWindow __instance)
		{
			FitToScreen(__instance);
		}

		private static void EnsureRows(UIStationWindow window, int count)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			UIStationStorage[] array = storageUIsRef.Invoke(window);
			if (array.Length >= count)
			{
				return;
			}
			UIStationStorage[] array2 = (UIStationStorage[])(object)new UIStationStorage[count];
			array.CopyTo(array2, 0);
			for (int i = array.Length; i < count; i++)
			{
				UIStationStorage val = Object.Instantiate<UIStationStorage>(window.storageUIPrefab, ((Component)window.storageUIPrefab).transform.parent);
				((RectTransform)((Component)val).transform).anchoredPosition = new Vector2(40f, (float)(-90 - 76 * i));
				val.stationWindow = window;
				((ManualBehaviour)val)._Create();
				if (((ManualBehaviour)window).inited)
				{
					((ManualBehaviour)val)._Init(((ManualBehaviour)window).data);
				}
				array2[i] = val;
			}
			storageUIsRef.Invoke(window) = array2;
		}

		private static void FitToScreen(UIStationWindow window)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			RectTransform windowTrans = window.windowTrans;
			Canvas componentInParent = ((Component)windowTrans).GetComponentInParent<Canvas>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				float y = windowTrans.sizeDelta.y;
				Rect rect = ((RectTransform)((Component)componentInParent.rootCanvas).transform).rect;
				float num = ((Rect)(ref rect)).height - 80f;
				float num2 = ((y > num && y > 0f) ? (num / y) : 1f);
				((Transform)windowTrans).localScale = new Vector3(num2, num2, 1f);
			}
		}
	}
}