Decompiled source of ContactSorter v1.2.1

plugins/ContactSorter/ContactSorter.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using BepisLocaleLoader;
using Elements.Core;
using FrooxEngine;
using FrooxEngine.UIX;
using HarmonyLib;
using SkyFrost.Base;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")]
[assembly: AssemblyCompany("LeCloutPanda")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+519669ef814223f6096d1c556b82e9fb70733915")]
[assembly: AssemblyProduct("ContactSorter")]
[assembly: AssemblyTitle("ContactSorter")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/lecloutpanda/ContactSorter")]
[assembly: AssemblyVersion("1.2.1.0")]
[module: RefSafetyRules(11)]
namespace ContactSorter;

[ResonitePlugin("dev.lecloutpanda.contactsorter", "ContactSorter", "1.2.1", "LeCloutPanda", "https://github.com/lecloutpanda/ContactSorter")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
	[HarmonyPatch(typeof(ContactsDialog))]
	private static class ContactsDialogPatches
	{
		[HarmonyPatch("OnCommonUpdate")]
		[HarmonyPrefix]
		private static void Prefix(ContactsDialog __instance, SyncRef<TextField> ____searchBar, ref bool ___sortList, out bool __state)
		{
			__state = ___sortList;
			if (ENABLED.Value && Utility.IsNullOrWhiteSpace(____searchBar.Target.TargetString))
			{
				___sortList = false;
			}
		}

		[HarmonyPatch("OnCommonUpdate")]
		[HarmonyPostfix]
		private static void Postfix(ContactsDialog __instance, SyncRef<Slot> ____listRoot, SyncRef<TextField> ____searchBar, ref bool ___sortList, bool __state)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ContactsDialog __instance2 = __instance;
			SyncRef<Slot> ____listRoot2 = ____listRoot;
			if (!ENABLED.Value || !__state || !WorldExtensions.IsUserspace(((Worker)__instance2).World) || !Utility.IsNullOrWhiteSpace(____searchBar.Target.TargetString))
			{
				return;
			}
			try
			{
				((Component)__instance2).Slot.RunInUpdates(3, (Action)delegate
				{
					TriggerSort(__instance2, ((SyncElement)____listRoot2).Slot);
				});
			}
			catch
			{
				___sortList = true;
			}
		}

		private static void TriggerSort(ContactsDialog instance, Slot listRoot)
		{
			List<ContactItem> val = SortContacts(listRoot.GetComponentsInChildren<ContactItem>((Predicate<ContactItem>)null, false, false, (Predicate<Slot>)null));
			for (int i = 0; i < val.Count; i++)
			{
				((Component)val[i]).Slot.OrderOffset = (long)i * 100L;
			}
		}

		[HarmonyPatch("UpdateSelectedContactUI")]
		[HarmonyPostfix]
		private static void PinUserAdder(ContactsDialog __instance, UIBuilder ___actionsUi)
		{
			//IL_00b0: 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)
			//IL_00b5: 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)
			//IL_00ce: Expected O, but got Unknown
			ContactsDialog __instance2 = __instance;
			if (!ADD_PIN_BUTTON.Value || !WorldExtensions.IsUserspace(((Worker)__instance2).World) || __instance2.SelectedContact == null || __instance2.SelectedContactId == ((SkyFrostInterface)((Worker)__instance2).Cloud).Platform.AppUserId || __instance2.SelectedContact.IsSelfContact || !__instance2.SelectedContact.IsValid)
			{
				return;
			}
			LocaleString val = (IsPinned(__instance2.SelectedContact) ? LocaleLoader.T("Settings.dev.lecloudpands.contactsorter.Unpin", (string)null, true, (Dictionary<string, object>)null) : LocaleLoader.T("Settings.dev.lecloudpands.contactsorter.Pin", (string)null, true, (Dictionary<string, object>)null));
			___actionsUi.Button(ref val).LocalPressed += (ButtonEventHandler)delegate(IButton btn, ButtonEventData _)
			{
				StringList value = PINNED_CONTACTS.Value;
				bool flag = IsPinned(__instance2.SelectedContact);
				if (!flag)
				{
					((List<string>)(object)value).Add(__instance2.SelectedContactId);
				}
				else
				{
					((List<string>)(object)value).Remove(__instance2.SelectedContactId);
				}
				LocaleHelper.SetLocalized(btn.LabelTextField, (!flag) ? "Settings.dev.lecloudpands.contactsorter.Unpin" : "Settings.dev.lecloudpands.contactsorter.Pin", (string)null, (Dictionary<string, object>)null);
				PINNED_CONTACTS.Value = value;
			};
		}
	}

	public class StringList : List<string>
	{
		public StringList()
		{
		}

		public StringList(global::System.Collections.Generic.IEnumerable<string> items)
			: base(items)
		{
		}

		public override string ToString()
		{
			return string.Join(", ", Enumerable.Select<string, string>((global::System.Collections.Generic.IEnumerable<string>)this, (Func<string, string>)((string s) => s.Trim())));
		}

		public static StringList Parse(string str)
		{
			return new StringList(Enumerable.Select<string, string>((global::System.Collections.Generic.IEnumerable<string>)str.Split(',', (StringSplitOptions)1), (Func<string, string>)((string s) => s.Trim())));
		}
	}

	internal static ManualLogSource? Log;

	private static ConfigEntry<bool> ENABLED;

	private static ConfigEntry<bool> ALPHABETICAL_SORT;

	private static ConfigEntry<bool> SHOW_OFFLINE_CONTACTS;

	private static ConfigEntry<bool> ADD_PIN_BUTTON;

	private static ConfigEntry<int> MESSAGED_PRIORITY;

	private static ConfigEntry<int> PINNED_PRIORITY;

	private static ConfigEntry<int> RESONITE_PRIORITY;

	private static ConfigEntry<int> SELF_PRIORITY;

	private static ConfigEntry<int> SOCIABLE_PRIORITY;

	private static ConfigEntry<int> ONLINE_PRIORITY;

	private static ConfigEntry<int> BUSY_PRIORITY;

	private static ConfigEntry<int> AWAY_PRIORITY;

	private static ConfigEntry<int> OFFLINE_PRIORITY;

	private static ConfigEntry<int> HEADLESS_PRIORITY;

	private static ConfigEntry<int> CONTACT_REQUEST_ORDER;

	private static ConfigEntry<StringList> PINNED_CONTACTS;

	public override void Load()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_009e: 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)
		//IL_00b3: Expected O, but got Unknown
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected O, but got Unknown
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Expected O, but got Unknown
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Expected O, but got Unknown
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Expected O, but got Unknown
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Expected O, but got Unknown
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Expected O, but got Unknown
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Expected O, but got Unknown
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Expected O, but got Unknown
		//IL_0308: 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)
		//IL_031d: Expected O, but got Unknown
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: Expected O, but got Unknown
		//IL_0390: Unknown result type (might be due to invalid IL or missing references)
		//IL_039b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a5: Expected O, but got Unknown
		//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03df: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Expected O, but got Unknown
		//IL_0418: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_042d: Expected O, but got Unknown
		//IL_045b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0466: Unknown result type (might be due to invalid IL or missing references)
		//IL_0470: Expected O, but got Unknown
		//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b7: Expected O, but got Unknown
		Log = ((BasePlugin)this).Log;
		TomlTypeConverter.AddConverter(typeof(StringList), new TypeConverter
		{
			ConvertToObject = (string str, global::System.Type _) => StringList.Parse(str),
			ConvertToString = (object obj, global::System.Type _) => ((object)(StringList)obj).ToString()
		});
		((BasePlugin)this).HarmonyInstance.PatchAll();
		ENABLED = ((BasePlugin)this).Config.Bind<bool>("Toggles", "Enabled", true, new ConfigDescription("Enable the mod.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Toggles.Enabled", "Settings.dev.lecloutpanda.contactsorter.Toggles.Enabled.Description") }));
		ALPHABETICAL_SORT = ((BasePlugin)this).Config.Bind<bool>("Toggles", "Alphabetical Sort", true, new ConfigDescription("Alphabetically sort users between groupings.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Toggles.AlphabeticalSort", "Settings.dev.lecloutpanda.contactsorter.Toggles.AlphabeticalSort.Description") }));
		SHOW_OFFLINE_CONTACTS = ((BasePlugin)this).Config.Bind<bool>("Toggles", "Show offline users", true, new ConfigDescription("Show offline contacts in list.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Toggles.ShowOfflineContacts", "Settings.dev.lecloutpanda.contactsorter.Toggles.ShowOfflineContacts.Description") }));
		ADD_PIN_BUTTON = ((BasePlugin)this).Config.Bind<bool>("Toggles", "Add Pin Button", true, new ConfigDescription("Adds a pin button to the contact.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Toggles.AddPinButton", "Settings.dev.lecloutpanda.contactsorter.Toggles.AddPinButton.Description") }));
		MESSAGED_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "MESSAGED_PRIORITY", 1337, new ConfigDescription("Contact with a message priority (Default is 1337).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.MessagedPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.MessagedPriority.Description") }));
		PINNED_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "PINNED_PRIORITY", 720, new ConfigDescription("Pinned contact priority (Default is 720)\nDisabled at -1.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.PinnedPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.PinnedPriority.Description") }));
		RESONITE_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "RESONITE_PRIORITY", 420, new ConfigDescription("Resonite Account priority (Default is 420)\nDisabled at -1.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.ResonitePriority", "Settings.dev.lecloutpanda.contactsorter.Orders.ResonitePriority.Description") }));
		SELF_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "SELF_PRIORITY", 69, new ConfigDescription("Self priority (Default is 69)\nDisabled at -1.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.SelfPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.SelfPriority.Description") }));
		SOCIABLE_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "SOCIABLE_PRIORITY", 60, new ConfigDescription("Sociable priority (Default is 10).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.SociablePriority", "Settings.dev.lecloutpanda.contactsorter.Orders.SociablePriority.Description") }));
		ONLINE_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "ONLINE_PRIORITY", 50, new ConfigDescription("Online priority (Default is 50).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.OnlinePriority", "Settings.dev.lecloutpanda.contactsorter.Orders.OnlinePriority.Description") }));
		BUSY_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "BUSY_PRIORITY", 40, new ConfigDescription("Busy priority (Default is 40).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.BusyPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.BusyPriority.Description") }));
		AWAY_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "AWAY_PRIORITY", 30, new ConfigDescription("Away priority (Default is 30).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.AwayPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.AwayPriority.Description") }));
		HEADLESS_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "HEADLESS_PRIORITY", 20, new ConfigDescription("Headless priority (Default is 20).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.HeadlessPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.HeadlessPriority.Description") }));
		CONTACT_REQUEST_ORDER = ((BasePlugin)this).Config.Bind<int>("Orders", "CONTACT_REQUEST_ORDER", 10, new ConfigDescription("Contact request priority (Default is 10)\nDisabled at -1.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.ContactRequestPriority", "Settings.dev.lecloutpanda.contactsorter.Orders.ContactRequestPriority.Description") }));
		OFFLINE_PRIORITY = ((BasePlugin)this).Config.Bind<int>("Orders", "OFFLINE_PRIORITY", 0, new ConfigDescription("Offline priority (Default is 0).", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Orders.OfflinePriority", "Settings.dev.lecloutpanda.contactsorter.Orders.OfflinePriority.Description") }));
		PINNED_CONTACTS = ((BasePlugin)this).Config.Bind<StringList>("Misc", "Pinned Contacts", new StringList(), new ConfigDescription("',' separated list of U-UserIds or Usernames that you want pinned based on PINNED_PRIORITY.", (AcceptableValueBase)null, new object[1] { (object)new ConfigLocale("Settings.dev.lecloutpanda.contactsorter.Misc.PinnedContacts", "Settings.dev.lecloutpanda.contactsorter.Misc.PinnedContacts.Description") }));
	}

	private static bool IsPinned(Contact contact)
	{
		if (!((List<string>)(object)PINNED_CONTACTS.Value).Contains(contact.ContactUserId))
		{
			return ((List<string>)(object)PINNED_CONTACTS.Value).Contains(contact.ContactUsername);
		}
		return true;
	}

	public static List<ContactItem> SortContacts(List<ContactItem> contacts)
	{
		if (ALPHABETICAL_SORT.Value)
		{
			return Enumerable.ToList<ContactItem>((global::System.Collections.Generic.IEnumerable<ContactItem>)Enumerable.ThenBy<ContactItem, string>(Enumerable.OrderByDescending<ContactItem, int>((global::System.Collections.Generic.IEnumerable<ContactItem>)contacts, (Func<ContactItem, int>)((ContactItem c) => GetPriority(c))), (Func<ContactItem, string>)((ContactItem c) => c.Username)));
		}
		return Enumerable.ToList<ContactItem>((global::System.Collections.Generic.IEnumerable<ContactItem>)Enumerable.OrderByDescending<ContactItem, int>((global::System.Collections.Generic.IEnumerable<ContactItem>)contacts, (Func<ContactItem, int>)((ContactItem c) => GetPriority(c))));
	}

	private static int GetPriority(ContactItem c)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: 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_003f: 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_00aa: Invalid comparison between Unknown and I4
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Expected I4, but got Unknown
		try
		{
			UserStatus currentStatus = c.Data.CurrentStatus;
			OnlineStatus valueOrDefault = ((currentStatus != null) ? currentStatus.OnlineStatus : null).GetValueOrDefault();
			UserStatus currentStatus2 = c.Data.CurrentStatus;
			UserSessionType val = (UserSessionType)((currentStatus2 != null) ? ((int)currentStatus2.SessionType) : 0);
			if (c.HasMessages)
			{
				return MESSAGED_PRIORITY.Value;
			}
			if (PINNED_PRIORITY.Value != -1 && (((List<string>)(object)PINNED_CONTACTS.Value).Contains(c.Data.UserId) || ((List<string>)(object)PINNED_CONTACTS.Value).Contains(c.Username)))
			{
				return PINNED_PRIORITY.Value;
			}
			if ((int)val == 3)
			{
				return HEADLESS_PRIORITY.Value;
			}
			if (RESONITE_PRIORITY.Value != -1 && c.Data.Contact.ContactUserId == "U-Resonite")
			{
				return RESONITE_PRIORITY.Value;
			}
			if (SELF_PRIORITY.Value != -1 && c.Data.Contact.IsSelfContact)
			{
				return SELF_PRIORITY.Value;
			}
			if (CONTACT_REQUEST_ORDER.Value != -1 && c.Data.Contact.IsContactRequest)
			{
				return CONTACT_REQUEST_ORDER.Value;
			}
			return (int)valueOrDefault switch
			{
				5 => SOCIABLE_PRIORITY.Value, 
				4 => ONLINE_PRIORITY.Value, 
				3 => BUSY_PRIORITY.Value, 
				2 => AWAY_PRIORITY.Value, 
				1 => OFFLINE_PRIORITY.Value, 
				0 => OFFLINE_PRIORITY.Value, 
				_ => 0, 
			};
		}
		catch
		{
			return 0;
		}
	}
}
public static class PluginMetadata
{
	public const string GUID = "dev.lecloutpanda.contactsorter";

	public const string NAME = "ContactSorter";

	public const string VERSION = "1.2.1";

	public const string AUTHORS = "LeCloutPanda";

	public const string REPOSITORY_URL = "https://github.com/lecloutpanda/ContactSorter";
}