using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppSystem.Collections.Generic; using ProjectM; using ProjectM.Network; using ProjectM.Scripting; using SlotSort.Commands.Converters; using SlotSort.Models; using SlotSort.Services; using SlotSort.Ui; using Stunlock.Core; using Unity.Collections; using Unity.Entities; using Unity.Scenes; using VampireCommandFramework; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("SlotSort")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Custom inventory slot sorting on sort button")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("SlotSort")] [assembly: AssemblyTitle("SlotSort")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.0")] [module: UnverifiableCode] namespace SlotSort { internal static class Core { private static bool hasInitialized; public static World Server { get; } = GetWorld("Server") ?? throw new Exception("Server world not found. Install this mod on the dedicated server."); public static EntityManager EntityManager { get; } = Server.EntityManager; public static PrefabCollectionSystem PrefabCollectionSystem { get; private set; } = null; public static ServerScriptMapper ServerScriptMapper { get; private set; } = null; public static ServerGameManager ServerGameManager => ServerScriptMapper.GetServerGameManager(); public static SlotAssignmentService SlotAssignments { get; } = new SlotAssignmentService(); public static InventorySlotService InventorySlots { get; } = new InventorySlotService(); public static SlotSortUiService Ui { get; } = new SlotSortUiService(); public static ManualLogSource Log => Plugin.LogInstance; public static bool HasInitialized => hasInitialized; public static void Initialize() { if (!hasInitialized) { PrefabCollectionSystem = Server.GetExistingSystemManaged(); ServerScriptMapper = Server.GetExistingSystemManaged(); SlotAssignments.LoadDefaults(); SlotAssignments.LoadAllPlayers(); hasInitialized = true; Log.LogInfo((object)"SlotSort initialized"); } } private static World GetWorld(string name) { Enumerator enumerator = World.s_AllWorlds.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current.Name == name) { return current; } } return null; } public static void LogException(Exception e, string context) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown ManualLogSource log = Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(4, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(context); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(e.Message); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\n"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(e.StackTrace); } log.LogError(val); } } internal static class ECSExtensions { private static EntityManager EntityManager => Core.EntityManager; public unsafe static void Write(this Entity entity, T componentData) where T : struct { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) ComponentType val = default(ComponentType); ((ComponentType)(ref val))..ctor(Il2CppType.Of(), (AccessMode)0); byte[] array = StructureToByteArray(componentData); int num = Marshal.SizeOf(); fixed (byte* ptr = array) { EntityManager entityManager = EntityManager; ((EntityManager)(ref entityManager)).SetComponentDataRaw(entity, val.TypeIndex, (void*)ptr, num); } } private static byte[] StructureToByteArray(T structure) where T : struct { int num = Marshal.SizeOf(structure); byte[] array = new byte[num]; IntPtr intPtr = Marshal.AllocHGlobal(num); Marshal.StructureToPtr(structure, intPtr, fDeleteOld: true); Marshal.Copy(intPtr, array, 0, num); Marshal.FreeHGlobal(intPtr); return array; } public unsafe static T Read(this Entity entity) where T : struct { //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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) ComponentType val = default(ComponentType); ((ComponentType)(ref val))..ctor(Il2CppType.Of(), (AccessMode)0); EntityManager entityManager = EntityManager; return Marshal.PtrToStructure(new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, val.TypeIndex))); } public static DynamicBuffer ReadBuffer(this Entity entity) where T : struct { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = EntityManager; return ((EntityManager)(ref entityManager)).GetBuffer(entity, false); } public static bool Has(this Entity entity) where T : struct { //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_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) ComponentType val = default(ComponentType); ((ComponentType)(ref val))..ctor(Il2CppType.Of(), (AccessMode)0); EntityManager entityManager = EntityManager; return ((EntityManager)(ref entityManager)).HasComponent(entity, val); } public static string PrefabName(this PrefabGUID prefabGuid) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = Core.PrefabCollectionSystem._SpawnableNameToPrefabGuidDictionary.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; PrefabGUID value = current.Value; if (((PrefabGUID)(ref value)).Equals(prefabGuid)) { return current.Key; } } return $"Unknown ({((PrefabGUID)(ref prefabGuid)).GuidHash})"; } public static string LookupName(this PrefabGUID prefabGuid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return prefabGuid.PrefabName(); } } [BepInPlugin("SlotSort", "SlotSort", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { private static Plugin instance; private Harmony harmony; public static Harmony Harmony => instance.harmony; public static ManualLogSource LogInstance => ((BasePlugin)instance).Log; public override void Load() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown instance = this; ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("SlotSort"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("1.1.1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded."); } log.LogInfo(val); harmony = new Harmony("SlotSort"); harmony.PatchAll(typeof(Plugin).Assembly); CommandRegistry.RegisterAll(); } public override bool Unload() { CommandRegistry.UnregisterAssembly(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } return true; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "SlotSort"; public const string PLUGIN_NAME = "SlotSort"; public const string PLUGIN_VERSION = "1.1.1"; } } namespace SlotSort.Ui { internal sealed class SlotSortUiService { private readonly ZuiPacketService packets = new ZuiPacketService(); private static readonly (string Label, string ItemQuery, int Slot)[] QuickPresets = new(string, string, int)[5] { ("Blood Rose -> slot 9", "BloodRose", 9), ("Blood Potion -> slot 10", "BloodPotion", 10), ("Cloak -> slot 11", "Cloak", 11), ("Vermin Salve -> slot 12", "VerminSalve", 12), ("Wolf Pelt -> slot 13", "WolfPelt", 13) }; public void Open(User user, ulong steamId) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) bool enabled = Core.SlotAssignments.IsEnabled(steamId); IReadOnlyList assignments = Core.SlotAssignments.GetAssignments(steamId); packets.Send(user, "SetPlugin", new Dictionary { { "Plugin", "SlotSort" } }); packets.Send(user, "SetTargetWindow", new Dictionary { { "Window", "SlotSortPanel" } }); packets.Send(user, "SetUICustom", new Dictionary { { "W", "640" }, { "H", "560" } }); packets.Send(user, "SetTitle", new Dictionary { { "Text", "SlotSort — fixed inventory slots" } }); BuildMainTab(user, enabled); BuildRulesTab(user, assignments); BuildAddTab(user); BuildSearchTab(user, steamId); packets.Send(user, "Open", new Dictionary()); } private void BuildMainTab(User user, bool enabled) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) packets.Send(user, "CreateTab", new Dictionary { { "Name", "Main" } }); string text = (enabled ? "Enabled" : "Disabled"); packets.Send(user, "AddText", new Dictionary { { "Text", "Status: " + text }, { "X", "20" }, { "Y", "20" } }); packets.Send(user, "AddText", new Dictionary { { "Text", $"Slots 1-{8} = hotbar, {9}+ = bag. Press Sort to apply." }, { "X", "20" }, { "Y", "50" } }); AddButton(user, "Toggle on/off", ".slotsort toggle", 20, 90, 600, 36); AddButton(user, "Apply slots now", ".slotsort sort", 20, 136, 600, 36); AddButton(user, "Refresh window", ".slotsort gui", 20, 182, 600, 36); packets.Send(user, "AddCategory", new Dictionary { { "Name", "How it works" }, { "X", "20" }, { "Y", "240" } }); packets.Send(user, "AddText", new Dictionary { { "Text", "1) Add rules on the Add tab\n2) Press Sort in inventory\n3) Items move to your chosen slots" }, { "X", "20" }, { "Y", "270" } }); packets.Send(user, "AddText", new Dictionary { { "Text", "Requires ZUI client mod (Zanakinz/ZUI)" }, { "X", "20" }, { "Y", "360" } }); } private void BuildRulesTab(User user, IReadOnlyList assignments) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) packets.Send(user, "CreateTab", new Dictionary { { "Name", "Rules" } }); packets.Send(user, "AddText", new Dictionary { { "Text", "Active slot rules:" }, { "X", "20" }, { "Y", "20" } }); if (assignments.Count == 0) { packets.Send(user, "AddText", new Dictionary { { "Text", "No rules yet. Use the Add tab." }, { "X", "20" }, { "Y", "55" } }); return; } int num = 55; int num2 = 0; foreach (SlotAssignmentEntry assignment in assignments) { if (num2 >= 10) { packets.Send(user, "AddText", new Dictionary { { "Text", "...and more. Use .slotsort list" }, { "X", "20" }, { "Y", num.ToString() } }); break; } string displayName = GetDisplayName(assignment); string value = ((displayName.Length > 42) ? (displayName.Substring(0, 39) + "...") : displayName); packets.Send(user, "AddText", new Dictionary { { "Text", $"Slot {assignment.Slot} {value}" }, { "X", "20" }, { "Y", num.ToString() } }); AddButton(user, "X", $".slotsort rmid {assignment.ItemGuid}", 560, num - 4, 50, 28); num += 42; num2++; } } private void BuildAddTab(User user) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0111: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) packets.Send(user, "CreateTab", new Dictionary { { "Name", "Add" } }); packets.Send(user, "AddCategory", new Dictionary { { "Name", "Quick presets" }, { "X", "20" }, { "Y", "20" } }); int num = 55; (string, string, int)[] quickPresets = QuickPresets; for (int i = 0; i < quickPresets.Length; i++) { (string, string, int) tuple = quickPresets[i]; PrefabGUID val = InventorySlotService.ResolveItemGuidByName(tuple.Item2); if (((PrefabGUID)(ref val)).GuidHash != 0) { AddButton(user, tuple.Item1, $".slotsort setid {((PrefabGUID)(ref val)).GuidHash} {tuple.Item3}", 20, num, 600, 34); num += 42; } } packets.Send(user, "AddCategory", new Dictionary { { "Name", "Pick a bag slot (9-16)" }, { "X", "20" }, { "Y", (num + 10).ToString() } }); num += 45; int num2 = 0; for (int j = 9; j <= 16; j++) { int x = 20 + num2 * 74; AddButton(user, j.ToString(), $".slotsort pickslot {j}", x, num, 68, 32); num2++; } packets.Send(user, "AddText", new Dictionary { { "Text", "Pick slot, then chat: .slotsort setheld\nOr: .slotsort set \"item name\" 12\nOr: .slotsort search blood" }, { "X", "20" }, { "Y", (num + 45).ToString() } }); } private void BuildSearchTab(User user, ulong steamId) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) packets.Send(user, "CreateTab", new Dictionary { { "Name", "Search" } }); packets.Send(user, "AddText", new Dictionary { { "Text", "Chat: .slotsort search blood (or any part of the item name)" }, { "X", "20" }, { "Y", "20" } }); int slot; string value = (Core.SlotAssignments.TryGetPendingSlot(steamId, out slot) ? $"Selected slot: {slot}" : "Pick a slot below before assigning"); packets.Send(user, "AddText", new Dictionary { { "Text", value }, { "X", "20" }, { "Y", "50" } }); int num = 80; for (int i = 9; i <= 16; i++) { int x = 20 + (i - 9) * 74; AddButton(user, i.ToString(), $".slotsort pickslot {i}", x, num, 68, 32); } num += 45; if (!Core.SlotAssignments.TryGetSearchResults(steamId, out var query, out var itemGuids) || itemGuids.Count == 0) { packets.Send(user, "AddText", new Dictionary { { "Text", "No search yet. Run .slotsort search in chat." }, { "X", "20" }, { "Y", num.ToString() } }); return; } packets.Send(user, "AddCategory", new Dictionary { { "Name", "Results for \"" + query + "\"" }, { "X", "20" }, { "Y", num.ToString() } }); num += 35; int num2 = 0; foreach (int item in itemGuids) { if (num2 >= 8) { packets.Send(user, "AddText", new Dictionary { { "Text", $"...and {itemGuids.Count - 8} more. Refine your search." }, { "X", "20" }, { "Y", num.ToString() } }); break; } string text = ItemSearchService.FormatDisplayName(ECSExtensions.PrefabName(new PrefabGUID(item))); if (text.Length > 36) { text = text.Substring(0, 33) + "..."; } string cmd = $".slotsort setid {item}"; AddButton(user, text, cmd, 20, num, 520, 34); num += 42; num2++; } } private static string GetDisplayName(SlotAssignmentEntry entry) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (entry.ItemGuid != 0) { return ECSExtensions.PrefabName(new PrefabGUID(entry.ItemGuid)); } return entry.ItemName; } private void AddButton(User user, string text, string cmd, int x, int y, int w, int h) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) packets.Send(user, "AddButton", new Dictionary { { "Text", text }, { "Cmd", cmd }, { "X", x.ToString() }, { "Y", y.ToString() }, { "W", w.ToString() }, { "H", h.ToString() } }); } } internal sealed class ZuiPacketService { public const string PluginName = "SlotSort"; public const string WindowName = "SlotSortPanel"; public void Send(User user, string type, Dictionary data) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown string text = JsonSerializer.Serialize(new { Type = type, Plugin = "SlotSort", Window = "SlotSortPanel", Data = data }); string text2 = "[[ZUI]]" + text; if (text2.Length >= 511) { ManualLogSource log = Core.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ZUI packet too long ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2.Length); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" chars): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(type); } log.LogWarning(val); } else { ServerChatUtils.SendSystemMessageToClient(Core.EntityManager, user, text2); } } } } namespace SlotSort.Services { internal sealed class InventorySlotService { public const int HotbarSlots = 8; public void ApplyAssignments(Entity character, ulong steamId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Entity val = default(Entity); if (!InventoryUtilities.TryGetInventoryEntity(Core.EntityManager, character, ref val, 0)) { return; } ServerGameManager serverGameManager = Core.ServerGameManager; DynamicBuffer buffer = default(DynamicBuffer); if (!((ServerGameManager)(ref serverGameManager)).TryGetBuffer(val, ref buffer)) { return; } IReadOnlyList assignments = Core.SlotAssignments.GetAssignments(steamId); if (assignments.Count == 0) { return; } foreach (SlotAssignmentEntry item in assignments) { PrefabGUID itemGuid = (PrefabGUID)((item.ItemGuid != 0) ? new PrefabGUID(item.ItemGuid) : ResolveItemGuid(item.ItemName)); if (((PrefabGUID)(ref itemGuid)).GuidHash != 0) { int num = ToBufferIndex(item.Slot, buffer.Length); if (num >= 0 && TryFindItemSlot(buffer, itemGuid, num, out var sourceIndex) && sourceIndex != num) { SwapSlots(val, buffer, sourceIndex, num); } } } } public static PrefabGUID ResolveItemGuidByName(string itemName) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(itemName)) { return PrefabGUID.Empty; } if (ItemSearchService.TryResolveExact(itemName, out var prefab)) { return prefab; } List list = ItemSearchService.FindItems(itemName, 2); if (list.Count != 1) { return PrefabGUID.Empty; } return list[0].Guid; } private static PrefabGUID ResolveItemGuid(string itemName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return ResolveItemGuidByName(itemName); } private static int ToBufferIndex(int slotNumber, int bufferLength) { int num = slotNumber - 1; if (num < 0 || num >= bufferLength) { return -1; } return num; } private static bool TryFindItemSlot(DynamicBuffer buffer, PrefabGUID itemGuid, int skipIndex, out int sourceIndex) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < buffer.Length; i++) { if (i != skipIndex) { InventoryBuffer val = buffer[i]; if (val.Amount > 0 && ((PrefabGUID)(ref val.ItemType)).Equals(itemGuid)) { sourceIndex = i; return true; } } } sourceIndex = -1; return false; } private static void SwapSlots(Entity inventory, DynamicBuffer buffer, int sourceIndex, int targetIndex) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) InventoryBuffer val = buffer[sourceIndex]; InventoryBuffer entry = (buffer[sourceIndex] = buffer[targetIndex]); buffer[targetIndex] = val; UpdateItemEntityContainer(val, inventory); UpdateItemEntityContainer(entry, inventory); } private static void UpdateItemEntityContainer(InventoryBuffer entry, Entity inventory) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) Entity entityOnServer = ((NetworkedEntity)(ref entry.ItemEntity)).GetEntityOnServer(); if (!((Entity)(ref entityOnServer)).Equals(Entity.Null) && entityOnServer.Has()) { InventoryItem componentData = entityOnServer.Read(); componentData.ContainerEntity = inventory; entityOnServer.Write(componentData); } } } internal static class ItemSearchService { public readonly record struct ItemMatch(PrefabGUID Guid, string PrefabName); public static bool TryResolveExact(string query, out PrefabGUID prefab) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) Enumerator enumerator = Core.PrefabCollectionSystem._SpawnableNameToPrefabGuidDictionary.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; if (current.Key.Equals(query, StringComparison.OrdinalIgnoreCase)) { prefab = current.Value; return true; } } prefab = PrefabGUID.Empty; return false; } public static List FindItems(string query, int maxResults = 20) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (string.IsNullOrWhiteSpace(query) || maxResults < 1) { return list; } Enumerator enumerator = Core.PrefabCollectionSystem._SpawnableNameToPrefabGuidDictionary.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; if (current.Key.StartsWith("Item_") && current.Key.Contains(query, StringComparison.OrdinalIgnoreCase)) { list.Add(new ItemMatch(current.Value, current.Key)); } } return list.OrderBy((ItemMatch m) => m.PrefabName, StringComparer.OrdinalIgnoreCase).Take(maxResults).ToList(); } public static string FormatDisplayName(string prefabName) { if (prefabName.StartsWith("Item_", StringComparison.Ordinal)) { string text = prefabName; prefabName = text.Substring(5, text.Length - 5); } return prefabName.Replace('_', ' '); } } internal sealed class SlotAssignmentService { private const string ConfigFolderName = "SlotSort"; private const string DefaultsFileName = "defaults.json"; private readonly Dictionary playerData = new Dictionary(); private readonly Dictionary pendingSlots = new Dictionary(); private readonly Dictionary ItemGuids)> searchResults = new Dictionary)>(); private SlotAssignmentData globalDefaults = new SlotAssignmentData(); private string ConfigRoot => Path.Combine(Paths.ConfigPath, "SlotSort"); private string DefaultsPath => Path.Combine(ConfigRoot, "defaults.json"); private string PlayersPath => Path.Combine(ConfigRoot, "players"); public void LoadDefaults() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown Directory.CreateDirectory(ConfigRoot); Directory.CreateDirectory(PlayersPath); if (!File.Exists(DefaultsPath)) { globalDefaults = CreateExampleDefaults(); ResolveMissingGuids(globalDefaults); SaveDefaults(); return; } try { string json = File.ReadAllText(DefaultsPath); globalDefaults = JsonSerializer.Deserialize(json) ?? new SlotAssignmentData(); ResolveMissingGuids(globalDefaults); } catch (Exception ex) { ManualLogSource log = Core.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to load defaults.json: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); globalDefaults = new SlotAssignmentData(); } } public void LoadAllPlayers() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown playerData.Clear(); bool flag = default(bool); foreach (string item in Directory.EnumerateFiles(PlayersPath, "*.json")) { if (!ulong.TryParse(Path.GetFileNameWithoutExtension(item), out var result)) { continue; } try { SlotAssignmentData slotAssignmentData = JsonSerializer.Deserialize(File.ReadAllText(item)); if (slotAssignmentData != null) { playerData[result] = slotAssignmentData; } } catch (Exception ex) { ManualLogSource log = Core.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to load player config "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } public bool IsEnabled(ulong steamId) { return GetMergedData(steamId).Enabled; } public bool ToggleEnabled(ulong steamId) { SlotAssignmentData orCreatePlayerData = GetOrCreatePlayerData(steamId); orCreatePlayerData.Enabled = !orCreatePlayerData.Enabled; SavePlayer(steamId); return orCreatePlayerData.Enabled; } public IReadOnlyList GetAssignments(ulong steamId) { SlotAssignmentData orCreatePlayerData = GetOrCreatePlayerData(steamId); HashSet disabled = new HashSet(orCreatePlayerData.DisabledDefaultGuids); return MergeAssignments(globalDefaults.Assignments.Where((SlotAssignmentEntry a) => !disabled.Contains(a.ItemGuid)), orCreatePlayerData.Assignments); } public void SetPendingSlot(ulong steamId, int slot) { pendingSlots[steamId] = slot; } public bool TryGetPendingSlot(ulong steamId, out int slot) { return pendingSlots.TryGetValue(steamId, out slot); } public void SetSearchResults(ulong steamId, string query, IReadOnlyList results) { searchResults[steamId] = (query, results.Select(delegate(ItemSearchService.ItemMatch r) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) PrefabGUID guid = r.Guid; return ((PrefabGUID)(ref guid)).GuidHash; }).ToList()); } public bool TryGetSearchResults(ulong steamId, out string query, out IReadOnlyList itemGuids) { if (searchResults.TryGetValue(steamId, out (string, List) value)) { (query, itemGuids) = value; return true; } query = string.Empty; itemGuids = Array.Empty(); return false; } public bool TrySetAssignment(ulong steamId, PrefabGUID item, int slotNumber, out string error) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) error = string.Empty; if (slotNumber < 1) { error = "Slot number must be at least 1."; return false; } SlotAssignmentData orCreatePlayerData = GetOrCreatePlayerData(steamId); orCreatePlayerData.DisabledDefaultGuids.Remove(((PrefabGUID)(ref item)).GuidHash); orCreatePlayerData.Assignments.RemoveAll((SlotAssignmentEntry a) => a.ItemGuid == ((PrefabGUID)(ref item)).GuidHash); orCreatePlayerData.Assignments.Add(new SlotAssignmentEntry { ItemGuid = ((PrefabGUID)(ref item)).GuidHash, ItemName = item.PrefabName(), Slot = slotNumber }); SavePlayer(steamId); return true; } public bool TryRemoveAssignment(ulong steamId, PrefabGUID item, out string error) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) error = string.Empty; SlotAssignmentData orCreatePlayerData = GetOrCreatePlayerData(steamId); if (orCreatePlayerData.Assignments.RemoveAll((SlotAssignmentEntry a) => a.ItemGuid == ((PrefabGUID)(ref item)).GuidHash) > 0) { SavePlayer(steamId); return true; } if (globalDefaults.Assignments.Exists((SlotAssignmentEntry a) => a.ItemGuid == ((PrefabGUID)(ref item)).GuidHash) && !orCreatePlayerData.DisabledDefaultGuids.Contains(((PrefabGUID)(ref item)).GuidHash)) { orCreatePlayerData.DisabledDefaultGuids.Add(((PrefabGUID)(ref item)).GuidHash); SavePlayer(steamId); return true; } error = "No assignment found for " + item.PrefabName() + "."; return false; } public bool TryRemoveByGuid(ulong steamId, int itemGuid, out string error) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (itemGuid == 0) { error = "Invalid item id."; return false; } return TryRemoveAssignment(steamId, new PrefabGUID(itemGuid), out error); } public bool TrySetByGuid(ulong steamId, int itemGuid, int slotNumber, out string error) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (itemGuid == 0) { error = "Invalid item id."; return false; } return TrySetAssignment(steamId, new PrefabGUID(itemGuid), slotNumber, out error); } private SlotAssignmentData GetMergedData(ulong steamId) { SlotAssignmentData orCreatePlayerData = GetOrCreatePlayerData(steamId); HashSet disabled = new HashSet(orCreatePlayerData.DisabledDefaultGuids); IEnumerable defaults = globalDefaults.Assignments.Where((SlotAssignmentEntry a) => !disabled.Contains(a.ItemGuid)); return new SlotAssignmentData { Enabled = orCreatePlayerData.Enabled, Assignments = MergeAssignments(defaults, orCreatePlayerData.Assignments), DisabledDefaultGuids = orCreatePlayerData.DisabledDefaultGuids }; } private SlotAssignmentData GetOrCreatePlayerData(ulong steamId) { if (!playerData.TryGetValue(steamId, out var value)) { value = new SlotAssignmentData(); playerData[steamId] = value; } return value; } private static List MergeAssignments(IEnumerable defaults, IEnumerable playerOverrides) { Dictionary dictionary = new Dictionary(); foreach (SlotAssignmentEntry @default in defaults) { dictionary[@default.ItemGuid] = @default; } foreach (SlotAssignmentEntry playerOverride in playerOverrides) { dictionary[playerOverride.ItemGuid] = playerOverride; } return dictionary.Values.OrderBy((SlotAssignmentEntry v) => v.Slot).ToList(); } private void SaveDefaults() { string contents = JsonSerializer.Serialize(globalDefaults, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(DefaultsPath, contents); } private void SavePlayer(ulong steamId) { if (playerData.TryGetValue(steamId, out var value)) { string path = Path.Combine(PlayersPath, $"{steamId}.json"); string contents = JsonSerializer.Serialize(value, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(path, contents); } } private static void ResolveMissingGuids(SlotAssignmentData data) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (Core.PrefabCollectionSystem == null) { return; } foreach (SlotAssignmentEntry assignment in data.Assignments) { if (assignment.ItemGuid == 0) { PrefabGUID val = InventorySlotService.ResolveItemGuidByName(assignment.ItemName); if (((PrefabGUID)(ref val)).GuidHash != 0) { assignment.ItemGuid = ((PrefabGUID)(ref val)).GuidHash; } } } } private static SlotAssignmentData CreateExampleDefaults() { return new SlotAssignmentData { Enabled = true, Assignments = { new SlotAssignmentEntry { ItemName = "Item_Consumable_BloodRose", ItemGuid = 0, Slot = 9 }, new SlotAssignmentEntry { ItemName = "Item_Consumable_BloodPotion", ItemGuid = 0, Slot = 10 }, new SlotAssignmentEntry { ItemName = "Item_Equipment_Cloak", ItemGuid = 0, Slot = 11 } } }; } } } namespace SlotSort.Patches { [HarmonyPatch(typeof(SceneSectionStreamingSystem), "ShutdownAsynchrnonousStreamingSupport")] internal static class InitializationPatch { [HarmonyPostfix] private static void OneShot_AfterLoad() { Core.Initialize(); Plugin.Harmony.Unpatch((MethodBase)typeof(SceneSectionStreamingSystem).GetMethod("ShutdownAsynchrnonousStreamingSupport"), typeof(InitializationPatch).GetMethod("OneShot_AfterLoad")); } } [HarmonyPatch(typeof(SortSingleInventorySystem), "OnUpdate")] internal static class SortInventoryPatch { [HarmonyPostfix] private static void AfterSort(SortSingleInventorySystem __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if (!Core.HasInitialized) { return; } EntityQuery eventQuery = __instance._EventQuery; NativeArray val = ((EntityQuery)(ref eventQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); try { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((Entity)(ref current)).Equals(Entity.Null)) { continue; } FromCharacter val2 = current.Read(); SortSingleInventoryEvent val3 = current.Read(); InventoryOwner val4 = val2.Character.Read(); ref NetworkId inventory = ref val3.Inventory; object obj = val4; if (((object)Unsafe.As(ref inventory)/*cast due to .constrained prefix*/).Equals(obj)) { ulong platformId = val2.User.Read().PlatformId; if (Core.SlotAssignments.IsEnabled(platformId)) { Core.InventorySlots.ApplyAssignments(val2.Character, platformId); } } } } catch (Exception e) { Core.LogException(e, "SortInventoryPatch"); } finally { val.Dispose(); } } } } namespace SlotSort.Models { internal sealed class SlotAssignmentData { public bool Enabled { get; set; } = true; public List Assignments { get; set; } = new List(); public List DisabledDefaultGuids { get; set; } = new List(); } internal sealed class SlotAssignmentEntry { public int ItemGuid { get; set; } public string ItemName { get; set; } = string.Empty; public int Slot { get; set; } } } namespace SlotSort.Commands { [CommandGroup("slotsort", "ss")] internal static class SlotSortCommands { [Command("gui", null, null, "Open SlotSort settings window (requires ZUI client mod).", null, false)] public static void OpenGui(ChatCommandContext ctx) { //IL_000b: 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) Core.Ui.Open(ctx.Event.User, ctx.Event.User.PlatformId); ctx.Reply("Opening SlotSort panel. Install ZUI on your client if the window does not appear."); } [Command("set", null, null, "Assign an item to a fixed inventory slot (1 = first hotbar slot).", null, false)] public static void SetSlot(ChatCommandContext ctx, ItemPrefab item, int slot = -1) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) ulong platformId = ctx.Event.User.PlatformId; if (slot < 1 && !Core.SlotAssignments.TryGetPendingSlot(platformId, out slot)) { ctx.Reply("Specify a slot number or pick one in GUI (.slotsort pickslot 12)."); return; } if (!Core.SlotAssignments.TrySetAssignment(platformId, item.Prefab, slot, out var error)) { ctx.Reply(error); return; } ctx.Reply($"{item.Prefab.PrefabName()} -> slot {slot}. Press Sort in inventory."); } [Command("setid", null, null, "Assign item by internal GUID hash (used by GUI).", null, false)] public static void SetSlotById(ChatCommandContext ctx, int itemGuid, int slot = -1) { //IL_0006: 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) ulong platformId = ctx.Event.User.PlatformId; if (slot < 1 && !Core.SlotAssignments.TryGetPendingSlot(platformId, out slot)) { ctx.Reply("Specify a slot number or pick one first (.slotsort pickslot 12)."); return; } if (!Core.SlotAssignments.TrySetByGuid(platformId, itemGuid, slot, out var error)) { ctx.Reply(error); return; } string prefabName = ECSExtensions.PrefabName(new PrefabGUID(itemGuid)); ctx.Reply($"{ItemSearchService.FormatDisplayName(prefabName)} -> slot {slot}."); } [Command("search", null, null, "Search items by name and show matches in chat and GUI.", null, false)] public static void SearchItems(ChatCommandContext ctx, string query) { //IL_0006: 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) ulong platformId = ctx.Event.User.PlatformId; List list = ItemSearchService.FindItems(query); if (list.Count == 0) { ctx.Reply("No items found matching \"" + query + "\"."); return; } Core.SlotAssignments.SetSearchResults(platformId, query, list); StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(44, 2, stringBuilder2); handler.AppendLiteral("Found "); handler.AppendFormatted(list.Count); handler.AppendLiteral(" item(s) for \""); handler.AppendFormatted(query); handler.AppendLiteral("\":"); stringBuilder3.AppendLine(ref handler); int num = 0; foreach (ItemSearchService.ItemMatch item in list) { if (num >= 10) { stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(37, 1, stringBuilder2); handler.AppendLiteral(" ...and "); handler.AppendFormatted(list.Count - 10); handler.AppendLiteral(" more in GUI (.slotsort gui)"); stringBuilder4.AppendLine(ref handler); break; } stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(23, 1, stringBuilder2); handler.AppendLiteral(" "); handler.AppendFormatted(ItemSearchService.FormatDisplayName(item.PrefabName)); handler.AppendLiteral(""); stringBuilder5.AppendLine(ref handler); num++; } ctx.Reply(stringBuilder.ToString().TrimEnd()); Core.Ui.Open(ctx.Event.User, platformId); } [Command("pickslot", null, null, "Remember a slot for the next .slotsort set command.", null, false)] public static void PickSlot(ChatCommandContext ctx, int slot) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (slot < 1) { ctx.Reply("Slot must be at least 1."); return; } Core.SlotAssignments.SetPendingSlot(ctx.Event.User.PlatformId, slot); ctx.Reply($"Selected slot {slot}. Now run: .slotsort set \"item name\""); } [Command("remove", "rm", null, "Remove a slot assignment for an item.", null, false)] public static void RemoveSlot(ChatCommandContext ctx, ItemPrefab item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) ulong platformId = ctx.Event.User.PlatformId; if (!Core.SlotAssignments.TryRemoveAssignment(platformId, item.Prefab, out var error)) { ctx.Reply(error); } else { ctx.Reply("Removed rule for " + item.Prefab.PrefabName() + "."); } } [Command("rmid", null, null, "Remove assignment by item GUID (used by GUI).", null, false)] public static void RemoveById(ChatCommandContext ctx, int itemGuid) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ulong platformId = ctx.Event.User.PlatformId; if (!Core.SlotAssignments.TryRemoveByGuid(platformId, itemGuid, out var error)) { ctx.Reply(error); } else { ctx.Reply("Rule removed."); } } [Command("list", "ls", null, "Show your active slot assignments.", null, false)] public static void ListSlots(ChatCommandContext ctx) { //IL_0006: 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) ulong platformId = ctx.Event.User.PlatformId; IReadOnlyList assignments = Core.SlotAssignments.GetAssignments(platformId); bool flag = Core.SlotAssignments.IsEnabled(platformId); if (assignments.Count == 0) { ctx.Reply("SlotSort is " + (flag ? "enabled" : "disabled") + ". No assignments configured."); return; } StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(10, 1, stringBuilder2); handler.AppendLiteral("SlotSort: "); handler.AppendFormatted(flag ? "enabled" : "disabled"); stringBuilder3.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(26, 2, stringBuilder2); handler.AppendLiteral("Slots 1-"); handler.AppendFormatted(8); handler.AppendLiteral(" = hotbar, "); handler.AppendFormatted(9); handler.AppendLiteral("+ = bag"); stringBuilder4.AppendLine(ref handler); stringBuilder.AppendLine("Assignments:"); foreach (SlotAssignmentEntry item in assignments) { string value = ((item.ItemGuid != 0) ? ECSExtensions.PrefabName(new PrefabGUID(item.ItemGuid)) : item.ItemName); stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(28, 2, stringBuilder2); handler.AppendLiteral(" "); handler.AppendFormatted(item.Slot); handler.AppendLiteral(" -> "); handler.AppendFormatted(value); stringBuilder5.AppendLine(ref handler); } ctx.Reply(stringBuilder.ToString().TrimEnd()); } [Command("toggle", null, null, "Enable or disable slot sorting for your character.", null, false)] public static void Toggle(ChatCommandContext ctx) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ulong platformId = ctx.Event.User.PlatformId; bool flag = Core.SlotAssignments.ToggleEnabled(platformId); ctx.Reply("SlotSort is " + (flag ? "enabled" : "disabled") + "."); } [Command("sort", null, null, "Apply slot assignments without pressing the sort button.", null, false)] public static void SortNow(ChatCommandContext ctx) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) ulong platformId = ctx.Event.User.PlatformId; if (!Core.SlotAssignments.IsEnabled(platformId)) { ctx.Reply("SlotSort is disabled. Use .slotsort toggle"); return; } Core.InventorySlots.ApplyAssignments(ctx.Event.SenderCharacterEntity, platformId); ctx.Reply("Slot assignments applied."); } } } namespace SlotSort.Commands.Converters { internal readonly record struct ItemPrefab(PrefabGUID Prefab); internal sealed class ItemPrefabConverter : CommandArgumentConverter { public override ItemPrefab Parse(ICommandContext ctx, string input) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (ItemSearchService.TryResolveExact(input, out var prefab)) { return new ItemPrefab(prefab); } List list = ItemSearchService.FindItems(input, 2); if (list.Count == 1) { return new ItemPrefab(list[0].Guid); } if (list.Count > 1) { throw ctx.Error("Multiple items match \"" + input + "\". Be more specific or use .slotsort search " + input); } throw ctx.Error("No item found matching \"" + input + "\"."); } } }