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 BepInEx;
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
{
[HarmonyPostfix]
[HarmonyAfter(new string[] { "crecheng.DSPModSave" })]
[HarmonyPatch(typeof(GameData), "NewGame")]
[HarmonyPatch(typeof(GameSave), "LoadCurrentGame")]
public static void InitCounts()
{
InitSPAndCPCounts();
}
[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_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Expected O, but got Unknown
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Expected O, but got Unknown
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Expected O, but got Unknown
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(instructions, generator);
Label label = default(Label);
val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
{
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => CodeInstructionExtensions.LoadsConstant(x)), (string)null),
new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => CodeInstructionExtensions.LoadsConstant(x)), (string)null),
new CodeMatch((OpCode?)OpCodes.Conv_I8, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(DeepProfiler), "EndSample", (Type[])null, (Type[])null), (string)null)
}).CreateLabel(ref label);
val.Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(DysonSphere), "nrdPool"), (string)null)
}).Advance(-6)
.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)label)
});
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 class DSPModSaveWrapper : IModCanSave
{
void IModCanSave.Export(BinaryWriter w)
{
int value = 2;
w.Write(value);
}
void IModCanSave.Import(BinaryReader r)
{
if (r.ReadInt32() == 1)
{
LowResShellsSaveManager.ImportWrapper(r);
}
UpdateShells();
}
void IModCanSave.IntoOtherSave()
{
UpdateShells();
_ = DSPGame.IsMenuDemo;
}
}
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();
foreach (Type type in types)
{
try
{
foreach (Attribute customAttribute in type.GetCustomAttributes())
{
if (customAttribute is RunPatchesAttribute)
{
harmony.PatchAll((customAttribute as RunPatchesAttribute).Patches);
}
}
}
catch (Exception ex)
{
Plugin.logger.LogError((object)("PatchManager error: " + type.Name + "\n" + ex.StackTrace));
}
}
}
}
[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.19")]
[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.19";
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();
}
void IModCanSave.IntoOtherSave()
{
LowResShellsLegacySupport.UpdateShells();
_ = 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("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();
}
}
}
[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: Unknown result type (might be due to invalid IL or missing references)
UIRoot.instance.uiGame.ShutAllFunctionWindow();
PlanetFactory factory = planet.factory;
PlanetTransport transport = factory.transport;
GalacticTransport galacticTransport = GameMain.data.galacticTransport;
for (int i = 1; i < transport.stationCursor; i++)
{
StationComponent val = transport.stationPool[i];
if (val != null && val.id == i && val.gid > 0)
{
galacticTransport.RemoveStationComponent(val.gid);
}
}
WarningSystem warningSystem = GameMain.data.warningSystem;
for (int j = 1; j < warningSystem.warningCursor; j++)
{
WarningData val2 = warningSystem.warningPool[j];
if (val2.id == j && val2.factoryId == factory.index)
{
warningSystem.RemoveWarningData(j);
}
}
planet.audio.nearAudioLogic.RefreshAudiosOnArrayChange();
planet.physics.nearColliderLogic.RefreshCollidersLive();
planet.physics.nearColliderLogic.DeleteDeadColliders();
}
private static void CacheFactoryIndex(PlanetData planet)
{
if (planetIdToFactoryIdx == null)
{
planetIdToFactoryIdx = new Dictionary<int, int>();
}
if (planetIdToFactoryIdx.ContainsKey(planet.id))
{
planetIdToFactoryIdx[planet.id] = planet.factory.index;
}
else
{
planetIdToFactoryIdx.Add(planet.id, planet.factory.index);
}
}
private static void ResetPlanet(PlanetData planet)
{
PrepareReset(planet);
GameMain.data.LeavePlanet();
planet.Unload();
CacheFactoryIndex(planet);
planet.loaded = (planet.loading = (planet.factoryLoaded = (planet.factoryLoading = false)));
planet.data = null;
planet.factory = null;
planet.onLoaded += ResetPlanetFinish;
PlanetModelingManager.RequestLoadPlanet(planet);
}
private static void ResetPlanetFinish(PlanetData planet)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
if (planetIdToFactoryIdx.TryGetValue(planet.id, out var value))
{
planetIdToFactoryIdx.Remove(planet.id);
planet.onLoaded -= ResetPlanetFinish;
GameData data = GameMain.data;
PlanetFactory val = new PlanetFactory();
val.Init(data, planet, value);
data.factories[value] = val;
planet.factory = val;
}
}
private static void ResetFactory(PlanetData planet)
{
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Expected O, but got Unknown
PrepareReset(planet);
planet.UnloadFactory();
PlanetFactory factory = planet.factory;
GameData data = GameMain.data;
int index = factory.index;
PlanetRawData data2 = planet.data;
data2.veinCursor = factory.veinCursor;
data2.SetVeinCapacity(data2.veinCursor + 2);
Array.Copy(factory.veinPool, data2.veinPool, data2.veinCursor);
data2.vegeCursor = factory.vegeCursor;
data2.SetVegeCapacity(data2.vegeCursor + 2);
Array.Copy(factory.vegePool, data2.vegePool, data2.vegeCursor);
lock (planet.veinGroupsLock)
{
int num = Math.Max(factory.veinGroups.Length, 1);
planet.veinGroups = (VeinGroup[])(object)new VeinGroup[num];
Array.Copy(factory.veinGroups, planet.veinGroups, num);
}
PlatformSystem platformSystem = factory.platformSystem;
PlanetFactory val = new PlanetFactory();
val.Init(data, planet, index);
data.factories[index] = val;
planet.factory = val;
val.platformSystem = platformSystem;
platformSystem.factory = val;
PlanetModelingManager.fctPlanetReqList.Enqueue(planet);
}
}
internal class SphereCommands
{
private enum EResetError
{
None,
InvalidIndex,
DoesNotExist,
Unknown
}
private static EResetError ResetSwarm(int star_index)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
DysonSphere val = GameMain.data.dysonSpheres[star_index];
if (val?.swarm == null)
{
return EResetError.DoesNotExist;
}
for (int i = 0; i < 10; i++)
{
DysonSphereLayer val2 = val.layersSorted[i];
if (val2 == null)
{
continue;
}
for (int j = 1; j < val2.nodeCursor; j++)
{
DysonNode val3 = val2.nodePool[j];
if (val3 != null && val3.id == j)
{
val3.cpOrdered = 0;
}
}
}
val.swarm = new DysonSwarm(val);
val.swarm.Init();
val.swarm.ResetNew();
return EResetError.None;
}
[Command("resetLocalSwarm")]
public static string CmdResetLocalSwarm(string param)
{
StarData localStar = GameMain.data.localStar;
if (localStar == null)
{
return "Failed to reset local swarm: No nearby star";
}
return ResetSwarm(localStar.index) switch
{
EResetError.None => "Successfully reset local swarm",
EResetError.DoesNotExist => "Failed to reset local swarm: No swarm exists",
_ => "Failed to reset local swarm: Cause unknown",
};
}
[Command("resetLocalSphereLayer")]
public static string CmdResetLocalSphereLayer(string param)
{
if (param == "")
{
return "Invalid Usage. Correct usage: -resetLocalSphereLayer layerId";
}
GameData data = GameMain.data;
StarData localStar = data.localStar;
if (localStar == null)
{
return "Failed to reset local sphere layer: No nearby star";
}
DysonSphere val = data.dysonSpheres[localStar.index];
if (val == null)
{
return "Failed to reset local sphere layer: sphere does not exist";
}
if (!int.TryParse(param, out var result) || result < 1 || result > 10)
{
return "Failed to reset local sphere layer: invalid layer id";
}
DysonSphereLayer val2 = val.layersIdBased[result];
if (val2 == null)
{
return "Failed to reset local sphere layer: layer does not exist";
}
for (int i = 0; i < val2.nodePool.Length; i++)
{
if (val2.nodePool[i] != null)
{
val.swarm.OnNodeRemove(val2.id, i);
val.RemoveAutoNode(val2.nodePool[i]);
val.RemoveNodeRocket(val2.nodePool[i]);
val.RemoveDysonNodeRData(val2.nodePool[i]);
}
}
val.RemoveLayer(result);
UIDysonEditor dysonEditor = UIRoot._instance.uiGame.dysonEditor;
if (!dysonEditor.IsRender(result, false, true))
{
dysonEditor.SwitchRenderState(result, false, true);
}
if (!dysonEditor.IsRender(result, false, false))
{
dysonEditor.SwitchRenderState(result, false, false);
}
dysonEditor.selection.ClearAllSelection();
val.CheckAutoNodes();
val.PickAutoNode();
val.modelRenderer.RebuildModels();
return "Successfully reset sphere layer " + result;
}
[Command("resetAllSpheresAndSwarms")]
public static string CmdResetAllSpheresAndSwarms(string param)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
int num = 0;
GameData data = GameMain.data;
for (int i = 0; i < data.dysonSpheres.Length; i++)
{
if (data.dysonSpheres[i] != null)
{
data.dysonSpheres[i] = new DysonSphere();
data.dysonSpheres[i].Init(data, data.galaxy.stars[i]);
data.dysonSpheres[i].ResetNew();
num++;
}
}
return $"Reset spheres and swarms around {num}/{data.dysonSpheres.Length} stars";
}
}
internal static class Utils
{
private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list, int n = -1)
{
if (n == -1)
{
n = list.Count;
}
while (n > 1)
{
list.RandomPrefixSwap(--n);
}
}
public static void RandomPrefixSwap<T>(this IList<T> list, int idx)
{
int index = rng.Next(idx + 1);
T value = list[index];
list[index] = list[idx];
list[idx] = value;
}
public static int LowerBound<T>(IList<T> list, T val) where T : IComparable<T>
{
return LowerBound(list, val, 0, list.Count);
}
public static int LowerBound<T>(IList<T> list, T val, int low, int high) where T : IComparable<T>
{
while (low < high)
{
int num = low + (high - low) / 2;
if (val.CompareTo(list[num]) <= 0)
{
high = num;
}
else
{
low = num + 1;
}
}
return low;
}
}