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 ShipSort v4.0.1
baer1.ShipSort.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ChatCommandAPI; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("baer1.ShipSort")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("4.0.1.0")] [assembly: AssemblyInformationalVersion("4.0.1+62ebc2c16dca921132be2d4d1064ebd118a663a2")] [assembly: AssemblyProduct("LethalShipSort")] [assembly: AssemblyTitle("baer1.ShipSort")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 LethalShipSort { public class AutoSortToggle : ToggleCommand { public override string Name => "AutoSort"; public override string ToggleDescription => "Toggles automatic item sorting when leaving a planet"; public override bool Value { get { return LethalShipSort.Instance.AutoSort; } set { LethalShipSort.Instance.AutoSort = value; } } } public struct ItemPosition { public struct Flags { public const char NO_AUTO_SORT = 'A'; public bool NoAutoSort; public const char KEEP_ON_CRUISER = 'C'; public bool KeepOnCruiser; public const char IGNORE = 'N'; public bool Ignore; public const char PARENT = 'P'; public bool Parent; public const char EXACT = 'X'; public bool Exact; public Flags(string s) { NoAutoSort = false; KeepOnCruiser = false; Ignore = false; Parent = false; Exact = false; foreach (char c in s) { switch (c) { case 'A': NoAutoSort = true; break; case 'C': KeepOnCruiser = true; break; case 'N': Ignore = true; break; case 'P': Parent = true; break; case 'X': Exact = true; break; default: throw new ArgumentException($"Unknown flag ({c})"); } } } public override string ToString() { return $"{(NoAutoSort ? ((object)'A') : string.Empty)}{(KeepOnCruiser ? ((object)'C') : string.Empty)}{(Ignore ? ((object)'N') : string.Empty)}{(Parent ? ((object)'P') : string.Empty)}{(Exact ? ((object)'X') : string.Empty)}"; } public Flags FilterPositionRelated() { return this & new Flags { Parent = true, Exact = true }; } public Flags FilterFilteringRelated() { return this & new Flags { NoAutoSort = true, KeepOnCruiser = true, Ignore = true }; } public static Flags operator |(Flags _this, Flags other) { Flags result = default(Flags); result.NoAutoSort = _this.NoAutoSort || other.NoAutoSort; result.KeepOnCruiser = _this.KeepOnCruiser || other.KeepOnCruiser; result.Ignore = _this.Ignore || other.Ignore; result.Parent = _this.Parent || other.Parent; result.Exact = _this.Exact || other.Exact; return result; } public static Flags operator &(Flags _this, Flags other) { Flags result = default(Flags); result.NoAutoSort = _this.NoAutoSort && other.NoAutoSort; result.KeepOnCruiser = _this.KeepOnCruiser && other.KeepOnCruiser; result.Ignore = _this.Ignore && other.Ignore; result.Parent = _this.Parent && other.Parent; result.Exact = _this.Exact && other.Exact; return result; } } public Vector3? position; public Vector3? positionOffset; public GameObject? parentTo; public int? floorYRot; public int? rotationOffset; public float? randomOffset; public Flags flags; public ItemPosition(string s) { //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) position = null; positionOffset = null; parentTo = null; floorYRot = null; rotationOffset = null; randomOffset = null; Match match = new Regex("(?:([\\w/\\\\]+):)?(?:(-?\\d+(?:\\.\\d+)?)([+-]\\d+(?:\\.\\d+)?)?,)(?:(-?\\d+(?:\\.\\d+)?)([+-]\\d+(?:\\.\\d+)?)?,)(-?\\d+(?:\\.\\d+)?)([+-]\\d+(?:\\.\\d+)?)?(?:,(\\d+)([+-]\\d+)?)?(?:,(\\d+(?:\\.\\d+)?))?(?::([A-Z]+))?$", RegexOptions.Multiline).Match(s); if (!match.Success) { Match match2 = new Regex("([A-Z]+)$", RegexOptions.Multiline).Match(s); if (!match2.Success) { throw new ArgumentException("Invalid format (" + s + ")"); } StringBuilder stringBuilder = new StringBuilder(">> ItemPosition init flags \"" + s + "\""); flags = new Flags(match2.Groups[1].Value); LethalShipSort.Logger.LogDebug((object)stringBuilder.ToString()); return; } StringBuilder stringBuilder2 = new StringBuilder(">> ItemPosition init \"" + s + "\""); string value = match.Groups[2].Value; string value2 = match.Groups[4].Value; string value3 = match.Groups[6].Value; if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { throw new ArgumentException("Invalid x value (" + value + ")"); } if (!float.TryParse(value2, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { throw new ArgumentException("Invalid y value (" + value2 + ")"); } if (!float.TryParse(value3, NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { throw new ArgumentException("Invalid z value (" + value3 + ")"); } position = new Vector3(result, result2, result3); stringBuilder2.Append($"\n position is {position}"); string value4 = match.Groups[3].Value; string value5 = match.Groups[5].Value; string value6 = match.Groups[7].Value; float? num = null; float? num2 = null; float? num3 = null; if (match.Groups[3].Success) { if (!float.TryParse(value4, NumberStyles.Float, CultureInfo.InvariantCulture, out var result4)) { throw new ArgumentException("Invalid xoffset value (" + value4 + ")"); } num = result4; } if (match.Groups[5].Success) { if (!float.TryParse(value5, NumberStyles.Float, CultureInfo.InvariantCulture, out var result5)) { throw new ArgumentException("Invalid yoffset value (" + value2 + ")"); } num2 = result5; } if (match.Groups[7].Success) { if (!float.TryParse(value6, NumberStyles.Float, CultureInfo.InvariantCulture, out var result6)) { throw new ArgumentException("Invalid zoffset value (" + value3 + ")"); } num3 = result6; } if (num.HasValue || num2.HasValue || num3.HasValue) { positionOffset = new Vector3(num.GetValueOrDefault(), num2.GetValueOrDefault(), num3.GetValueOrDefault()); stringBuilder2.Append($"\n fixed positional offset is {positionOffset}"); } else { stringBuilder2.Append("\n fixed positional offset is not specified"); } string value7 = match.Groups[8].Value; if (match.Groups[8].Success) { if (!int.TryParse(value7, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result7)) { throw new ArgumentException("Invalid floorYRot value (" + value7 + ")"); } floorYRot = result7; stringBuilder2.Append($"\n rotation is {floorYRot}"); } else { stringBuilder2.Append("\n rotation not specified"); } string value8 = match.Groups[9].Value; if (match.Groups[9].Success) { if (!int.TryParse(value8, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result8)) { throw new ArgumentException("Invalid roffset value (" + value8 + ")"); } rotationOffset = ((result8 == 0) ? null : new int?(result8)); stringBuilder2.Append($"\n rotational offset is {result8}"); } else { stringBuilder2.Append("\n rotational offset not specified"); } string value9 = match.Groups[10].Value; if (match.Groups[10].Success) { if (!float.TryParse(value9, NumberStyles.Float, CultureInfo.InvariantCulture, out var result9)) { throw new ArgumentException("Invalid randomOffset value (" + value9 + ")"); } randomOffset = result9; stringBuilder2.Append($"\n random positional offset is {randomOffset}"); } else { stringBuilder2.Append("\n random positional offset not specified"); } flags = new Flags(match.Groups[11].Value); stringBuilder2.Append($"\n flags are {flags}"); string value10 = match.Groups[1].Value; if (match.Groups[1].Success) { switch (value10.ToLower().Trim('/', '\\')) { case "cupboard": case "closet": case "storage": case "storagecloset": stringBuilder2.Append("\n parent object is closet"); parentTo = GameObject.Find("Environment/HangarShip/StorageCloset"); if ((Object)(object)parentTo == (Object)null) { throw new Exception("Storage closet not found"); } break; case "file": case "filecabinet": case "filecabinets": stringBuilder2.Append("\n parent object is file cabinet"); parentTo = GameObject.Find("Environment/HangarShip/FileCabinet"); if ((Object)(object)parentTo == (Object)null) { throw new Exception("File cabinet not found"); } break; case "bunkbed": case "bunkbeds": stringBuilder2.Append("\n parent object is bunkbeds"); parentTo = GameObject.Find("Environment/HangarShip/Bunkbeds"); if ((Object)(object)parentTo == (Object)null) { throw new Exception("Bunkbeds not found"); } break; case "ship": stringBuilder2.Append("\n parent object is ship"); parentTo = null; break; case "environment": case "none": stringBuilder2.Append("\n parent object is none (environment)"); parentTo = GameObject.Find("Environment"); if ((Object)(object)parentTo == (Object)null) { throw new Exception("Environment not found"); } break; default: stringBuilder2.Append("\n parent object is custom (" + value10 + ") "); parentTo = GameObject.Find(value10); if ((Object)(object)parentTo == (Object)null) { throw new ArgumentException("Invalid parent object"); } stringBuilder2.Append(((object)parentTo).ToString()); break; } } else { stringBuilder2.Append("\n parent object not specified"); } LethalShipSort.Logger.LogDebug((object)stringBuilder2.ToString()); } public override string ToString() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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) string text = ""; if ((Object)(object)parentTo != (Object)null) { text = ((Object)parentTo).name; Transform parent = parentTo.transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } text += ":"; } string[] obj = new string[6] { text, position.HasValue ? string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", position.Value.x, position.Value.y, position.Value.z) : string.Empty, floorYRot.HasValue ? string.Format(CultureInfo.InvariantCulture, ",{0}", floorYRot) : ((!randomOffset.HasValue) ? ",0" : string.Empty), (!rotationOffset.HasValue) ? string.Empty : string.Format(CultureInfo.InvariantCulture, "{0}{1}", (rotationOffset < 0) ? "-" : "+", Math.Abs(rotationOffset.Value)), ((this.flags.ToString().Length > 0) ? ((object)':') : string.Empty)?.ToString(), null }; Flags flags = this.flags; obj[5] = flags.ToString(); return string.Concat(obj); } } [BepInPlugin("baer1.ShipSort", "LethalShipSort", "4.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LethalShipSort : BaseUnityPlugin { [HarmonyPatch(typeof(NetworkManager), "StartClient")] [HarmonyPatch(typeof(NetworkManager), "StartServer")] [HarmonyPatch(typeof(NetworkManager), "StartHost")] internal class RoundOverrideResetPatch { private static void Postfix() { int count = Instance.roundOverrides.Count; Instance.roundOverrides.Clear(); Logger.LogDebug((object)$"roundOverrides cleared (was {count} items)"); } } [HarmonyPatch(typeof(HUDManager), "Start")] internal class HUDManager_Start { private static void Postfix() { if (Instance.ConfigVersion < Instance.CurrentConfigVersion) { ChatCommandAPI.PrintWarning("[LethalShipSort] Your configuration file is outdated.\nPlease verify your configuration file and update it accordingly.\n" + $"<indent=10px>Expected: v{Instance.CurrentConfigVersion}\n" + $"Config: v{Instance.ConfigVersion}</indent>"); Logger.LogWarning((object)$"Config file outdated: Expected v{Instance.CurrentConfigVersion}, got v{Instance.ConfigVersion}"); } else if (Instance.ConfigVersion > Instance.CurrentConfigVersion) { ChatCommandAPI.PrintWarning("[LethalShipSort] Your configuration file is using a newer, unsupported format.\nThere have been changes to the configuration file format which could cause errors.\nPlease verify your configuration file and mod version.\n" + $"<indent=10px>Expected: v{Instance.CurrentConfigVersion}\n" + $"Config: v{Instance.ConfigVersion}</indent>"); Logger.LogWarning((object)$"Config file unsupported: Expected v{Instance.CurrentConfigVersion}, got v{Instance.ConfigVersion}"); } } } private ConfigEntry<int> configVersion = null; private ConfigEntry<bool> autoSort = null; private ConfigEntry<uint> sortDelay = null; private ConfigEntry<string> defaultOneHand = null; private ConfigEntry<string> defaultTwoHand = null; private ConfigEntry<string> defaultTool = null; private ConfigEntry<string> customItemPositions = null; internal Dictionary<string, ConfigEntry<string>> itemPositions = new Dictionary<string, ConfigEntry<string>>(); internal Dictionary<string, ConfigEntry<string>> modItemPositions = new Dictionary<string, ConfigEntry<string>>(); internal Dictionary<string, string> vanillaItems = new Dictionary<string, string>(); internal Dictionary<string, string> modItems = new Dictionary<string, string>(); internal Dictionary<string, (Vector3, GameObject?)> roundOverrides = new Dictionary<string, (Vector3, GameObject)>(); public const float CUPBOARD_ABOVE = 3.2f; public const float CUPBOARD_TOP = 2.4f; public const float CUPBOARD_MIDDLE_1 = 2f; public const float CUPBOARD_MIDDLE_2 = 1.5f; public const float CUPBOARD_BOTTOM = 0.5f; public static LethalShipSort Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } public int ConfigVersion => configVersion.Value; public int CurrentConfigVersion => (int)((ConfigEntryBase)configVersion).DefaultValue; public bool AutoSort { get { return autoSort.Value; } set { autoSort.Value = value; } } public uint SortDelay { get { return sortDelay.Value; } set { sortDelay.Value = value; } } [Obsolete("Direct modifications of the modItemPositions list is not recommended, use the ItemPositionConfig functions instead")] public Dictionary<string, ConfigEntry<string>> modItemPositionsList => modItemPositions; public ItemPosition DefaultOneHand { get { try { return new ItemPosition(defaultOneHand.Value); } catch (ArgumentException) { Logger.LogError((object)("Invalid DefaultOneHand position (" + defaultOneHand.Value + "), using fallback")); return new ItemPosition((string)((ConfigEntryBase)defaultOneHand).DefaultValue); } } set { defaultOneHand.Value = value.ToString(); } } public ItemPosition DefaultTwoHand { get { try { return new ItemPosition(defaultTwoHand.Value); } catch (ArgumentException) { Logger.LogError((object)("Invalid DefaultTwoHand position (" + defaultTwoHand.Value + "), using fallback")); return new ItemPosition((string)((ConfigEntryBase)defaultTwoHand).DefaultValue); } } set { defaultTwoHand.Value = value.ToString(); } } public ItemPosition DefaultTool { get { try { return new ItemPosition(defaultTool.Value); } catch (ArgumentException) { Logger.LogError((object)("Invalid DefaultTool position (" + defaultTool.Value + "), using fallback")); return new ItemPosition((string)((ConfigEntryBase)defaultTool).DefaultValue); } } set { defaultTool.Value = value.ToString(); } } public Dictionary<string, ItemPosition> CustomItemPositions { get { Dictionary<string, ItemPosition> dictionary = new Dictionary<string, ItemPosition>(); string[] array = customItemPositions.Value.Split(';'); foreach (string text in array) { string[] array2 = text.Split(":", 2); if (array2.Length != 2) { Logger.LogDebug((object)"split.Length != 2"); goto IL_00c2; } if (dictionary.ContainsKey(array2[0])) { Logger.LogWarning((object)("Multiple CustomItemPositions for item " + array2[0])); } try { dictionary[array2[0]] = new ItemPosition(array2[1]); } catch (ArgumentException arg) { Logger.LogDebug((object)$"{array2[0]} {array2[1]} {arg}"); goto IL_00c2; } continue; IL_00c2: Logger.LogError((object)("Invalid custom item position (" + text + ")")); } return dictionary; } } public Dictionary<string, ItemPosition?> VanillaItemPositions { get { Dictionary<string, ItemPosition?> dictionary = new Dictionary<string, ItemPosition?>(); foreach (KeyValuePair<string, ConfigEntry<string>> itemPosition in itemPositions) { try { dictionary[itemPosition.Key] = (string.IsNullOrWhiteSpace(itemPosition.Value.Value) ? null : new ItemPosition?(new ItemPosition(itemPosition.Value.Value))); } catch (ArgumentException) { Logger.LogError((object)("Invalid item position for " + itemPosition.Key + " (" + itemPosition.Value.Value + "), using fallback")); dictionary[itemPosition.Key] = (string.IsNullOrWhiteSpace((string)((ConfigEntryBase)itemPosition.Value).DefaultValue) ? null : new ItemPosition?(new ItemPosition((string)((ConfigEntryBase)itemPosition.Value).DefaultValue))); } } return dictionary; } } public Dictionary<string, ItemPosition?> ModItemPositions { get { Dictionary<string, ItemPosition?> dictionary = new Dictionary<string, ItemPosition?>(); foreach (KeyValuePair<string, ConfigEntry<string>> modItemPosition in modItemPositions) { try { dictionary[modItemPosition.Key] = (string.IsNullOrWhiteSpace(modItemPosition.Value.Value) ? null : new ItemPosition?(new ItemPosition(modItemPosition.Value.Value))); } catch (ArgumentException) { Logger.LogError((object)("Invalid mod item position for " + modItemPosition.Key + " (" + modItemPosition.Value.Value + "), using fallback")); dictionary[modItemPosition.Key] = (string.IsNullOrWhiteSpace((string)((ConfigEntryBase)modItemPosition.Value).DefaultValue) ? null : new ItemPosition?(new ItemPosition((string)((ConfigEntryBase)modItemPosition.Value).DefaultValue))); } } return dictionary; } } public ItemPosition GetPosition(GrabbableObject item) { //IL_00a1: 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) string text = Utils.ItemKey(item); ItemPosition? itemPosition = null; Logger.LogDebug((object)string.Format(">> {0}({1}) {2}:{3} {4}:{5} {6}:{7}", "GetPosition", item, "itemName", text, "isScrap", item.itemProperties.isScrap, "twoHanded", item.itemProperties.twoHanded)); ConfigEntry<string> value2; ItemPosition value3; if (roundOverrides.TryGetValue(text.ToLower(), out (Vector3, GameObject) value)) { itemPosition = new ItemPosition { position = value.Item1, parentTo = value.Item2 }; Logger.LogDebug((object)string.Format("<< {0} ({1}) {2} ({3}, {4})", "GetPosition", "roundOverrides", itemPosition, value.Item1, value.Item2)); } else if (itemPositions.TryGetValue(text, out value2)) { try { if (!Utility.IsNullOrWhiteSpace(value2.Value)) { itemPosition = new ItemPosition(value2.Value); Logger.LogDebug((object)string.Format("<< {0} ({1}) {2} ({3})", "GetPosition", "itemPositions", itemPosition, value2.Value)); } } catch (ArgumentException) { Logger.LogError((object)("Invalid item position for " + text + " (" + value2.Value + "), using fallback")); if (!Utility.IsNullOrWhiteSpace((string)((ConfigEntryBase)value2).DefaultValue)) { itemPosition = new ItemPosition((string)((ConfigEntryBase)value2).DefaultValue); Logger.LogDebug((object)string.Format("<< {0} ({1} - {2}) {3} ({4})", "GetPosition", "itemPositions", "DefaultValue", itemPosition, ((ConfigEntryBase)value2).DefaultValue)); } } } else if (modItemPositions.TryGetValue(text, out value2)) { try { if (!Utility.IsNullOrWhiteSpace(value2.Value)) { itemPosition = new ItemPosition(value2.Value); Logger.LogDebug((object)string.Format("<< {0} ({1}) {2} ({3})", "GetPosition", "modItemPositions", itemPosition, value2.Value)); } } catch (ArgumentException) { Logger.LogError((object)("Invalid mod item position for " + text + " (" + value2.Value + "), using fallback")); try { if (!Utility.IsNullOrWhiteSpace((string)((ConfigEntryBase)value2).DefaultValue)) { itemPosition = new ItemPosition((string)((ConfigEntryBase)value2).DefaultValue); Logger.LogDebug((object)string.Format("<< {0} ({1} - {2}) {3} ({4})", "GetPosition", "modItemPositions", "DefaultValue", itemPosition, ((ConfigEntryBase)value2).DefaultValue)); } } catch (ArgumentException ex2) { Logger.LogError((object)("Invalid default mod item position for " + text + " (" + value2.Value + "). The mod developer seems to have screwed something up")); Logger.LogError((object)ex2); } } } else if (CustomItemPositions.TryGetValue(text, out value3)) { itemPosition = value3; Logger.LogDebug((object)string.Format("<< {0} ({1}) {2}", "GetPosition", "CustomItemPositions", itemPosition)); } if (!itemPosition.HasValue) { itemPosition = ((!item.itemProperties.isScrap) ? DefaultTool : (item.itemProperties.twoHanded ? DefaultTwoHand : DefaultOneHand)); Logger.LogDebug((object)string.Format("<< {0} ({1}) {2}", "GetPosition", (!item.itemProperties.isScrap) ? "DefaultTool" : (item.itemProperties.twoHanded ? "DefaultTwoHand" : "DefaultOneHand"), itemPosition)); } else if (!itemPosition.Value.position.HasValue) { ItemPosition itemPosition2 = ((!item.itemProperties.isScrap) ? DefaultTool : (item.itemProperties.twoHanded ? DefaultTwoHand : DefaultOneHand)); itemPosition = new ItemPosition { flags = (itemPosition.Value.flags.FilterFilteringRelated() | itemPosition2.flags.FilterPositionRelated()), position = itemPosition2.position, parentTo = itemPosition2.parentTo }; Logger.LogDebug((object)string.Format("<< {0} ({1} with flags) {2}", "GetPosition", (!item.itemProperties.isScrap) ? "DefaultTool" : (item.itemProperties.twoHanded ? "DefaultTwoHand" : "DefaultOneHand"), itemPosition)); } return itemPosition.Value; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; configVersion = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ConfigVersion", 6, "The version of this config file"); autoSort = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoSort", false, "Whether to automatically sort the ship when leaving a planet (toggle ingame with /autosort)"); sortDelay = ((BaseUnityPlugin)this).Config.Bind<uint>("General", "SortDelay", 0u, "The amount of milliseconds to wait between moving items, mostly for the satisfying visual effect.\nYou can't pick anything up while sorting items."); BindItemPositionConfigs(); Patch(); new SortItemsCommand(); new AutoSortToggle(); new SetItemPositionCommand(); new PrintItemNames(); Logger.LogInfo((object)"baer1.ShipSort v4.0.1 has loaded!"); static void Patch() { //IL_000d: 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_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("baer1.ShipSort"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } } private void BindItemPositionConfigs() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_06a6: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_0739: Unknown result type (might be due to invalid IL or missing references) //IL_077f: Unknown result type (might be due to invalid IL or missing references) //IL_08fa: Unknown result type (might be due to invalid IL or missing references) //IL_0956: Unknown result type (might be due to invalid IL or missing references) //IL_0997: Unknown result type (might be due to invalid IL or missing references) //IL_09d8: Unknown result type (might be due to invalid IL or missing references) //IL_0a19: Unknown result type (might be due to invalid IL or missing references) //IL_0a5a: Unknown result type (might be due to invalid IL or missing references) //IL_0a9b: Unknown result type (might be due to invalid IL or missing references) //IL_0adc: Unknown result type (might be due to invalid IL or missing references) //IL_0b18: Unknown result type (might be due to invalid IL or missing references) //IL_0b59: Unknown result type (might be due to invalid IL or missing references) //IL_0b9a: Unknown result type (might be due to invalid IL or missing references) //IL_0bdb: Unknown result type (might be due to invalid IL or missing references) //IL_0c52: Unknown result type (might be due to invalid IL or missing references) //IL_0c93: Unknown result type (might be due to invalid IL or missing references) //IL_0cd4: Unknown result type (might be due to invalid IL or missing references) //IL_0d10: Unknown result type (might be due to invalid IL or missing references) //IL_0d51: Unknown result type (might be due to invalid IL or missing references) defaultOneHand = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "DefaultOneHand", "-2.25,3,-5.25,0.05", "Default position for one-handed items."); defaultTwoHand = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "DefaultTwoHand", "-4.5,3,-5.25,0.05", "Default position for two-handed items."); defaultTool = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "DefaultTool", $"cupboard:-2,0.6,{0.5f},0,0.02:{'C'}{'P'}", "Default position for tool items."); VItemPositionConfig("Airhorn"); VItemPositionConfig("LungApparatus", "Apparatice", new Vector3(-6.8f, 4.4f, -6.65f)); itemPositions["LungApparatusTurnedOff"] = itemPositions["LungApparatus"]; VItemPositionConfig("HandBell", "Brass bell"); VItemPositionConfig("BigBolt", "Big bolt"); VItemPositionConfig("Bone"); VItemPositionConfig("BinFullOfBottles", "Bottles"); VItemPositionConfig("Hairbrush", "Hair brush"); VItemPositionConfig("Candy"); VItemPositionConfig("CashRegisterItem", "Cash register"); VItemPositionConfig("ChemicalJug", "Chemical jug"); VItemPositionConfig("Clock"); VItemPositionConfig("Clownhorn", "Clown horn"); VItemPositionConfig("ComedyMask", "Comedy"); VItemPositionConfig("ControlPad", "Control pad"); VItemPositionConfig("CookieMoldPan", "Cookie mold pan"); VItemPositionConfig("Dustpan", "Dust pan"); VItemPositionConfig("Ear"); VItemPositionConfig("EasterEgg", "Easter egg"); VItemPositionConfig("KiwiBabyItem", "Egg", new Vector3(4.85f, 2f, -4f)); VItemPositionConfig("EggBeater", "Egg beater"); VItemPositionConfig("FancyLamp", "Fancy lamp"); VItemPositionConfig("Flask"); VItemPositionConfig("SeveredFootLOD0", "Foot"); VItemPositionConfig("GarbageLid", "Garbage lid"); VItemPositionConfig("GiftBox", "Gift box"); VItemPositionConfig("GoldBar", "Gold Bar"); VItemPositionConfig("FancyGlass", "Golden cup"); VItemPositionConfig("SeveredHandLOD0", "Hand"); VItemPositionConfig("HeartContainer", "Heart"); VItemPositionConfig("Hairdryer"); VItemPositionConfig("RedLocustHive", "Bee hive", new Vector3(-6.8f, 4.4f, -5.65f)); VItemPositionConfig("DiyFlashbang", "Homemade Flashbang"); VItemPositionConfig("PickleJar", "Jar of pickles"); VItemPositionConfig("KnifeItem", "Kitchen knife", new Vector3(-1.9f, 0.6f, 1.5f), isTool: false, true, true, 0); VItemPositionConfig("SeveredThighLOD0", "Knee"); VItemPositionConfig("Cog", "Large axle"); VItemPositionConfig("LaserPointer", "Laser pointer"); VItemPositionConfig("Magic7Ball", "Magic 7 ball"); VItemPositionConfig("MagnifyingGlass", "Magnifying glass"); VItemPositionConfig("MetalSheet", "Tattered metal sheet"); VItemPositionConfig("Mug", "Coffee mug"); VItemPositionConfig("OldPhone", "Old phone"); VItemPositionConfig("Painting"); VItemPositionConfig("PerfumeBottle", "Perfume bottle"); VItemPositionConfig("PillBottle", "Pill bottle"); VItemPositionConfig("PlasticCup", "Plastic cup"); VItemPositionConfig("FishTestProp", "Plastic fish"); VItemPositionConfig("RedSodaCan", "Red soda"); VItemPositionConfig("Remote"); VItemPositionConfig("RibcageBone", "Ribcage"); VItemPositionConfig("FancyRing", "Wedding ring"); VItemPositionConfig("RubberDucky", "Rubber ducky"); Vector3 defaultPosition = new Vector3(8.75f, 2f, -5.5f); bool? defaultKeepOnCruiser = true; int? defaultFloorYRot = 0; VItemPositionConfig("ShotgunItem", "Double-barrel", defaultPosition, isTool: false, null, defaultKeepOnCruiser, defaultFloorYRot); ConfigFile config = ((BaseUnityPlugin)this).Config; Vector3 defaultPosition2 = new Vector3(8.6f, 2f, -5.5f); defaultKeepOnCruiser = true; defaultFloorYRot = 0; ItemPositionConfig(config, "ShotgunItem-1", "Double-barrel (1 bullet)", defaultPosition2, isTool: false, null, defaultKeepOnCruiser, defaultFloorYRot, "ShotgunExtensions"); ConfigFile config2 = ((BaseUnityPlugin)this).Config; Vector3 defaultPosition3 = new Vector3(8.45f, 2f, -5.5f); defaultKeepOnCruiser = true; defaultFloorYRot = 0; ItemPositionConfig(config2, "ShotgunItem-2", "Double-barrel (2 bullets)", defaultPosition3, isTool: false, null, defaultKeepOnCruiser, defaultFloorYRot, "ShotgunExtensions"); VItemPositionConfig("SoccerBall", "Soccer ball", new Vector3(-6.8f, 4.4f, -7.75f)); VItemPositionConfig("SteeringWheel", "Steering wheel"); VItemPositionConfig("StopSign", "Stop sign"); VItemPositionConfig("TeaKettle", "Tea Kettle"); VItemPositionConfig("Dentures", "Teeth"); VItemPositionConfig("ToiletPaperRolls", "Toilet paper"); VItemPositionConfig("Toothpaste"); VItemPositionConfig("Tongue"); VItemPositionConfig("ToyCube", "Toy cube"); VItemPositionConfig("RobotToy", "Robot Toy"); VItemPositionConfig("ToyTrain", "Toy train"); VItemPositionConfig("TragedyMask", "Tragedy"); VItemPositionConfig("EnginePart", "V-type engine"); VItemPositionConfig("WhoopieCushion", "Whoopie cushion", new Vector3(9f, 2f, -8.25f)); VItemPositionConfig("YieldSign", "Yield sign"); VItemPositionConfig("ZeddogPlushie", "Zed Dog", new Vector3(9f, 1.21f, -5.55f)); Vector3 defaultPosition4 = new Vector3(-1.4f, 0.6f, 2.4f); defaultFloorYRot = 0; VItemPositionConfig("WalkieTalkie", "Walkie-talkie", defaultPosition4, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition5 = new Vector3(-1.3f, 0.2f, 2f); defaultFloorYRot = 0; VItemPositionConfig("BBFlashlight", "Flashlight", defaultPosition5, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition6 = new Vector3(-1.5f, 0.3f, 1.5f); defaultFloorYRot = 0; VItemPositionConfig("ShovelItem", "Shovel", defaultPosition6, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition7 = new Vector3(-2f, 0.5f, 2.4f); defaultFloorYRot = 0; VItemPositionConfig("LockPickerItem", "Lockpicker", defaultPosition7, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition8 = new Vector3(-1.3f, 0.65f, 2f); defaultFloorYRot = 0; VItemPositionConfig("FlashlightItem", "Pro-flashlight", defaultPosition8, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition9 = new Vector3(-1.2f, 0.5f, 2f); defaultFloorYRot = 0; VItemPositionConfig("StunGrenade", "Stun grenade", defaultPosition9, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition10 = new Vector3(-0.3f, 0.5f, 3.2f); defaultFloorYRot = 0; VItemPositionConfig("Boombox", defaultPosition10, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition11 = new Vector3(-0.55f, 0.2f, 2f); defaultFloorYRot = 0; VItemPositionConfig("TZPChemical", "TZP-Inhalant", defaultPosition11, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition12 = new Vector3(-1.1f, 0.6f, 2.4f); defaultFloorYRot = 0; VItemPositionConfig("PatcherGunItem", "Zap gun", defaultPosition12, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition13 = new Vector3(-0.3f, 0.2f, 0.5f); defaultFloorYRot = 0; VItemPositionConfig("JetpackItem", "Jetpack", defaultPosition13, isTool: true, null, null, defaultFloorYRot); VItemPositionConfig("ExtensionLadderItem", "Extension ladder", isTool: true); VItemPositionConfig("RadarBoosterDevice", "Radar booster", isTool: true); Vector3 defaultPosition14 = new Vector3(-1.7f, 0.5f, 2f); defaultFloorYRot = 0; VItemPositionConfig("SprayPaintItem", "Spray paint", defaultPosition14, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition15 = new Vector3(-2.05f, 0.5f, 2f); defaultFloorYRot = 0; VItemPositionConfig("WeedKillerItem", "Weed killer", defaultPosition15, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition16 = new Vector3(-0.35f, 0.5f, 2.3000002f); defaultFloorYRot = 0; VItemPositionConfig("BeltBagItem", "Belt bag", defaultPosition16, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition17 = new Vector3(-0.3f, 0.6f, 1.5f); defaultFloorYRot = 0; VItemPositionConfig("Key", defaultPosition17, isTool: true, null, null, defaultFloorYRot); Vector3 defaultPosition18 = new Vector3(-0.3f, 0.6f, 2f); defaultFloorYRot = 0; VItemPositionConfig("ShotgunShell", "Shotgun Shell", defaultPosition18, isTool: true, null, null, defaultFloorYRot); customItemPositions = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "CustomItemPositions", "ClipboardManual:N;StickyNoteItem:N", "Semicolon-separated list of internal item names and their positions."); } private void VItemPositionConfig(string internalName, string itemName, bool isTool = false, bool? defaultKeepOnCruiser = null) { itemPositions[internalName] = ((BaseUnityPlugin)this).Config.Bind<string>(isTool ? "Tools" : "Scrap", internalName, $"{(defaultKeepOnCruiser.GetValueOrDefault(isTool) ? ((object)'C') : string.Empty)}", "Position for the " + itemName + " item."); vanillaItems[itemName.ToLower()] = internalName.ToLower(); } private void VItemPositionConfig(string itemName, bool isTool = false, bool? defaultKeepOnCruiser = null) { itemPositions[itemName] = ((BaseUnityPlugin)this).Config.Bind<string>(isTool ? "Tools" : "Scrap", itemName, $"{(defaultKeepOnCruiser.GetValueOrDefault(isTool) ? ((object)'C') : string.Empty)}", "Position for the " + itemName + " item."); vanillaItems[itemName.ToLower()] = itemName.ToLower(); } public void ItemPositionConfig(ConfigFile configFile, string internalName, string itemName, bool isTool = false, bool? defaultKeepOnCruiser = null, string? section = null) { if (modItemPositions.ContainsKey(internalName)) { Logger.LogWarning((object)("Multiple configuration values registered for mod item position " + internalName)); } modItemPositions[internalName] = configFile.Bind<string>(section ?? (isTool ? "Tools" : "Scrap"), internalName, $"{(defaultKeepOnCruiser.GetValueOrDefault(isTool) ? ((object)'C') : string.Empty)}", "Position for the " + itemName + " item."); modItems[itemName.ToLower()] = internalName.ToLower(); } public void ItemPositionConfig(ConfigFile configFile, string itemName, bool isTool = false, bool? defaultKeepOnCruiser = null, string? section = null) { if (modItemPositions.ContainsKey(itemName)) { Logger.LogWarning((object)("Multiple configuration values registered for mod item position " + itemName)); } modItemPositions[itemName] = configFile.Bind<string>(section ?? (isTool ? "Tools" : "Scrap"), itemName, $"{(defaultKeepOnCruiser.GetValueOrDefault(isTool) ? ((object)'C') : string.Empty)}", "Position for the " + itemName + " item."); modItems[itemName.ToLower()] = itemName.ToLower(); } private static string Flags(bool keepOnCruiser, bool inCupboard) { return (keepOnCruiser || inCupboard) ? $":{(keepOnCruiser ? ((object)'C') : string.Empty)}{(inCupboard ? ((object)'P') : string.Empty)}" : string.Empty; } private void VItemPositionConfig(string internalName, string itemName, Vector3 defaultPosition, bool isTool = false, bool? defaultInCupboard = null, bool? defaultKeepOnCruiser = null, int? defaultFloorYRot = null) { //IL_004b: 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_0067: Unknown result type (might be due to invalid IL or missing references) itemPositions[internalName] = ((BaseUnityPlugin)this).Config.Bind<string>(isTool ? "Tools" : "Scrap", internalName, string.Format(CultureInfo.InvariantCulture, "{0}{1},{2},{3}{4}{5}", defaultInCupboard.GetValueOrDefault(isTool) ? "cupboard:" : "", defaultPosition.x, defaultPosition.y, defaultPosition.z, defaultFloorYRot.HasValue ? string.Format(CultureInfo.InvariantCulture, ",{0}", defaultFloorYRot) : string.Empty, Flags(defaultKeepOnCruiser.GetValueOrDefault(isTool), defaultInCupboard.GetValueOrDefault(isTool))), "Position for the " + itemName + " item."); vanillaItems[itemName.ToLower()] = internalName.ToLower(); } private void VItemPositionConfig(string itemName, Vector3 defaultPosition, bool isTool = false, bool? defaultInCupboard = null, bool? defaultKeepOnCruiser = null, int? defaultFloorYRot = null) { //IL_0049: 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_0065: Unknown result type (might be due to invalid IL or missing references) itemPositions[itemName] = ((BaseUnityPlugin)this).Config.Bind<string>(isTool ? "Tools" : "Scrap", itemName, string.Format(CultureInfo.InvariantCulture, "{0}{1},{2},{3}{4}{5}", defaultInCupboard.GetValueOrDefault(isTool) ? "cupboard:" : "", defaultPosition.x, defaultPosition.y, defaultPosition.z, defaultFloorYRot.HasValue ? string.Format(CultureInfo.InvariantCulture, ",{0}", defaultFloorYRot) : string.Empty, Flags(defaultKeepOnCruiser.GetValueOrDefault(isTool), defaultInCupboard.GetValueOrDefault(isTool))), "Position for the " + itemName + " item."); vanillaItems[itemName.ToLower()] = itemName.ToLower(); } public void ItemPositionConfig(ConfigFile configFile, string internalName, string itemName, Vector3 defaultPosition, bool isTool = false, bool? defaultInCupboard = null, bool? defaultKeepOnCruiser = null, int? defaultFloorYRot = null, string? section = null) { //IL_0072: 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_0090: Unknown result type (might be due to invalid IL or missing references) if (modItemPositions.ContainsKey(internalName)) { Logger.LogWarning((object)("Multiple configuration values registered for mod item position " + internalName)); } modItemPositions[internalName] = configFile.Bind<string>(section ?? (isTool ? "Tools" : "Scrap"), internalName, string.Format(CultureInfo.InvariantCulture, "{0}{1},{2},{3}{4}{5}", defaultInCupboard.GetValueOrDefault(isTool) ? "cupboard:" : "", defaultPosition.x, defaultPosition.y, defaultPosition.z, defaultFloorYRot.HasValue ? string.Format(CultureInfo.InvariantCulture, ",{0}", defaultFloorYRot) : string.Empty, Flags(defaultKeepOnCruiser.GetValueOrDefault(isTool), defaultInCupboard.GetValueOrDefault(isTool))), "Position for the " + itemName + " item."); modItems[itemName.ToLower()] = internalName.ToLower(); } public void ItemPositionConfig(ConfigFile configFile, string itemName, Vector3 defaultPosition, bool isTool = false, bool? defaultInCupboard = null, bool? defaultKeepOnCruiser = null, int? defaultFloorYRot = null, string? section = null) { //IL_0072: 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_008e: Unknown result type (might be due to invalid IL or missing references) if (modItemPositions.ContainsKey(itemName)) { Logger.LogWarning((object)("Multiple configuration values registered for mod item position " + itemName)); } modItemPositions[itemName] = configFile.Bind<string>(section ?? (isTool ? "Tools" : "Scrap"), itemName, string.Format(CultureInfo.InvariantCulture, "{0}{1},{2},{3}{4}{5}", defaultInCupboard.GetValueOrDefault(isTool) ? "cupboard:" : "", defaultPosition.x, defaultPosition.y, defaultPosition.z, defaultFloorYRot.HasValue ? string.Format(CultureInfo.InvariantCulture, ",{0}", defaultFloorYRot) : string.Empty, Flags(defaultKeepOnCruiser.GetValueOrDefault(isTool), defaultInCupboard.GetValueOrDefault(isTool))), "Position for the " + itemName + " item."); modItems[itemName.ToLower()] = itemName.ToLower(); } } public class PrintItemNames : Command { public override string[] Commands => new string[2] { "itemnames", ((Command)this).Name }; public override string Description => "Lists all currently loaded item names which do not have assigned sorting positions"; public override string[] Syntax => new string[2] { "", "[ -a | --all ]" }; public override bool Invoke(string[] args, Dictionary<string, string> kwargs, out string? error) { error = "The ship must be in orbit"; if (!StartOfRound.Instance.inShipPhase) { return false; } bool flag = args.Contains("-a") || args.Contains("--all"); error = "No items on the ship"; Dictionary<string, string> dictionary = new Dictionary<string, string>(); GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); foreach (GrabbableObject val in array) { string text = Utils.RemoveClone(((Object)val).name); if (flag || (!LethalShipSort.Instance.vanillaItems.ContainsValue(text.ToLower()) && !LethalShipSort.Instance.modItems.ContainsValue(text.ToLower()))) { dictionary.TryAdd(text, val.itemProperties?.itemName); } } if (dictionary.Count == 0) { return false; } string text2 = string.Join('\n', dictionary.Select((KeyValuePair<string, string> kvp) => kvp.Key + ((kvp.Value != null) ? (": " + kvp.Value) : "")).OrderBy<string, string>((string i) => i, StringComparer.CurrentCultureIgnoreCase)); string text3 = "The following" + (flag ? "" : " unknown") + " items are currently on the ship:\n"; ChatCommandAPI.Print(text3 + "<indent=10px>" + text2 + "</indent>"); LethalShipSort.Logger.LogInfo((object)(text3 + text2)); return true; } } public class SetItemPositionCommand : Command { public enum where { here, there, error } public enum when { once, game, always, error } [CompilerGenerated] private sealed class <SortItemsDelayed>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public uint delay; public GrabbableObject[] items; public Vector3 position; public GameObject relativeTo; public string errorPrefix; private int <itemsFailed>5__1; private string <error>5__2; private GrabbableObject[] <>s__3; private int <>s__4; private GrabbableObject <item>5__5; private Exception <e>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SortItemsDelayed>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <error>5__2 = null; <>s__3 = null; <item>5__5 = null; <e>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <itemsFailed>5__1 = 0; <>s__3 = items; <>s__4 = 0; break; case 1: <>1__state = -1; <item>5__5 = null; <>s__4++; break; } if (<>s__4 < <>s__3.Length) { <item>5__5 = <>s__3[<>s__4]; try { if (!Utils.MoveItem(<item>5__5, new ItemPosition { position = position, parentTo = relativeTo })) { <itemsFailed>5__1++; } } catch (Exception ex) { <e>5__6 = ex; LethalShipSort.Logger.LogError((object)<e>5__6); <itemsFailed>5__1++; } <>2__current = (object)new WaitForSeconds((float)delay / 1000f); <>1__state = 1; return true; } <>s__3 = null; <error>5__2 = $"{<itemsFailed>5__1} items couldn't be sorted"; if (<itemsFailed>5__1 != 0) { ChatCommandAPI.PrintError(errorPrefix + ": <noparse>" + <error>5__2 + "</noparse>"); } else { ChatCommandAPI.Print("Finished sorting items"); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public override string Name => "SetItemPosition"; public override string Description => "Sets the position for an item when sorting"; public override string[] Commands => new string[2] { "put", ((Command)this).Name }; public override string[] Syntax => new string[1] { "\"<item>\" { here | there } [ once | game | always ]\nExample: /put \"easter egg\" there always" }; public override bool Invoke(string[] args, Dictionary<string, string> kwargs, out string error) { error = "The ship must be in orbit"; return StartOfRound.Instance.inShipPhase && SetItemPosition(args, out error); } public static bool SetItemPosition(string[] args, out string error) { error = "Invalid arguments"; Utils.objectCount.Clear(); switch (args.Length) { case 2: { string name2 = args[0]; string text3 = args[1].ToLower(); if (1 == 0) { } where where = ((!(text3 == "here")) ? ((text3 == "there") ? where.there : where.error) : where.here); if (1 == 0) { } return SetItemPosition(name2, where, when.once, out error); } case 3: { string name = args[0]; string text = args[1].ToLower(); if (1 == 0) { } where where = ((!(text == "here")) ? ((text == "there") ? where.there : where.error) : where.here); if (1 == 0) { } where where2 = where; string text2 = args[2].ToLower(); if (1 == 0) { } when when; switch (text2) { case "once": case "now": when = when.once; break; case "game": case "round": when = when.game; break; case "always": case "save": when = when.always; break; default: when = when.error; break; } if (1 == 0) { } return SetItemPosition(name, where2, when, out error); } default: return false; } } public static bool SetItemPosition(string name, where where, when when, out string error) { //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) error = "Invalid arguments"; if (where == where.error || when == when.error) { return false; } error = "Invalid item name"; if (!LethalShipSort.Instance.vanillaItems.TryGetValue(name.ToLower(), out string internalName)) { if (LethalShipSort.Instance.vanillaItems.ContainsValue(name.ToLower())) { internalName = name; } else if (!LethalShipSort.Instance.modItems.TryGetValue(name.ToLower(), out internalName)) { if (!LethalShipSort.Instance.modItems.ContainsValue(name.ToLower())) { return false; } internalName = name; } } LethalShipSort.Logger.LogDebug((object)("internalName: " + internalName + " (" + name + ")")); ConfigEntry<string> val = null; if (when == when.always) { if (LethalShipSort.Instance.itemPositions.All<KeyValuePair<string, ConfigEntry<string>>>((KeyValuePair<string, ConfigEntry<string>> kvp) => !string.Equals(kvp.Key, internalName, StringComparison.CurrentCultureIgnoreCase))) { if (LethalShipSort.Instance.modItemPositions.All<KeyValuePair<string, ConfigEntry<string>>>((KeyValuePair<string, ConfigEntry<string>> kvp) => !string.Equals(kvp.Key, internalName, StringComparison.CurrentCultureIgnoreCase))) { return false; } val = LethalShipSort.Instance.modItemPositions.First<KeyValuePair<string, ConfigEntry<string>>>((KeyValuePair<string, ConfigEntry<string>> kvp) => string.Equals(kvp.Key, internalName, StringComparison.CurrentCultureIgnoreCase)).Value; } else { val = LethalShipSort.Instance.itemPositions.First<KeyValuePair<string, ConfigEntry<string>>>((KeyValuePair<string, ConfigEntry<string>> kvp) => string.Equals(kvp.Key, internalName, StringComparison.CurrentCultureIgnoreCase)).Value; } } error = "Error getting position"; if (!GetPosition(where, out Vector3 position, out GameObject relativeTo)) { return false; } LethalShipSort.Logger.LogDebug((object)string.Format("position: {0} relative to {1} ({2}, {3})", position, relativeTo, ((Object)(object)relativeTo == (Object)null) ? "null" : Utils.GameObjectPath(relativeTo), ((Object)(object)relativeTo == (Object)null) ? "" : ((string)(object)GameObject.Find(Utils.GameObjectPath(relativeTo))))); GrabbableObject[] array; switch (when) { case when.once: ChatCommandAPI.Print($"Moving all items of type {internalName} to position {(((Object)(object)relativeTo == (Object)null) ? position : relativeTo.transform.InverseTransformPoint(position))}"); error = "No items to sort"; array = Object.FindObjectsOfType<GrabbableObject>(); if (array == null) { return false; } array = array.Where((GrabbableObject i) => i != null && i.playerHeldBy == null && !(i is RagdollGrabbableObject) && string.Equals(Utils.RemoveClone(((Object)i).name), internalName, StringComparison.CurrentCultureIgnoreCase)).ToArray(); if (array.Length == 0) { return false; } if (LethalShipSort.Instance.SortDelay < 10) { int num = array.Count(delegate(GrabbableObject item) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) try { return !Utils.MoveItem(item, new ItemPosition { position = position, parentTo = relativeTo }); } catch (Exception ex2) { LethalShipSort.Logger.LogError((object)ex2); return true; } }); error = $"{num} items couldn't be sorted"; ChatCommandAPI.Print("Finished sorting items"); return num == 0; } if (SortItemsCommand.sorting != null) { ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StopCoroutine(SortItemsCommand.sorting); } SortItemsCommand.sorting = ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StartCoroutine(SortItemsDelayed(LethalShipSort.Instance.SortDelay, array, position, relativeTo)); return true; case when.game: LethalShipSort.Instance.roundOverrides[internalName.ToLower()] = (position, relativeTo); ChatCommandAPI.Print($"Items of type {internalName} will be put on position {(((Object)(object)relativeTo == (Object)null) ? position : relativeTo.transform.InverseTransformPoint(position))} for this game"); goto IL_0517; case when.always: { val.Value = (((Object)(object)relativeTo == (Object)null) ? $"none:{position.x},{position.y},{position.z}" : $"{Utils.GameObjectPath(relativeTo)}:{position.x},{position.y},{position.z}"); ChatCommandAPI.Print($"Items of type {internalName} will be put on position {(((Object)(object)relativeTo == (Object)null) ? position : relativeTo.transform.InverseTransformPoint(position))}"); goto IL_0517; } IL_0517: array = Object.FindObjectsOfType<GrabbableObject>(); if (array == null) { break; } array = array.Where((GrabbableObject i) => i != null && i.playerHeldBy == null && !(i is RagdollGrabbableObject) && string.Equals(Utils.RemoveClone(((Object)i).name), internalName, StringComparison.CurrentCultureIgnoreCase)).ToArray(); if (array.Length == 0) { break; } if (LethalShipSort.Instance.SortDelay < 10) { int num2 = array.Count(delegate(GrabbableObject item) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) try { return !Utils.MoveItem(item, new ItemPosition { position = position, parentTo = relativeTo }); } catch (Exception ex) { LethalShipSort.Logger.LogError((object)ex); return true; } }); error = $"{num2} items couldn't be sorted"; return num2 == 0; } if (SortItemsCommand.sorting != null) { ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StopCoroutine(SortItemsCommand.sorting); } SortItemsCommand.sorting = ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StartCoroutine(SortItemsDelayed(LethalShipSort.Instance.SortDelay, array, position, relativeTo)); break; } return true; } [IteratorStateMachine(typeof(<SortItemsDelayed>d__13))] private static IEnumerator SortItemsDelayed(uint delay, GrabbableObject[] items, Vector3 position, GameObject? relativeTo, string errorPrefix = "Error running command") { //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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SortItemsDelayed>d__13(0) { delay = delay, items = items, position = position, relativeTo = relativeTo, errorPrefix = errorPrefix }; } private static bool GetPosition(where where, out Vector3 position, out GameObject? relativeTo) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0082: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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) position = default(Vector3); relativeTo = null; RaycastHit val = default(RaycastHit); switch (where) { case where.here: if (Physics.Raycast(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, Vector3.down, ref val, 80f, 268437761, (QueryTriggerInteraction)1)) { position = ((Component)((RaycastHit)(ref val)).collider).gameObject.transform.InverseTransformPoint(((RaycastHit)(ref val)).point + new Vector3(0f, 0.2f, 0f)); relativeTo = ((Component)((RaycastHit)(ref val)).collider).gameObject; return true; } break; case where.there: if (Physics.Raycast(((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.forward, ref val, 80f, 268437761, (QueryTriggerInteraction)1)) { position = ((Component)((RaycastHit)(ref val)).collider).gameObject.transform.InverseTransformPoint(((RaycastHit)(ref val)).point + new Vector3(0f, 0.2f, 0f)); relativeTo = ((Component)((RaycastHit)(ref val)).collider).gameObject; return true; } break; } return false; } } public class SortItemsCommand : Command { private enum ForceLevel { None, IncludeCruiser, IncludeAll } [HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")] internal static class AutoSortPatch { private static void Prefix() { if (LethalShipSort.Instance.AutoSort && GameNetworkManager.Instance.localPlayerController.isHostPlayerObject) { AutoSortAllItems(); } } } [CompilerGenerated] private sealed class <SortAllItemsDelayed>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public uint delay; public Dictionary<GrabbableObject, ItemPosition> scrap; public Dictionary<GrabbableObject, ItemPosition> tools; public string errorPrefix; private int <scrapFailed>5__1; private int <toolsFailed>5__2; private string <error>5__3; private Dictionary<GrabbableObject, ItemPosition>.Enumerator <>s__4; private KeyValuePair<GrabbableObject, ItemPosition> <kvp>5__5; private Exception <e>5__6; private Dictionary<GrabbableObject, ItemPosition>.Enumerator <>s__7; private KeyValuePair<GrabbableObject, ItemPosition> <kvp>5__8; private Exception <e>5__9; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SortAllItemsDelayed>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; } <error>5__3 = null; <>s__4 = default(Dictionary<GrabbableObject, ItemPosition>.Enumerator); <kvp>5__5 = default(KeyValuePair<GrabbableObject, ItemPosition>); <e>5__6 = null; <>s__7 = default(Dictionary<GrabbableObject, ItemPosition>.Enumerator); <kvp>5__8 = default(KeyValuePair<GrabbableObject, ItemPosition>); <e>5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <scrapFailed>5__1 = 0; <toolsFailed>5__2 = 0; <>s__4 = scrap.GetEnumerator(); <>1__state = -3; goto IL_0116; case 1: <>1__state = -3; <kvp>5__5 = default(KeyValuePair<GrabbableObject, ItemPosition>); goto IL_0116; case 2: { <>1__state = -4; <kvp>5__8 = default(KeyValuePair<GrabbableObject, ItemPosition>); break; } IL_0116: if (<>s__4.MoveNext()) { <kvp>5__5 = <>s__4.Current; try { if (!Utils.MoveItem(<kvp>5__5.Key, <kvp>5__5.Value)) { <scrapFailed>5__1++; } } catch (Exception ex) { <e>5__6 = ex; LethalShipSort.Logger.LogError((object)<e>5__6); <scrapFailed>5__1++; } <>2__current = (object)new WaitForSeconds((float)delay / 1000f); <>1__state = 1; return true; } <>m__Finally1(); <>s__4 = default(Dictionary<GrabbableObject, ItemPosition>.Enumerator); <>s__7 = tools.GetEnumerator(); <>1__state = -4; break; } if (<>s__7.MoveNext()) { <kvp>5__8 = <>s__7.Current; try { if (!Utils.MoveItem(<kvp>5__8.Key, <kvp>5__8.Value)) { <toolsFailed>5__2++; } } catch (Exception ex) { <e>5__9 = ex; LethalShipSort.Logger.LogError((object)<e>5__9); <toolsFailed>5__2++; } <>2__current = (object)new WaitForSeconds((float)delay / 1000f); <>1__state = 2; return true; } <>m__Finally2(); <>s__7 = default(Dictionary<GrabbableObject, ItemPosition>.Enumerator); <error>5__3 = ((<scrapFailed>5__1 > 0) ? string.Format("{0} scrap items {1}", <scrapFailed>5__1, (<toolsFailed>5__2 > 0) ? "and " : "") : "") + ((<toolsFailed>5__2 > 0) ? $"{<toolsFailed>5__2} tool items" : "") + " couldn't be sorted"; if (<scrapFailed>5__1 != 0 || <toolsFailed>5__2 != 0) { ChatCommandAPI.PrintError(errorPrefix + ": <noparse>" + <error>5__3 + "</noparse>"); } else { ChatCommandAPI.Print("Finished sorting items"); } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__4).Dispose(); } private void <>m__Finally2() { <>1__state = -1; ((IDisposable)<>s__7).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static Coroutine? sorting; public override string Name => "SortItems"; public override string[] Commands => new string[3] { "sort", "ShipSort", ((Command)this).Name }; public override string Description => "Sorts all items on the ship\n-a: sort all items, even items on cruiser"; public override string[] Syntax => new string[3] { "", "[ -a | -A ]", "<item> { here | there } [ once | game | always ]" }; public override bool Invoke(string[] args, Dictionary<string, string> kwargs, out string error) { error = "The ship must be in orbit"; return StartOfRound.Instance.inShipPhase && ((args.Length < 2) ? SortAllItems((args.Contains("-A") || args.Contains<string>("--all", StringComparer.InvariantCultureIgnoreCase)) ? ForceLevel.IncludeAll : (args.Contains("-a") ? ForceLevel.IncludeCruiser : ForceLevel.None), out error) : SetItemPositionCommand.SetItemPosition(args, out error)); } private static bool SortAllItems(ForceLevel forceLevel, out string error) { error = "No items to sort"; Utils.objectCount.Clear(); GameNetworkManager.Instance.localPlayerController.DropAllHeldItemsAndSyncNonexact(); GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); if (array == null) { return false; } array = array.Where((GrabbableObject i) => i != null && i.playerHeldBy == null && !(i is RagdollGrabbableObject)).ToArray(); if (array.Length == 0) { return false; } ChatCommandAPI.Print("Sorting all items..."); VehicleController[] cars = Object.FindObjectsOfType<VehicleController>() ?? Array.Empty<VehicleController>(); Dictionary<GrabbableObject, ItemPosition> dictionary = FilterFlags(array.Where((GrabbableObject i) => i.itemProperties.isScrap).ToDictionary((GrabbableObject i) => i, (GrabbableObject item) => LethalShipSort.Instance.GetPosition(item))); Dictionary<GrabbableObject, ItemPosition> dictionary2 = FilterFlags(array.Where((GrabbableObject i) => !i.itemProperties.isScrap).ToDictionary((GrabbableObject i) => i, (GrabbableObject item) => LethalShipSort.Instance.GetPosition(item))); if (LethalShipSort.Instance.SortDelay < 10) { int num = 0; int num2 = 0; if (dictionary.Count != 0) { num = SortItems(dictionary); } if (dictionary2.Count != 0) { num2 = SortItems(dictionary2); } error = ((num > 0) ? string.Format("{0} scrap items {1}", num, (num2 > 0) ? "and " : "") : "") + ((num2 > 0) ? $"{num2} tool items" : "") + " couldn't be sorted"; if (num != 0 || num2 != 0) { return false; } ChatCommandAPI.Print("Finished sorting items"); } else { if (sorting != null) { ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StopCoroutine(sorting); } sorting = ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StartCoroutine(SortAllItemsDelayed(LethalShipSort.Instance.SortDelay, dictionary, dictionary2)); } return true; Dictionary<GrabbableObject, ItemPosition> FilterFlags(Dictionary<GrabbableObject, ItemPosition> dict) { return dict.Where<KeyValuePair<GrabbableObject, ItemPosition>>((KeyValuePair<GrabbableObject, ItemPosition> kvp) => (forceLevel == ForceLevel.IncludeAll || !kvp.Value.flags.Ignore) && (forceLevel >= ForceLevel.IncludeCruiser || !kvp.Value.flags.KeepOnCruiser || !cars.Any((VehicleController car) => (Object)(object)((Component)kvp.Key).transform.parent == (Object)(object)((Component)car).transform))).ToDictionary((KeyValuePair<GrabbableObject, ItemPosition> kvp) => kvp.Key, (KeyValuePair<GrabbableObject, ItemPosition> kvp) => kvp.Value); } } private static void AutoSortAllItems() { try { Utils.objectCount.Clear(); GameNetworkManager.Instance.localPlayerController.DropAllHeldItemsAndSyncNonexact(); GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); if (array == null) { return; } array = array.Where((GrabbableObject i) => i != null && i.playerHeldBy == null && !(i is RagdollGrabbableObject)).ToArray(); if (array.Length == 0) { return; } ChatCommandAPI.Print("Sorting all items..."); VehicleController[] cars = Object.FindObjectsOfType<VehicleController>() ?? Array.Empty<VehicleController>(); Dictionary<GrabbableObject, ItemPosition> dictionary = FilterFlags(array.Where((GrabbableObject i) => i.itemProperties.isScrap).ToDictionary((GrabbableObject i) => i, (GrabbableObject item) => LethalShipSort.Instance.GetPosition(item))); Dictionary<GrabbableObject, ItemPosition> dictionary2 = FilterFlags(array.Where((GrabbableObject i) => !i.itemProperties.isScrap).ToDictionary((GrabbableObject i) => i, (GrabbableObject item) => LethalShipSort.Instance.GetPosition(item))); if (LethalShipSort.Instance.SortDelay < 10) { int num = 0; int num2 = 0; if (dictionary.Count != 0) { num = SortItems(dictionary); } if (dictionary2.Count != 0) { num2 = SortItems(dictionary2); } if (num != 0 || num2 != 0) { ChatCommandAPI.PrintError("Automatic sorting failed: " + ((num > 0) ? string.Format("{0} scrap items {1}", num, (num2 > 0) ? "and " : "") : "") + ((num2 > 0) ? $"{num2} tool items" : "") + " couldn't be sorted"); } else { ChatCommandAPI.Print("Finished sorting items"); } } else { if (sorting != null) { ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StopCoroutine(sorting); } sorting = ((MonoBehaviour)GameNetworkManager.Instance.localPlayerController).StartCoroutine(SortAllItemsDelayed(LethalShipSort.Instance.SortDelay, dictionary, dictionary2, "Automatic sorting failed")); } Dictionary<GrabbableObject, ItemPosition> FilterFlags(Dictionary<GrabbableObject, ItemPosition> dict) { return dict.Where<KeyValuePair<GrabbableObject, ItemPosition>>(delegate(KeyValuePair<GrabbableObject, ItemPosition> kvp) { ItemPosition.Flags flags = kvp.Value.flags; return !flags.Ignore && !flags.NoAutoSort && (!kvp.Value.flags.KeepOnCruiser || !cars.Any((VehicleController car) => (Object)(object)((Component)kvp.Key).transform.parent == (Object)(object)((Component)car).transform)); }).ToDictionary((KeyValuePair<GrabbableObject, ItemPosition> kvp) => kvp.Key, (KeyValuePair<GrabbableObject, ItemPosition> kvp) => kvp.Value); } } catch (Exception arg) { ChatCommandAPI.PrintError("Automatic sorting failed due to an internal error, check the log for details"); LethalShipSort.Logger.LogError((object)$"Error while autosorting items: {arg}"); } } [IteratorStateMachine(typeof(<SortAllItemsDelayed>d__13))] public static IEnumerator SortAllItemsDelayed(uint delay, Dictionary<GrabbableObject, ItemPosition> scrap, Dictionary<GrabbableObject, ItemPosition> tools, string errorPrefix = "Error running command") { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SortAllItemsDelayed>d__13(0) { delay = delay, scrap = scrap, tools = tools, errorPrefix = errorPrefix }; } public static int SortItems(Dictionary<GrabbableObject, ItemPosition> items) { return items.Count<KeyValuePair<GrabbableObject, ItemPosition>>(delegate(KeyValuePair<GrabbableObject, ItemPosition> kvp) { try { return !Utils.MoveItem(kvp.Key, kvp.Value); } catch (Exception ex) { LethalShipSort.Logger.LogError((object)ex); return true; } }); } } public static class Utils { private const string CLONE = "(Clone)"; internal static readonly Dictionary<string, int> objectCount = new Dictionary<string, int>(); internal const int LAYER_MASK = 268437761; public static IReadOnlyDictionary<string, int> ObjectCount => objectCount; public static string RemoveClone(string name) { string result; if (!name.EndsWith("(Clone)")) { result = name; } else { int length = "(Clone)".Length; result = name.Substring(0, name.Length - length); } return result; } public static bool MoveItem(GrabbableObject item, ItemPosition position) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if (!position.position.HasValue) { throw new ArgumentNullException("ItemPosition.position can not be null"); } Vector3 positionOffset = (position.positionOffset.HasValue ? (position.positionOffset.Value * (float)GetItemCount(item)) : Vector3.zero); int floorYRot = position.floorYRot.GetValueOrDefault(-1) + position.rotationOffset.GetValueOrDefault() * GetItemCount(item) % 360; return ((position.flags.Parent && (Object)(object)position.parentTo != (Object)null) ? MoveItem(item, position.position.Value, positionOffset, position.parentTo, floorYRot, position.randomOffset, position.flags) : MoveItemRelativeTo(item, position.position.Value, positionOffset, position.parentTo, floorYRot, position.randomOffset, position.flags)) && IncreaseItemCount(item); } private static bool IncreaseItemCount(GrabbableObject item) { string key = ItemKey(item); objectCount[key] = objectCount.GetValueOrDefault(key) + 1; return true; } private static int GetItemCount(GrabbableObject item) { return objectCount.GetValueOrDefault(ItemKey(item)); } public static string ItemKey(GrabbableObject item) { ShotgunItem val = (ShotgunItem)(object)((item is ShotgunItem) ? item : null); if (val != null && val.shellsLoaded > 0) { return string.Format("{0}-{1}", "ShotgunItem", Math.Min(val.shellsLoaded, 2)); } return RemoveClone(((Object)item).name); } public static bool MoveItemRelativeTo(GrabbableObject item, Vector3 position, Vector3 positionOffset, GameObject? relativeTo, int floorYRot, float? randomOffset, ItemPosition.Flags flags) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_0097: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00e1: 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) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) LethalShipSort.Logger.LogInfo((object)string.Format(">> Moving item {0} to position {1} relative to {2}", RemoveClone(((Object)item).name), position, ((Object)(object)relativeTo == (Object)null) ? "ship" : RemoveClone(((Object)relativeTo).name))); GameObject val = GameObject.Find("Environment/HangarShip"); if ((Object)(object)val == (Object)null) { LethalShipSort.Logger.LogWarning((object)" Couldn't find ship"); return false; } if ((Object)(object)relativeTo == (Object)null) { relativeTo = val; } if (!flags.Exact) { RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(relativeTo.transform.TransformPoint(position), Vector3.down, ref val2, 80f, 268437761, (QueryTriggerInteraction)1)) { LethalShipSort.Logger.LogWarning((object)" Raycast unsuccessful"); return false; } position = Randomize(val.transform.InverseTransformPoint(((RaycastHit)(ref val2)).point + item.itemProperties.verticalOffset * Vector3.up + positionOffset), randomOffset); } else { position = Randomize(position + item.itemProperties.verticalOffset * Vector3.up + positionOffset, randomOffset); } LethalShipSort.Logger.LogDebug((object)$" true position: {position}"); GameNetworkManager.Instance.localPlayerController.SetObjectAsNoLongerHeld(true, true, position, item, floorYRot); GameNetworkManager.Instance.localPlayerController.ThrowObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), true, true, position, floorYRot); return true; } public static bool MoveItem(GrabbableObject item, Vector3 position, Vector3 positionOffset, GameObject parentTo, int floorYRot, float? randomOffset, ItemPosition.Flags flags) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00eb: 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_0104: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_0049: Unknown result type (might be due to invalid IL or missing references) //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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: 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_0082: 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_00a0: 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_00ab: 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_00b7: 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) LethalShipSort.Logger.LogInfo((object)$">> Moving item {RemoveClone(((Object)item).name)} to position {position} in {RemoveClone(((Object)parentTo).name)}"); if (!flags.Exact) { RaycastHit val = default(RaycastHit); if (!Physics.Raycast(parentTo.transform.TransformPoint(position), Vector3.down, ref val, 80f, 268437761, (QueryTriggerInteraction)1)) { LethalShipSort.Logger.LogWarning((object)" Raycast unsuccessful"); return false; } position = parentTo.transform.InverseTransformPoint(Randomize(((RaycastHit)(ref val)).point + item.itemProperties.verticalOffset * Vector3.up - new Vector3(0f, 0.05f, 0f) + positionOffset, randomOffset)); } else { position = Randomize(position + item.itemProperties.verticalOffset * Vector3.up - new Vector3(0f, 0.05f, 0f) + positionOffset, randomOffset); } LethalShipSort.Logger.LogDebug((object)$" true position: {position}"); GameNetworkManager.Instance.localPlayerController.SetObjectAsNoLongerHeld(true, true, position, item, floorYRot); GameNetworkManager.Instance.localPlayerController.ThrowObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), true, true, position, floorYRot); GameNetworkManager.Instance.localPlayerController.PlaceGrabbableObject(parentTo.transform, position, false, item); GameNetworkManager.Instance.localPlayerController.PlaceObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), NetworkObjectReference.op_Implicit(parentTo), position, false); return true; } public static Vector3 Randomize(Vector3 position, float? maxDistance = null) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (maxDistance < 0f) { throw new ArgumentException("Invalid randomOffset (must be positive)"); } if (!maxDistance.HasValue || Mathf.Approximately(maxDistance.Value, 0f)) { return position; } Random random = new Random(); return new Vector3(position.x + (float)random.NextDouble() * maxDistance.Value * 2f - maxDistance.Value, position.y, position.z + (float)random.NextDouble() * maxDistance.Value * 2f - maxDistance.Value); } public static string GameObjectPath(GameObject gameObject) { Transform parent = gameObject.transform.parent; string text = ((Object)gameObject).name; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = ((Component)parent).transform.parent; } return text; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "baer1.ShipSort"; public const string PLUGIN_NAME = "LethalShipSort"; public const string PLUGIN_VERSION = "4.0.1"; } }