Decompiled source of InterstellarLogisticsOpt v1.2.0

InterstellarLogisticsOpt.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UXAssist.Common;
using UXAssist.UI;
using UnityEngine;
using UnityEngine.UI;

[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("InterstellarLogisticsOpt")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Staggers interstellar logistics scheduling to reduce CPU load / 相位分散星际物流调度,降低 CPU 开销")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+85595c55e003b209486f944cf622b06320ca049a")]
[assembly: AssemblyProduct("InterstellarLogisticsOpt")]
[assembly: AssemblyTitle("InterstellarLogisticsOpt")]
[assembly: AssemblyVersion("1.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace InterstellarLogisticsOpt
{
	[HarmonyPatch(typeof(StationComponent), "DetermineDispatch")]
	internal static class DispatchOptimization
	{
		internal static readonly bool SupportedGame = typeof(StationComponent).Module.ModuleVersionId == new Guid("ece4a40e-5e73-43f4-a9f8-4e74970b5942");

		internal static volatile bool Enabled;

		internal static string Failure;

		private static bool NeedsLock(StationComponent peer, int index, int priority)
		{
			if (priority == 0 || priority > 4)
			{
				return false;
			}
			ref StationPriorityLock reference = ref peer.priorityLocks[index];
			if (reference.priorityIndex != 0 && reference.priorityIndex < priority)
			{
				return false;
			}
			int num;
			switch (priority)
			{
			default:
				num = 60;
				break;
			case 2:
			case 3:
				num = 30;
				break;
			case 1:
				num = 10;
				break;
			}
			int num2 = num;
			if (reference.priorityIndex == priority)
			{
				return reference.lockTick != num2;
			}
			return true;
		}

		[HarmonyTranspiler]
		[HarmonyAfter(new string[] { "org.fyyy.logisticsprofiler" })]
		internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Expected O, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Expected O, but got Unknown
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Expected O, but got Unknown
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Expected O, but got Unknown
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Expected O, but got Unknown
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Expected O, but got Unknown
			List<CodeInstruction> code = instructions.ToList();
			FieldInfo fieldInfo = AccessTools.Field(typeof(StationComponent), "storage");
			List<int> list = new List<int>();
			for (int i = 0; i + 8 < code.Count; i++)
			{
				if (CodeInstructionExtensions.IsLdarg(code[i], (int?)5) && CodeInstructionExtensions.IsLdloc(code[i + 1], (LocalBuilder)null) && (CodeInstructionExtensions.LoadsField(code[i + 2], AccessTools.Field(typeof(SupplyDemandPair), "supplyId"), false) || CodeInstructionExtensions.LoadsField(code[i + 2], AccessTools.Field(typeof(SupplyDemandPair), "demandId"), false)) && code[i + 3].opcode == OpCodes.Ldelem_Ref && CodeInstructionExtensions.IsStloc(code[i + 4], (LocalBuilder)null) && CodeInstructionExtensions.IsLdloc(code[i + 5], (LocalBuilder)null) && code[i + 6].opcode == OpCodes.Brfalse && CodeInstructionExtensions.IsLdloc(code[i + 7], (LocalBuilder)null) && CodeInstructionExtensions.LoadsField(code[i + 8], fieldInfo, false))
				{
					list.Add(i);
				}
			}
			if (!SupportedGame || list.Count != 2 || list.Any((int num) => code[num + 7].blocks.Count != 0))
			{
				Failure = "Unsupported DetermineDispatch body; dispatch optimization was not applied.";
				return code;
			}
			Failure = null;
			LocalBuilder localBuilder = generator.DeclareLocal(typeof(bool));
			foreach (int item in list.AsEnumerable().Reverse())
			{
				int index = item + 7;
				Label label = generator.DefineLabel();
				bool flag = CodeInstructionExtensions.LoadsField(code[item + 2], AccessTools.Field(typeof(SupplyDemandPair), "demandId"), false);
				List<CodeInstruction> list2 = new List<CodeInstruction>
				{
					new CodeInstruction(OpCodes.Ldloc, (object)localBuilder),
					new CodeInstruction(OpCodes.Brfalse, (object)label),
					new CodeInstruction(code[index].opcode, code[index].operand),
					new CodeInstruction(code[item + 1].opcode, code[item + 1].operand),
					new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(SupplyDemandPair), flag ? "demandIndex" : "supplyIndex")),
					new CodeInstruction(OpCodes.Ldarg_S, (object)(byte)4),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DispatchOptimization), "NeedsLock", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Brfalse, code[item + 6].operand)
				};
				list2[0].labels.AddRange(code[index].labels);
				code[index].labels.Clear();
				code[index].labels.Add(label);
				code.InsertRange(index, list2);
			}
			code.InsertRange(0, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(DispatchOptimization), "Enabled")),
				new CodeInstruction(OpCodes.Stloc, (object)localBuilder)
			});
			return code;
		}
	}
	[HarmonyPatch(typeof(GalacticTransport), "GameTick")]
	internal static class DispatchScheduler
	{
		internal static volatile int Factor = 1;

		[HarmonyPrefix]
		private static bool Prefix(GalacticTransport __instance, long time)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Invalid comparison between Unknown and I4
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Invalid comparison between Unknown and I4
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Invalid comparison between Unknown and I4
			int factor = Factor;
			if (!DispatchOptimization.Enabled || factor <= 1 || !DispatchOptimization.SupportedGame || DispatchOptimization.Failure != null)
			{
				return true;
			}
			GameData gameData = __instance.gameData;
			GameHistoryData history = gameData.history;
			float logisticShipSailSpeedModified = history.logisticShipSailSpeedModified;
			float num = (history.logisticShipWarpDrive ? history.logisticShipWarpSpeedModified : logisticShipSailSpeedModified);
			StationComponent[] stationPool = __instance.stationPool;
			for (int i = 1; i <= 6; i++)
			{
				int num2 = i % 6;
				int num3;
				switch (i)
				{
				default:
					num3 = 60;
					break;
				case 2:
				case 3:
					num3 = 30;
					break;
				case 1:
					num3 = 10;
					break;
				}
				int num4 = num3 * factor;
				for (int j = (int)(time % num4) + 1; j < __instance.stationCursor; j += num4)
				{
					StationComponent val = stationPool[j];
					if (val == null || val.id <= 0 || val.gid != j)
					{
						continue;
					}
					ERemoteRoutePriority routePriority = val.routePriority;
					bool num5;
					if (num2 != 0)
					{
						if ((int)routePriority != 2)
						{
							if (num2 > 4)
							{
								continue;
							}
							if ((int)routePriority != 3)
							{
								num5 = (int)routePriority == 4;
								goto IL_00e3;
							}
						}
						goto IL_00e5;
					}
					num5 = (int)routePriority == 1;
					goto IL_00e3;
					IL_00e5:
					val.DetermineDispatch(logisticShipSailSpeedModified, num, history.logisticShipCarries, num2, stationPool, gameData.statistics.production.factoryStatPool, gameData.factories, gameData.galaxy, gameData.statistics.traffic);
					continue;
					IL_00e3:
					if (!num5)
					{
						continue;
					}
					goto IL_00e5;
				}
			}
			return false;
		}
	}
	[BepInPlugin("org.fyyy.interstellarlogisticsopt", "InterstellarLogisticsOpt", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class InterstellarLogisticsOptPlugin : BaseUnityPlugin
	{
		public static ConfigEntry<bool> ModEnabled;

		public static ConfigEntry<int> AmortizeFactor;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Optimize interstellar dispatch / 优化星际物流派船");
			AmortizeFactor = ((BaseUnityPlugin)this).Config.Bind<int>("General", "AmortizeFactor", 1, new ConfigDescription("All-route scheduling multiplier. 1 = vanilla cadence. At N > 1, stagger stations across ticks and run dispatch checks at 1/N frequency. Trades priority fidelity and responsiveness for lower CPU cost; may limit throughput. / 全航线调度间隔系数。1 为原版节奏;N > 1 时按塔错开调度,检查频率降为 1/N。以部分优先级准确性和响应速度换取更低 CPU 开销,可能限制吞吐。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			ModEnabled.SettingChanged += UpdateSettings;
			AmortizeFactor.SettingChanged += UpdateSettings;
			UpdateSettings(null, EventArgs.Empty);
			_harmony = new Harmony("org.fyyy.interstellarlogisticsopt");
			_harmony.PatchAll(typeof(DispatchOptimization));
			_harmony.PatchAll(typeof(DispatchScheduler));
			if (DispatchOptimization.Failure != null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)DispatchOptimization.Failure);
			}
			I18N.Add("InterstellarLogisticsOpt", "InterstellarLogisticsOpt", "星际物流优化");
			I18N.Add("Optimize interstellar dispatch", "Optimize interstellar dispatch", "优化星际物流派船计算");
			I18N.Add("Dispatch interval multiplier", "Dispatch interval multiplier", "全航线调度间隔系数");
			I18N.Apply();
			MyConfigWindow.OnUICreated = (Action<MyConfigWindow, RectTransform>)Delegate.Combine(MyConfigWindow.OnUICreated, new Action<MyConfigWindow, RectTransform>(CreateUI));
		}

		private static void UpdateSettings(object sender, EventArgs e)
		{
			DispatchOptimization.Enabled = ModEnabled.Value;
			DispatchScheduler.Factor = AmortizeFactor.Value;
		}

		private void OnDestroy()
		{
			MyConfigWindow.OnUICreated = (Action<MyConfigWindow, RectTransform>)Delegate.Remove(MyConfigWindow.OnUICreated, new Action<MyConfigWindow, RectTransform>(CreateUI));
			if (ModEnabled != null)
			{
				ModEnabled.SettingChanged -= UpdateSettings;
			}
			if (AmortizeFactor != null)
			{
				AmortizeFactor.SettingChanged -= UpdateSettings;
			}
			DispatchOptimization.Enabled = false;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void CreateUI(MyConfigWindow wnd, RectTransform trans)
		{
			((MyWindowWithTabs)wnd).AddSplitter(trans, 10f);
			((MyWindowWithTabs)wnd).AddTabGroup(trans, "InterstellarLogisticsOpt", "tab-group-interstellarlogisticsopt");
			RectTransform val = ((MyWindowWithTabs)wnd).AddTab(trans, "InterstellarLogisticsOpt");
			((MyWindow)wnd).AddCheckBox(0f, 10f, val, ModEnabled, "Optimize interstellar dispatch", 15);
			Text val2 = ((MyWindow)wnd).AddText2(0f, 51f, val, "Dispatch interval multiplier", 14, "label");
			((MyWindow)wnd).AddSlider<int>(val2.preferredWidth + 10f, 46f, val, AmortizeFactor, (ValueMapper<int>)(object)new RangeValueMapper<int>(1, 30), "0", 200f).WithSmallerHandle(10f, 0f);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "org.fyyy.interstellarlogisticsopt";

		public const string PLUGIN_NAME = "InterstellarLogisticsOpt";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}