Decompiled source of LossyCompression v0.3.5

LossyCompression.dll

Decompiled 3 months ago
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 System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using NebulaAPI;
using NebulaAPI.Interfaces;
using NebulaAPI.Networking;
using NebulaAPI.Packets;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using crecheng.DSPModSave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LossyCompression")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LossyCompression")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d05132ad-b613-4b05-9ec5-b7a4194d7d2b")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.5.0")]
[module: UnverifiableCode]
namespace LossyCompression;

internal class Utils
{
	private const float FLOAT_PRECISION_MULT = 32000f;

	private static readonly Quaternion[] array = (Quaternion[])(object)new Quaternion[4]
	{
		Quaternion.identity,
		Quaternion.Euler(0f, 90f, 0f),
		Quaternion.Euler(0f, 180f, 0f),
		Quaternion.Euler(0f, 270f, 0f)
	};

	public static bool WriteCompressedRotation(BinaryWriter writer, in Vector3 pos, in Quaternion rot)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		Quaternion val = Quaternion.Inverse(Maths.SphericalRotation(pos, 0f)) * rot;
		for (int i = 0; i < 4; i++)
		{
			if ((double)Quaternion.Dot(val, array[i]) > 0.99984769515)
			{
				writer.Write((byte)(4 + i));
				return true;
			}
		}
		int num = 0;
		float num2 = float.MinValue;
		Quaternion val2;
		for (int j = 0; j < 4; j++)
		{
			val2 = rot;
			float num3 = ((Quaternion)(ref val2))[j];
			val2 = rot;
			float num4 = num3 * ((Quaternion)(ref val2))[j];
			if (num4 > num2)
			{
				num = j;
				num2 = num4;
			}
		}
		val2 = rot;
		float num5 = ((((Quaternion)(ref val2))[num] + 3.125E-05f >= 0f) ? 1f : (-1f));
		writer.Write((byte)num);
		for (int k = 0; k < 4; k++)
		{
			if (k != num)
			{
				val2 = rot;
				writer.Write((short)(((Quaternion)(ref val2))[k] * num5 * 32000f));
			}
		}
		return false;
	}

	public static Quaternion ReadCompressedRotation(BinaryReader reader, in Vector3 pos)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		int num = reader.ReadByte();
		if (num >= 4 && num <= 8)
		{
			return Maths.SphericalRotation(pos, 0f) * array[num - 4];
		}
		float num2 = (float)reader.ReadInt16() / 32000f;
		float num3 = (float)reader.ReadInt16() / 32000f;
		float num4 = (float)reader.ReadInt16() / 32000f;
		float num5 = Mathf.Sqrt(1f - (num2 * num2 + num3 * num3 + num4 * num4));
		return (Quaternion)(num switch
		{
			0 => new Quaternion(num5, num2, num3, num4), 
			1 => new Quaternion(num2, num5, num3, num4), 
			2 => new Quaternion(num2, num3, num5, num4), 
			3 => new Quaternion(num2, num3, num4, num5), 
			_ => Quaternion.identity, 
		});
	}
}
public static class LazyLoading
{
	private static readonly Dictionary<DysonSphere, int> dysonSphereMasks = new Dictionary<DysonSphere, int>();

	private static DysonSphere viewingSphere = null;

	private static int editorMask;

	private static int gameMask;

	private static readonly Random random = new Random();

	private static readonly AutoResetEvent autoEvent = new AutoResetEvent(initialState: false);

	private static readonly List<DysonNode> emptyNodes = new List<DysonNode>(0);

	private static readonly Dictionary<int, int> emptyNodeIndexMap = new Dictionary<int, int>(0);

	private static readonly List<DysonFrame> emptyFrames = new List<DysonFrame>(0);

	private static readonly List<VectorLF3> emptyPolygon = new List<VectorLF3>(0);

	private static int shellCount = 0;

	public static bool Enable { get; set; } = true;


	public static bool ReduceRAM { get; set; } = false;


	[HarmonyPostfix]
	[HarmonyPatch(typeof(GameMain), "End")]
	public static void Reset()
	{
		Log.Debug("Lazyload Reset. Clear masks: " + GameMain.isEnded);
		viewingSphere = null;
		if (GameMain.isEnded)
		{
			dysonSphereMasks.Clear();
		}
	}

	public static void Add(DysonSphere dysonSphere)
	{
		dysonSphereMasks[dysonSphere] = 0;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DysonSphereSegmentRenderer), "DrawModels")]
	public static void DrawModels(DysonSphere ___dysonSphere)
	{
		if (___dysonSphere == viewingSphere && editorMask == ___dysonSphere.inEditorRenderMaskL && gameMask == ___dysonSphere.inGameRenderMaskL)
		{
			return;
		}
		viewingSphere = ___dysonSphere;
		editorMask = ___dysonSphere.inEditorRenderMaskL;
		gameMask = ___dysonSphere.inGameRenderMaskL;
		if (!dysonSphereMasks.TryGetValue(___dysonSphere, out var value))
		{
			return;
		}
		value |= editorMask | gameMask;
		if (value != dysonSphereMasks[___dysonSphere])
		{
			dysonSphereMasks[___dysonSphere] |= editorMask | gameMask;
			DysonShellCompress.GenerateModel(viewingSphere, dysonSphereMasks[___dysonSphere]);
			if (dysonSphereMasks[___dysonSphere] == -1)
			{
				dysonSphereMasks.Remove(___dysonSphere);
			}
			DysonShellCompress.FreeRAM();
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(GameData), "Export")]
	public static void AfterGameDataExport()
	{
		DysonShellCompress.FreeRAM();
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DysonSphere), "Export")]
	public static void Export_Prefix(DysonSphere __instance)
	{
		if (DysonShellCompress.Enable || !dysonSphereMasks.ContainsKey(__instance))
		{
			return;
		}
		bool generateModel = !ReduceRAM;
		if (ThreadingHelper.Instance.InvokeRequired)
		{
			autoEvent.Reset();
			ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
			{
				DysonShellCompress.GenerateModel(__instance, -1, generateModel);
				autoEvent.Set();
			});
			autoEvent.WaitOne(-1);
		}
		else
		{
			DysonShellCompress.GenerateModel(__instance, -1, generateModel);
		}
		if (generateModel)
		{
			dysonSphereMasks.Remove(__instance);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(DysonSphere), "Export")]
	public static void Export_Postfix(DysonSphere __instance)
	{
		if (DysonShellCompress.Enable || !dysonSphereMasks.ContainsKey(__instance))
		{
			return;
		}
		if (ThreadingHelper.Instance.InvokeRequired)
		{
			autoEvent.Reset();
			ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
			{
				RemoveAllVerts(__instance);
				autoEvent.Set();
			});
			autoEvent.WaitOne(-1);
		}
		else
		{
			RemoveAllVerts(__instance);
		}
	}

	private static void RemoveAllVerts(DysonSphere dysonSphere)
	{
		if (dysonSphere == viewingSphere)
		{
			viewingSphere = null;
		}
		dysonSphereMasks[dysonSphere] = 0;
		int num = 0;
		for (int i = 1; i < dysonSphere.layersIdBased.Length; i++)
		{
			if (dysonSphere.layersIdBased[i] == null || dysonSphere.layersIdBased[i].id != i)
			{
				continue;
			}
			DysonSphereLayer val = dysonSphere.layersIdBased[i];
			for (int j = 1; j < val.shellCursor; j++)
			{
				if (val.shellPool[j] != null && val.shellPool[j].id == j)
				{
					RemoveVerts(val.shellPool[j]);
					num++;
				}
			}
		}
		Log.Debug($"ReduceRAM: Remove verts for {num} shells.");
		GC.Collect();
	}

	public static void RemoveVerts(DysonShell dysonShell)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		int layerId = dysonShell.layerId;
		int id = dysonShell.id;
		int protoId = dysonShell.protoId;
		int randSeed = dysonShell.randSeed;
		Color32 color = dysonShell.color;
		int[] nodecps = dysonShell.nodecps;
		int[] vertsqOffset = dysonShell.vertsqOffset;
		int vertexCount = dysonShell.vertexCount;
		int cpPerVertex = dysonShell.cpPerVertex;
		List<DysonNode> nodes = dysonShell.nodes;
		Dictionary<int, int> nodeIndexMap = dysonShell.nodeIndexMap;
		List<DysonFrame> frames = dysonShell.frames;
		List<VectorLF3> polygon = dysonShell.polygon;
		dysonShell.nodes = emptyNodes;
		dysonShell.nodeIndexMap = emptyNodeIndexMap;
		dysonShell.frames = emptyFrames;
		dysonShell.polygon = emptyPolygon;
		dysonShell.SetEmpty();
		dysonShell.layerId = layerId;
		dysonShell.id = id;
		dysonShell.protoId = protoId;
		dysonShell.randSeed = randSeed;
		dysonShell.color = color;
		dysonShell.nodecps = nodecps;
		dysonShell.vertsqOffset = vertsqOffset;
		dysonShell.vertexCount = vertexCount;
		dysonShell.cpPerVertex = cpPerVertex;
		dysonShell.nodes = nodes;
		dysonShell.nodeIndexMap = nodeIndexMap;
		dysonShell.frames = frames;
		dysonShell.polygon = polygon;
	}

	public static void GenerateModelObjectsGuard(DysonShell dysonShell)
	{
		if (Enable)
		{
			RemoveVerts(dysonShell);
			shellCount++;
		}
		else
		{
			dysonShell.GenerateModelObjects();
		}
	}

	[HarmonyTranspiler]
	[HarmonyPatch(typeof(DysonShell), "Import")]
	public static IEnumerable<CodeInstruction> DysonShellImport_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iL)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		try
		{
			return new CodeMatcher(instructions, iL).End().MatchBack(true, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "GenerateModelObjects"), (string)null)
			}).SetOperandAndAdvance((object)typeof(LazyLoading).GetMethod("GenerateModelObjectsGuard"))
				.InstructionEnumeration();
		}
		catch (Exception obj)
		{
			Log.Error("DysonShellImport_Transpiler error! Lazyload will not work on vanilla save");
			Log.Error(obj);
			return instructions;
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(DysonSphere), "Import")]
	[HarmonyPriority(200)]
	private static void DysonSphereImportPostfix(DysonSphere __instance)
	{
		if (Enable && shellCount > 0)
		{
			Add(__instance);
			Log.Debug($"[{__instance.starData.index,2}] lazy load: skip {shellCount} shells.");
			shellCount = 0;
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DysonSphereLayer), "RemoveDysonShell")]
	public static bool RemoveDysonShell(DysonSphereLayer __instance, int shellId)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.shellPool[shellId].id == 0 || __instance.shellPool[shellId].verts != null)
		{
			return true;
		}
		int num = (int)(GameMain.history.solarSailLife * 60f + 0.1f);
		long num2 = GameMain.gameTick + num;
		DysonShell val = __instance.shellPool[shellId];
		Vector3 val2 = Vector3.zero;
		int num3 = 0;
		for (int i = 0; i < val.nodes.Count; i++)
		{
			val2 += val.nodes[i].pos;
			num3 += val.nodecps[i] / 2;
		}
		val2 /= (float)val.nodes.Count;
		int num4 = num3 / val.nodes.Count;
		int num5 = num3 % val.nodes.Count;
		int num6 = shellId;
		for (int j = 0; j < val.nodes.Count; j++)
		{
			Vector3 pos = val.nodes[j].pos;
			Vector3 val3 = ((j + 1 != val.nodes.Count) ? val.nodes[j + 1].pos : val.nodes[0].pos);
			int num7 = ((j + 1 != val.nodes.Count) ? num4 : (num4 + num5));
			for (int k = 0; k < num7; k++)
			{
				float num8 = (float)random.NextDouble();
				float num9 = (float)random.NextDouble();
				if (num8 + num9 > 1f)
				{
					num8 = 1f - num8;
					num9 = 1f - num9;
				}
				Vector3 val4 = (1f - num8 - num9) * val2 + num8 * pos + num9 * val3;
				val4 = __instance.orbitRadius * ((Vector3)(ref val4)).normalized;
				Vector3 val5 = __instance.currentRotation * (Vector3.Cross(val4, Vector3.up) * __instance.orbitAngularSpeed * ((float)Math.PI / 180f));
				val4 = __instance.currentRotation * val4;
				val5 += VectorLF3.op_Implicit(RandomTable.SphericNormal(ref num6, 1.2000000476837158));
				DysonSail val6 = default(DysonSail);
				val6.px = val4.x;
				val6.py = val4.y;
				val6.pz = val4.z;
				val6.vx = val5.x;
				val6.vy = val5.y;
				val6.vz = val5.z;
				val6.gs = 1f;
				__instance.dysonSphere.swarm.AddSolarSail(val6, 30, num2);
			}
		}
		foreach (DysonNode node in __instance.shellPool[shellId].nodes)
		{
			node.shells.Remove(__instance.shellPool[shellId]);
			node.RecalcCpReq();
		}
		__instance.shellPool[shellId].Free();
		__instance.shellPool[shellId] = null;
		int[] shellRecycle = __instance.shellRecycle;
		int shellRecycleCursor = __instance.shellRecycleCursor;
		__instance.shellRecycleCursor = shellRecycleCursor + 1;
		shellRecycle[shellRecycleCursor] = shellId;
		return false;
	}
}
public class ModCompatibility
{
	public static class SphereOpt
	{
		public const string GUID = "SphereOpt";

		public static void Init(Harmony _)
		{
			try
			{
				if (Chainloader.PluginInfos.TryGetValue("SphereOpt", out var _) && LazyLoading.Enable)
				{
					string text = "Lazy loading is disabled due to compat with SphereOpt.\n侦测到SphereOpt,已将延迟载入功能关闭";
					dialogMessage = dialogMessage + text + "\n";
					LazyLoading.Enable = false;
					Log.Debug("SphereOpt compatibility - OK");
				}
			}
			catch (Exception obj)
			{
				LogNotice("SphereOpt", "0.8.3");
				Log.Warn(obj);
			}
		}
	}

	public static class DSPOptimizations
	{
		public const string GUID = "com.Selsion.DSPOptimizations";

		public static void Init(Harmony harmony)
		{
			try
			{
				if (Chainloader.PluginInfos.TryGetValue("com.Selsion.DSPOptimizations", out var value))
				{
					AfeterImport = AccessTools.MethodDelegate<Action>(AccessTools.Method(((object)value.Instance).GetType().Assembly.GetType("DSPOptimizations.DysonNodeOpt"), "InitSPAndCPCounts", (Type[])null, (Type[])null), (object)null, true);
					harmony.PatchAll(typeof(DSPOptimizations));
					Log.Debug("DSPOptimizations compatibility - OK");
				}
			}
			catch (Exception obj)
			{
				LogNotice("DSPOptimizations", "1.1.14");
				Log.Warn(obj);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(DysonShell), "SetMaterialDynamicVars")]
		public static bool SetMaterialDynamicVars(DysonShell __instance)
		{
			if (__instance.nodeProgressArr != null)
			{
				int num = __instance.nodecps.Length - 1;
				for (int i = 0; i < num && i < 768; i++)
				{
					__instance.nodeProgressArr[i] = (float)((double)__instance.nodecps[i] / (double)((__instance.vertsqOffset[i + 1] - __instance.vertsqOffset[i]) * __instance.cpPerVertex));
				}
				if (__instance.nodecps.Length <= 768)
				{
					__instance.nodeProgressArr[num] = (float)((double)__instance.nodecps[num] / (double)__instance.vertsqOffset[num]);
				}
			}
			if ((Object)(object)__instance.material != (Object)null)
			{
				__instance.material.SetFloat("_State", (float)__instance.state);
				int num2 = (__instance.color.a << 24) | (__instance.color.b << 16) | (__instance.color.g << 8) | __instance.color.r;
				__instance.material.SetInt("_Color32Int", num2);
				__instance.material.SetFloatArray("_NodeProgressArr", __instance.nodeProgressArr);
			}
			return false;
		}
	}

	public static class NebulaAPI
	{
		public const string GUID = "dsp.nebula-multiplayer-api";

		public static void Init(Harmony harmony)
		{
			try
			{
				if (Chainloader.PluginInfos.TryGetValue("dsp.nebula-multiplayer-api", out var _))
				{
					Patch(harmony);
					Log.Debug("Nebula compatibility - OK");
				}
			}
			catch (Exception obj)
			{
				LogNotice("Nebula", "0.8.14");
				Log.Warn(obj);
			}
		}

		private static void Patch(Harmony harmony)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if (NebulaModAPI.NebulaIsInstalled)
			{
				NebulaModAPI.RegisterPackets(Assembly.GetExecutingAssembly());
				MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("NebulaWorld.Universe.DysonSphereManager"), "RegisterPlayer", (Type[])null, (Type[])null);
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(NebulaAPI), "DysonDataPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(DysonSwarm), "RemoveSailsByOrbit", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NebulaAPI), "RemoveSailsByOrbitPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public static void DysonDataPostfix(INebulaConnection conn, int starIndex)
		{
			conn.SendPacket<LC_DysonData>(new LC_DysonData(starIndex));
		}

		public static bool RemoveSailsByOrbitPrefix(int orbitId)
		{
			if (orbitId == 0 && (bool)AccessTools.Property(AccessTools.TypeByName("NebulaWorld.Multiplayer"), "IsDedicated")?.GetValue(null))
			{
				Log.Debug("Skip sails rearrange");
				return false;
			}
			return true;
		}
	}

	internal class LC_DysonData
	{
		public int StarIndex { get; set; }

		public int EnableFlags { get; set; }

		public byte[] Bytes { get; set; }

		public long GameTick { get; set; }

		public LC_DysonData()
		{
		}

		public LC_DysonData(int starIndex)
		{
			StarIndex = starIndex;
			EnableFlags = Plugin.GetEnables();
			DysonSphere dysonSphere = GameMain.data.dysonSpheres[starIndex];
			IWriterProvider binaryWriter = NebulaModAPI.GetBinaryWriter();
			try
			{
				if (DysonShellCompress.Enable)
				{
					DysonShellCompress.Encode(dysonSphere, binaryWriter.BinaryWriter);
				}
				if (DysonSwarmCompress.Enable)
				{
					DysonSwarmCompress.Encode(dysonSphere, binaryWriter.BinaryWriter);
				}
				Bytes = binaryWriter.CloseAndGetBytes();
			}
			finally
			{
				((IDisposable)binaryWriter)?.Dispose();
			}
			GameTick = GameMain.gameTick;
			Log.Debug($"Send compressed data {Bytes.Length:N0}");
			DysonShellCompress.FreeRAM();
		}
	}

	[RegisterPacketProcessor]
	internal class NC_ModSaveDataProcessor : BasePacketProcessor<LC_DysonData>
	{
		public override void ProcessPacket(LC_DysonData packet, INebulaConnection conn)
		{
			if (!base.IsClient)
			{
				return;
			}
			Log.Debug($"Recv compressed data {packet.Bytes.Length:N0}, flag {packet.EnableFlags}");
			DysonSphere dysonSphere = GameMain.data.dysonSpheres[packet.StarIndex];
			IReaderProvider binaryReader = NebulaModAPI.GetBinaryReader(packet.Bytes);
			try
			{
				if (((uint)packet.EnableFlags & 2u) != 0)
				{
					DysonShellCompress.Decode(dysonSphere, binaryReader.BinaryReader, DysonShellCompress.EncodedVersion);
				}
				if (((uint)packet.EnableFlags & 4u) != 0)
				{
					DysonSwarmCompress.Decode(dysonSphere, binaryReader.BinaryReader, packet.GameTick);
				}
			}
			finally
			{
				((IDisposable)binaryReader)?.Dispose();
			}
			DysonShellCompress.FreeRAM();
			AfeterImport?.Invoke();
			LazyLoading.Reset();
		}
	}

	public static Action AfeterImport;

	private static string dialogMessage = "";

	public static void Init(Harmony harmony)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		SphereOpt.Init(harmony);
		DSPOptimizations.Init(harmony);
		NebulaAPI.Init(harmony);
		if (!string.IsNullOrEmpty(dialogMessage))
		{
			harmony.Patch((MethodBase)AccessTools.Method(typeof(VFPreload), "InvokeOnLoadWorkEnded", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ModCompatibility), "ShowMessage", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}

	private static void ShowMessage()
	{
		UIMessageBox.Show("Lossy Compression兼容性提示", dialogMessage, Localization.Translate("确定"), 3);
	}

	private static void LogNotice(string modName, string lastWorkingVersion)
	{
		string text = modName + " compatibility failed!(兼容失效) Last working version: " + lastWorkingVersion;
		dialogMessage = dialogMessage + text + "\n";
		Log.Warn(text);
	}
}
internal class DysonSwarmCompress
{
	public static readonly int EncodedVersion = 1;

	private const int DIVISION = 350;

	public static bool Enable { get; set; }

	public static bool IsMultithread { get; set; }

	public static void Export(BinaryWriter w)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		if (!Enable)
		{
			w.Write(0);
			return;
		}
		HighStopwatch val = new HighStopwatch();
		val.Begin();
		long num = -w.BaseStream.Length;
		w.Write(EncodedVersion);
		w.Write(GameMain.data.dysonSpheres.Length);
		for (int i = 0; i < GameMain.data.dysonSpheres.Length; i++)
		{
			if (GameMain.data.dysonSpheres[i] != null)
			{
				w.Write(i);
				Encode(GameMain.data.dysonSpheres[i], w);
			}
			else
			{
				w.Write(-1);
			}
		}
		num += w.BaseStream.Length;
		PerformanceMonitor.dataLengths[1] += num;
		PerformanceMonitor.dataLengths[32] += num;
		PerformanceMonitor.dataLengths[33] += num;
		Log.Info($"Compress DysonSwarm: {num:N0} bytes {val.duration}s");
	}

	public static void Import(BinaryReader r)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		int num = r.ReadInt32();
		if (num == 0 || num != EncodedVersion)
		{
			return;
		}
		long num2 = -r.BaseStream.Length;
		HighStopwatch val = new HighStopwatch();
		val.Begin();
		int num3 = r.ReadInt32();
		Assert.True(num3 == GameMain.data.dysonSpheres.Length);
		for (int i = 0; i < num3; i++)
		{
			int num4 = r.ReadInt32();
			if (num4 != -1)
			{
				Decode(GameMain.data.dysonSpheres[num4], r, GameMain.gameTick);
			}
		}
		num2 += r.BaseStream.Length;
		PerformanceMonitor.dataLengths[1] += num2;
		PerformanceMonitor.dataLengths[32] += num2;
		PerformanceMonitor.dataLengths[36] += num2;
		Log.Info($"Decompress DysonSwarm: {num2:N0} bytes {val.duration}s");
	}

	public static void Encode(DysonSphere dysonSphere, BinaryWriter w)
	{
		ExpiryOrder[] expiryOrder = dysonSphere.swarm.expiryOrder;
		long num = (long)(GameMain.history.solarSailLife * 60f / 350f);
		long gameTick = GameMain.gameTick;
		int[] array = new int[351];
		for (int i = 0; i < expiryOrder.Length; i++)
		{
			if (expiryOrder[i].index != 0 || expiryOrder[i].time != 0L)
			{
				int num2 = (int)((expiryOrder[i].time - gameTick) / num);
				if (num2 > 350)
				{
					num2 = 350;
				}
				else if (num2 < 0)
				{
					num2 = 0;
				}
				array[num2]++;
			}
		}
		int num3 = dysonSphere.swarm.absorbEnding - dysonSphere.swarm.absorbCursor;
		if (num3 < 0)
		{
			num3 += dysonSphere.swarm.sailCapacity;
		}
		w.Write(array.Length);
		for (int j = 0; j < array.Length; j++)
		{
			w.Write(array[j]);
		}
		w.Write(num3);
	}

	public static void Decode(DysonSphere dysonSphere, BinaryReader r, long time)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		HighStopwatch val = new HighStopwatch();
		DysonSwarm dysonSwarm = dysonSphere.swarm;
		long num = 0L;
		int[] array = new int[r.ReadInt32() + 1];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = r.ReadInt32();
			num += array[i];
		}
		if (num == 0L)
		{
			return;
		}
		RemoveSailsByOrbit_NoSync(dysonSwarm, -1);
		int num2;
		for (num2 = 512; num2 <= num; num2 *= 2)
		{
		}
		dysonSwarm.SetSailCapacity(num2);
		dysonSwarm.sailPoolForSave = (DysonSail[])(object)new DysonSail[num2];
		List<int> activeOrbitIds = new List<int>();
		for (int j = 1; j < dysonSwarm.orbitCursor; j++)
		{
			if (dysonSwarm.orbits[j].id == j && dysonSwarm.orbits[j].enabled)
			{
				activeOrbitIds.Add(j);
			}
		}
		if (activeOrbitIds.Count == 0)
		{
			activeOrbitIds.Add(1);
		}
		dysonSwarm.sailCursor = 0;
		dysonSwarm.sailRecycleCursor = 0;
		dysonSwarm.expiryEnding = 0;
		dysonSwarm.expiryCursor = 0;
		long num3 = (long)(GameMain.history.solarSailLife * 60f);
		long num4 = (long)(GameMain.history.solarSailLife * 60f / 350f);
		for (int k = 0; k < array.Length; k++)
		{
			long num5 = num4 * (k + 1);
			if (num5 > num3)
			{
				num5 = num3;
			}
			long num6 = time + num5;
			for (int l = 0; l < array[k]; l++)
			{
				dysonSwarm.expiryOrder[dysonSwarm.expiryEnding].time = num6;
				dysonSwarm.expiryOrder[dysonSwarm.expiryEnding].index = dysonSwarm.sailCursor;
				dysonSwarm.sailInfos[dysonSwarm.sailCursor].kill = (uint)(num6 & 0xFFFFFFFFu);
				dysonSwarm.sailInfos[dysonSwarm.sailCursor].orbit = (uint)activeOrbitIds[dysonSwarm.sailCursor % activeOrbitIds.Count];
				DysonSwarm obj = dysonSwarm;
				obj.expiryEnding++;
				DysonSwarm obj2 = dysonSwarm;
				obj2.sailCursor++;
			}
		}
		val.Begin();
		if (!IsMultithread || dysonSwarm.sailCursor < 1000)
		{
			GenerateSails(dysonSwarm, 0, dysonSwarm.sailCursor, activeOrbitIds);
		}
		else
		{
			int processorCount = Environment.ProcessorCount;
			int num7 = dysonSwarm.sailCursor / processorCount;
			Task[] array2 = new Task[processorCount - 1];
			for (int m = 0; m < processorCount - 1; m++)
			{
				int startIndex = num7 * m;
				int endIndex = num7 * (m + 1);
				array2[m] = Task.Run(delegate
				{
					GenerateSails(dysonSwarm, startIndex, endIndex, activeOrbitIds);
				});
			}
			GenerateSails(dysonSwarm, num7 * (processorCount - 1), dysonSwarm.sailCursor, activeOrbitIds);
			Task.WaitAll(array2);
		}
		dysonSwarm.swarmBuffer.SetData((Array)dysonSwarm.sailPoolForSave, 0, 0, dysonSwarm.sailCursor);
		dysonSwarm.swarmInfoBuffer.SetData((Array)dysonSwarm.sailInfos, 0, 0, dysonSwarm.sailCursor);
		Log.Debug($"[{dysonSphere.starData.index,2}] Generate {dysonSwarm.sailCursor:N0} sails. Time:{val.duration} s");
	}

	public static void GenerateSails(DysonSwarm dysonSwarm, int startIndex, int endIndex, List<int> activeOrbitIds)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		int num = dysonSwarm.autoConstructSeed + startIndex;
		int num2 = dysonSwarm.randSeed + startIndex * 3;
		float gravity = dysonSwarm.dysonSphere.gravity;
		for (int i = startIndex; i < endIndex; i++)
		{
			int num3 = activeOrbitIds[i % activeOrbitIds.Count];
			ref SailOrbit reference = ref dysonSwarm.orbits[num3];
			ref DysonSail reference2 = ref dysonSwarm.sailPoolForSave[i];
			VectorLF3 val = VectorLF3.Cross(VectorLF3.op_Implicit(reference.up), RandomTable.SphericNormal(ref num, 1.0));
			VectorLF3 val2 = ((VectorLF3)(ref val)).normalized * (double)reference.radius;
			val2 += RandomTable.SphericNormal(ref num2, 200.0);
			reference2.st = num3;
			reference2.px = (float)val2.x;
			reference2.py = (float)val2.y;
			reference2.pz = (float)val2.z;
			val = VectorLF3.Cross(val2, VectorLF3.op_Implicit(reference.up));
			val2 = ((VectorLF3)(ref val)).normalized * Math.Sqrt(gravity / reference.radius);
			val2 += RandomTable.SphericNormal(ref num2, 0.6000000238418579);
			val2 += RandomTable.SphericNormal(ref num2, 0.5);
			reference2.vx = (float)val2.x;
			reference2.vy = (float)val2.y;
			reference2.vz = (float)val2.z;
			reference2.gs = 1f;
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DysonSwarm), "Export")]
	public static bool DysonSwarm_Export_Prefix(DysonSwarm __instance, BinaryWriter w)
	{
		if (!Enable)
		{
			return true;
		}
		if (ThreadingHelper.Instance.InvokeRequired)
		{
			return false;
		}
		int sailCapacity = __instance.sailCapacity;
		int sailCursor = __instance.sailCursor;
		int sailRecycleCursor = __instance.sailRecycleCursor;
		int expiryCursor = __instance.expiryCursor;
		int expiryEnding = __instance.expiryEnding;
		int absorbCursor = __instance.absorbCursor;
		int absorbEnding = __instance.absorbEnding;
		ExpiryOrder[] expiryOrder = __instance.expiryOrder;
		AbsorbOrder[] absorbOrder = __instance.absorbOrder;
		__instance.sailCapacity = 512;
		__instance.sailCursor = 0;
		__instance.sailRecycleCursor = 0;
		__instance.expiryCursor = 0;
		__instance.expiryEnding = 0;
		__instance.absorbCursor = 0;
		__instance.absorbEnding = 0;
		__instance.expiryOrder = Array.Empty<ExpiryOrder>();
		__instance.absorbOrder = Array.Empty<AbsorbOrder>();
		DysonSwarm_Export_NoGPU(__instance, w);
		__instance.sailCapacity = sailCapacity;
		__instance.sailCursor = sailCursor;
		__instance.sailRecycleCursor = sailRecycleCursor;
		__instance.expiryCursor = expiryCursor;
		__instance.expiryEnding = expiryEnding;
		__instance.absorbCursor = absorbCursor;
		__instance.absorbEnding = absorbEnding;
		__instance.expiryOrder = expiryOrder;
		__instance.absorbOrder = absorbOrder;
		return false;
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(DysonSwarm), "Export")]
	public static void DysonSwarm_Export_NoGPU(DysonSwarm __instance, BinaryWriter _)
	{
	}

	[HarmonyTranspiler]
	[HarmonyPatch(typeof(DysonNode), "Export")]
	private static IEnumerable<CodeInstruction> DysonNodeExport_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator iL)
	{
		//IL_0002: 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_0036: Expected O, but got Unknown
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Expected O, but got Unknown
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Expected O, but got Unknown
		try
		{
			CodeMatcher val = new CodeMatcher(instructions, iL).MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldarg_0), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "cpOrdered"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "Write"), (string)null)
			});
			Label label = default(Label);
			Label label2 = default(Label);
			val.CreateLabelAt(val.Pos, ref label).CreateLabelAt(val.Pos + 2, ref label2);
			val.Insert((CodeInstruction[])(object)new CodeInstruction[4]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DysonSwarmCompress), "get_Enable", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Brfalse_S, (object)label),
				new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
				new CodeInstruction(OpCodes.Br_S, (object)label2)
			});
			return val.InstructionEnumeration();
		}
		catch (Exception obj)
		{
			Log.Error("DysonNodeExport_Transpiler error!");
			Log.Error(obj);
			Enable = false;
			return instructions;
		}
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(DysonSwarm), "RemoveSailsByOrbit")]
	public static void RemoveSailsByOrbit_NoSync(DysonSwarm __instance, int orbitId)
	{
	}
}
internal class DysonShellCompress
{
	public static readonly int EncodedVersion = 2;

	private static readonly Dictionary<int, Vector3>[] s_vmap = new Dictionary<int, Vector3>[3];

	private static readonly Dictionary<int, Vector3>[] s_outvmap = new Dictionary<int, Vector3>[3];

	private static readonly Dictionary<int, int>[] s_ivmap = new Dictionary<int, int>[3];

	private static int shellCapacity;

	private static int shellCursor;

	private static int shellRecycleCursor;

	public static bool Enable { get; set; }

	public static bool IsMultithread { get; set; }

	public static void Export(BinaryWriter w)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		if (!Enable)
		{
			w.Write(0);
			return;
		}
		HighStopwatch val = new HighStopwatch();
		val.Begin();
		long num = -w.BaseStream.Length;
		w.Write(EncodedVersion);
		w.Write(GameMain.data.dysonSpheres.Length);
		for (int i = 0; i < GameMain.data.dysonSpheres.Length; i++)
		{
			if (GameMain.data.dysonSpheres[i] != null)
			{
				w.Write(i);
				Encode(GameMain.data.dysonSpheres[i], w);
			}
			else
			{
				w.Write(-1);
			}
		}
		num += w.BaseStream.Length;
		PerformanceMonitor.dataLengths[1] += num;
		PerformanceMonitor.dataLengths[32] += num;
		PerformanceMonitor.dataLengths[36] += num;
		Log.Info($"Compress DysonShell: {num:N0} bytes {val.duration}s");
	}

	public static void Encode(DysonSphere dysonSphere, BinaryWriter w)
	{
		w.Write(dysonSphere.layersIdBased.Length);
		for (int i = 1; i < dysonSphere.layersIdBased.Length; i++)
		{
			if (dysonSphere.layersIdBased[i] != null && dysonSphere.layersIdBased[i].id == i)
			{
				DysonSphereLayer val = dysonSphere.layersIdBased[i];
				w.Write(i);
				w.Write(val.shellCapacity);
				w.Write(val.shellCursor);
				w.Write(val.shellRecycleCursor);
				int num = 0;
				for (int j = 1; j < val.shellCursor; j++)
				{
					if (val.shellPool[j] != null && val.shellPool[j].id == j)
					{
						DysonShell val2 = val.shellPool[j];
						w.Write(val2.id);
						w.Write(val2.protoId);
						w.Write(val2.randSeed);
						w.Write(val2.color.r);
						w.Write(val2.color.g);
						w.Write(val2.color.b);
						w.Write(val2.color.a);
						w.Write(val2.nodes.Count);
						for (int k = 0; k < val2.nodes.Count; k++)
						{
							w.Write(val2.nodes[k].id);
						}
						for (int l = 0; l < val2.nodes.Count + 1; l++)
						{
							w.Write(val2.nodecps[l]);
						}
						for (int m = 0; m < val2.nodes.Count + 1; m++)
						{
							w.Write(val2.vertsqOffset[m]);
						}
						w.Write(val2.vertexCount);
						w.Write(val2.cpPerVertex);
						num++;
					}
				}
				Assert.True(num == shellCursor - shellRecycleCursor - 1);
				for (int n = 0; n < val.shellRecycleCursor; n++)
				{
					w.Write(val.shellRecycle[n]);
				}
			}
			else
			{
				w.Write(0);
			}
		}
	}

	public static void Import(BinaryReader r)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		int num = r.ReadInt32();
		if (num == 0 || (num != EncodedVersion && num != 1))
		{
			return;
		}
		long num2 = -r.BaseStream.Length;
		HighStopwatch val = new HighStopwatch();
		val.Begin();
		int num3 = r.ReadInt32();
		Assert.True(num3 == GameMain.data.dysonSpheres.Length);
		for (int i = 0; i < num3; i++)
		{
			int num4 = r.ReadInt32();
			if (num4 != -1)
			{
				Decode(GameMain.data.dysonSpheres[num4], r, num);
			}
		}
		num2 += r.BaseStream.Length;
		PerformanceMonitor.dataLengths[1] += num2;
		PerformanceMonitor.dataLengths[32] += num2;
		PerformanceMonitor.dataLengths[36] += num2;
		Log.Info($"Decompress DysonShell: {num2:N0} bytes {val.duration}s");
		FreeRAM();
	}

	public static void Decode(DysonSphere dysonSphere, BinaryReader r, int version)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Expected O, but got Unknown
		//IL_033a: Unknown result type (might be due to invalid IL or missing references)
		//IL_033f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		List<DysonShell> list = new List<DysonShell>();
		List<int> list2 = new List<int>(12);
		int num = r.ReadInt32();
		Assert.True(num == dysonSphere.layersIdBased.Length);
		for (int i = 1; i < num; i++)
		{
			int num2 = r.ReadInt32();
			if (num2 == 0)
			{
				continue;
			}
			DysonSphereLayer val = dysonSphere.layersIdBased[num2];
			val.shellCapacity = r.ReadInt32();
			val.shellCursor = r.ReadInt32();
			val.shellRecycleCursor = r.ReadInt32();
			val.shellPool = (DysonShell[])(object)new DysonShell[val.shellCapacity];
			val.shellRecycle = new int[val.shellCapacity];
			int num3 = val.shellCursor - val.shellRecycleCursor - 1;
			for (int j = 1; j <= num3; j++)
			{
				DysonShell val2 = new DysonShell(val)
				{
					layerId = num2,
					id = r.ReadInt32(),
					protoId = r.ReadInt32(),
					randSeed = r.ReadInt32(),
					color = new Color32(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte())
				};
				list2.Clear();
				int num4 = r.ReadInt32();
				for (int k = 0; k < num4; k++)
				{
					list2.Add(r.ReadInt32());
				}
				val2.nodecps = new int[num4 + 1];
				for (int l = 0; l < num4 + 1; l++)
				{
					val2.nodecps[l] = r.ReadInt32();
				}
				if (version >= 2)
				{
					val2.vertsqOffset = new int[num4 + 1];
					for (int m = 0; m < num4 + 1; m++)
					{
						val2.vertsqOffset[m] = r.ReadInt32();
					}
					val2.vertexCount = r.ReadInt32();
					val2.cpPerVertex = r.ReadInt32();
				}
				for (int n = 0; n < num4; n++)
				{
					int num5 = list2[n];
					DysonNode val3 = dysonSphere.FindNode(val2.layerId, num5);
					Assert.NotNull((object)val3);
					if (val3 != null)
					{
						val2.nodeIndexMap[num5] = val2.nodes.Count;
						val2.nodes.Add(val3);
						if (!val3.shells.Contains(val2))
						{
							val3.shells.Add(val2);
						}
					}
				}
				for (int num6 = 0; num6 < num4; num6++)
				{
					int index = num6;
					int index2 = (num6 + 1) % num4;
					DysonFrame val4 = DysonNode.FrameBetween(val2.nodes[index], val2.nodes[index2]);
					Assert.NotNull((object)val4);
					val2.frames.Add(val4);
				}
				DysonNode[] nodePool = dysonSphere.layersIdBased[val2.layerId].nodePool;
				for (int num7 = 0; num7 < list2.Count; num7++)
				{
					DysonNode val5 = nodePool[list2[num7 % list2.Count]];
					DysonNode val6 = nodePool[list2[(num7 + 1) % list2.Count]];
					DysonFrame val7 = DysonNode.FrameBetween(val5, val6);
					List<Vector3> segments = val7.GetSegments();
					if (val5 == val7.nodeA)
					{
						for (int num8 = 0; num8 < segments.Count - 1; num8++)
						{
							val2.polygon.Add(VectorLF3.op_Implicit(segments[num8]));
						}
						continue;
					}
					for (int num9 = segments.Count - 1; num9 >= 1; num9--)
					{
						val2.polygon.Add(VectorLF3.op_Implicit(segments[num9]));
					}
				}
				list.Add(val2);
				val.shellPool[val2.id] = val2;
			}
			for (int num10 = 0; num10 < val.shellRecycleCursor; num10++)
			{
				val.shellRecycle[num10] = r.ReadInt32();
			}
		}
		if (list.Count <= 0)
		{
			return;
		}
		if (LazyLoading.Enable && version >= 2)
		{
			LazyLoading.Add(dysonSphere);
		}
		else
		{
			GenerateModel(dysonSphere, -1);
		}
		for (int num11 = 1; num11 < dysonSphere.layersIdBased.Length; num11++)
		{
			if (dysonSphere.layersIdBased[num11] == null || dysonSphere.layersIdBased[num11].id != num11)
			{
				continue;
			}
			DysonSphereLayer val8 = dysonSphere.layersIdBased[num11];
			for (int num12 = 1; num12 < val8.nodeCursor; num12++)
			{
				if (val8.nodePool[num12] != null && val8.nodePool[num12].id == num12)
				{
					val8.nodePool[num12].RecalcCpReq();
				}
			}
		}
	}

	public static int GenerateModel(DysonSphere dysonSphere, int bitMask, bool generateModel = true)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		HighStopwatch val = new HighStopwatch();
		val.Begin();
		List<DysonShell> list = new List<DysonShell>();
		for (int i = 1; i < dysonSphere.layersIdBased.Length; i++)
		{
			if ((bitMask & (1 << i)) <= 0 || dysonSphere.layersIdBased[i] == null || dysonSphere.layersIdBased[i].id != i)
			{
				continue;
			}
			DysonSphereLayer val2 = dysonSphere.layersIdBased[i];
			for (int j = 1; j < val2.shellCursor; j++)
			{
				if (val2.shellPool[j] != null && val2.shellPool[j].id == j && val2.shellPool[j].verts == null)
				{
					list.Add(val2.shellPool[j]);
				}
			}
		}
		if (list.Count > 0)
		{
			val.Begin();
			if (IsMultithread && list.Count > 8)
			{
				GenerateGeometryParallel(list);
			}
			else
			{
				foreach (DysonShell item in list)
				{
					item.GenerateGeometry();
				}
			}
			double duration = val.duration;
			double num = 0.0;
			if (generateModel)
			{
				val.Begin();
				foreach (DysonShell item2 in list)
				{
					item2.GenerateModelObjects();
				}
				num = val.duration;
			}
			Log.Debug($"[{dysonSphere.starData.index,2}] Generated {list.Count,4} shells.  Time: {duration:F4} | {num:F4}");
		}
		return list.Count;
	}

	private static void GenerateGeometryParallel(List<DysonShell> dysonShells)
	{
		int currentIndex = dysonShells.Count;
		Task[] array = new Task[3];
		for (int i = 0; i < 3; i++)
		{
			if (s_vmap[i] == null)
			{
				s_vmap[i] = new Dictionary<int, Vector3>();
				s_outvmap[i] = new Dictionary<int, Vector3>();
				s_ivmap[i] = new Dictionary<int, int>();
			}
		}
		array[0] = Task.Run(delegate
		{
			while (true)
			{
				int num4 = Interlocked.Decrement(ref currentIndex);
				if (num4 < 0)
				{
					break;
				}
				GenerateGeometry0(dysonShells[num4]);
			}
		});
		array[1] = Task.Run(delegate
		{
			while (true)
			{
				int num3 = Interlocked.Decrement(ref currentIndex);
				if (num3 < 0)
				{
					break;
				}
				GenerateGeometry1(dysonShells[num3]);
			}
		});
		array[2] = Task.Run(delegate
		{
			while (true)
			{
				int num2 = Interlocked.Decrement(ref currentIndex);
				if (num2 < 0)
				{
					break;
				}
				GenerateGeometry2(dysonShells[num2]);
			}
		});
		while (true)
		{
			int num = Interlocked.Decrement(ref currentIndex);
			if (num < 0)
			{
				break;
			}
			dysonShells[num].GenerateGeometry();
		}
		Task.WaitAll(array);
	}

	public static void FreeRAM()
	{
		for (int i = 0; i < 3; i++)
		{
			if (s_vmap[i] == null)
			{
				s_vmap[i] = null;
				s_outvmap[i] = null;
				s_ivmap[i] = null;
			}
		}
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(DysonShell), "GenerateGeometry")]
	public static void GenerateGeometry0(DysonShell _)
	{
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(DysonShell), "GenerateGeometry")]
	public static void GenerateGeometry1(DysonShell _)
	{
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(DysonShell), "GenerateGeometry")]
	public static void GenerateGeometry2(DysonShell _)
	{
	}

	public static IEnumerable<CodeInstruction> ReplaceDictionary(IEnumerable<CodeInstruction> instructions, int index)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Expected O, but got Unknown
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Expected O, but got Unknown
		return new CodeMatcher(new CodeMatcher(new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
		{
			new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldsfld && ((FieldInfo)i.operand).Name == "s_vmap"), (string)null)
		}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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
			matcher.SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(DysonShellCompress), "s_vmap")).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_I4_S, (object)index)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldelem_Ref, (object)null)
			});
		}, (Action<string>)null).InstructionEnumeration(), (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
		{
			new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldsfld && ((FieldInfo)i.operand).Name == "s_outvmap"), (string)null)
		}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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
			matcher.SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(DysonShellCompress), "s_outvmap")).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_I4_S, (object)index)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldelem_Ref, (object)null)
			});
		}, (Action<string>)null).InstructionEnumeration(), (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
		{
			new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldsfld && ((FieldInfo)i.operand).Name == "s_ivmap"), (string)null)
		}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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
			matcher.SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(DysonShellCompress), "s_ivmap")).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_I4_S, (object)index)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldelem_Ref, (object)null)
			});
		}, (Action<string>)null).InstructionEnumeration();
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DysonSphereLayer), "Export")]
	public static void DysonSphereLayer_Export_Prefix(DysonSphereLayer __instance)
	{
		if (Enable)
		{
			shellCapacity = __instance.shellCapacity;
			shellCursor = __instance.shellCursor;
			shellRecycleCursor = __instance.shellRecycleCursor;
			__instance.shellCapacity = 64;
			__instance.shellCursor = 1;
			__instance.shellRecycleCursor = 0;
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(DysonSphereLayer), "Export")]
	public static void DysonSphereLayer_Export_Postfix(DysonSphereLayer __instance)
	{
		if (Enable)
		{
			__instance.shellCapacity = shellCapacity;
			__instance.shellCursor = shellCursor;
			__instance.shellRecycleCursor = shellRecycleCursor;
		}
	}
}
internal class CargoPathCompress
{
	public static readonly int EncodedVersion = 62;

	private static int version = 62;

	public static bool Enable { get; set; }

	public static void Encode(CargoPath cargoPath, BinaryWriter w)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		w.Write(cargoPath.capacity);
		w.Write(cargoPath.bufferLength);
		int num = 0;
		Vector3 pos = Vector3.zero;
		Quaternion rot = Quaternion.identity;
		Quaternion val = Quaternion.Euler(180f, 0f, 0f);
		Vector3[] pointPos = cargoPath.pointPos;
		Quaternion[] pointRot = cargoPath.pointRot;
		for (int i = 0; i < cargoPath.bufferLength; i++)
		{
			if (Quaternion.Dot(pointRot[i], rot) > 0.9999619f && (double)Quaternion.Dot(pointRot[i], val) > 0.99984769515)
			{
				num++;
			}
			else
			{
				if (num > 0)
				{
					w.Write((float)num * 10000f);
					w.Write(pos.x);
					w.Write(pos.y);
					w.Write(pos.z);
					Utils.WriteCompressedRotation(w, in pos, in rot);
					num = 0;
				}
				w.Write(pointPos[i].x);
				w.Write(pointPos[i].y);
				w.Write(pointPos[i].z);
				Utils.WriteCompressedRotation(w, in pointPos[i], in pointRot[i]);
				val = pointRot[i];
			}
			pos = pointPos[i];
			rot = pointRot[i];
		}
		if (num > 0)
		{
			w.Write((float)num * 10000f);
			w.Write(pos.x);
			w.Write(pos.y);
			w.Write(pos.z);
			Utils.WriteCompressedRotation(w, in pos, in rot);
		}
	}

	public static void Decode(CargoPath cargoPath, BinaryReader r)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		int num = r.ReadInt32();
		int num2 = r.ReadInt32();
		int num3 = 0;
		Vector3 pos = Vector3.zero;
		Quaternion val = Quaternion.identity;
		Vector3[] array = (Vector3[])(object)new Vector3[num];
		Quaternion[] array2 = (Quaternion[])(object)new Quaternion[num];
		int num4 = 0;
		Vector3 pos2 = default(Vector3);
		Quaternion val2 = default(Quaternion);
		while (num4 < num2)
		{
			float num5 = r.ReadSingle();
			if (num5 > 9999f)
			{
				int num6 = (int)num5 / 10000;
				pos2.x = r.ReadSingle();
				pos2.y = r.ReadSingle();
				pos2.z = r.ReadSingle();
				if (version >= 62)
				{
					val2 = Utils.ReadCompressedRotation(r, in pos2);
				}
				else
				{
					val2.x = r.ReadSingle();
					val2.y = r.ReadSingle();
					val2.z = r.ReadSingle();
					val2.w = r.ReadSingle();
				}
				for (int i = 1; i <= num6; i++)
				{
					array[num4] = Vector3.Slerp(pos, pos2, (float)i / (float)num6);
					array2[num4] = Quaternion.Slerp(val, val2, (float)i / (float)num6);
					num4++;
				}
				num3 += num6 - 1;
			}
			else
			{
				pos.x = num5;
				pos.y = r.ReadSingle();
				pos.z = r.ReadSingle();
				if (version >= 62)
				{
					val = Utils.ReadCompressedRotation(r, in pos);
				}
				else
				{
					val.x = r.ReadSingle();
					val.y = r.ReadSingle();
					val.z = r.ReadSingle();
					val.w = r.ReadSingle();
				}
				array[num4] = pos;
				array2[num4] = val;
				num4++;
				_ = ((Vector3)(ref pos)).sqrMagnitude;
				_ = 10000f;
			}
		}
		cargoPath.capacity = num;
		cargoPath.bufferLength = num2;
		cargoPath.pointPos = array;
		cargoPath.pointRot = array2;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(CargoPath), "Export")]
	public static bool CargoPath_Export(CargoPath __instance, BinaryWriter w)
	{
		if (!Enable)
		{
			return true;
		}
		w.Write(EncodedVersion);
		w.Write(__instance.id);
		Encode(__instance, w);
		w.Write(__instance.chunkCapacity);
		w.Write(__instance.chunkCount);
		w.Write(__instance.updateLen);
		w.Write(__instance.closed);
		w.Write((__instance.outputPath != null) ? __instance.outputPath.id : 0);
		w.Write((__instance.outputPath == null) ? (-1) : __instance.outputIndex);
		w.Write(__instance.belts.Count);
		w.Write(__instance.inputPaths.Count);
		w.Write(__instance.buffer, 0, __instance.bufferLength);
		for (int i = 0; i < __instance.chunkCount; i++)
		{
			w.Write(__instance.chunks[i * 3]);
			w.Write(__instance.chunks[i * 3 + 1]);
			w.Write(__instance.chunks[i * 3 + 2]);
		}
		for (int j = 0; j < __instance.belts.Count; j++)
		{
			w.Write(__instance.belts[j]);
		}
		for (int k = 0; k < __instance.inputPaths.Count; k++)
		{
			w.Write(__instance.inputPaths[k]);
		}
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(CargoPath), "Import")]
	public static bool CargoPathImport_Prefix(CargoPath __instance, BinaryReader r)
	{
		version = r.ReadInt32();
		if (version <= 60)
		{
			CargoPathImport(__instance, r);
			return false;
		}
		__instance.Free();
		__instance.id = r.ReadInt32();
		Decode(__instance, r);
		__instance.buffer = new byte[__instance.capacity];
		__instance.SetChunkCapacity(r.ReadInt32());
		__instance.chunkCount = r.ReadInt32();
		__instance.updateLen = r.ReadInt32();
		__instance.closed = r.ReadBoolean();
		__instance.outputPathIdForImport = r.ReadInt32();
		__instance.outputIndex = r.ReadInt32();
		int num = r.ReadInt32();
		int num2 = r.ReadInt32();
		r.BaseStream.Read(__instance.buffer, 0, __instance.bufferLength);
		for (int i = 0; i < __instance.chunkCount; i++)
		{
			__instance.chunks[i * 3] = r.ReadInt32();
			__instance.chunks[i * 3 + 1] = r.ReadInt32();
			__instance.chunks[i * 3 + 2] = r.ReadInt32();
		}
		__instance.belts = new List<int>();
		for (int j = 0; j < num; j++)
		{
			__instance.belts.Add(r.ReadInt32());
		}
		__instance.inputPaths = new List<int>();
		for (int k = 0; k < num2; k++)
		{
			__instance.inputPaths.Add(r.ReadInt32());
		}
		return false;
	}

	[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch(typeof(CargoPath), "Import")]
	public static void CargoPathImport(CargoPath __instance, BinaryReader r)
	{
	}
}
[BepInPlugin("starfi5h.plugin.LossyCompression", "LossyCompression", "0.3.5")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin, IModCanSave
{
	public const string GUID = "starfi5h.plugin.LossyCompression";

	public const string NAME = "LossyCompression";

	public const string VERSION = "0.3.5";

	public const int FORMAT_VERSION = 1;

	private static int enableFlags = 0;

	private Harmony harmony;

	public static Plugin Instance { get; private set; }

	public static bool Enable { get; set; } = true;


	public void Awake()
	{
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Expected O, but got Unknown
		Instance = this;
		Log.LogSource = ((BaseUnityPlugin)this).Logger;
		ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Advance", "LazyLoad", true, "Delay generation of shell model until viewing\n延迟载入戴森壳的模型");
		ConfigEntry<bool> obj = ((BaseUnityPlugin)this).Config.Bind<bool>("Advance", "ReduceRAM", false, "Release models generated by lazy load for vanilla game save to reduce RAM usage.\n不保留延迟载入在保存原版存档时生成的模型。可减少内存占用");
		ConfigEntry<bool> val2 = ((BaseUnityPlugin)this).Config.Bind<bool>("Dependent", "CargoPath", false, "Lossy compress for belts & cargo (will change vanilla save)\n有损压缩传送带数据(将更改原档)");
		ConfigEntry<bool> val3 = ((BaseUnityPlugin)this).Config.Bind<bool>("Independent", "DysonShell", true, "Lossless compress for dyson shells\n无损压缩戴森壳面");
		ConfigEntry<bool> val4 = ((BaseUnityPlugin)this).Config.Bind<bool>("Independent", "DysonSwarm", true, "Lossy compress for dyson swarm\n有损压缩太阳帆");
		enableFlags += (val2.Value ? 1 : 0);
		enableFlags += (val3.Value ? 2 : 0);
		enableFlags += (val4.Value ? 4 : 0);
		LazyLoading.Enable = val.Value;
		LazyLoading.ReduceRAM = obj.Value;
		SetEnables(enableFlags);
		DysonShellCompress.IsMultithread = true;
		DysonSwarmCompress.IsMultithread = true;
		harmony = new Harmony("starfi5h.plugin.LossyCompression");
		ModCompatibility.Init(harmony);
		harmony.PatchAll(typeof(Plugin));
		harmony.PatchAll(typeof(CargoPathCompress));
		harmony.PatchAll(typeof(DysonShellCompress));
		harmony.PatchAll(typeof(DysonSwarmCompress));
		if (LazyLoading.Enable)
		{
			try
			{
				harmony.PatchAll(typeof(LazyLoading));
			}
			catch (Exception obj2)
			{
				Log.Error("Lazy load patching fail! The function is now disabled");
				Log.Error(obj2);
				LazyLoading.Enable = false;
			}
		}
		harmony.PatchAll(typeof(UIcontrol));
		Log.Info($"cargoPath:{CargoPathCompress.Enable} dysonShell:{DysonShellCompress.Enable} dysonSwarm:{DysonSwarmCompress.Enable}\n" + $"lazyLoad:{LazyLoading.Enable} reduceRAM:{LazyLoading.ReduceRAM}");
	}

	public void OnDestroy()
	{
		UIcontrol.OnDestory();
		harmony.UnpatchSelf();
	}

	public static int GetEnables()
	{
		int num = 0;
		if (CargoPathCompress.Enable)
		{
			num |= 1;
		}
		if (DysonShellCompress.Enable)
		{
			num |= 2;
		}
		if (DysonSwarmCompress.Enable)
		{
			num |= 4;
		}
		return num;
	}

	public static void SetEnables(int mask)
	{
		CargoPathCompress.Enable = (mask & 1) != 0;
		DysonShellCompress.Enable = (mask & 2) != 0;
		DysonSwarmCompress.Enable = (mask & 4) != 0;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(GameData), "Export")]
	public static void BeforeGameExport()
	{
		if (!Enable)
		{
			enableFlags = GetEnables();
			SetEnables(0);
			Log.Info("Normal compression");
		}
	}

	public void Export(BinaryWriter w)
	{
		if (GameMain.instance.isMenuDemo)
		{
			return;
		}
		if (Enable)
		{
			string text = "Format version:" + 1 + " Compress version:";
			if (CargoPathCompress.Enable)
			{
				text = text + " CargoPath(v" + (CargoPathCompress.EncodedVersion - 60) + ")";
			}
			if (DysonShellCompress.Enable)
			{
				string text2 = text;
				int encodedVersion = DysonShellCompress.EncodedVersion;
				text = text2 + " DysonShell(v" + encodedVersion + ")";
			}
			if (DysonSwarmCompress.Enable)
			{
				string text3 = text;
				int encodedVersion = DysonSwarmCompress.EncodedVersion;
				text = text3 + " DysonSwarm(v" + encodedVersion + ")";
			}
			Log.Warn(text);
			w.Write(1);
			DysonShellCompress.Export(w);
			DysonSwarmCompress.Export(w);
		}
		else
		{
			w.Write(0);
			SetEnables(enableFlags);
		}
	}

	public void Import(BinaryReader r)
	{
		if (GameMain.instance.isMenuDemo)
		{
			return;
		}
		int num = r.ReadInt32();
		if (num == 1)
		{
			Log.Info("Import format version: " + num);
			DysonShellCompress.Import(r);
			DysonSwarmCompress.Import(r);
			UIRoot.instance.uiGame.statWindow.performancePanelUI.RefreshDataStatTexts();
			if (ModCompatibility.AfeterImport != null)
			{
				Log.Info("Processing compatibility process...");
				ModCompatibility.AfeterImport();
			}
		}
	}

	public void IntoOtherSave()
	{
	}
}
public static class Log
{
	public static ManualLogSource LogSource;

	public static void Error(object obj)
	{
		LogSource.LogError(obj);
	}

	public static void Warn(object obj)
	{
		LogSource.LogWarning(obj);
	}

	public static void Info(object obj)
	{
		LogSource.LogInfo(obj);
	}

	public static void Debug(object obj)
	{
		LogSource.LogDebug(obj);
	}
}
internal class UIcontrol
{
	private static GameObject compressButton;

	private static Text compressButtonText;

	private static Image compressButtonColor;

	private static Color orange = new Color(1f, 0.5961f, 0.3804f, 0.7216f);

	private static Color grey = new Color(0.6196f, 0.6196f, 0.6196f, 0.7216f);

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIPerformancePanel), "_OnOpen")]
	public static void Init()
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)compressButton == (Object)null)
		{
			try
			{
				UIButton dataActiveButton = UIRoot.instance.uiGame.statWindow.performancePanelUI.dataActiveButton;
				compressButton = Object.Instantiate<GameObject>(((Component)dataActiveButton).gameObject, ((Component)dataActiveButton).transform.parent);
				((Object)compressButton).name = "LossyCompression - ActiveButton";
				Transform transform = compressButton.transform;
				transform.localPosition += new Vector3(120f, 0f);
				Object.Destroy((Object)(object)compressButton.GetComponent<UIButton>());
				Button component = compressButton.GetComponent<Button>();
				((UnityEventBase)component.onClick).RemoveAllListeners();
				((UnityEvent)component.onClick).AddListener(new UnityAction(OnCompressActiveButtonClick));
				Transform obj = compressButton.transform.Find("button-text");
				Object.Destroy((Object)(object)((Component)obj).GetComponent<Localizer>());
				compressButtonText = ((Component)obj).GetComponent<Text>();
				compressButtonColor = compressButton.GetComponent<Image>();
				compressButtonText.text = "Compress - ON";
				((Graphic)compressButtonColor).color = orange;
				Log.Debug("UI component init");
			}
			catch
			{
				Log.Warn("UI component initial fail!");
			}
		}
	}

	public static void OnDestory()
	{
		if ((Object)(object)compressButton != (Object)null)
		{
			Object.Destroy((Object)(object)compressButton);
			compressButtonText = null;
			compressButtonColor = null;
		}
	}

	public static void OnCompressActiveButtonClick()
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		Plugin.Enable = !Plugin.Enable;
		if (Plugin.Enable)
		{
			compressButtonText.text = "Compress - ON";
			((Graphic)compressButtonColor).color = orange;
		}
		else
		{
			compressButtonText.text = "Compress - OFF";
			((Graphic)compressButtonColor).color = grey;
		}
	}
}