using System; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.IO; using Microsoft.CodeAnalysis; using Quantum.Commands; using SerializableTypes; using UnityEngine; using WildSkies.Gameplay.Building; using WildSkies.Gameplay.ShipBuilding; using WildSkies.Player; using WildSkies.Service; using WildSkies.Service.Instantiation; using WildSkies.Ship; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("ShipManagement")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Nines (Natives)")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyProduct("ShipManagement")] [assembly: AssemblyTitle("ShipManagement")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ShipManagement { [BepInPlugin("ShipManagement", "ShipManagement", "1.0.2")] public class Plugin : BasePlugin { private class ShipSimpleChatCommands { public static string Save(int saveIndex) { PlayersService obj = SceneContextInstaller.ResolveObject(); object obj2; if (obj == null) { obj2 = null; } else { ShipControl shipToControl = ((Il2CppObjectBase)obj.LocalPlayer).Cast().UserControlShip.ShipToControl; obj2 = ((shipToControl != null) ? shipToControl.ShipController : null); } ConstructedShipController val = (ConstructedShipController)obj2; if ((Object)(object)val == (Object)null) { return "Get to a ship helm to save to a preset."; } if (val.ShipFrameBuilder.GetHologramBlockCount() > 0) { return "Clear the hologram blocks before saving the ship."; } if (!Object.op_Implicit((Object)(object)val.ShipCore)) { return "Add a core before saving the ship."; } try { ShipHull shipHullHardCopy = ShipSerializationUtils.GetShipHullHardCopy(val.NetworkShipyard._shipFrameBuilder.ShipHull, val.NetworkShipyard._itemService, val.NetworkShipyard._buildingService, val.NetworkShipyard._craftingService); shipHullHardCopy.ShipDesignName = val.shipName; string contents = Convert.ToBase64String(CompressionHelper.Compress(ShipSerializationUtils.BinarySerializeShipHull(shipHullHardCopy, val.NetworkShipyard._itemService, val.NetworkShipyard._buildingService, val.NetworkShipyard._craftingService))); File.WriteAllText(Path.Combine(ProjectContextInstaller.ResolveObject().GetSaveDataRootPath(), $"SaveData_ShipHull_{saveIndex}.sav"), contents); return $"Saved \"{val.shipName}\" to preset {saveIndex}."; } catch (Exception ex) { return $"Failed to save ship {saveIndex}. {ex.Message}"; } } public static string Load(int saveIndex) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown WildSkiesInstantiationService val = SceneContextInstaller.ResolveObject(); if (val == null) { return "Failed to resolve WildSkiesInstantiationService"; } PlayersService val2 = SceneContextInstaller.ResolveObject(); if (val2 == null) { return "Failed to resolve PlayersService"; } Transform transform = ((Component)val2.LocalPlayer.DynamikaCharacter).transform; ConstructedShipController component = ((InstantiationService)val).Instantiate(((InstantiationService)val).AssetReferences.ConstructedShip, new AssetLoadRequest((Action)null) { Position = transform.position + Vector3.up * 20f + transform.forward * 20f }).GetComponent(); try { ShipHull val3 = ShipSerializationUtils.BinaryDeserializeShipHull(Il2CppStructArray.op_Implicit(CompressionHelperDecompress(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Convert.FromBase64String(File.ReadAllText(Path.Combine(ProjectContextInstaller.ResolveObject().GetSaveDataRootPath(), $"SaveData_ShipHull_{saveIndex}.sav")))))), component.NetworkShipyard._itemService, component.NetworkShipyard._buildingService, component.NetworkShipyard._craftingService); val3.ShipSaveSlot = -1; val3.ShipHullUUID = component.CoherenceSync.ManualUniqueId; component.SetShipName(val3.ShipDesignName); component.NetworkShipyard._saveSlot = -1; component.NetworkShipyard._isDesignSave = false; component.NetworkShipyard._receivedFullSync = true; component.NetworkShipyard.SetShipHullDataFromSave(val3); component.NetworkShipyard._shipFrameBuilder.ShipHull.SetIsDirty(true); component.NetworkShipyard._timeSinceLastStateSync = 1f; InstantiationCommands._spawnedShips.Add(component); InstantiationCommands.LaunchSpawnedShip(component); return "Loaded saved ship " + component.shipName + "."; } catch (Exception ex) { Object.Destroy((Object)(object)((Component)component).gameObject); return $"Failed to load saved ship {saveIndex}. {ex.Message}"; } } } internal static ManualLogSource Log; internal static Harmony harmonyInstance; public override void Load() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BasePlugin)this).Log; ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("ShipManagement"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!"); } log.LogInfo(val); harmonyInstance = Harmony.CreateAndPatchAll(typeof(Plugin), (string)null); } public override bool Unload() { Harmony obj = harmonyInstance; if (obj != null) { obj.UnpatchSelf(); } return true; } public static byte[] CompressionHelperDecompress(byte[] compressedData) { using MemoryStream stream = new MemoryStream(compressedData); using MemoryStream memoryStream = new MemoryStream(); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); byte[] array = new byte[1024]; int count; while ((count = gZipStream.Read(array, 0, array.Length)) > 0) { memoryStream.Write(array, 0, count); } gZipStream.Close(); return memoryStream.ToArray(); } public static ComponentData ComponentDataDeserialize(BinaryReader reader, int version) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ComponentData val = new ComponentData(); val.ComponentID = reader.ReadString(); val.ResourceIDs = new List(); int num = reader.ReadInt32(); for (int i = 0; i < num; i++) { val.ResourceIDs.Add(reader.ReadString()); } if (version >= 260) { val.VariationSeed = reader.ReadInt32(); } val.IsMainComponent = reader.ReadBoolean(); return val; } public static HullObjectData HullObjectDataDeserialize(BinaryReader reader, int version) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00c4: Unknown result type (might be due to invalid IL or missing references) HullObjectData val = new HullObjectData(); if (version >= 257) { val.ParentId = reader.ReadInt32(); } else { val.ParentId = -1; } if (version >= 258) { val.UpgradeLevel = reader.ReadInt32(); } else { val.UpgradeLevel = 0; } val.FaceId = reader.ReadInt32(); val.ItemId = reader.ReadString(); HullObjectData val2 = val; string itemId = val.ItemId; string itemId2 = ((itemId == "ship.part.helm.saborian.2") ? "ship.part.helm.saborian.1" : ((!(itemId == "ship.part.helm.saborian.3")) ? val.ItemId : "ship.part.helm.saborian.1")); val2.ItemId = itemId2; val.HullObjectType = (HullObjectType)reader.ReadInt32(); val.LocalPosition = SerializableVector3.Deserialize(reader); if (version >= 257) { val.LocalRotationQuat = SerializableQuaternion.Deserialize(reader); } else { SerializableVector3 val3 = SerializableVector3.Deserialize(reader); val.LocalRotationQuat = SerializableQuaternion.op_Implicit(Quaternion.Euler(SerializableVector3.op_Implicit(val3))); } val.ComponentDataList = new List(); int num = reader.ReadInt32(); for (int i = 0; i < num; i++) { val.ComponentDataList.Add(ComponentDataDeserialize(reader, version)); } val.CraftingItemIds = new List(); int num2 = reader.ReadInt32(); for (int j = 0; j < num2; j++) { val.CraftingItemIds.Add(reader.ReadString()); } return val; } public static HullVertex HullVertexDeserialize(BinaryReader reader, int version) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) HullVertex val = new HullVertex(reader.ReadInt32()); val.LinkedFaces.Clear(); val.LinkedFacesIDs.Clear(); int num = reader.ReadInt32(); for (int i = 0; i < num; i++) { int num2 = reader.ReadInt32(); val.LinkedFacesIDs.Add(num2); } val.PositionOffsetsRelativeToBounds = SerializableVector3.Deserialize(reader); val.VertexBoundZeroIndex = SerializableVector3Int.Deserialize(reader); return val; } public static HullEdge HullEdgeDeserialize(BinaryReader reader, int version) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown HullEdge val = new HullEdge(reader.ReadInt32()); int num = reader.ReadInt32(); val.Verts = Il2CppReferenceArray.op_Implicit((HullVertex[])(object)new HullVertex[num]); val.VertsIDs = Il2CppStructArray.op_Implicit(new int[num]); for (int i = 0; i < num; i++) { int num2 = reader.ReadInt32(); ((Il2CppArrayBase)(object)val.VertsIDs)[i] = num2; } val.materialIndex = reader.ReadByte(); val.beamTypeIndex = reader.ReadUInt16(); return val; } public static HullFace HullFaceDeserialize(BinaryReader reader, int version) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown HullFace val = new HullFace(reader.ReadInt32()); int num = reader.ReadInt32(); val.Verts = Il2CppReferenceArray.op_Implicit((HullVertex[])(object)new HullVertex[num]); val.VertsIDs = Il2CppStructArray.op_Implicit(new int[num]); for (int i = 0; i < num; i++) { int num2 = reader.ReadInt32(); ((Il2CppArrayBase)(object)val.VertsIDs)[i] = num2; } val.FaceAxis = (Axis)reader.ReadInt16(); val.CurveIsV0ToV1 = reader.ReadBoolean(); val.CurvynessV0ToV1 = reader.ReadSingle(); val.CurvynessV0ToV3 = reader.ReadSingle(); val.negOffset = reader.ReadBoolean(); val.materialIndexFront = reader.ReadByte(); val.materialIndexBack = reader.ReadByte(); val.faceFillIndex = reader.ReadUInt16(); val.craftingItemIdsFront.Clear(); int num3 = reader.ReadInt32(); for (int j = 0; j < num3; j++) { val.craftingItemIdsFront.Add(reader.ReadString()); } val.craftingItemIdsBack.Clear(); num3 = reader.ReadInt32(); for (int k = 0; k < num3; k++) { val.craftingItemIdsBack.Add(reader.ReadString()); } return val; } public static HullBlock HullBlockDeserialize(BinaryReader reader, int version) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown HullBlock val = new HullBlock(); val.SetID(reader.ReadInt32()); val._isCrafted = reader.ReadBoolean(); int num = reader.ReadInt32(); val.Verts.Clear(); val.VertsIDs.Clear(); for (int i = 0; i < num; i++) { int num2 = reader.ReadInt32(); val.VertsIDs.Add(num2); } int num3 = reader.ReadInt32(); val.Edges.Clear(); val.EdgesIDs.Clear(); for (int j = 0; j < num3; j++) { int num4 = reader.ReadInt32(); val.EdgesIDs.Add(num4); } int num5 = reader.ReadInt32(); val.Faces.Clear(); val.FacesIDs.Clear(); for (int k = 0; k < num5; k++) { int num6 = reader.ReadInt32(); val.FacesIDs.Add(num6); } return val; } [HarmonyPatch(typeof(ShipHull), "Deserialize")] [HarmonyPrefix] public static bool ShipHull_Deserialize(BinaryReader reader, IItemService itemService, BuildingService buildingService, ICraftingService craftingService, ref ShipHull __result) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown int num = reader.ReadInt32(); if (num >= 512) { reader.BaseStream.Seek(0L, (SeekOrigin)0); return true; } ShipHull val = new ShipHull(8); val.ShipDesignName = reader.ReadString(); val.IsCrafted = reader.ReadBoolean(); val.ShipSaveSlot = reader.ReadInt32(); val.ShipHullVersion = reader.ReadInt32(); val.ShipHullUUID = reader.ReadString(); reader.ReadInt32(); reader.ReadInt32(); val._nextFaceID = reader.ReadInt32(); reader.ReadInt32(); val.ShipStatsPresetId = reader.ReadInt32(); val.UseVisualShipHull = reader.ReadBoolean(); val.VisualShipHullAttachmentIndex = reader.ReadInt32(); int num2 = reader.ReadInt32(); List val2 = new List(num2); for (int i = 0; i < num2; i++) { if (reader.ReadBoolean()) { val2.Add(HullObjectDataDeserialize(reader, num)); } else { val2.Add((HullObjectData)null); } } num2 = reader.ReadInt32(); val.HullObjectDataList = Il2CppReferenceArray.op_Implicit((HullObjectData[])(object)new HullObjectData[1024]); for (int j = 0; j < num2; j++) { if (reader.ReadBoolean()) { ((Il2CppArrayBase)(object)val.HullObjectDataList)[j] = HullObjectDataDeserialize(reader, num); } else { ((Il2CppArrayBase)(object)val.HullObjectDataList)[j] = null; } } for (int k = 0; k < val2.Count; k++) { ((Il2CppArrayBase)(object)val.HullObjectDataList)[k] = val2[k]; } val.HullEdgeCraftingItemIds.Clear(); if (num >= 259) { num2 = reader.ReadInt32(); val.HullEdgeCraftingItemIds.Add(reader.ReadString()); } else { val.HullEdgeCraftingItemIds.Add("resource.metal.iron.1"); } num2 = reader.ReadInt32(); val.HullVertices.Clear(); for (int l = 0; l < num2; l++) { HullVertex val3 = HullVertexDeserialize(reader, num); val.HullVertices[val3.ID] = val3; } num2 = reader.ReadInt32(); val.HullEdges.Clear(); for (int m = 0; m < num2; m++) { HullEdge val4 = HullEdgeDeserialize(reader, num); val.HullEdges[val4.ID] = val4; } num2 = reader.ReadInt32(); val.HullFaces.Clear(); for (int n = 0; n < num2; n++) { HullFace val5 = HullFaceDeserialize(reader, num); val.HullFaces[val5.ID] = val5; } num2 = reader.ReadInt32(); val.HullBlocks.Clear(); for (int num3 = 0; num3 < num2; num3++) { HullBlock val6 = HullBlockDeserialize(reader, num); val.HullBlocks[val6.ID] = val6; } Enumerator enumerator = val.HullVertices.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.Value.ResolveDependencies(val.HullFaces); } Enumerator enumerator2 = val.HullEdges.GetEnumerator(); while (enumerator2.MoveNext()) { enumerator2.Current.Value.ResolveDependencies(val.HullVertices); } Enumerator enumerator3 = val.HullFaces.GetEnumerator(); while (enumerator3.MoveNext()) { enumerator3.Current.Value.ResolveDependencies(val.HullVertices); } Enumerator enumerator4 = val.HullBlocks.GetEnumerator(); while (enumerator4.MoveNext()) { enumerator4.Current.Value.ResolveDependencies(val.HullVertices, val.HullEdges, val.HullFaces); } enumerator = new Dictionary(((Il2CppObjectBase)val.HullVertices).Cast>()).GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; current.Value.SetIDToHashCode(); val.HullVertices.Remove(current.Key); val.HullVertices.Add(current.Value.ID, current.Value); } enumerator2 = new Dictionary(((Il2CppObjectBase)val.HullEdges).Cast>()).GetEnumerator(); while (enumerator2.MoveNext()) { KeyValuePair current2 = enumerator2.Current; current2.Value.SetIDToHashCode(); val.HullEdges.Remove(current2.Key); val.HullEdges.Add(current2.Value.ID, current2.Value); } enumerator4 = new Dictionary(((Il2CppObjectBase)val.HullBlocks).Cast>()).GetEnumerator(); while (enumerator4.MoveNext()) { KeyValuePair current3 = enumerator4.Current; current3.Value.SetIDToHashCode(); val.HullBlocks.Remove(current3.Key); val.HullBlocks.Add(current3.Value.ID, current3.Value); } __result = val; return false; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ShipManagement"; public const string PLUGIN_NAME = "ShipManagement"; public const string PLUGIN_VERSION = "1.0.2"; } }