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 AeroltItemLoadouts v1.0.0
ItemLoadouts.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Aerolt.API; using Aerolt.Managers; using Aerolt.Messages; using Aerolt.UI; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using RoR2; using RoR2.ContentManagement; using UnityEngine; using UnityEngine.UI; using UniverseLib.UI; using UniverseLib.UI.Models; using UniverseLib.UI.Widgets; [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("ItemLoadouts")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+0ecb305ab623e51e147cc7e90f8437b981f65907")] [assembly: AssemblyProduct("ItemLoadouts")] [assembly: AssemblyTitle("ItemLoadouts")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace ItemLoadouts { public class LoadoutProfile { public string Name; public readonly Dictionary<string, int> Items = new Dictionary<string, int>(); public LoadoutProfile(string name) { Name = name; } } public class LoadoutsSection : IAeroltSection { private GameObject _listContent = null; private InputFieldRef _nameInput = null; public string Title => "Loadouts"; public GameObject Root { get; private set; } = null; public bool ScrollableContent => false; public void Build(GameObject contentParent) { //IL_000f: 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_0025: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) Root = UIFactory.CreateVerticalGroup(contentParent, "LoadoutsSection", false, false, true, true, 4, default(Vector4), new Color(0.14f, 0.14f, 0.14f), (TextAnchor?)null); GameObject root = Root; int? num = 9999; int? num2 = 9999; UIFactory.SetLayoutElement(root, (int?)null, (int?)null, num, num2, (int?)null, (int?)null, (bool?)null); GameObject val = UIFactory.CreateHorizontalGroup(Root, "AddRow", false, false, true, true, 4, default(Vector4), default(Color), (TextAnchor?)null); num2 = 30; num = 0; int? num3 = 9999; UIFactory.SetLayoutElement(val, (int?)null, num2, num3, num, (int?)null, (int?)null, (bool?)null); _nameInput = UIFactory.CreateInputField(val, "NameInput", "New profile name..."); GameObject gameObject = ((Component)_nameInput.Component).gameObject; num3 = 28; num = 9999; UIFactory.SetLayoutElement(gameObject, (int?)null, num3, num, (int?)null, (int?)null, (int?)null, (bool?)null); ButtonRef val2 = UIFactory.CreateButton(val, "Add", "Add Profile", (Color?)null); GameObject gameObject2 = ((Component)val2.Component).gameObject; num = 28; UIFactory.SetLayoutElement(gameObject2, (int?)110, num, (int?)0, (int?)null, (int?)null, (int?)null, (bool?)null); val2.OnClick = (Action)Delegate.Combine(val2.OnClick, new Action(AddProfile)); Text val3 = UIFactory.CreateLabel(Root, "Hint", "Add Profile copies the selected player's current items. Click a profile to clear the inventory and load it.", (TextAnchor)3, default(Color), true, 14); GameObject gameObject3 = ((Component)val3).gameObject; num = 20; num3 = 9999; UIFactory.SetLayoutElement(gameObject3, (int?)null, num, num3, (int?)null, (int?)null, (int?)null, (bool?)null); val3.fontSize = 12; AutoSliderScrollbar val4 = default(AutoSliderScrollbar); UIFactory.CreateScrollView(Root, "List", ref _listContent, ref val4, new Color(0.1f, 0.1f, 0.1f)); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(_listContent, (bool?)false, (bool?)false, (bool?)true, (bool?)true, (int?)2, (int?)2, (int?)2, (int?)2, (int?)2, (TextAnchor?)null); RebuildList(); } public void OnShown() { RebuildList(); } private void AddProfile() { Inventory val = SelectedInventory(); if (!Object.op_Implicit((Object)(object)val)) { Chat.AddMessage("<color=red>Item Loadouts: no player selected.</color>"); return; } Dictionary<string, int> dictionary = new Dictionary<string, int>(); ItemDef[] itemDefs = ContentManager.itemDefs; foreach (ItemDef val2 in itemDefs) { if (Object.op_Implicit((Object)(object)val2)) { int itemCountEffective = val.GetItemCountEffective(val2); if (itemCountEffective > 0) { dictionary[((Object)val2).name] = itemCountEffective; } } } string text = (string.IsNullOrWhiteSpace(_nameInput.Text) ? $"Loadout {Plugin.Store.Profiles.Count + 1}" : _nameInput.Text.Trim()); Plugin.Store.Add(text, dictionary); _nameInput.Text = ""; RebuildList(); Chat.AddMessage($"<color=cyan>Saved loadout '{text}' ({dictionary.Count} items).</color>"); } private static void LoadProfile(LoadoutProfile profile) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) Inventory val = SelectedInventory(); if (!Object.op_Implicit((Object)(object)val)) { Chat.AddMessage("<color=red>Item Loadouts: no player selected.</color>"); return; } Dictionary<ItemDef, int> dictionary = new Dictionary<ItemDef, int>(); ItemDef[] itemDefs = ContentManager.itemDefs; foreach (ItemDef val2 in itemDefs) { if (Object.op_Implicit((Object)(object)val2)) { dictionary[val2] = (profile.Items.TryGetValue(((Object)val2).name, out var value) ? value : 0); } } ((AeroltMessageBase)new SetItemCountMessage(val, dictionary)).SendToServer(); Chat.AddMessage("<color=cyan>Loaded loadout '" + profile.Name + "'.</color>"); } private void RebuildList() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_listContent == (Object)null) { return; } foreach (Transform item in _listContent.transform) { Transform val = item; Object.Destroy((Object)(object)((Component)val).gameObject); } if (Plugin.Store.Profiles.Count == 0) { Text val2 = UIFactory.CreateLabel(_listContent, "Empty", "No loadouts yet. Grab some items, then click Add Profile.", (TextAnchor)3, default(Color), true, 14); GameObject gameObject = ((Component)val2).gameObject; int? num = 26; int? num2 = 9999; UIFactory.SetLayoutElement(gameObject, (int?)null, num, num2, (int?)null, (int?)null, (int?)null, (bool?)null); return; } foreach (LoadoutProfile item2 in Plugin.Store.Profiles.ToList()) { CreateRow(item2); } } private void CreateRow(LoadoutProfile profile) { //IL_0039: 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) GameObject val = UIFactory.CreateHorizontalGroup(_listContent, "Row", false, false, true, true, 4, new Vector4(2f, 2f, 2f, 2f), new Color(0.13f, 0.13f, 0.13f), (TextAnchor?)null); int? num = 30; int? num2 = 9999; UIFactory.SetLayoutElement(val, (int?)null, num, num2, (int?)null, (int?)null, (int?)null, (bool?)null); ButtonRef val2 = UIFactory.CreateButton(val, "Load", $"{profile.Name} ({profile.Items.Count} items)", (Color?)null); GameObject gameObject = ((Component)val2.Component).gameObject; num2 = 26; num = 9999; UIFactory.SetLayoutElement(gameObject, (int?)null, num2, num, (int?)null, (int?)null, (int?)null, (bool?)null); val2.OnClick = (Action)Delegate.Combine(val2.OnClick, (Action)delegate { LoadProfile(profile); }); ButtonRef val3 = UIFactory.CreateButton(val, "Delete", "X", (Color?)null); GameObject gameObject2 = ((Component)val3.Component).gameObject; num = 26; UIFactory.SetLayoutElement(gameObject2, (int?)30, num, (int?)0, (int?)null, (int?)null, (int?)null, (bool?)null); val3.OnClick = (Action)Delegate.Combine(val3.OnClick, (Action)delegate { Plugin.Store.Remove(profile); RebuildList(); }); } private static Inventory? SelectedInventory() { NetworkUser selectedPlayer = AeroltAPI.SelectedPlayer; if (!Object.op_Implicit((Object)(object)selectedPlayer) || !Object.op_Implicit((Object)(object)selectedPlayer.master)) { return null; } return Object.op_Implicit((Object)(object)selectedPlayer.master.inventory) ? selectedPlayer.master.inventory : null; } } public class LoadoutStore { private readonly string _path; public readonly List<LoadoutProfile> Profiles = new List<LoadoutProfile>(); public LoadoutStore(string path) { _path = path; Load(); } public LoadoutProfile Add(string name, Dictionary<string, int> items) { LoadoutProfile loadoutProfile = new LoadoutProfile(name); foreach (KeyValuePair<string, int> item in items) { if (item.Value > 0) { loadoutProfile.Items[item.Key] = item.Value; } } Profiles.Add(loadoutProfile); Save(); return loadoutProfile; } public void Remove(LoadoutProfile profile) { if (Profiles.Remove(profile)) { Save(); } } public void Rename(LoadoutProfile profile, string name) { profile.Name = name; Save(); } public void Save() { try { string directoryName = Path.GetDirectoryName(_path); if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } IEnumerable<string> source = Profiles.Select(delegate(LoadoutProfile p) { string text = string.Join(",", p.Items.Select<KeyValuePair<string, int>, string>((KeyValuePair<string, int> i) => $"{i.Key}:{i.Value}")); return Sanitize(p.Name) + "|" + text; }); File.WriteAllLines(_path, source.ToArray()); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to save loadouts: {arg}"); } } private void Load() { Profiles.Clear(); if (!File.Exists(_path)) { return; } try { string[] array = File.ReadAllLines(_path); foreach (string text in array) { if (string.IsNullOrWhiteSpace(text)) { continue; } int num = text.IndexOf('|'); if (num < 0) { continue; } string name = text.Substring(0, num); string text2 = text.Substring(num + 1); LoadoutProfile loadoutProfile = new LoadoutProfile(name); if (!string.IsNullOrEmpty(text2)) { string[] array2 = text2.Split(','); foreach (string text3 in array2) { int num2 = text3.LastIndexOf(':'); if (num2 >= 0) { string key = text3.Substring(0, num2); if (int.TryParse(text3.Substring(num2 + 1), out var result) && result > 0) { loadoutProfile.Items[key] = result; } } } } Profiles.Add(loadoutProfile); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to load loadouts: {arg}"); } } private static string Sanitize(string name) { return (name ?? "Profile").Replace('|', ' '); } } [BepInPlugin("com.Lodington.ItemLoadouts", "Aerolt - Item Loadouts", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Name = "Aerolt - Item Loadouts"; public const string Guid = "com.Lodington.ItemLoadouts"; public const string Version = "1.0.0"; public static ManualLogSource Log; public static LoadoutStore Store; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; string path = Path.Combine(Paths.ConfigPath, "Aerolt", "ItemLoadouts.txt"); Store = new LoadoutStore(path); AeroltAPI.RegisterSection((IAeroltSection)(object)new LoadoutsSection()); Log.LogInfo((object)string.Format("{0} {1} loaded ({2} saved loadouts).", "Aerolt - Item Loadouts", "1.0.0", Store.Profiles.Count)); } } }