Decompiled source of AeroltItemLoadouts v1.0.0

ItemLoadouts.dll

Decompiled a day ago
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.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));
		}
	}
}