Decompiled source of DSPOptimizations v1.1.17
patchers/DSPOptimizationsPreloader.dll
Decompiled 3 months agousing System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx.Logging; using Mono.Cecil; using Mono.Cecil.Rocks; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("DSPOptimizationsPreloader")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DSPOptimizationsPreloader")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ee4a6510-8720-40df-8810-7c2d3b93c650")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace DSPOptimizations; public class Preloader { public static ManualLogSource logSource; public static IEnumerable<string> TargetDLLs { get; } = new string[1] { "Assembly-CSharp.dll" }; public static void Initialize() { logSource = Logger.CreateLogSource("DSPOptimizations Preloader"); } private static TypeDefinition GetType(AssemblyDefinition assembly, string type) { TypeDefinition type2 = assembly.MainModule.GetType(type); if (type2 == null) { logSource.LogError((object)("Preloader patch failed: unable to get type " + type)); } return type2; } public static void Patch(AssemblyDefinition assembly) { TypeSystem typeSystem = assembly.MainModule.TypeSystem; GetType(assembly, "DysonShell")?.AddField("vertsqOffset_lowRes", (TypeReference)(object)TypeReferenceRocks.MakeArrayType(typeSystem.Int32), (FieldAttributes)6)?.AddField("radius_lowRes", typeSystem.Single, (FieldAttributes)6)?.AddField("surfaceAreaUnitSphere", typeSystem.Single, (FieldAttributes)6); GetType(assembly, "DysonSphereLayer")?.AddField("radius_lowRes", typeSystem.Single, (FieldAttributes)6)?.AddField("surfaceAreaUnitSphere", typeSystem.Single, (FieldAttributes)6)?.AddField("totalNodeSP", typeSystem.Int64, (FieldAttributes)6)?.AddField("totalFrameSP", typeSystem.Int64, (FieldAttributes)6)?.AddField("totalCP", typeSystem.Int64, (FieldAttributes)6); GetType(assembly, "DysonSphereSegmentRenderer")?.AddField("layersDirtyMask", (TypeReference)(object)TypeReferenceRocks.MakeArrayType(typeSystem.Int32), (FieldAttributes)6); GetType(assembly, "PowerSystem")?.AddField("receiverCursor", typeSystem.Int32, (FieldAttributes)6)?.AddField("receiverPool", (TypeReference)(object)TypeReferenceRocks.MakeArrayType(typeSystem.Int32), (FieldAttributes)6)?.AddField("chargerCursor", typeSystem.Int32, (FieldAttributes)6)?.AddField("chargerPool", (TypeReference)(object)TypeReferenceRocks.MakeArrayType(typeSystem.Int32), (FieldAttributes)6)?.AddField("poleCursor", typeSystem.Int32, (FieldAttributes)6)?.AddField("polePool", (TypeReference)(object)TypeReferenceRocks.MakeArrayType(typeSystem.Int32), (FieldAttributes)6)?.AddField("substationEnergyDemand", typeSystem.Int64, (FieldAttributes)6); GetType(assembly, "AssemblerComponent")?.AddField("needsDirty", typeSystem.Boolean, (FieldAttributes)6); GetType(assembly, "MonitorComponent")?.AddField("startIdx", typeSystem.Int32, (FieldAttributes)6); logSource.LogInfo((object)"Successfully ran preloader patch"); } } public static class PreloaderExtensions { public static TypeDefinition AddField(this TypeDefinition type, string name, TypeReference fieldType, FieldAttributes attr = 6) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown type.Fields.Add(new FieldDefinition(name, attr, fieldType)); return type; } }
plugins/DSPOptimizations.dll
Decompiled 3 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using PowerNetworkStructures; using UnityEngine; using crecheng.DSPModSave; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("DSPOptimizations")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DSPOptimizations")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("08c4e686-b111-425e-b9eb-c8fc72bda1f7")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace DSPOptimizations; [Optimization("ConstructionDroneOpt", "Optimizes the logic for construction drones", false, new Type[] { })] internal class ConstructionDroneOpt : OptimizationSet { private class Patch { } } [RunPatches(typeof(Patch))] internal class DysonBPOpt : OptimizationSet { private class Patch { [HarmonyPrefix] [HarmonyPatch(typeof(DysonBlueprintData), "CheckValidType")] public static bool DysonBPTest(ref string str64Data, out EDysonBlueprintType readType, ref bool __result) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected I4, but got Unknown int hashCode = str64Data.GetHashCode(); if (hashCode == lastHash) { readType = (EDysonBlueprintType)(int)lastType; __result = lastReturn; return false; } readType = (EDysonBlueprintType)0; lastHash = hashCode; return true; } [HarmonyPostfix] [HarmonyPatch(typeof(DysonBlueprintData), "CheckValidType")] public static void DysonBPTest2(EDysonBlueprintType readType, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) lastType = readType; lastReturn = __result; } } private static int lastHash; private static EDysonBlueprintType lastType; private static bool lastReturn; } [RunPatches(typeof(Patch))] [Optimization("DysonNodeOpt", "Optimizes the game logic for dyson nodes", false, new Type[] { })] internal class DysonNodeOpt : OptimizationSet { private class Patch { [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphereLayer), "GameTick")] private static IEnumerable<CodeInstruction> NodeIterSkipPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonNode), "id"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Rem, (object)null, (string)null) }).Advance(-1); OpCode opcode = val.Opcode; object operand = val.Operand; val.Advance(2); OpCode opcode2 = val.Opcode; object operand2 = val.Operand; val.Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Conv_I8, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Rem, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Conv_I4, (object)null, (string)null) }).Advance(2) .SetInstructionAndAdvance(new CodeInstruction(opcode2, operand2)); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonNode), "OrderConstructCp", (Type[])null, (Type[])null), (string)null) }).Advance(2).SetInstructionAndAdvance(new CodeInstruction(opcode, operand)); return val.InstructionEnumeration(); } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateProgress", new Type[] { typeof(DysonNode) })] public static void DysonSphere_UpdateProgress_Postfix1(DysonSphere __instance, DysonNode node) { lock (__instance) { DysonSphereLayer obj = __instance.layersIdBased[node.layerId]; obj.totalNodeSP++; } } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateProgress", new Type[] { typeof(DysonFrame) })] public static void DysonSphere_UpdateProgress_Postfix1(DysonSphere __instance, DysonFrame frame) { lock (__instance) { DysonSphereLayer obj = __instance.layersIdBased[frame.layerId]; obj.totalFrameSP++; } } [HarmonyPostfix] [HarmonyPatch(typeof(DysonShell), "Construct")] public static void DysonShell_Construct_Postfix(DysonShell __instance, bool __result) { if (__result) { DysonSphereLayer parentLayer = __instance.parentLayer; parentLayer.totalCP++; } } [HarmonyPrefix] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveDysonNode")] public static void DysonSphereLayer_RemoveDysonNode_Prefix(ref DysonSphereLayer __instance, int nodeId) { if (__instance.nodePool[nodeId].id != 0) { DysonSphereLayer obj = __instance; obj.totalNodeSP -= __instance.nodePool[nodeId].sp; } } [HarmonyPrefix] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveDysonFrame")] public static void DysonSphereLayer_RemoveDysonFrame_Prefix(ref DysonSphereLayer __instance, int frameId) { if (__instance.framePool[frameId].id != 0) { DysonSphereLayer obj = __instance; obj.totalFrameSP -= __instance.framePool[frameId].spA + __instance.framePool[frameId].spB; } } [HarmonyPrefix] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveDysonShell")] public static void DysonSphereLayer_RemoveDysonShell_Prefix(ref DysonSphereLayer __instance, int shellId) { if (__instance.shellPool[shellId].id != 0) { DysonSphereLayer obj = __instance; obj.totalCP -= __instance.shellPool[shellId].cellPoint; } } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphere), "BeforeGameTick")] private static IEnumerable<CodeInstruction> SpherePowerPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonSphereLayer), "set_energyGenCurrentTick", (Type[])null, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null) }); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(DysonSphere), "energyGenCurrentTick"), (string)null) }).Advance(1); Label label = default(Label); val.CreateLabel(ref label); val.Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Conv_I8, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonSphereLayer), "set_energyGenCurrentTick", (Type[])null, (Type[])null), (string)null) }).Advance(-1); OpCode opcode = val.Opcode; object operand = val.Operand; Label label2 = default(Label); val.Insert((CodeInstruction[])(object)new CodeInstruction[4] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(opcode, operand), Transpilers.EmitDelegate<Action<DysonSphere, DysonSphereLayer>>((Action<DysonSphere, DysonSphereLayer>)delegate(DysonSphere sphere, DysonSphereLayer layer) { layer.energyGenCurrentTick = layer.totalNodeSP * sphere.energyGenPerNode + layer.totalFrameSP * sphere.energyGenPerFrame + layer.totalCP * sphere.energyGenPerShell; sphere.energyGenCurrentTick += layer.energyGenCurrentTick; }), new CodeInstruction(OpCodes.Br, (object)label) }).CreateLabel(ref label2); val.Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonSphereLayer), "get_grossRadius", (Type[])null, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSphere), "grossRadius"), (string)null) }).Advance(1) .SetOperandAndAdvance((object)label2); return val.InstructionEnumeration(); } public static void UpdateColourPostfix(DysonSphere __instance, DysonNode node) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(Color32.op_Implicit(node.color), ref num, ref num2, ref num3); __instance.nrdPool[node.rid].color = new Vector4(num, num2, num3, (float)(int)node.color.a); } private static IEnumerable<CodeInstruction> SphereGameTickPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(DysonSphere), "FindNode", (Type[])null, (Type[])null), (string)null) }).Advance(3); Label label = (Label)val.Operand; val.Advance(-10).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Br, (object)label) }); Label label2 = default(Label); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => CodeInstructionExtensions.LoadsConstant(x)), (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(PerformanceMonitor), "BeginSample", (Type[])null, (Type[])null), (string)null) }).CreateLabel(ref label2); val.Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSphere), "nrdPool"), (string)null) }).Advance(-4) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DysonNodeOpt), "SailsVisible", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Brfalse_S, (object)label2) }); return val.InstructionEnumeration(); } } public static void InitSPAndCPCounts() { DysonSphere[] dysonSpheres = GameMain.data.dysonSpheres; foreach (DysonSphere val in dysonSpheres) { if (val == null) { continue; } for (int j = 1; j < val.layersIdBased.Length; j++) { DysonSphereLayer val2 = val.layersIdBased[j]; if (val2 == null || val2.id != j) { continue; } val2.totalNodeSP = 0L; val2.totalFrameSP = 0L; val2.totalCP = 0L; DysonNode[] nodePool = val2.nodePool; for (int k = 1; k < val2.nodeCursor; k++) { if (nodePool[k] != null && nodePool[k].id == k) { val2.totalNodeSP += nodePool[k].sp; } } DysonFrame[] framePool = val2.framePool; for (int l = 1; l < val2.frameCursor; l++) { if (framePool[l] != null && framePool[l].id == l) { val2.totalFrameSP += framePool[l].spA + framePool[l].spB; } } DysonShell[] shellPool = val2.shellPool; for (int m = 1; m < val2.shellCursor; m++) { if (shellPool[m] != null && shellPool[m].id == m) { val2.totalCP += shellPool[m].cellPoint; } } } } } private static bool SailsVisible(DysonSphere sphere) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0040: Expected I4, but got Unknown if (sphere?.swarm == null) { return false; } GameData data = GameMain.data; UIGame uiGame = UIRoot.instance.uiGame; UIDysonEditor dysonEditor = uiGame.dysonEditor; ERenderPlace renderPlace = DysonSphere.renderPlace; switch ((int)renderPlace) { case 0: if (data.localStar == sphere.starData) { return sphere.inGameRenderMaskS != 0; } return false; case 1: if (!UIStarmap.isChangingToMilkyWay && uiGame.starmap.viewStarSystem == sphere.starData) { return sphere.inGameRenderMaskS != 0; } return false; case 2: if (dysonEditor.selection.viewDysonSphere == sphere) { return sphere.inEditorRenderMaskS != 0; } return false; default: return true; } } } [RunPatches(typeof(Patch))] internal class LowResShellsLegacySupport { private class Patch { [HarmonyPrefix] [HarmonyPatch(typeof(GameData), "Import")] public static void ResetShellUpdateListPatch() { shellsToUpdate = new List<DysonShell>(); } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonShell), "Import")] private static IEnumerable<CodeInstruction> ShellUpdateTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.Start(); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(DysonShell), "GenerateGeometry", (Type[])null, (Type[])null), (string)null) }).MatchForward(false, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(DysonShell), "vertsqOffset"), (string)null) }).RemoveInstructions(6) .MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(DysonShell), "GenerateGeometry", (Type[])null, (Type[])null), (string)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), Transpilers.EmitDelegate<Action<DysonShell>>((Action<DysonShell>)delegate(DysonShell shell) { shellsToUpdate.Add(shell); }), new CodeInstruction(OpCodes.Ret, (object)null) }); return val.InstructionEnumeration(); } } private static List<DysonShell> shellsToUpdate; public static void UpdateShells() { if (shellsToUpdate == null) { return; } foreach (DysonShell item in shellsToUpdate) { double[] array = new double[item.nodes.Count]; for (int i = 0; i < item.nodes.Count; i++) { array[i] = (double)item.nodecps[i] / (double)((item.vertsqOffset[i + 1] - item.vertsqOffset[i]) * 2); } item.vertsqOffset = null; item.nodecps = null; item.GenerateGeometry(); int num = 0; item.nodecps = new int[item.nodes.Count + 1]; for (int j = 0; j < item.nodes.Count; j++) { item.nodecps[j] = (int)(array[j] * (double)((item.vertsqOffset[j + 1] - item.vertsqOffset[j]) * item.cpPerVertex) + 0.1); num += item.nodecps[j]; } item.nodecps[item.nodes.Count] = num; item.GenerateModelObjects(); } shellsToUpdate = null; } } internal class PatchManager { public static void Init(Harmony harmony) { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); for (int i = 0; i < types.Length; i++) { foreach (Attribute customAttribute in types[i].GetCustomAttributes()) { if (customAttribute is RunPatchesAttribute) { harmony.PatchAll((customAttribute as RunPatchesAttribute).Patches); } } } } } [RunPatches(typeof(Patch))] internal class PerformanceStatsFix { private class Patch { [HarmonyTranspiler] [HarmonyPatch(typeof(GameData), "GameTick")] private static IEnumerable<CodeInstruction> StatsFixPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); MethodInfo methodInfo = AccessTools.Method(typeof(PerformanceMonitor), "BeginSample", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(PerformanceMonitor), "EndSample", (Type[])null, (Type[])null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)(sbyte)12, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null) }).RemoveInstructions(2); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)(sbyte)12, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo2, (string)null) }).RemoveInstructions(2); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)(sbyte)10, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null) }).RemoveInstructions(2); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_S, (object)(sbyte)10, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo2, (string)null) }).RemoveInstructions(2); return val.InstructionEnumeration(); } } } [Optimization("EntityNeedsOpt", "", false, new Type[] { })] internal class EntityNeedsOpt : OptimizationSet { private class Patch { [HarmonyTranspiler] [HarmonyPatch(typeof(AssemblerComponent), "InternalUpdate")] private static IEnumerable<CodeInstruction> NeedsDirtyPatch1(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(AssemblerComponent), "replicating"), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldc_I4_1, (object)null), new CodeInstruction(OpCodes.Stfld, (object)AccessTools.Field(typeof(AssemblerComponent), "needsDirty")) }); return val.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(UIAssemblerWindow), "OnManualServingContentChange")] private static IEnumerable<CodeInstruction> NeedsDirtyPatch2(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.End().MatchBack(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ret, (object)null, (string)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[8] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(UIAssemblerWindow), "factorySystem")), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(FactorySystem), "assemblerPool")), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UIAssemblerWindow), "get_assemblerId", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Ldelema, (object)typeof(AssemblerComponent)), new CodeInstruction(OpCodes.Ldc_I4_1, (object)null), new CodeInstruction(OpCodes.Stfld, (object)AccessTools.Field(typeof(AssemblerComponent), "needsDirty")) }); return val.InstructionEnumeration(); } [HarmonyPostfix] [HarmonyPatch(typeof(PlanetFactory), "InsertInto")] public static void NeedsDirtyPatch3(PlanetFactory __instance, int __result, int entityId) { if (__result != 0) { int assemblerId = __instance.entityPool[entityId].assemblerId; if (assemblerId > 0) { __instance.factorySystem.assemblerPool[assemblerId].needsDirty = true; } } } [HarmonyTranspiler] [HarmonyPatch(typeof(PlanetFactory), "EntityFastFillIn")] private static IEnumerable<CodeInstruction> NeedsDirtyPatch4(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(AssemblerComponent), "requires"), (string)null) }).Advance(-3).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[11] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlanetFactory), "factorySystem")), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(FactorySystem), "assemblerPool")), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlanetFactory), "entityPool")), new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Ldelema, (object)typeof(EntityData)), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(EntityData), "assemblerId")), new CodeInstruction(OpCodes.Ldelema, (object)typeof(AssemblerComponent)), new CodeInstruction(OpCodes.Ldc_I4_1, (object)null), new CodeInstruction(OpCodes.Stfld, (object)AccessTools.Field(typeof(AssemblerComponent), "needsDirty")) }); return val.InstructionEnumeration(); } [HarmonyPostfix] [HarmonyPatch(typeof(AssemblerComponent), "Import")] [HarmonyPatch(typeof(AssemblerComponent), "SetEmpty")] [HarmonyPatch(typeof(AssemblerComponent), "SetRecipe")] public static void NeedsDirtyPatch5(ref AssemblerComponent __instance) { __instance.needsDirty = true; } } } [RunPatches(typeof(Patch))] [Optimization("LayerDismantleOpt", "", false, new Type[] { })] public class LayerDismantleOpt { private class Patch { [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveDysonFrame")] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveDysonNode")] private static IEnumerable<CodeInstruction> RemoveRebuildModelsCall(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); Label label = default(Label); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[4] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSphereLayer), "dysonSphere"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSphere), "modelRenderer"), (string)null), new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonSphereSegmentRenderer), "RebuildModels", (Type[])null, (Type[])null), (string)null) }).Advance(1).CreateLabel(ref label) .Advance(-4) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(LayerDismantleOpt), "dismantling")), new CodeInstruction(OpCodes.Brtrue, (object)label) }); return val.InstructionEnumeration(); } [HarmonyPrefix] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveAllStructure")] public static void DismantlePrefix(DysonSphereLayer __instance) { dismantling = true; } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphereLayer), "RemoveAllStructure")] public static void DismantlePostfix(DysonSphereLayer __instance) { __instance.dysonSphere.modelRenderer.RebuildModels(); dismantling = false; } } public static bool dismantling; } [RunPatches(typeof(Patch))] [Optimization("MonitorOpt", "Optimizes the game logic for traffic monitors", false, new Type[] { })] internal class MonitorOpt : OptimizationSet { private class Patch { [HarmonyPostfix] [HarmonyPatch(typeof(MonitorComponent), "SetEmpty")] [HarmonyPatch(typeof(MonitorComponent), "Import")] public static void InitIdxPatch(ref MonitorComponent __instance) { __instance.startIdx = 0; } [HarmonyPrefix] [HarmonyPatch(typeof(MonitorComponent), "Export")] [HarmonyPatch(typeof(MonitorComponent), "SetPeriodTickCount")] public static void ResizeArraysPatch(ref MonitorComponent __instance) { ResetArrays(ref __instance); } [HarmonyPrefix] [HarmonyPatch(typeof(UIMonitorWindow), "_OnUpdate")] public static void WindowPatch(UIMonitorWindow __instance) { if (__instance.monitorAvailable && __instance.monitorId != 0 && __instance.factory != null) { ResetArrays(ref __instance.cargoTraffic.monitorPool[__instance.monitorId]); } } [HarmonyTranspiler] [HarmonyPatch(typeof(MonitorComponent), "InternalUpdate")] private static IEnumerable<CodeInstruction> UpdatePatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Expected O, but got Unknown //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); LocalBuilder localBuilder = generator.DeclareLocal(typeof(int)); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(MonitorComponent), "cargoFlow"), (string)null) }).Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(MonitorComponent), "startIdx")), new CodeInstruction(OpCodes.Stloc_S, (object)localBuilder) }); val.Advance(5).SetInstruction(new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder)); for (int i = 0; i < 2; i++) { val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Array), "Copy", new Type[5] { typeof(Array), typeof(int), typeof(Array), typeof(int), typeof(int) }, (Type[])null), (string)null) }); val.Advance(-10).SetOpcodeAndAdvance(OpCodes.Nop).RemoveInstructions(10); } val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[9] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(MonitorComponent), "startIdx")), new CodeInstruction(OpCodes.Ldc_I4_1, (object)null), new CodeInstruction(OpCodes.Add, (object)null), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(MonitorComponent), "periodTickCount")), new CodeInstruction(OpCodes.Rem, (object)null), new CodeInstruction(OpCodes.Stfld, (object)AccessTools.Field(typeof(MonitorComponent), "startIdx")) }); for (int j = 0; j < 2; j++) { val.Advance(2).RemoveInstructions(4).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder) }) .Advance(2); } val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(MonitorComponent), "cargoBytesArray"), (string)null) }); for (int k = 0; k < 2; k++) { val.Advance(2).RemoveInstructions(4).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder) }) .Advance(3); } return val.InstructionEnumeration(); } } private const int MAX_TICK_COUNT = 3600; private static int[] COPY_BUFFER = new int[3600]; private static sbyte[] COPY_BUFFER_2 = new sbyte[3600]; private static void ResetArrays(ref MonitorComponent monitor) { if (monitor.startIdx != 0) { int num = monitor.periodTickCount - monitor.startIdx; Array.Copy(monitor.periodCargoBytesArray, monitor.startIdx, COPY_BUFFER, 0, num); Array.Copy(monitor.periodCargoBytesArray, 0, COPY_BUFFER, num, monitor.startIdx); Array.Copy(COPY_BUFFER, monitor.periodCargoBytesArray, monitor.periodTickCount); Array.Copy(monitor.cargoBytesArray, monitor.startIdx, COPY_BUFFER_2, 0, num); Array.Copy(monitor.cargoBytesArray, 0, COPY_BUFFER_2, num, monitor.startIdx); Array.Copy(COPY_BUFFER_2, monitor.cargoBytesArray, monitor.periodTickCount); monitor.startIdx = 0; } } } [Optimization("ChargerOpt", "", false, new Type[] { })] internal class ChargerOpt { private class Patch { [HarmonyPostfix] [HarmonyPatch(typeof(PowerSystem), "Import")] public static void ImportPatch(PowerSystem __instance) { __instance.substationEnergyDemand = 0L; for (int i = 1; i < __instance.netCursor; i++) { PowerNetwork val = __instance.netPool[i]; if (val == null || val.id != i) { continue; } foreach (Node node in val.nodes) { int id = node.id; if (__instance.nodePool[id].id == id && __instance.nodePool[id].isCharger) { if (IsSubstation(__instance, id)) { __instance.substationEnergyDemand += __instance.nodePool[id].idleEnergyPerTick; } else { AddCharger(__instance, id); } } } } } [HarmonyPostfix] [HarmonyPatch(typeof(PowerSystem), "NewNodeComponent")] public static void AddNodePatch(PowerSystem __instance, int __result) { if (__instance.nodePool[__result].isCharger) { if (IsSubstation(__instance, __result)) { __instance.substationEnergyDemand += __instance.nodePool[__result].idleEnergyPerTick; } else { AddCharger(__instance, __result); } } } [HarmonyPrefix] [HarmonyPatch(typeof(PowerSystem), "RemoveNodeComponent")] public static void RemoveNodePatch(PowerSystem __instance, int id) { if (__instance.nodePool[id].isCharger) { if (IsSubstation(__instance, id)) { __instance.substationEnergyDemand -= __instance.nodePool[id].idleEnergyPerTick; } else { RemoveCharger(__instance, id); } } } } private const int INITIAL_CHARGER_POOL_SIZE = 8; private static void SetChargerCapacity(PowerSystem powerSystem, int newCapacity) { int[] chargerPool = powerSystem.chargerPool; powerSystem.chargerPool = new int[newCapacity]; if (chargerPool != null) { int num = chargerPool.Length; Array.Copy(chargerPool, powerSystem.chargerPool, (newCapacity > num) ? num : newCapacity); } } private static void AddCharger(PowerSystem powerSystem, int nodeId) { if (powerSystem.chargerPool == null) { SetChargerCapacity(powerSystem, 8); powerSystem.chargerCursor = 0; } else if (powerSystem.chargerCursor == powerSystem.chargerPool.Length) { SetChargerCapacity(powerSystem, powerSystem.chargerCursor * 2); } powerSystem.chargerPool[powerSystem.chargerCursor] = nodeId; powerSystem.chargerCursor++; } private static void RemoveCharger(PowerSystem powerSystem, int nodeId) { int i; for (i = 0; i < powerSystem.chargerCursor && powerSystem.chargerPool[i] != nodeId; i++) { } if (i != powerSystem.chargerCursor) { int num = powerSystem.chargerCursor - 1; if (i < num) { powerSystem.chargerPool[i] = powerSystem.chargerPool[num]; } powerSystem.chargerPool[num] = 0; powerSystem.chargerCursor--; } } private static bool IsSubstation(PowerSystem powerSystem, int nodeId) { return powerSystem.nodePool[nodeId].coverRadius >= 15f; } } [Optimization("PCStateOpt", "", false, new Type[] { })] internal class PCStateOpt { private class Patch { } } [Optimization("ReceiverOpt", "", false, new Type[] { })] internal class ReceiverOpt : OptimizationSet { private class Patch { [HarmonyPostfix] [HarmonyPatch(typeof(PowerSystem), "Import")] public static void ImportPatch(PowerSystem __instance) { for (int i = 1; i < __instance.genCursor; i++) { if (__instance.genPool[i].gamma) { AddReceiver(__instance, i); } } } [HarmonyPostfix] [HarmonyPatch(typeof(PowerSystem), "NewGeneratorComponent")] public static void AddGenPatch(PowerSystem __instance, int __result) { if (__instance.genPool[__result].gamma) { AddReceiver(__instance, __result); } } [HarmonyPrefix] [HarmonyPatch(typeof(PowerSystem), "RemoveGeneratorComponent")] public static void RemoveGenPatch(PowerSystem __instance, int id) { if (__instance.genPool[id].gamma) { RemoveReceiver(__instance, id); } } } private const int INITIAL_RECEIVER_POOL_SIZE = 8; private static void SetReceiverCapacity(PowerSystem powerSystem, int newCapacity) { int[] receiverPool = powerSystem.receiverPool; powerSystem.receiverPool = new int[newCapacity]; if (receiverPool != null) { int num = receiverPool.Length; Array.Copy(receiverPool, powerSystem.receiverPool, (newCapacity > num) ? num : newCapacity); } } private static void AddReceiver(PowerSystem powerSystem, int genId) { if (powerSystem.receiverPool == null) { SetReceiverCapacity(powerSystem, 8); powerSystem.receiverCursor = 0; } else if (powerSystem.receiverCursor == powerSystem.receiverPool.Length) { SetReceiverCapacity(powerSystem, powerSystem.receiverCursor * 2); } powerSystem.receiverPool[powerSystem.receiverCursor] = genId; powerSystem.receiverCursor++; } private static void RemoveReceiver(PowerSystem powerSystem, int genId) { int i; for (i = 0; i < powerSystem.receiverCursor && powerSystem.receiverPool[i] != genId; i++) { } if (i != powerSystem.receiverCursor) { int num = powerSystem.receiverCursor - 1; if (i < num) { powerSystem.receiverPool[i] = powerSystem.receiverPool[num]; } powerSystem.receiverPool[num] = 0; powerSystem.receiverCursor--; } } } internal class ShipRendererOpt : OptimizationSet { private class Patch { [HarmonyTranspiler] [HarmonyPatch(typeof(StationComponent), "ShipRenderersOnTick")] private static IEnumerable<CodeInstruction> IdleShipPoseFix(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); LocalBuilder localBuilder = generator.DeclareLocal(typeof(bool)); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Assert), "Zero", new Type[1] { typeof(int) }, (Type[])null), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), Transpilers.EmitDelegate<Func<StationComponent, bool>>((Func<StationComponent, bool>)delegate(StationComponent station) { PlanetData localPlanet = GameMain.data.localPlanet; return localPlanet != null && localPlanet.id == station.planetId; }), new CodeInstruction(OpCodes.Stloc_S, (object)localBuilder) }); Label label = default(Label); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(ShipRenderingData), "SetPose", (Type[])null, (Type[])null), (string)null) }).Advance(1).CreateLabel(ref label) .MatchBack(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(ShipRenderingData), "gid"), (string)null) }) .Advance(-4); OpCode opcode = val.Opcode; object operand = val.Operand; Label label2 = default(Label); val.Advance(5).CreateLabel(ref label2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[10] { new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder), new CodeInstruction(OpCodes.Brtrue, (object)label2), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(StationComponent), "shipRenderers")), new CodeInstruction(opcode, operand), new CodeInstruction(OpCodes.Ldelema, (object)typeof(ShipRenderingData)), new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(ShipRenderingData), "pos")), new CodeInstruction(OpCodes.Ldc_R4, (object)1E+09f), new CodeInstruction(OpCodes.Stfld, (object)AccessTools.Field(typeof(Vector3), "x")), new CodeInstruction(OpCodes.Br, (object)label) }); return val.InstructionEnumeration(); } } } [BepInPlugin("com.Selsion.DSPOptimizations", "DSPOptimizations", "1.1.17")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin, IModCanSave { public const string MOD_GUID = "com.Selsion.DSPOptimizations"; public const string MOD_NAME = "DSPOptimizations"; public const string MOD_VERSION = "1.1.17"; private static Harmony harmony; public static ManualLogSource logger; internal void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown logger = ((BaseUnityPlugin)this).Logger; CommandManager.QueueInit(); OptimizationSetManager.Init((BaseUnityPlugin)(object)this); harmony = new Harmony("com.Selsion.DSPOptimizations"); PatchManager.Init(harmony); if (((BaseUnityPlugin)this).Config.Bind<bool>("General", "disableShadows", false, "Set to true to disable shadows.").Value) { QualitySettings.shadows = (ShadowQuality)0; } } public void OnDestroy() { OptimizationSetManager.OnDestroy(); CommandManager.OnDestroy(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } void IModCanSave.Export(BinaryWriter w) { int value = 2; w.Write(value); } void IModCanSave.Import(BinaryReader r) { if (r.ReadInt32() == 1) { LowResShellsSaveManager.ImportWrapper(r); } LowResShellsLegacySupport.UpdateShells(); DysonNodeOpt.InitSPAndCPCounts(); } void IModCanSave.IntoOtherSave() { LowResShellsLegacySupport.UpdateShells(); DysonNodeOpt.InitSPAndCPCounts(); _ = DSPGame.IsMenuDemo; } } public class LowResShellsSaveManager { private class Patch { [HarmonyPostfix] [HarmonyPatch(typeof(GameSave), "LoadCurrentGame")] [HarmonyAfter(new string[] { "crecheng.DSPModSave" })] public static void DSPModSaveLoadingFix() { if (!DSPGame.IsMenuDemo) { if (!loaded) { Plugin.logger.LogWarning((object)"The mod initialization was not called properly for this save, but will now be loaded. Are you using the correct version of DSPModSave?"); IntoOtherSave(); } loaded = false; } } [HarmonyPrefix] [HarmonyPatch(typeof(GameData), "Export")] [HarmonyPatch(typeof(GameData), "Import")] public static void ClearErrorCounts() { shellImportFailCount = 0; shellExportFailCount = 0; } [HarmonyPostfix] [HarmonyPatch(typeof(GameData), "Export")] [HarmonyPatch(typeof(GameData), "Import")] public static void CheckForErrors() { if (shellExportFailCount > 0) { Plugin.logger.LogError((object)$"{shellExportFailCount} shells had a null vertsqOffset_lowRes array"); shellExportFailCount = 0; } if (shellImportFailCount > 0) { Plugin.logger.LogError((object)$"{shellImportFailCount} shells required a full regen (includes vanilla cp counts)"); shellImportFailCount = 0; } } } private static MemoryStream stream; public static bool loaded; private static int shellImportFailCount; private static int shellExportFailCount; public static void ExportWrapper(BinaryWriter w) { try { MemoryStream memoryStream = new MemoryStream(); BinaryWriter binaryWriter = new BinaryWriter(memoryStream); Export(binaryWriter); binaryWriter.Flush(); memoryStream.Position = 0L; stream = memoryStream; w.Write(1); } catch (Exception ex) { Plugin.logger.LogError((object)("Failed to export current low res shells data to buffer. Error message: " + ex.InnerException)); w.Write(-1); } if (stream == null) { w.Write(0); return; } w.Write((int)stream.Length); try { stream.WriteTo(w.BaseStream); Plugin.logger.LogDebug((object)$"Wrote {stream.Length} bytes to disk for LowResShells"); } catch { Plugin.logger.LogError((object)"CRITICAL ERROR: Failed to write LowResShells export buffer to output stream"); throw; } } public static void ImportWrapper(BinaryReader r) { r.ReadInt32(); int num = r.ReadInt32(); Plugin.logger.LogDebug((object)$"LowResShells has {num} bytes to import"); if (num > 0) { stream = new MemoryStream(); stream.Write(r.ReadBytes(num), 0, num); stream.Position = 0L; try { Import(new BinaryReader(stream), num); } catch (EndOfStreamException) { Plugin.logger.LogError((object)"Reached the end of the low res shells save data when reading. The data is likely either corrupt or invalid and will be ignored. New data will be generated."); IntoOtherSave(); } catch (Exception ex2) { Plugin.logger.LogError((object)("Unhandled exception when loading low res shells data. New data will be generated in place of the old data. Error message:\n" + ex2.InnerException)); IntoOtherSave(); } } else { stream = null; Plugin.logger.LogWarning((object)"No low res shells save data exists. New data will be generated."); IntoOtherSave(); } if (!loaded) { RecalcAllCpReq(); loaded = true; } } public static void Export(BinaryWriter w) { int value = 1; w.Write(value); DysonSphere[] dysonSpheres = GameMain.data.dysonSpheres; int num = dysonSpheres.Length; w.Write(num); for (int i = 0; i < num; i++) { DysonSphere val = dysonSpheres[i]; if (val != null) { w.Write(1); int num2 = val.layersIdBased.Length; w.Write(num2); for (int j = 1; j < num2; j++) { DysonSphereLayer val2 = val.layersIdBased[j]; if (val2 != null && val2.id == j) { w.Write(val2.orbitRadius); w.Write(val2.id); w.Write(val2.radius_lowRes); w.Write(val2.shellCursor); for (int k = 1; k < val2.shellCursor; k++) { DysonShell val3 = val2.shellPool[k]; if (val3 != null && val3.id == k) { w.Write(val3.id); w.Write(val3.radius_lowRes); w.Write(val3.surfaceAreaUnitSphere); w.Write(val3.vertsqOffset.Length); for (int l = 0; l < val3.vertsqOffset.Length; l++) { w.Write(val3.vertsqOffset[l]); } w.Write(val3.vertsqOffset_lowRes.Length); for (int m = 0; m < val3.vertsqOffset_lowRes.Length; m++) { w.Write(val3.vertsqOffset_lowRes[m]); } } else { w.Write(0); } } } else { w.Write(-1f); w.Write(0); } } } else { w.Write(0); } } } public static void Import(BinaryReader r, int streamLength) { int num = r.ReadInt32(); if (num == 1) { DysonSphere[] dysonSpheres = GameMain.data.dysonSpheres; int num2 = r.ReadInt32(); for (int i = 0; i < num2; i++) { DysonSphere val = dysonSpheres[i]; int num3 = r.ReadInt32(); if (val != null && num3 == 1) { ImportSphere(r, val); } else if (val != null && num3 == 0) { ImportSphereGenerate(val); } else if (val == null && num3 == 1) { ImportSphereIgnore(r); } } } else { Plugin.logger.LogError((object)$"Invalid shell save version: {num}. Shell save data will be discarded. New data will be generated."); r.ReadBytes(streamLength - 4); IntoOtherSave(); } } private static void ImportSphere(BinaryReader r, DysonSphere sphere) { int num = r.ReadInt32(); for (int i = 1; i < num; i++) { DysonSphereLayer val = sphere.layersIdBased[i]; float num2 = r.ReadSingle(); int num3 = r.ReadInt32(); if (val != null && val.id == i && val.orbitRadius != num2) { if (num3 != 0) { ImportLayerIgnore(r); } ImportLayerGenerate(val); } if (val != null && val.id == i && num3 == i) { ImportLayer(r, val); } else if (val != null && val.id == i && num3 != i) { ImportLayerGenerate(val); } else if (num3 == i) { ImportLayerIgnore(r); } } } private static void ImportSphereIgnore(BinaryReader r) { int num = r.ReadInt32(); for (int i = 1; i < num; i++) { r.ReadSingle(); if (r.ReadInt32() == i) { ImportLayerIgnore(r); } } } private static void ImportSphereGenerate(DysonSphere sphere) { int num = sphere.layersIdBased.Length; for (int i = 1; i < num; i++) { DysonSphereLayer val = sphere.layersIdBased[i]; if (val != null && val.id == i) { ImportLayerGenerate(val); } } } private static void ImportLayer(BinaryReader r, DysonSphereLayer layer) { layer.radius_lowRes = r.ReadSingle(); if (layer.radius_lowRes <= 0f || layer.radius_lowRes > layer.orbitRadius) { layer.radius_lowRes = layer.orbitRadius; } int num = r.ReadInt32(); int shellCursor = layer.shellCursor; int num2 = Math.Min(num, shellCursor); for (int i = 1; i < num2; i++) { DysonShell val = layer.shellPool[i]; int num3 = r.ReadInt32(); if (val != null && val.id == i && num3 == i) { ImportShell(r, val); } else if (val != null && val.id == i && num3 != i) { ImportShellGenerate(val); } else if (num3 == i) { ImportShellIgnore(r); } } if (num < shellCursor) { for (int j = num2; j < shellCursor; j++) { DysonShell val2 = layer.shellPool[j]; if (val2 != null && val2.id == j) { ImportShellGenerate(val2); } } } else { if (shellCursor >= num) { return; } for (int k = num2; k < num; k++) { if (r.ReadInt32() == k) { ImportShellIgnore(r); } } } } private static void ImportLayerIgnore(BinaryReader r) { r.ReadSingle(); int num = r.ReadInt32(); for (int i = 1; i < num; i++) { if (r.ReadInt32() == i) { ImportShellIgnore(r); } } } private static void ImportLayerGenerate(DysonSphereLayer layer) { layer.radius_lowRes = layer.orbitRadius; int shellCursor = layer.shellCursor; for (int i = 1; i < shellCursor; i++) { DysonShell val = layer.shellPool[i]; if (val != null && val.id == i) { ImportShellGenerate(val); } } } private static void ImportShell(BinaryReader r, DysonShell shell) { shell.radius_lowRes = r.ReadSingle(); r.ReadSingle(); int num = r.ReadInt32(); int[] array = new int[num]; for (int i = 0; i < num; i++) { array[i] = r.ReadInt32(); } int num2 = r.ReadInt32(); int[] array2 = new int[num2]; for (int j = 0; j < num2; j++) { array2[j] = r.ReadInt32(); } int num3 = shell.vertsqOffset.Length; bool flag = num == num3 && num2 == num3; if (flag) { for (int k = 0; k < num3; k++) { if (shell.vertsqOffset[k] != array2[k]) { flag = false; break; } } if (array2[num3 - 1] > array[num3 - 1]) { flag = false; } } if (flag) { shell.vertsqOffset_lowRes = array2; shell.vertsqOffset = array; } else { ImportShellGenerate(shell, overrideFlag: true); } } private static void ImportShellIgnore(BinaryReader r) { r.ReadSingle(); r.ReadSingle(); int num = r.ReadInt32(); for (int i = 0; i < num; i++) { r.ReadInt32(); } int num2 = r.ReadInt32(); for (int j = 0; j < num2; j++) { r.ReadInt32(); } } private static void ImportShellGenerate(DysonShell shell, bool overrideFlag = false) { } public static void IntoOtherSave() { Plugin.logger.LogWarning((object)"Calling IntoOtherSave(). If this is your first time loading this save with LowResShells enabled, then ignore this warning."); DysonSphere[] array = GameMain.data?.dysonSpheres; if (array != null) { DysonSphere[] array2 = array; foreach (DysonSphere val in array2) { if (val != null) { ImportSphereGenerate(val); } } } RecalcAllCpReq(); loaded = true; } private static void RecalcAllCpReq() { DysonSphere[] dysonSpheres = GameMain.data.dysonSpheres; if (dysonSpheres == null) { return; } DysonSphere[] array = dysonSpheres; foreach (DysonSphere val in array) { if (val?.layersIdBased == null) { continue; } DysonSphereLayer[] layersIdBased = val.layersIdBased; foreach (DysonSphereLayer val2 in layersIdBased) { if (val2 == null) { continue; } for (int k = 1; k < val2.nodeCursor; k++) { if (val2.nodePool[k] != null && val2.nodePool[k].id == k) { val2.nodePool[k].RecalcCpReq(); } } } } } public static void SwapVertOffsetArrays(DysonShell shell) { int[] vertsqOffset = shell.vertsqOffset; shell.vertsqOffset = shell.vertsqOffset_lowRes; shell.vertsqOffset_lowRes = vertsqOffset; } } [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] internal class ConfigValueAttribute : Attribute { private string description; private object defaultValue; public string Description => description; public object DefaultValue => defaultValue; public ConfigValueAttribute(object defaultValue, string description) { this.description = description; this.defaultValue = defaultValue; } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] internal class OptimizationAttribute : Attribute { private string name; private string description; private bool hasSaveData; private Type[] subModules; public string Name => name; public string Description => description; public Type[] SubModules => subModules; public bool HasSaveData => hasSaveData; public OptimizationAttribute(string name, string description, bool hasSaveData, Type[] subModules = null) { this.name = name; this.description = description; this.hasSaveData = hasSaveData; this.subModules = subModules; } } public abstract class OptimizationSet { protected bool enabled = true; public bool Enabled { get { return enabled; } set { enabled = value; } } public virtual void Init(BaseUnityPlugin plugin) { } public virtual void OnDestroy() { } } internal class OptimizationSetManager { private static List<OptimizationSet> optSetInstances; public static void Init(BaseUnityPlugin plugin) { optSetInstances = new List<OptimizationSet>(); int num = 0; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); for (int i = 0; i < types.Length; i++) { if (RegisterOptimization(types[i], isSubModule: false)) { num++; } } Plugin.logger.LogInfo((object)string.Format("{0} optimization set{1} loaded", num, (num == 1) ? "" : "s")); foreach (OptimizationSet optSetInstance in optSetInstances) { optSetInstance.Init(plugin); } } private static bool RegisterOptimization(Type type, bool isSubModule) { if (!type.IsSubclassOf(typeof(OptimizationSet))) { return false; } OptimizationSet item = (OptimizationSet)Activator.CreateInstance(type); optSetInstances.Add(item); return true; } public static void OnDestroy() { foreach (OptimizationSet optSetInstance in optSetInstances) { optSetInstance.OnDestroy(); } optSetInstances.Clear(); } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] internal class RunPatchesAttribute : Attribute { private Type patches; public Type Patches => patches; public RunPatchesAttribute(Type patches) { this.patches = patches; } } [Optimization("PrebuildOpt", "Reduces permanent lag caused by placing large blueprints", false, new Type[] { })] internal class PrebuildOpt : OptimizationSet { private class Patch { } } [RunPatches(typeof(Patch))] [Optimization("SailBulletOpt", "Optimizes logic for ejected sails", false, new Type[] { })] internal class SailBulletOpt : OptimizationSet { private class Patch { [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSwarm), "GameTick")] private static IEnumerable<CodeInstruction> SailBulletBufferPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Expected O, but got Unknown //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Expected O, but got Unknown //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Expected O, but got Unknown //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Expected O, but got Unknown //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Expected O, but got Unknown //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); LocalBuilder localBuilder = generator.DeclareLocal(typeof(bool)); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(GameHistoryData), "solarSailLife"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null) }).Advance(11).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(SailBulletOpt), "SailBulletsVisible", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Stloc_S, (object)localBuilder) }); Label label = default(Label); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[8] { new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSwarm), "bulletCursor"), (string)null), new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null) }).CreateLabel(ref label); val.Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[4] { new CodeMatch((OpCode?)OpCodes.Ldelema, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)AccessTools.Field(typeof(DysonSphere), "renderPlace"), (string)null) }).SetOpcodeAndAdvance(OpCodes.Nop) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder), new CodeInstruction(OpCodes.Brfalse_S, (object)label), new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(DysonSphere), "renderPlace")) }); Label label2 = default(Label); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSwarm), "bulletBuffer"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSwarm), "bulletPool"), (string)null), new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(ComputeBuffer), "SetData", new Type[1] { typeof(Array) }, (Type[])null), (string)null) }).Advance(1).CreateLabel(ref label2) .Advance(-5) .SetOpcodeAndAdvance(OpCodes.Nop) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder), new CodeInstruction(OpCodes.Brfalse_S, (object)label2), new CodeInstruction(OpCodes.Ldarg_0, (object)null) }); return val.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSwarm), "DrawPost")] private static IEnumerable<CodeInstruction> SailBulletHidePatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); Label label = default(Label); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(DysonSwarm), "GpuAnalysisPost", (Type[])null, (Type[])null), (string)null) }).CreateLabel(ref label).Start() .MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSwarm), "bulletMaterial"), (string)null) }) .SetOpcodeAndAdvance(OpCodes.Nop) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4] { new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(SailBulletOpt), "ejectedSailsVisible")), new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.Method(typeof(ConfigEntry<bool>), "get_Value", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Brfalse_S, (object)label), new CodeInstruction(OpCodes.Ldarg_0, (object)null) }); return val.InstructionEnumeration(); } } private static ConfigEntry<bool> ejectedSailsVisible; public override void Init(BaseUnityPlugin plugin) { ejectedSailsVisible = plugin.Config.Bind<bool>("Spheres and Swarms", "EjectedSailsVisible", true, "Set to false to hide sails being ejected, which can improve UPS"); } private static bool SailBulletsVisible(DysonSwarm swarm) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown if (swarm == null) { return false; } if (!ejectedSailsVisible.Value) { return false; } GameData data = GameMain.data; UIGame uiGame = UIRoot.instance.uiGame; UIDysonEditor dysonEditor = uiGame.dysonEditor; ERenderPlace renderPlace = DysonSphere.renderPlace; switch ((int)renderPlace) { case 0: return data.localStar == swarm.starData; case 1: if (!UIStarmap.isChangingToMilkyWay) { return uiGame.starmap.viewStarSystem == swarm.starData; } return false; case 2: return dysonEditor.selection.viewDysonSphere == swarm.dysonSphere; default: return true; } } } [RunPatches(typeof(Patch))] [Optimization("ShellShaderVarOpt", "Improves fps when rendering dyson shells", false, new Type[] { })] internal class ShellShaderVarOpt : OptimizationSet { private class Patch { [HarmonyPatch(typeof(DysonShell), "GenerateModelObjects")] public static void ShellMatInitPostfix(DysonShell __instance) { __instance.material.SetFloat("_State", (float)__instance.state); } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateStates", new Type[] { typeof(DysonShell), typeof(uint), typeof(bool), typeof(bool) })] public static void UpdateStatePostfix(DysonShell shell) { Material material = shell.material; if (material != null) { material.SetFloat("_State", (float)shell.state); } } [HarmonyPostfix] [HarmonyPatch(typeof(DysonShell), "Construct")] public static void UpdateCPProgressPostfix(DysonShell __instance) { __instance.SetMaterialDynamicVars(); } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphereSegmentRenderer), "DrawModels")] private static IEnumerable<CodeInstruction> RemoveShaderVarCall(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(DysonShell), "SetMaterialDynamicVars", (Type[])null, (Type[])null), (string)null) }).Advance(-1).SetOpcodeAndAdvance(OpCodes.Nop) .SetOpcodeAndAdvance(OpCodes.Nop); return val.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonShell), "SetMaterialDynamicVars")] private static IEnumerable<CodeInstruction> RemoveSetFloatCall(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Material), "SetFloat", new Type[2] { typeof(string), typeof(float) }, (Type[])null), (string)null) }).Advance(-7).SetOpcodeAndAdvance(OpCodes.Nop) .RemoveInstructions(7); return val.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(UIDEToolbox), "OnColorChange")] private static IEnumerable<CodeInstruction> UpdateShellColourPatch1(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(DysonShell), "color"), (string)null) }).Advance(-1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Dup, (object)null) }) .Advance(2) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DysonShell), "SetMaterialDynamicVars", (Type[])null, (Type[])null)) }); return val.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(UIDysonBrush_Paint), "_OnUpdate")] private static IEnumerable<CodeInstruction> UpdateShellColourPatch2(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(DysonShell), "color"), (string)null) }).Advance(-12); OpCode opcode = val.Opcode; object operand = val.Operand; val.Advance(13).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(opcode, operand), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DysonShell), "SetMaterialDynamicVars", (Type[])null, (Type[])null)) }); return val.InstructionEnumeration(); } } } [RunPatches(typeof(Patch))] [Optimization("SphereBufferOpt", "Reduces lag for hidden layers under construction", false, new Type[] { })] internal class SphereBufferOpt : OptimizationSet { private class Patch { [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphereSegmentRenderer), "Init")] public static void InitBatchMasks_Postfix(DysonSphereSegmentRenderer __instance) { __instance.layersDirtyMask = new int[DysonSphereSegmentRenderer.protoMeshes.Length]; } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateProgress", new Type[] { typeof(DysonNode) })] public static void BatchMask_UpdateProgress_Postfix1(DysonSphere __instance, DysonNode node) { __instance.modelRenderer.layersDirtyMask[node.protoId] |= 1 << node.layerId; } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateProgress", new Type[] { typeof(DysonFrame) })] public static void BatchMask_UpdateProgress_Postfix2(DysonSphere __instance, DysonFrame frame) { __instance.modelRenderer.layersDirtyMask[frame.protoId] |= 1 << frame.layerId; } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphereSegmentRenderer), "RebuildModels")] public static void DysonSphereSegmentRenderer_RebuildModels_Postfix(DysonSphereSegmentRenderer __instance) { for (int i = 0; i < DysonSphereSegmentRenderer.totalProtoCount; i++) { __instance.layersDirtyMask[i] = -1; } } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateStates", new Type[] { typeof(DysonNode), typeof(uint), typeof(bool), typeof(bool) })] public static void DysonSphere_UpdateStates_Postfix1(DysonSphere __instance, DysonNode node) { __instance.modelRenderer.layersDirtyMask[node.protoId] |= 1 << node.layerId; } [HarmonyPostfix] [HarmonyPatch(typeof(DysonSphere), "UpdateStates", new Type[] { typeof(DysonFrame), typeof(uint), typeof(bool), typeof(bool) })] public static void DysonSphere_UpdateStates_Postfix2(DysonSphere __instance, DysonFrame frame) { __instance.modelRenderer.layersDirtyMask[frame.protoId] |= 1 << frame.layerId; } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphereSegmentRenderer), "DrawModels")] private static IEnumerable<CodeInstruction> DrawModels_SyncBuffers_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Batch), "SyncBufferData", (Type[])null, (Type[])null), (string)null) }).Advance(-3).SetOpcodeAndAdvance(OpCodes.Nop) .Advance(1) .RemoveInstructions(2) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_2, (object)null), new CodeInstruction(OpCodes.Ldarg_3, (object)null), Transpilers.EmitDelegate<Action<DysonSphereSegmentRenderer, int, int, int>>((Action<DysonSphereSegmentRenderer, int, int, int>)delegate(DysonSphereSegmentRenderer renderer, int batchIdx, int editorMask, int gameMask) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if (((((int)DysonSphere.renderPlace == 2) ? editorMask : gameMask) & renderer.layersDirtyMask[batchIdx]) != 0) { renderer.batches[batchIdx].SyncBufferData(); renderer.layersDirtyMask[batchIdx] = 0; } }) }); return val.InstructionEnumeration(); } } } [RunPatches(typeof(Patch))] [Optimization("StationStorageOpt", "Adds multithreading to station storage logic", false, new Type[] { })] internal class StationStorageOpt : OptimizationSet { private class WorkerThread { private int id; public WaitCallback callback; public AutoResetEvent completeEvent; public WorkerThread(int id) { this.id = id; callback = ThreadCallback; completeEvent = new AutoResetEvent(initialState: true); } private void ThreadCallback(object state = null) { bool flag = (bool)state; bool sandboxToolsEnabled = GameMain.sandboxToolsEnabled; int num = (stationIdMap.Length - 1) / numThreads + 1; int num2 = num * id; int num3 = Math.Min(num2 + num, stationIdMap.Length); for (int i = num2; i < num3; i++) { int num4 = stationIdMap[i]; int num5 = Utils.LowerBound(factorySizesPrefixSum, num4 + 1, 0, GameMain.data.factoryCount); int num6 = num4 - ((num5 > 0) ? factorySizesPrefixSum[num5 - 1] : 0); PlanetFactory val = GameMain.data.factories[num5]; StationComponent val2 = val.transport.stationPool[num6]; bool flag2 = (GameMain.instance.timei + num5) % 30 == 0L || val.planet == GameMain.data.localPlanet; if (val2 == null || val2.id != num6) { continue; } CargoTraffic cargoTraffic = val.cargoTraffic; SignData[] entitySignPool = val.entitySignPool; if (flag) { val2.UpdateInputSlots(cargoTraffic, entitySignPool, flag2); continue; } val2.UpdateOutputSlots(cargoTraffic, entitySignPool, GameMain.history.stationPilerLevel, flag2); if (sandboxToolsEnabled) { val2.UpdateKeepMode(); } } completeEvent.Set(); } } private class Patch { [HarmonyPrefix] [HarmonyPatch(typeof(PlanetTransport), "SetStationCapacity")] public static void SetStationCapacityPostfix(PlanetTransport __instance, int newCapacity) { int index = __instance.factory.index; if (index >= 0 && index < factorySizes.Length) { int num = stationIdMap.Length + newCapacity - factorySizes[index]; stationIdMap = new int[num]; for (int i = 0; i < num; i++) { stationIdMap[i] = i; } stationIdMap.Shuffle(); int factoryCount = GameMain.data.factoryCount; factorySizes[index] = newCapacity; int num2 = Math.Min(factoryCount + 1, factorySizes.Length); for (int j = index; j < num2; j++) { factorySizesPrefixSum[j] = ((j > 0) ? factorySizesPrefixSum[j - 1] : 0) + factorySizes[j]; } } } private static void ReplaceCall(CodeMatcher matcher, bool isInput) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown string text = (isInput ? "GameTick_InputFromBelt" : "GameTick_OutputToBelt"); matcher.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(PlanetTransport), text, (Type[])null, (Type[])null), (string)null) }).Advance(isInput ? (-15) : (-19)).RemoveInstructions(isInput ? 3 : 6) .SetOpcodeAndAdvance(OpCodes.Nop) .RemoveInstructions(isInput ? 12 : 19) .SetOpcodeAndAdvance(OpCodes.Nop) .RemoveInstructions(3) .SetOpcodeAndAdvance(OpCodes.Nop) .RemoveInstructions(3) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(isInput ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(StationStorageOpt), "RunStorageLogic", (Type[])null, (Type[])null)) }); } [HarmonyTranspiler] [HarmonyPatch(typeof(GameData), "GameTick")] private static IEnumerable<CodeInstruction> StorageCallSkipPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //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_000e: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); ReplaceCall(val, isInput: true); ReplaceCall(val, isInput: false); return val.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(GameData), "NewGame")] [HarmonyPatch(typeof(GameData), "Import")] private static IEnumerable<CodeInstruction> InitFactoryInfoPatch(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[4] { new CodeMatch((OpCode?)OpCodes.Ldc_I4_6, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Newarr, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(GameData), "factories"), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(StationStorageOpt), "InitFactoryInfo", (Type[])null, (Type[])null)) }); return val.InstructionEnumeration(); } [HarmonyPostfix] [HarmonyPatch(typeof(MultithreadSystem), "Init")] [HarmonyPatch(typeof(MultithreadSystem), "ResetUsedThreadCnt")] public static void SetThreadCount(MultithreadSystem __instance) { numThreads = __instance.usedThreadCnt; } } private static int[] stationIdMap; private static int[] factorySizes; private static int[] factorySizesPrefixSum; private static int numThreads; private static WorkerThread[] threads; public override void Init(BaseUnityPlugin plugin) { threads = new WorkerThread[128]; for (int i = 0; i < 128; i++) { threads[i] = new WorkerThread(i); } } private static void InitFactoryInfo(GameData data) { int num = data.factories.Length; factorySizes = new int[num]; factorySizesPrefixSum = new int[num]; stationIdMap = new int[0]; } private static void RunStorageLogic(bool isInput) { for (int i = 0; i < numThreads; i++) { threads[i].completeEvent.Reset(); ThreadPool.QueueUserWorkItem(threads[i].callback, isInput); } for (int j = 0; j < numThreads; j++) { threads[j].completeEvent.WaitOne(); } } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class CommandAttribute : Attribute { private string name; public string Name => name; public CommandAttribute(string name) { this.name = name; } } [RunPatches(typeof(Patch))] public class CommandManager { private class Patch { [HarmonyPostfix] [HarmonyPatch(typeof(XConsole), "InitCommands")] public static void InitCommandsPostfix() { foreach (Assembly item in initQueue) { Init(item); } initQueue.Clear(); initialized = true; } } private static List<string> cmds; private static List<Assembly> srcAssm; private static List<Assembly> initQueue; private static bool initialized; public static void QueueInit(Assembly assm = null) { if (initialized) { Init(assm); return; } if (initQueue == null) { initQueue = new List<Assembly>(); } initQueue.Add(assm); } private static void Init(Assembly assm) { if (assm == null) { assm = Assembly.GetExecutingAssembly(); } if (cmds == null) { cmds = new List<string>(); } if (srcAssm == null) { srcAssm = new List<Assembly>(); } int num = FindCommands(assm); Plugin.logger.LogInfo((object)string.Format("{0} command{1} loaded from {2}", num, (num == 1) ? "" : "s", assm.GetName().Name)); } public static void OnDestroy(Assembly assm = null) { if (cmds == null || cmds.Count == 0) { return; } for (int i = 0; i < cmds.Count; i++) { string text = cmds[i]; Assembly assembly = srcAssm[i]; if (assm == null || assm == assembly) { XConsole.UnregisterCommand(text); cmds.RemoveAt(i); srcAssm.RemoveAt(i); i--; } } } private static void AddCommand(string name, Func<string, string> cmd, Assembly assm) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown XConsole.RegisterCommand(name, new DCommandFunc(cmd.Invoke)); cmds.Add(name); srcAssm.Add(assm); } private static bool IsValidCommand(MethodInfo method) { if (method.ReturnType != typeof(string)) { return false; } ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 1 && !parameters[0].IsOut) { return parameters[0].ParameterType == typeof(string); } return false; } private static int FindCommands(Assembly assm) { int num = 0; Type[] types = assm.GetTypes(); foreach (Type type in types) { MethodInfo[] methods = type.GetMethods(); foreach (MethodInfo methodInfo in methods) { CommandAttribute commandAttribute = (CommandAttribute)methodInfo.GetCustomAttribute(typeof(CommandAttribute)); if (commandAttribute != null) { if (IsValidCommand(methodInfo)) { AddCommand(commandAttribute.Name, (Func<string, string>)methodInfo.CreateDelegate(typeof(Func<string, string>)), assm); num++; } else { Plugin.logger.LogError((object)$"{type.Name}.{methodInfo.Name} from {assm.GetName().Name} is not a valid command"); } } } } return num; } } internal class FactoryCommands { private static Dictionary<int, int> planetIdToFactoryIdx; public static string CmdResetLocalPlanet(string param) { PlanetData localPlanet = GameMain.localPlanet; if (localPlanet == null) { return "no local planet"; } ResetPlanet(localPlanet); return "successfully reset local planet"; } [Command("resetLocalFactory")] public static string CmdResetLocalFactory(string param) { PlanetData localPlanet = GameMain.localPlanet; if (localPlanet == null) { return "no local planet"; } if (localPlanet.factory == null) { return "local factory is null"; } ResetFactory(localPlanet); return "successfully reset local factory"; } private static void PrepareReset(PlanetData planet) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0098: Un