Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Ship Layout Restorer v1.5.0
Ship_Layout_Restorer.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using ChatCommandAPI; using ChatCommandAPI.Utils; using GameNetcodeStuff; using Unity.Netcode; using UnityEngine; using UnityEngine.SceneManagement; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace Ship_Layout_Restorer; [BepInPlugin("Crispy_Depression.Ship_Layout_Restorer", "Ship_Layout_Restorer", "1.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal class Store { public string[] Names = new string[10]; public Dictionary<string, string>[] Data = new Dictionary<string, string>[10]; public bool Upgrade; public Dictionary<string, Dictionary<string, string>> Backups = new Dictionary<string, Dictionary<string, string>>(); } public const string DefaultsVersion = "1.4.1"; public const string GUID = "Crispy_Depression.Ship_Layout_Restorer"; private static readonly string[] Furniture = new string[26] { "Dog house", "Electric chair", "Classic painting", "Fridge", "Sofa chair", "Microwave", "Disco Ball", "Plushie pajama man", "Goldfish", "Welcome mat", "JackOLantern", "Inverse Teleporter", "Loud horn", "Signal translator", "Terminal", "Bunkbeds", "Romantic table", "Table", "Record player", "Light switch", "Shower", "Toilet", "File Cabinet", "Cupboard", "Television", "Teleporter" }; private static readonly string[] PresetNames = new string[10] { "Saved", "My Setup", "Crazy Teleporter", "Beehive", "Mirrored", "Ceiling Furniture", "Outside Furniture Grid", "Custom 7", "Custom 8", "Custom 9" }; private static readonly string[][] PresetData = new string[10][] { new string[0], new string[26] { "Dog house=1.13729048, 4.580828, -10.8193426 | 0, 1.00179122E-05, 0", "Electric chair=10.1209717, 3.63771582, -11.3743954 | 270, 270, 0", "Classic painting=-2.71196437, 1.14276636, -17.5732384 | 270, 180, 0", "Fridge=1.49420214, 4.420552, -10.8262568 | 270, 9.659345E-06, 0", "Sofa chair=3.227193, 4.32139254, -17.5127239 | 278.7447, 180.000031, 180.000015", "Microwave=1.34165788, 3.41585064, -10.7636261 | 270, 1.00179113E-05, 0", "Disco Ball=0.9585268, 4.040828, -10.7884607 | 270, 103.261269, 0", "Plushie pajama man=10.1071424, 2.115928, -14.6245174 | 270, 0, 0", "Goldfish=1.66791368, 3.26588416, -10.7976351 | 270, 0, 0", "Welcome mat=-5.05744171, 0.346222043, -14.1720371 | 270, 0, 0", "JackOLantern=0.9895336, 4.010828, -10.8093958 | 270, 270, 0", "Inverse Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0", "Loud horn=10.5750074, 2.73233724, -12.667819 | 270, 180, 0", "Signal translator=9.771228, 0.4208452, -14.5651722 | 270, 0, 0", "Terminal=10.8989182, 3.13425827, -12.9037714 | 270, 1.00179122E-05, 0", "Bunkbeds=4.949032, 2.04171371, -16.74276 | 270.027985, 90, 0", "Romantic table=1.48312461, 4.240828, -10.7176485 | 271.282379, 17.2424717, 73.9737244", "Table=1.10685444, 4.240828, -10.7842379 | 270, 180, 0", "Record player=1.2608974, 4.310828, -10.7022238 | 271.6528, 129.618774, 90.00093", "Light switch=-5.162993, 2.3265965, -15.9850826 | 270, 90, 0", "Shower=6.82965755, 1.86898124, -16.1021423 | 270, 0, 0", "Toilet=1.25805664, 4.44082832, -10.8133478 | 270, 359.992523, 0", "File Cabinet=1.50776386, 1.06898952, -10.7920094 | 270.019775, 0, 0", "Cupboard=9.892296, 1.630511, -11.4973116 | 270, 1.00179122E-05, 0", "Television=1.25773787, 4.160828, -10.8200827 | 6.728352E-07, 9.657237E-06, 89.99508", "Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0" }, new string[26] { "Dog house=1.13729048, 4.580828, -10.8193426 | 0, 1.00179122E-05, 0", "Electric chair=10.1209717, 3.63771582, -11.3743954 | 270, 270, 0", "Classic painting=-2.71196437, 1.14276636, -17.5732384 | 270, 180, 0", "Fridge=1.49420214, 4.420552, -10.8262568 | 270, 9.659345E-06, 0", "Sofa chair=3.227193, 4.32139254, -17.5127239 | 278.7447, 180.000031, 180.000015", "Microwave=1.34165788, 3.41585064, -10.7636261 | 270, 1.00179113E-05, 0", "Disco Ball=0.9585268, 4.040828, -10.7884607 | 270, 103.261269, 0", "Plushie pajama man=10.1071424, 2.115928, -14.6245174 | 270, 0, 0", "Goldfish=1.66791368, 3.26588416, -10.7976351 | 270, 0, 0", "Welcome mat=-5.05744171, 0.346222043, -14.1720371 | 270, 0, 0", "JackOLantern=0.9895336, 4.010828, -10.8093958 | 270, 270, 0", "Inverse Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0", "Loud horn=10.5750074, 2.73233724, -12.667819 | 270, 180, 0", "Signal translator=9.771228, 0.4208452, -14.5651722 | 270, 0, 0", "Terminal=10.8989182, 3.13425827, -12.9037714 | 270, 1.00179122E-05, 0", "Bunkbeds=4.949032, 2.04171371, -16.74276 | 270.027985, 90, 0", "Romantic table=1.48312461, 4.240828, -10.7176485 | 271.282379, 17.2424717, 73.9737244", "Table=1.10685444, 4.240828, -10.7842379 | 270, 180, 0", "Record player=1.2608974, 4.310828, -10.7022238 | 271.6528, 129.618774, 90.00093", "Light switch=-5.162993, 2.3265965, -15.9850826 | 270, 90, 0", "Shower=6.82965755, 1.86898124, -16.1021423 | 270, 0, 0", "Toilet=1.25805664, 4.44082832, -10.8133478 | 270, 359.992523, 0", "File Cabinet=1.50776386, 1.06898952, -10.7920094 | 270.019775, 0, 0", "Cupboard=9.892296, 1.630511, -11.4973116 | 270, 1.00179122E-05, 0", "Television=1.25773787, 4.160828, -10.8200827 | 6.728352E-07, 9.657237E-06, 89.99508", "Teleporter=6.819901, 2.13900828, -15.8713675 | 0, 270, 0" }, new string[5] { "Terminal=7.46616554, 1.93722069, -16.338316 | 270, 90, 0", "Bunkbeds=-5.187002, 3.79923439, -12.9998941 | 270, 270, 0", "Light switch=-5.162993, 2.3265965, -15.9850826 | 270, 90, 0", "File Cabinet=-5.21352243, 1.11267471, -13.2425184 | 270.019775, 90, 0", "Cupboard=9.819887, 1.63071132, -11.5646935 | 270.019775, 0, 0" }, new string[26] { "Dog house=1, 4.5, -17 | 0, 0, 0", "Electric chair=10.12097, 3.637716, -16.6256 | 270, 270, 0", "Classic painting=-2.5, 1, -10.5 | 270, 180, 0", "Fridge=1.5, 4.5, -17 | 270, 0, 0", "Sofa chair=3, 4.5, -10.5 | 279, 180, 180", "Microwave=1.5, 3.5, -17 | 270, 0, 0", "Disco Ball=0.9585268, 4.040828, -10.7884607 | 270, 103.261269, 0", "Plushie pajama man=10, 2, -13.5 | 270, 0, 0", "Goldfish=1.5, 3.5, -17 | 270, 0, 0", "Welcome mat=-5, 0.5, -14 | 270, 0, 0", "JackOLantern=1, 4, -17 | 270, 270, 0", "Inverse Teleporter=7, 2, -12 | 270, 65, 0", "Loud horn=10.5, 2.5, -15.5 | 270, 180, 0", "Signal translator=10, 0.5, -13.5 | 270, 0, 0", "Terminal=10.8989182, 3.13425827, -12.9037714 | 270, 1.00179122E-05, 0", "Bunkbeds=5, 2, -11.5 | 270, 90, 0", "Romantic table=1.5, 4, -17.5 | 271, 17, 74", "Table=1, 4, -17 | 270, 180, 0", "Record player=1.5, 4.5, -17.5 | 272, 130, 90", "Light switch=-5.162993, 2.3265965, -15.9850826 | 270, 90, 0", "Shower=7, 2, -12 | 270, 0, 0", "Toilet=1.5, 4.5, -17 | 270, 0, 0", "File Cabinet=1.5, 1, -17 | 270, 0, 0", "Cupboard=10, 1.5, -16.5 | 270, 0, 0", "Television=1.5, 4, -17 | 0, 0, 90", "Teleporter=7, 2, -12 | 270, 65, 0" }, new string[26] { "Dog house=6, 10, -14 | 0, 0, 0", "Electric chair=10.1209717, 3.63771582, -11.3743954 | 270, 270, 0", "Classic painting=6.5, 10, -14 | 270, 180, 0", "Fridge=5, 10, -14 | 270, 0, 0", "Sofa chair=7.5, 10, -14 | 270, 180, 0", "Microwave=4.5, 10, -14 | 270, 0, 0", "Disco Ball=0.9585268, 4.040828, -10.7884607 | 270, 103.261269, 0", "Plushie pajama man=4, 10, -14 | 270, 0, 0", "Goldfish=3.5, 10, -14 | 270, 0, 0", "Welcome mat=7, 10, -14 | 270, 0, 0", "JackOLantern=3, 10, -14 | 270, 270, 0", "Inverse Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0", "Loud horn=8, 10, -14 | 270, 180, 0", "Signal translator=9.771228, 0.4208452, -14.5651722 | 270, 0, 0", "Terminal=10.8989182, 3.13425827, -12.9037714 | 270, 1.00179122E-05, 0", "Bunkbeds=4.949032, 2.04171371, -16.74276 | 270.027985, 90, 0", "Romantic table=1.5, 10, -14 | 270, 0, 0", "Table=1, 10, -14 | 270, 180, 0", "Record player=2.5, 10, -14 | 270, 0, 0", "Light switch=-5.162993, 2.3265965, -15.9850826 | 270, 90, 0", "Shower=6.82965755, 1.86898124, -16.1021423 | 270, 0, 0", "Toilet=5.5, 10, -14 | 270, 0, 0", "File Cabinet=1.50776386, 1.06898952, -10.7920094 | 270.019775, 0, 0", "Cupboard=9.892296, 1.630511, -11.4973116 | 270, 1.00179122E-05, 0", "Television=2, 10, -14 | 0, 0, 90", "Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0" }, new string[26] { "Dog house=6, 4, 13 | 0, 0, 0", "Electric chair=10.1209717, 3.63771582, -11.3743954 | 270, 270, 0", "Classic painting=8, 4, 13 | 270, 180, 0", "Fridge=2, 4, 13 | 270, 0, 0", "Sofa chair=4, 4, 11 | 270, 180, 0", "Microwave=8, 4, 15 | 270, 0, 0", "Disco Ball=0.9585268, 4.040828, -10.7884607 | 270, 103.261269, 0", "Plushie pajama man=6, 4, 15 | 270, 0, 0", "Goldfish=4, 4, 15 | 270, 0, 0", "Welcome mat=2, 4, 11 | 270, 0, 0", "JackOLantern=2, 4, 15 | 270, 270, 0", "Inverse Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0", "Loud horn=6, 4, 11 | 270, 180, 0", "Signal translator=9.771228, 0.4208452, -14.5651722 | 270, 0, 0", "Terminal=10.8989182, 3.13425827, -12.9037714 | 270, 1.00179122E-05, 0", "Bunkbeds=4.949032, 2.04171371, -16.74276 | 270.027985, 90, 0", "Romantic table=4, 4, 17 | 270, 0, 0", "Table=2, 4, 17 | 270, 180, 0", "Record player=8, 4, 17 | 270, 0, 0", "Light switch=-5.162993, 2.3265965, -15.9850826 | 270, 90, 0", "Shower=6.82965755, 1.86898124, -16.1021423 | 270, 0, 0", "Toilet=4, 4, 13 | 270, 0, 0", "File Cabinet=1.50776386, 1.06898952, -10.7920094 | 270.019775, 0, 0", "Cupboard=9.892296, 1.630511, -11.4973116 | 270, 1.00179122E-05, 0", "Television=6, 4, 17 | 0, 0, 90", "Teleporter=6.819901, 2.13900828, -15.8713675 | 270, 64.7, 0" }, new string[0], new string[0], new string[0] }; internal static ConfigEntry<string> KeepOnClear; internal static ConfigEntry<string> PresetsFile; internal static ConfigEntry<bool> StoreExtras; internal static ConfigEntry<bool> AutoPlace; internal static string PluginDir; private int lastTick; private int cozyTick; private int baseAt; private bool baselined; private StartOfRound lastSor; private HashSet<string> known; private Dictionary<string, int> pending = new Dictionary<string, int>(); internal static string[] AllFurniture => Furniture; internal static string PresetPath => (!Path.IsPathRooted(PresetsFile.Value)) ? Path.Combine(PluginDir, PresetsFile.Value) : PresetsFile.Value; internal static string StatePath => Path.Combine(PluginDir, "Crispy_Depression.Ship_Layout_Restorer.State.txt"); private static Store Defaults() { Store store = new Store(); for (int i = 0; i < 10; i++) { store.Names[i] = PresetNames[i]; store.Data[i] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); string[] array = PresetData[i]; foreach (string text in array) { int num = text.IndexOf('='); store.Data[i][text.Substring(0, num)] = text.Substring(num + 1); } } return store; } internal static Store Load() { Store store = Defaults(); if (!File.Exists(PresetPath)) { return store; } string[] array = File.ReadAllLines(PresetPath); bool flag = array.Any((string x) => x.Trim() == "# Defaults: 1.4.1"); store.Upgrade = !flag; int num = -1; bool flag2 = false; string text = null; string[] array2 = array; foreach (string text2 in array2) { string text3 = text2.Trim(); if (text3.Length == 0 || text3[0] == '#') { continue; } Match match = Regex.Match(text3, "^\\[Backup\\s+(\\w+)\\]$"); if (match.Success) { text = match.Groups[1].Value; num = -1; flag2 = false; store.Backups[text] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); continue; } Match match2 = Regex.Match(text3, "^\\[Preset\\s+(\\d)\\s*(?:-\\s*(.*?))?\\s*\\]$"); if (match2.Success) { text = null; num = int.Parse(match2.Groups[1].Value); flag2 = store.Upgrade && num >= 1 && num <= 7; if (!flag2) { if (match2.Groups[2].Success && match2.Groups[2].Value.Length > 0) { store.Names[num] = match2.Groups[2].Value; } store.Data[num] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); } } else { int num3 = text3.IndexOf('='); if (text != null && num3 >= 0) { store.Backups[text][text3.Substring(0, num3).Trim()] = text3.Substring(num3 + 1).Trim(); } else if (num >= 0 && num3 >= 0 && !flag2) { store.Data[num][text3.Substring(0, num3).Trim()] = text3.Substring(num3 + 1).Trim(); } } } return store; } internal static void Write(Store s) { List<string> list = new List<string>(); list.Add("# Defaults: 1.4.1"); list.Add("# Ship_Layout_Restorer presets. One line per furniture:"); list.Add("# Name = x, y, z | rotX, rotY, rotZ (default = original spot, empty = skip)"); list.Add("# Preset 0 is what -s saves and -r restores. -s7 to -s9 save your own slots. [Backup] sections are old saves."); list.Add(""); for (int i = 0; i < 10; i++) { list.Add("[Preset " + i + " - " + s.Names[i] + "]"); string[] furniture = Furniture; foreach (string text in furniture) { if (!s.Data[i].TryGetValue(text, out var value)) { value = ""; } list.Add(text + " = " + value); } list.Add(""); } foreach (KeyValuePair<string, Dictionary<string, string>> backup in s.Backups) { if (!backup.Value.Any((KeyValuePair<string, string> x) => !string.IsNullOrWhiteSpace(x.Value))) { continue; } list.Add("[Backup " + backup.Key + "]"); foreach (KeyValuePair<string, string> item in backup.Value) { if (!string.IsNullOrWhiteSpace(item.Value)) { list.Add(item.Key + " = " + item.Value); } } list.Add(""); } File.WriteAllLines(PresetPath, list.ToArray()); } internal static string SaveId() { try { object obj = FurnitureCommand.Static(typeof(GameNetworkManager), "Instance"); FieldInfo field = obj.GetType().GetField("currentSaveFileName"); string text = ((!(field != null)) ? null : (field.GetValue(obj) as string)); return (!string.IsNullOrEmpty(text)) ? text : "save"; } catch (Exception) { return "save"; } } private static HashSet<string> StateLoad() { try { if (File.Exists(StatePath)) { return new HashSet<string>(from x in File.ReadAllLines(StatePath) where x.Trim().Length > 0 select x); } } catch (Exception) { } return new HashSet<string>(); } internal static bool StateHas(string item) { return StateLoad().Contains(SaveId() + "|" + item); } internal static void StateSet(string item, bool on) { try { HashSet<string> hashSet = StateLoad(); string item2 = SaveId() + "|" + item; if (on) { hashSet.Add(item2); } else { hashSet.Remove(item2); } File.WriteAllLines(StatePath, hashSet.ToArray()); } catch (Exception) { } } private void Update() { int tickCount = Environment.TickCount; if (tickCount - lastTick < 700) { return; } lastTick = tickCount; try { Tick(tickCount); } catch (Exception) { } } private void Tick(int now) { StartOfRound instance = StartOfRound.Instance; if (instance == null || instance.unlockablesList == null) { known = null; lastSor = null; } else { if (NetworkManager.Singleton == null || !NetworkManager.Singleton.IsHost) { return; } List<UnlockableItem> unlockables = instance.unlockablesList.unlockables; if (known == null || instance != lastSor) { lastSor = instance; known = new HashSet<string>(); baselined = false; baseAt = now + 8000; pending.Clear(); FurnitureCommand.CozyHidden = false; return; } if (!baselined) { if (now - baseAt < 0) { return; } foreach (UnlockableItem item in unlockables) { if (FurnitureCommand.Owned(item)) { known.Add(item.unlockableName); } } baselined = true; if (StoreExtras.Value) { FurnitureCommand.RestoreExtras(); } return; } if (StoreExtras.Value) { FurnitureCommand.ForceStorable(); } foreach (UnlockableItem item2 in unlockables) { string unlockableName = item2.unlockableName; if (FurnitureCommand.Owned(item2)) { if (known.Add(unlockableName) && AutoPlace.Value) { pending[unlockableName] = now + 20000; } } else { known.Remove(unlockableName); } } if (pending.Count > 0 && FurnitureCommand.StateOk()) { Store store = Load(); Dictionary<string, PlaceableShipObject> objs = FurnitureCommand.Objs(); Dictionary<string, int> ids = FurnitureCommand.Ids(); foreach (string item3 in pending.Keys.ToList()) { if (!store.Data[0].TryGetValue(item3, out var value) || string.IsNullOrWhiteSpace(value)) { pending.Remove(item3); continue; } try { switch (FurnitureCommand.ApplyOne(item3, value, ref objs, ids)) { case 1: Chat.Print("Placed " + item3 + ".", (Color?)null); pending.Remove(item3); goto end_IL_0252; default: if (now - pending[item3] > 0) { break; } goto end_IL_0252; case 0: break; } pending.Remove(item3); end_IL_0252:; } catch (Exception) { pending.Remove(item3); } } } if (StoreExtras.Value && FurnitureCommand.CozyHidden && now - cozyTick > 3000) { cozyTick = now; FurnitureCommand.KeepCozyHidden(); } } } private void Awake() { PluginDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); KeepOnClear = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Keep_On_Clear", "Signal translator", "Kept by -c and -h. Separate with commas"); PresetsFile = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Presets_File", "Crispy_Depression.Ship_Layout_Restorer.Presets.txt", "Preset list file, next to the dll"); StoreExtras = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Store_Mat_And_Lights", true, "Lets -c and -h store Welcome mat and Cozy lights (experimental)"); AutoPlace = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Auto_Place_Buys", false, "Place new purchases at their preset 0 spot"); try { if (!File.Exists(PresetPath)) { Write(Defaults()); } else { Store store = Load(); if (store.Upgrade) { Write(store); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Presets file: " + ex.Message)); } new FurnitureCommand(); } } public class FurnitureCommand : Command { internal static Dictionary<string, string> UndoSnap; internal static bool CozyHidden; internal static List<string> LastMissing; internal static readonly object[][] TrapSpec = new object[8][] { new object[7] { "Dog house", 0f, 1.4261162f, 0f, 0f, 90f, 0f }, new object[7] { "Classic painting", -1.5603738f, 1.9753027f, 0.087163f, 270f, 270f, 0f }, new object[7] { "Shower", 0.158236f, 2.011269f, 0.0078364f, 270f, 270f, 0f }, new object[7] { "Toilet", -0.3350753f, 3.9199402f, 0.0079918f, 270f, 90.00001f, 0f }, new object[7] { "JackOLantern", 0.2723749f, 4.343201f, 0.0077067f, 270f, 1.45E-05f, 0f }, new object[7] { "Plushie pajama man", 0.2723749f, 4.343201f, 0.0077067f, 270f, 1.45E-05f, 0f }, new object[7] { "Goldfish", 0.2723749f, 4.343201f, 0.0077067f, 270f, 1.45E-05f, 0f }, new object[7] { "Disco Ball", 0.2723749f, 4.343201f, 0.0077067f, 270f, 1.45E-05f, 0f } }; public override string Name => "Furniture"; public override string Description => "Save and restore ship layouts"; public override string Command => "furniture"; public override string[] Aliases => new string[2] { "f", "furn" }; public override string[] Syntax => new string[11] { "-r", "-s", "-l", "-c", "-h", "-u", "-p", "-d#", "-m", "-n#", "-0 ... -9" }; internal static StartOfRound SOR => StartOfRound.Instance; internal static object Build => Static(typeof(ShipBuildModeManager), "Instance"); internal static bool IsHost() { return NetworkManager.Singleton != null && NetworkManager.Singleton.IsHost; } public override void Invoke(string args) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0321: Unknown result type (might be due to invalid IL or missing references) args = (args ?? "").Trim(); if (SOR == null) { throw new CommandException("Not ready."); } bool flag = args.Length > 2 && args.StartsWith("-t", StringComparison.OrdinalIgnoreCase) && (char.IsDigit(args[2]) || args[2] == ':'); if (flag && !IsHost()) { throw new CommandException("Unknown option."); } if (!IsHost()) { throw new CommandException("Host only."); } if (!SOR.inShipPhase && (!SOR.shipHasLanded || SOR.shipIsLeaving)) { throw new CommandException("Only in orbit or landed."); } if (flag) { Trap(args.Substring(2)); return; } string text = args.ToLowerInvariant(); bool flag2 = text.Length == 3 && text[0] == '-' && char.IsDigit(text[2]); switch (text) { case "-r": case "-": Restore(0); return; case "-s": Save(0); return; case "-l": Luck(); return; case "-c": Clear(); return; case "-h": Quota(); return; case "-u": Undo(); return; case "-p": ListPresets(); return; case "-m": Missing(-1); return; case "-dump": Dump(); return; } if (flag2 && text[1] == 's') { Save(text[2] - 48); return; } if (flag2 && text[1] == 'm') { Missing(text[2] - 48); return; } if (flag2 && text[1] == 'd') { Preview(text[2] - 48); return; } if (text.Length >= 3 && text.StartsWith("-n") && char.IsDigit(text[2])) { Rename(text[2] - 48, args.Substring(3)); return; } if (text.Length == 2 && text[0] == '-' && char.IsDigit(text[1])) { Restore(text[1] - 48); return; } throw new CommandException("Use -r -s -l -c -h -u -p -d# -m -n# or -0 to -9"); } internal static UnlockableItem U(PlaceableShipObject p) { return SOR.unlockablesList.unlockables[p.unlockableID]; } internal static bool Owned(UnlockableItem u) { return u.alreadyUnlocked || u.hasBeenUnlockedByPlayer; } internal static object Static(Type t, string name) { PropertyInfo property = t.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(null, null); } FieldInfo field = t.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); return (!(field != null)) ? null : field.GetValue(null); } internal static int Me() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown try { object obj = Static(typeof(GameNetworkManager), "Instance"); FieldInfo field = obj.GetType().GetField("localPlayerController"); PlayerControllerB val = (PlayerControllerB)field.GetValue(obj); return (int)val.playerClientId; } catch (Exception) { return 0; } } internal static Dictionary<string, PlaceableShipObject> Objs() { Dictionary<string, PlaceableShipObject> dictionary = new Dictionary<string, PlaceableShipObject>(StringComparer.OrdinalIgnoreCase); PlaceableShipObject[] array = Object.FindObjectsOfType<PlaceableShipObject>(true); foreach (PlaceableShipObject val in array) { if (val.unlockableID >= 0 && val.unlockableID < SOR.unlockablesList.unlockables.Count) { string unlockableName = U(val).unlockableName; if (!dictionary.TryGetValue(unlockableName, out var value) || (!((Component)value).gameObject.activeInHierarchy && ((Component)val).gameObject.activeInHierarchy)) { dictionary[unlockableName] = val; } } } return dictionary; } internal static Dictionary<string, int> Ids() { Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); List<UnlockableItem> unlockables = SOR.unlockablesList.unlockables; for (int i = 0; i < unlockables.Count; i++) { if (!dictionary.ContainsKey(unlockables[i].unlockableName)) { dictionary[unlockables[i].unlockableName] = i; } } return dictionary; } internal static bool Call(object target, string name, params object[] args) { if (target == null) { return false; } MethodInfo[] methods = target.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != name) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length < args.Length) { continue; } object[] array = new object[parameters.Length]; bool flag = true; for (int j = 0; j < parameters.Length; j++) { if (!flag) { break; } if (j < args.Length) { if (args[j] != null && !parameters[j].ParameterType.IsAssignableFrom(args[j].GetType())) { flag = false; } array[j] = args[j]; } else if (parameters[j].IsOptional) { array[j] = parameters[j].DefaultValue; } else { flag = false; } } if (flag) { methodInfo.Invoke(target, array); return true; } } return false; } internal static string Fmt(Vector3 p, Vector3 r) { Func<float, string> func = (float v) => Math.Round(v, 4).ToString("0.####", CultureInfo.InvariantCulture); return func(p.x) + ", " + func(p.y) + ", " + func(p.z) + " | " + func(r.x) + ", " + func(r.y) + ", " + func(r.z); } internal static bool V3(string s, out Vector3 v) { ((Vector3)(ref v))..ctor(0f, 0f, 0f); string[] array = s.Split(','); if (array.Length != 3) { return false; } if (!float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return false; } if (!float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { return false; } if (!float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { return false; } ((Vector3)(ref v))..ctor(result, result2, result3); return true; } internal static bool Parse(string s, out Vector3 p, out Vector3 r) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) ((Vector3)(ref p))..ctor(0f, 0f, 0f); r = p; string[] array = s.Split('|'); return array.Length == 2 && V3(array[0], out p) && V3(array[1], out r); } internal static void Unstore(int id, PlaceableShipObject po) { Call(SOR, "ReturnUnlockableFromStorageServerRpc", id); SOR.unlockablesList.unlockables[id].inStorage = false; Track(SOR.unlockablesList.unlockables[id].unlockableName, stored: false); if (po != null) { po.parentObject.disableObject = false; } } internal static bool Place(PlaceableShipObject po, Vector3 p, Vector3 r) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0076: Unknown result type (might be due to invalid IL or missing references) po.parentObject.disableObject = false; object build = Build; bool result = Call(build, "PlaceShipObject", p, r, po, false); NetworkObject component = ((Component)po.parentObject).GetComponent<NetworkObject>(); if (component != null) { Call(build, "PlaceShipObjectServerRpc", p, r, (object)new NetworkObjectReference(component), Me()); } return result; } internal static void Fail() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) throw new CommandException("Game update broke this mod."); } internal static Dictionary<string, string> Snap() { //IL_00a1: 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) Dictionary<string, string> dictionary = new Dictionary<string, string>(); Dictionary<string, PlaceableShipObject> dictionary2 = Objs(); Dictionary<string, int> dictionary3 = Ids(); string[] allFurniture = Plugin.AllFurniture; foreach (string key in allFurniture) { if (!dictionary3.TryGetValue(key, out var value)) { continue; } UnlockableItem val = SOR.unlockablesList.unlockables[value]; if (Owned(val)) { if (val.inStorage) { dictionary[key] = "stored"; } else if (dictionary2.ContainsKey(key)) { dictionary[key] = ((!val.hasBeenMoved) ? "default" : Fmt(val.placedPosition, val.placedRotation)); } } } if (Plugin.StoreExtras.Value && dictionary3.TryGetValue("Cozy lights", out var value2) && Owned(SOR.unlockablesList.unlockables[value2]) && (CozyHidden || CozyObjs().Count > 0)) { dictionary["Cozy lights"] = ((!CozyHidden) ? "default" : "stored"); } return dictionary; } internal static void StoreOne(PlaceableShipObject po, UnlockableItem u) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!u.spawnPrefab) { po.parentObject.disableObject = true; } NetworkObject component = ((Component)po.parentObject).GetComponent<NetworkObject>(); if (component != null) { if (!Call(Build, "StoreObjectServerRpc", (object)new NetworkObjectReference(component), Me())) { Fail(); } Track(u.unlockableName, stored: true); } } internal static void Track(string name, bool stored) { if (Plugin.StoreExtras.Value && string.Equals(name, "Welcome mat", StringComparison.OrdinalIgnoreCase)) { Plugin.StateSet("Welcome mat", stored); } } internal static bool StateOk() { return SOR != null && (SOR.inShipPhase || (SOR.shipHasLanded && !SOR.shipIsLeaving)); } internal static int ApplyOne(string name, string v, ref Dictionary<string, PlaceableShipObject> objs, Dictionary<string, int> ids) { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(v)) { return 0; } if (!ids.TryGetValue(name, out var value) || !Owned(SOR.unlockablesList.unlockables[value])) { return -1; } UnlockableItem val = SOR.unlockablesList.unlockables[value]; objs.TryGetValue(name, out var value2); string text = v.Trim().ToLowerInvariant(); if (string.Equals(name, "Cozy lights", StringComparison.OrdinalIgnoreCase)) { return SetCozy(text == "stored") ? 1 : (-1); } if (text == "stored") { if (val.inStorage || !val.canBeStored || value2 == null) { return 0; } StoreOne(value2, val); return 1; } if (val.inStorage) { Unstore(value, value2); if (value2 == null) { objs = Objs(); objs.TryGetValue(name, out value2); } } if (value2 == null) { return -1; } if (text == "default") { if (!Call(Build, "ResetShipObjectToDefaultPosition", value2)) { Fail(); } return 1; } if (!Parse(v, out var p, out var r)) { return 0; } if (!Place(value2, p, r)) { Fail(); } return 1; } internal static void Restore(int n) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) Plugin.Store store = Plugin.Load(); if (!store.Data[n].Values.Any((string x) => !string.IsNullOrWhiteSpace(x))) { throw new CommandException("Preset " + n + " is empty."); } UndoSnap = Snap(); Dictionary<string, PlaceableShipObject> objs = Objs(); Dictionary<string, int> ids = Ids(); List<string> list = new List<string>(); int num = 0; string[] allFurniture = Plugin.AllFurniture; foreach (string text in allFurniture) { if (!store.Data[n].TryGetValue(text, out var value)) { value = ""; } switch (ApplyOne(text, value, ref objs, ids)) { case 1: num++; break; case -1: list.Add(text); break; } } LastMissing = list; string text2 = "Restored " + num + " (" + store.Names[n] + ")."; if (list.Count > 0) { string text3 = text2; text2 = text3 + " Missing " + list.Count + ": " + string.Join(", ", list.Take(5).ToArray()) + ((list.Count <= 5) ? "" : "... -m lists all"); } Chat.Print(text2, (Color?)null); } internal static void Undo() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (UndoSnap == null) { throw new CommandException("Nothing to undo."); } Dictionary<string, string> undoSnap = UndoSnap; UndoSnap = Snap(); Dictionary<string, PlaceableShipObject> objs = Objs(); Dictionary<string, int> ids = Ids(); int num = 0; foreach (KeyValuePair<string, string> item in undoSnap) { if (ApplyOne(item.Key, item.Value, ref objs, ids) == 1) { num++; } } Chat.Print("Undone " + num + ".", (Color?)null); } internal static void ListPresets() { Plugin.Store st = Plugin.Load(); Chat.Print(string.Join(", ", (from i in Enumerable.Range(0, 5) select i + " " + st.Names[i]).ToArray()), (Color?)null); Chat.Print(string.Join(", ", (from i in Enumerable.Range(5, 5) select i + " " + st.Names[i]).ToArray()), (Color?)null); } internal static void Luck() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = typeof(UnlockableItem).GetField("luckValue"); if (field == null) { throw new CommandException("No luck data."); } float num = 0f; foreach (UnlockableItem unlockable in SOR.unlockablesList.unlockables) { if (Owned(unlockable) && !unlockable.inStorage && (!CozyHidden || !(unlockable.unlockableName == "Cozy lights"))) { num += Convert.ToSingle(field.GetValue(unlockable), CultureInfo.InvariantCulture); } } Chat.Print("Luck Value: " + Math.Round(num, 3).ToString("0.###", CultureInfo.InvariantCulture), (Color?)null); } internal static void ForceStorable() { if (Ids().TryGetValue("Welcome mat", out var value)) { UnlockableItem val = SOR.unlockablesList.unlockables[value]; if (Owned(val)) { val.canBeStored = true; } } } internal static List<GameObject> CozyObjs() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val in array) { Scene scene = val.scene; if (((Scene)(ref scene)).IsValid() && ((Object)val).name.IndexOf("cozy", StringComparison.OrdinalIgnoreCase) >= 0 && val.GetComponentsInChildren<Light>(true).Length != 0) { list.Add(val); } } List<GameObject> list2 = new List<GameObject>(); foreach (GameObject item in list) { bool flag = false; Transform parent = item.transform.parent; while (parent != null && !flag) { foreach (GameObject item2 in list) { if (item2.transform == parent) { flag = true; } } parent = parent.parent; } if (!flag) { list2.Add(item); } } return list2; } internal static bool SetCozy(bool hidden) { List<GameObject> list = CozyObjs(); if (list.Count == 0) { return false; } foreach (GameObject item in list) { item.SetActive(!hidden); } CozyHidden = hidden; Plugin.StateSet("Cozy lights", hidden); return true; } internal static void KeepCozyHidden() { foreach (GameObject item in CozyObjs()) { if (item.activeSelf) { item.SetActive(false); } } } internal static void RestoreExtras() { Dictionary<string, int> dictionary = Ids(); string[] array = new string[2] { "Welcome mat", "Cozy lights" }; foreach (string text in array) { if (!Plugin.StateHas(text)) { continue; } if (!dictionary.TryGetValue(text, out var value) || !Owned(SOR.unlockablesList.unlockables[value])) { Plugin.StateSet(text, on: false); continue; } if (text == "Cozy lights") { CozyHidden = true; continue; } UnlockableItem val = SOR.unlockablesList.unlockables[value]; val.canBeStored = true; if (!val.inStorage && Objs().TryGetValue(text, out var value2)) { StoreOne(value2, val); } } } internal static void PrintNames(string title, List<string> names) { Chat.Print(title, (Color?)null); for (int i = 0; i < names.Count; i += 6) { Chat.Print(string.Join(", ", names.Skip(i).Take(6).ToArray()), (Color?)null); } } internal static void Analyze(int n, out List<string> move, out List<string> missing, out bool empty) { Plugin.Store store = Plugin.Load(); Dictionary<string, int> dictionary = Ids(); move = new List<string>(); missing = new List<string>(); empty = true; string[] allFurniture = Plugin.AllFurniture; foreach (string text in allFurniture) { if (store.Data[n].TryGetValue(text, out var value) && !string.IsNullOrWhiteSpace(value)) { empty = false; if (!dictionary.TryGetValue(text, out var value2) || !Owned(SOR.unlockablesList.unlockables[value2])) { missing.Add(text); } else { move.Add(text); } } } } internal static void Preview(int n) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) Analyze(n, out var move, out var missing, out var empty); if (empty) { throw new CommandException("Preset " + n + " is empty."); } LastMissing = missing; Chat.Print("Preset " + n + " (" + Plugin.Load().Names[n] + "): moves " + move.Count + ", missing " + missing.Count + ".", (Color?)null); if (missing.Count > 0) { Chat.Print("-m" + n + " lists the missing ones.", (Color?)null); } } internal static void Missing(int n) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) List<string> missing = LastMissing; if (n >= 0 || missing == null) { Analyze((n >= 0) ? n : 0, out var _, out missing, out var empty); if (empty) { throw new CommandException("Preset " + ((n >= 0) ? n : 0) + " is empty."); } } if (missing.Count == 0) { Chat.Print("Nothing missing.", (Color?)null); } else { PrintNames("Missing " + missing.Count + ":", missing); } } internal static void Rename(int n, string name) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (n != 0 && n < 7) { throw new CommandException("Presets 1-6 are locked."); } name = Regex.Replace(name ?? "", "[\\[\\]=\\r\\n]", "").Trim(); if (name.Length == 0) { throw new CommandException("Use -n7 Name"); } if (name.Length > 24) { name = name.Substring(0, 24); } Plugin.Store store = Plugin.Load(); store.Names[n] = name; try { Plugin.Write(store); } catch (Exception) { throw new CommandException("Can't write presets."); } Chat.Print("Preset " + n + " is now " + name + ".", (Color?)null); } internal static void Save(int n) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) //IL_00b5: 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) if (n != 0 && n < 7) { throw new CommandException("Presets 1-6 are locked."); } Dictionary<string, PlaceableShipObject> dictionary = Objs(); Plugin.Store store = Plugin.Load(); store.Backups[n.ToString()] = new Dictionary<string, string>(store.Data[n], StringComparer.OrdinalIgnoreCase); int num = 0; string[] allFurniture = Plugin.AllFurniture; foreach (string key in allFurniture) { if (dictionary.TryGetValue(key, out var value)) { UnlockableItem val = U(value); if (Owned(val) && !val.inStorage) { store.Data[n][key] = ((!val.hasBeenMoved) ? "default" : Fmt(val.placedPosition, val.placedRotation)); num++; } } } if (num == 0) { throw new CommandException("Nothing placed to save."); } try { Plugin.Write(store); } catch (Exception) { throw new CommandException("Can't write presets."); } Chat.Print("Saved " + num + " to " + n + ".", (Color?)null); } internal static int ClearCore() { HashSet<string> hashSet = new HashSet<string>(from s in Plugin.KeepOnClear.Value.Split(',') select s.Trim() into s where s.Length > 0 select s, StringComparer.OrdinalIgnoreCase); hashSet.Add("Cupboard"); hashSet.Add("Terminal"); hashSet.Add("Light switch"); if (Plugin.StoreExtras.Value) { ForceStorable(); } int num = 0; foreach (KeyValuePair<string, PlaceableShipObject> item in Objs()) { UnlockableItem val = U(item.Value); if (Owned(val) && !val.inStorage && val.canBeStored && !hashSet.Contains(item.Key)) { StoreOne(item.Value, val); num++; } } if (Plugin.StoreExtras.Value && !CozyHidden && !hashSet.Contains("Cozy lights") && Ids().TryGetValue("Cozy lights", out var value) && Owned(SOR.unlockablesList.unlockables[value]) && SetCozy(hidden: true)) { num++; } return num; } internal static void Clear() { UndoSnap = Snap(); Chat.Print("Cleared " + ClearCore() + ".", (Color?)null); } internal static void Quota() { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) Plugin.Store store = Plugin.Load(); if (store.Backups.ContainsKey("Quota") && store.Backups["Quota"].Count > 0) { Dictionary<string, string> dictionary = store.Backups["Quota"]; UndoSnap = Snap(); Dictionary<string, PlaceableShipObject> objs = Objs(); Dictionary<string, int> ids = Ids(); int num = 0; foreach (KeyValuePair<string, string> item in dictionary) { if (ApplyOne(item.Key, item.Value, ref objs, ids) == 1) { num++; } } store.Backups.Remove("Quota"); try { Plugin.Write(store); } catch (Exception) { } Chat.Print("Layout back (" + num + ").", (Color?)null); } else { Dictionary<string, string> dictionary2 = Snap(); if (dictionary2.Count == 0) { throw new CommandException("Nothing to clear."); } UndoSnap = dictionary2; store.Backups["Quota"] = new Dictionary<string, string>(dictionary2, StringComparer.OrdinalIgnoreCase); try { Plugin.Write(store); } catch (Exception) { throw new CommandException("Can't write presets."); } Chat.Print("Cleared " + ClearCore() + ". -h again brings it back.", (Color?)null); } } private static string F(float v) { return Math.Round(v, 2).ToString("0.##", CultureInfo.InvariantCulture); } private static bool BoundsOf(GameObject g, Type t, out Vector3 min, out Vector3 max) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_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_011d: 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_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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00ba: Unknown result type (might be due to invalid IL or missing references) ((Vector3)(ref min))..ctor(0f, 0f, 0f); max = min; if (g == null || t == null) { return false; } bool flag = false; Component[] componentsInChildren = g.GetComponentsInChildren(t, true); foreach (Component val in componentsInChildren) { PropertyInfo property = ((object)val).GetType().GetProperty("bounds"); if (property == null) { continue; } Bounds val2 = (Bounds)property.GetValue(val, null); if (!(((Bounds)(ref val2)).size.x <= 0f) || !(((Bounds)(ref val2)).size.y <= 0f) || !(((Bounds)(ref val2)).size.z <= 0f)) { if (!flag) { min = ((Bounds)(ref val2)).min; max = ((Bounds)(ref val2)).max; flag = true; } else { ((Vector3)(ref min))..ctor(Math.Min(min.x, ((Bounds)(ref val2)).min.x), Math.Min(min.y, ((Bounds)(ref val2)).min.y), Math.Min(min.z, ((Bounds)(ref val2)).min.z)); ((Vector3)(ref max))..ctor(Math.Max(max.x, ((Bounds)(ref val2)).max.x), Math.Max(max.y, ((Bounds)(ref val2)).max.y), Math.Max(max.z, ((Bounds)(ref val2)).max.z)); } } } return flag; } private static string Box(Vector3 mn, Vector3 mx, float[] d) { return "x " + F(mn.x - d[0]) + ".." + F(mx.x - d[0]) + " y " + F(mn.y - d[1]) + ".." + F(mx.y - d[1]) + " z " + F(mn.z - d[2]) + ".." + F(mx.z - d[2]) + " (size " + F(mx.x - mn.x) + " x " + F(mx.y - mn.y) + " x " + F(mx.z - mn.z) + ")"; } private static string Describe(GameObject g, float[] d) { //IL_0025: 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_0056: 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) List<string> list = new List<string>(); if (BoundsOf(g, Type.GetType("UnityEngine.Renderer, UnityEngine.CoreModule"), out var min, out var max)) { list.Add("mesh " + Box(min, max, d)); } if (BoundsOf(g, Type.GetType("UnityEngine.Collider, UnityEngine.PhysicsModule"), out min, out max)) { list.Add("collider " + Box(min, max, d)); } return (list.Count != 0) ? string.Join(" | ", list.ToArray()) : "no bounds"; } internal static void Dump() { //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); float[] array = Delta(); stringBuilder.AppendLine("Ship_Layout_Restorer measurements " + DateTime.Now.ToString("yyyy-MM-dd HH:mm")); stringBuilder.AppendLine("All coordinates are placement space (same as the presets). world = placement + (" + F(array[0]) + ", " + F(array[1]) + ", " + F(array[2]) + ")"); stringBuilder.AppendLine("ship landed: " + SOR.shipHasLanded + " in orbit: " + SOR.inShipPhase); stringBuilder.AppendLine(); stringBuilder.AppendLine("== Players =="); foreach (PlayerControllerB item in SOR.allPlayerScripts.Where((PlayerControllerB x) => x.isPlayerControlled || x.isPlayerDead)) { Vector3 position = ((Component)item).transform.position; stringBuilder.AppendLine("player " + item.playerClientId + " inShip=" + item.isInHangarShipRoom + " at " + F(position.x - array[0]) + ", " + F(position.y - array[1]) + ", " + F(position.z - array[2])); } stringBuilder.AppendLine(); stringBuilder.AppendLine("== Furniture =="); Dictionary<string, PlaceableShipObject> dictionary = Objs(); string[] allFurniture = Plugin.AllFurniture; foreach (string text in allFurniture) { if (!dictionary.TryGetValue(text, out var value)) { stringBuilder.AppendLine(text + ": not found"); continue; } UnlockableItem val = U(value); stringBuilder.AppendLine(text + ": owned=" + Owned(val) + " stored=" + val.inStorage + " moved=" + val.hasBeenMoved + " canBeStored=" + val.canBeStored); stringBuilder.AppendLine(" placed " + Fmt(val.placedPosition, val.placedRotation)); stringBuilder.AppendLine(" " + Describe(((Component)value.parentObject).gameObject, array)); } stringBuilder.AppendLine(); stringBuilder.AppendLine("== Ship =="); GameObject val2 = null; List<GameObject> list = new List<GameObject>(); GameObject[] array2 = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val3 in array2) { Scene scene = val3.scene; if (((Scene)(ref scene)).IsValid()) { if (((Object)val3).name == "HangarShip") { val2 = val3; } string text2 = ((Object)val3).name.ToLowerInvariant(); if (val3.activeInHierarchy && list.Count < 80 && (text2.Contains("lever") || text2.Contains("door") || text2.Contains("ramp") || text2.Contains("railing") || text2.Contains("catwalk") || text2.Contains("platform") || text2.Contains("monitor") || text2.Contains("window") || text2.Contains("cruiser") || text2.Contains("placementblocker") || text2.Contains("shipinside"))) { list.Add(val3); } } } if (val2 != null) { stringBuilder.AppendLine("HangarShip: " + Describe(val2, array)); for (int num3 = 0; num3 < val2.transform.childCount; num3++) { Transform child = val2.transform.GetChild(num3); stringBuilder.AppendLine(" " + ((Object)child).name + " (active=" + ((Component)child).gameObject.activeSelf + "): " + Describe(((Component)child).gameObject, array)); } } else { stringBuilder.AppendLine("HangarShip not found"); } stringBuilder.AppendLine(); stringBuilder.AppendLine("== Landmarks =="); foreach (GameObject item2 in list) { stringBuilder.AppendLine(((Object)item2).name + ((item2.transform.parent == null) ? "" : (" [in " + ((Object)item2.transform.parent).name + "]")) + ": " + Describe(item2, array)); } string path = Path.Combine(Plugin.PluginDir, "Ship_Layout_Restorer_Measurements.txt"); try { File.WriteAllText(path, stringBuilder.ToString()); } catch (Exception) { throw new CommandException("Can't write file."); } Chat.Print("Saved measurements file.", (Color?)null); } internal static Transform Anchor(PlaceableShipObject po) { FieldInfo field = typeof(PlaceableShipObject).GetField("mainMesh"); object obj = ((!(field != null)) ? null : field.GetValue(po)); Component val = (Component)((obj is Component) ? obj : null); if (val != null) { return val.transform; } GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); if (val2 != null) { return val2.transform; } return ((Component)po.parentObject).transform; } internal static float Median(List<float> l) { l.Sort(); return l[l.Count / 2]; } internal static float[] Delta() { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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) List<float> list = new List<float>(); List<float> list2 = new List<float>(); List<float> list3 = new List<float>(); foreach (KeyValuePair<string, PlaceableShipObject> item in Objs()) { UnlockableItem val = U(item.Value); if (Owned(val) && !val.inStorage && val.hasBeenMoved) { Vector3 position = Anchor(item.Value).position; list.Add(position.x - val.placedPosition.x); list2.Add(position.y - val.placedPosition.y); list3.Add(position.z - val.placedPosition.z); } } if (list.Count == 0) { Vector3 position2 = SOR.elevatorTransform.position; return new float[3] { position2.x, position2.y, position2.z }; } return new float[3] { Median(list), Median(list2), Median(list3) }; } internal static void Trap(string a) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) a = a.TrimStart(':').Trim(); if (!int.TryParse(a, out var result) || result < 1) { throw new CommandException("Bad number."); } List<PlayerControllerB> list = SOR.allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled || p.isPlayerDead).ToList(); if (result > list.Count) { throw new CommandException("No player."); } PlayerControllerB val = list[result - 1]; if (!val.isInHangarShipRoom) { throw new CommandException("Not in ship."); } Vector3 position = ((Component)val).transform.position; float[] array = Delta(); float num = position.x - array[0]; float num2 = position.z - array[2]; UndoSnap = Snap(); Dictionary<string, PlaceableShipObject> dictionary = Objs(); Dictionary<string, int> dictionary2 = Ids(); bool flag = false; object[][] trapSpec = TrapSpec; foreach (object[] array2 in trapSpec) { if (dictionary2.TryGetValue((string)array2[0], out var value) && Owned(SOR.unlockablesList.unlockables[value]) && SOR.unlockablesList.unlockables[value].inStorage) { dictionary.TryGetValue((string)array2[0], out var value2); Unstore(value, value2); flag = true; } } if (flag) { dictionary = Objs(); } int num4 = 0; object[][] trapSpec2 = TrapSpec; foreach (object[] array3 in trapSpec2) { string key = (string)array3[0]; if (dictionary2.TryGetValue(key, out var value3) && Owned(SOR.unlockablesList.unlockables[value3]) && dictionary.TryGetValue(key, out var value4)) { Place(value4, new Vector3(num + (float)array3[1], (float)array3[2], num2 + (float)array3[3]), new Vector3((float)array3[4], (float)array3[5], (float)array3[6])); num4++; } } if (num4 == 0) { throw new CommandException("No furniture."); } Chat.Print("Done.", (Color?)null); } }