Decompiled source of PartialItemDisplay v1.3.0

plugins/PartialItemDisplay/PartialItemDisplay.dll

Decompiled 2 months 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 System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using InLobbyConfig;
using InLobbyConfig.Fields;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour.HookGen;
using RoR2;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
namespace PartialItemDisplay;

public enum ListType
{
	Blacklist,
	Whitelist
}
public static class InLobbyConfigIntegration
{
	public const string GUID = "com.KingEnderBrine.InLobbyConfig";

	private static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.InLobbyConfig");

	private static object ModConfig { get; set; }

	public static void OnStart()
	{
		if (Enabled)
		{
			OnStartInternal();
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void OnStartInternal()
	{
		//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_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		ModConfigEntry val = new ModConfigEntry
		{
			DisplayName = "Partial Item Display",
			EnableField = (BooleanConfigField)/*isinst with value type is only supported in some contexts*/
		};
		PartialItemDisplayPlugin.DefaultSection.ApplyToInLobbyConfig(val);
		foreach (ItemDisplayConfigSection value in PartialItemDisplayPlugin.CharacterSections.Values)
		{
			value.ApplyToInLobbyConfig(val);
		}
		ModConfigCatalog.Add(val);
		ModConfig = val;
	}

	public static void OnDestroy()
	{
		if (Enabled)
		{
			OnDestroyInternal();
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void OnDestroyInternal()
	{
		object modConfig = ModConfig;
		ModConfigCatalog.Remove((ModConfigEntry)((modConfig is ModConfigEntry) ? modConfig : null));
	}
}
public class ItemDisplayConfigSection
{
	public string SectionName { get; private set; }

	public ConfigEntry<bool> SectionEnabled { get; private set; }

	public ConfigEntry<ListType> ItemListType { get; private set; }

	public ConfigEntry<string> ItemList { get; private set; }

	public ConfigEntry<ListType> EquipmentListType { get; private set; }

	public ConfigEntry<string> EquipmentList { get; private set; }

	public List<string> Items { get; } = new List<string>();


	public List<string> Equipments { get; } = new List<string>();


	public ItemDisplayConfigSection(ConfigFile file, string sectionName, bool isEnabledByDefault = false)
	{
		SectionName = RemoveInvalidCharacters(sectionName);
		SectionEnabled = file.Bind<bool>(SectionName, "SectionEnabled", isEnabledByDefault, "Should rules in this section be applied");
		ItemListType = file.Bind<ListType>(SectionName, "ItemListType", ListType.Blacklist, "Blacklist - show everything except selected items. Whitelist - show only selected items");
		EquipmentListType = file.Bind<ListType>(SectionName, "EquipmentListType", ListType.Blacklist, "Blacklist - show everything except selected items. Whitelist - show only selected items");
		ItemList = file.Bind<string>(SectionName, "ItemList", "", "Selected items for this section");
		EquipmentList = file.Bind<string>(SectionName, "EquipmentList", "", "Selected equipment for this section");
		try
		{
			Items.Clear();
			Items.AddRange((from el in ItemList.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select el.Trim()).Distinct());
		}
		catch (Exception ex)
		{
			PartialItemDisplayPlugin.InstanceLogger.LogWarning((object)"Failed to parse `ItemList` config");
			PartialItemDisplayPlugin.InstanceLogger.LogError((object)ex);
		}
		try
		{
			Equipments.Clear();
			Equipments.AddRange((from el in EquipmentList.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select el.Trim()).Distinct());
		}
		catch (Exception ex2)
		{
			PartialItemDisplayPlugin.InstanceLogger.LogWarning((object)"Failed to parse `EquipmentList` config");
			PartialItemDisplayPlugin.InstanceLogger.LogError((object)ex2);
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	public void ApplyToInLobbyConfig(ModConfigEntry configEntry)
	{
		List<IConfigField> value = new List<IConfigField>
		{
			ConfigFieldUtilities.CreateFromBepInExConfigEntry<ListType>(ItemListType),
			(IConfigField)(object)new SelectListField<string>(((ConfigEntryBase)ItemList).Definition.Key, ((ConfigEntryBase)ItemList).Description.Description, (Func<ICollection<string>>)GetItemList, (Action<string, int>)ItemListItemAdded, (Action<int>)ItemListItemRemoved, (Func<IDictionary<string, string>>)GetItemOptions),
			ConfigFieldUtilities.CreateFromBepInExConfigEntry<ListType>(EquipmentListType),
			(IConfigField)(object)new SelectListField<string>(((ConfigEntryBase)EquipmentList).Definition.Key, ((ConfigEntryBase)EquipmentList).Description.Description, (Func<ICollection<string>>)GetEquipmentList, (Action<string, int>)EquipmentListItemAdded, (Action<int>)EquipmentListItemRemoved, (Func<IDictionary<string, string>>)GetEquipmentOptions)
		};
		configEntry.SectionFields[SectionName] = value;
		Dictionary<string, BooleanConfigField> sectionEnableFields = configEntry.SectionEnableFields;
		string sectionName = SectionName;
		IConfigField obj = ConfigFieldUtilities.CreateFromBepInExConfigEntry<bool>(SectionEnabled);
		sectionEnableFields[sectionName] = (BooleanConfigField)(object)((obj is BooleanConfigField) ? obj : null);
	}

	private List<string> GetItemList()
	{
		return Items;
	}

	private void ItemListItemAdded(string value, int index)
	{
		Items.Insert(index, value);
		ItemList.Value = string.Join(", ", Items);
	}

	private void ItemListItemRemoved(int index)
	{
		Items.RemoveAt(index);
		ItemList.Value = string.Join(", ", Items);
	}

	private Dictionary<string, string> GetItemOptions()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		return ((IEnumerable<ItemDef>)(object)ItemCatalog.allItemDefs).Where(delegate(ItemDef el)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (el.hidden)
			{
				return false;
			}
			ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(el.tier);
			return Object.op_Implicit((Object)(object)itemTierDef) && itemTierDef.isDroppable;
		}).ToDictionary((ItemDef el) => ((Object)el).name, (ItemDef el) => Language.GetString(el.nameToken));
	}

	private List<string> GetEquipmentList()
	{
		return Equipments;
	}

	private void EquipmentListItemAdded(string value, int index)
	{
		Equipments.Insert(index, value);
		EquipmentList.Value = string.Join(", ", Equipments);
	}

	private void EquipmentListItemRemoved(int index)
	{
		Equipments.RemoveAt(index);
		EquipmentList.Value = string.Join(", ", Equipments);
	}

	private Dictionary<string, string> GetEquipmentOptions()
	{
		return EquipmentCatalog.equipmentDefs.Where((EquipmentDef el) => el.canDrop || el.isBoss || el.dropOnDeathChance > 0f).ToDictionary((EquipmentDef el) => ((Object)el).name, delegate(EquipmentDef el)
		{
			string @string = Language.GetString(el.nameToken);
			return string.IsNullOrWhiteSpace(@string) ? ((Object)el).name : @string;
		});
	}

	private string RemoveInvalidCharacters(string sectionName)
	{
		return Regex.Replace(sectionName, "[=\\n\\t\"'\\\\[\\]]", "").Trim();
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.KingEnderBrine.PartialItemDisplay", "Partial Item Display", "1.3.0")]
public class PartialItemDisplayPlugin : BaseUnityPlugin
{
	public const string GUID = "com.KingEnderBrine.PartialItemDisplay";

	public const string Name = "Partial Item Display";

	public const string Version = "1.3.0";

	internal static PartialItemDisplayPlugin Instance { get; private set; }

	internal static ManualLogSource InstanceLogger
	{
		get
		{
			PartialItemDisplayPlugin instance = Instance;
			if (instance == null)
			{
				return null;
			}
			return ((BaseUnityPlugin)instance).Logger;
		}
	}

	internal static ConfigEntry<bool> Enabled { get; set; }

	internal static ItemDisplayConfigSection DefaultSection { get; set; }

	internal static Dictionary<BodyIndex, ItemDisplayConfigSection> CharacterSections { get; set; }

	private void Start()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		Instance = this;
		HookEndpointManager.Modify((MethodBase)typeof(CharacterModel).GetMethod("UpdateItemDisplay"), (Delegate)new Manipulator(UpdateItemDisplayIL));
		HookEndpointManager.Modify((MethodBase)typeof(CharacterModel).GetMethod("SetEquipmentDisplay", BindingFlags.Instance | BindingFlags.NonPublic), (Delegate)new Manipulator(SetEquipmentDisplayIL));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnLoad));
	}

	private void OnLoad()
	{
		SetupConfig();
	}

	private void Destroy()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		Instance = null;
		HookEndpointManager.Unmodify((MethodBase)typeof(CharacterModel).GetMethod("UpdateItemDisplay"), (Delegate)new Manipulator(UpdateItemDisplayIL));
		HookEndpointManager.Unmodify((MethodBase)typeof(CharacterModel).GetMethod("SetEquipmentDisplay", BindingFlags.Instance | BindingFlags.NonPublic), (Delegate)new Manipulator(SetEquipmentDisplayIL));
		InLobbyConfigIntegration.OnDestroy();
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(OnLoad));
	}

	private static void UpdateItemDisplayIL(ILContext il)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		ILLabel elseLabel = null;
		MethodReference val2 = default(MethodReference);
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[5]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1),
			(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, ref val2),
			(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0),
			(Instruction x) => ILPatternMatchingExt.MatchBle(x, ref elseLabel)
		});
		val.Emit(OpCodes.Ldloc_0);
		val.Emit(OpCodes.Ldarg_0);
		val.Emit(OpCodes.Ldfld, typeof(CharacterModel).GetField("body"));
		val.Emit(OpCodes.Call, (MethodBase)typeof(PartialItemDisplayPlugin).GetMethod("IgnoreItemDisplay", BindingFlags.Static | BindingFlags.NonPublic));
		val.Emit(OpCodes.Brtrue, (object)elseLabel);
	}

	private static void SetEquipmentDisplayIL(ILContext il)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		ILLabel retLabel = null;
		int num = default(int);
		FieldReference val3 = default(FieldReference);
		MethodReference val2 = default(MethodReference);
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[4]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
			(Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val3),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, ref val2),
			(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref retLabel)
		});
		val.Emit(OpCodes.Ldarg_1);
		val.Emit(OpCodes.Ldarg_0);
		val.Emit(OpCodes.Ldfld, typeof(CharacterModel).GetField("body"));
		val.Emit(OpCodes.Call, (MethodBase)typeof(PartialItemDisplayPlugin).GetMethod("IgnoreEquipmentDisplay", BindingFlags.Static | BindingFlags.NonPublic));
		val.Emit(OpCodes.Brtrue, (object)retLabel);
	}

	private static bool IgnoreEquipmentDisplay(EquipmentIndex index, CharacterBody body)
	{
		//IL_001c: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		if (!Enabled.Value || !Object.op_Implicit((Object)(object)body))
		{
			return false;
		}
		CharacterSections.TryGetValue(body.bodyIndex, out var value);
		if (value != null && value.SectionEnabled.Value)
		{
			return ProcessEquipmentDisplay(index, value);
		}
		if (DefaultSection.SectionEnabled.Value)
		{
			return ProcessEquipmentDisplay(index, DefaultSection);
		}
		return false;
	}

	private static bool IgnoreItemDisplay(ItemIndex itemIndex, CharacterBody body)
	{
		//IL_001c: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		if (!Enabled.Value || !Object.op_Implicit((Object)(object)body))
		{
			return false;
		}
		CharacterSections.TryGetValue(body.bodyIndex, out var value);
		if (value != null && value.SectionEnabled.Value)
		{
			return ProcessItemDisplay(itemIndex, value);
		}
		if (DefaultSection.SectionEnabled.Value)
		{
			return ProcessItemDisplay(itemIndex, DefaultSection);
		}
		return false;
	}

	private static bool ProcessEquipmentDisplay(EquipmentIndex index, ItemDisplayConfigSection section)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(index);
		if (!Object.op_Implicit((Object)(object)equipmentDef))
		{
			return false;
		}
		return section.EquipmentListType.Value switch
		{
			ListType.Blacklist => section.Equipments.Contains(((Object)equipmentDef).name), 
			ListType.Whitelist => !section.Equipments.Contains(((Object)equipmentDef).name), 
			_ => false, 
		};
	}

	private static bool ProcessItemDisplay(ItemIndex index, ItemDisplayConfigSection section)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		ItemDef itemDef = ItemCatalog.GetItemDef(index);
		if (!Object.op_Implicit((Object)(object)itemDef))
		{
			return false;
		}
		return section.ItemListType.Value switch
		{
			ListType.Blacklist => section.Items.Contains(((Object)itemDef).name), 
			ListType.Whitelist => !section.Items.Contains(((Object)itemDef).name), 
			_ => false, 
		};
	}

	private void SetupConfig()
	{
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Main", "Enabled", true, "Is this mod enabled");
		DefaultSection = new ItemDisplayConfigSection(((BaseUnityPlugin)this).Config, "Default", isEnabledByDefault: true);
		CharacterSections = SurvivorCatalog.allSurvivorDefs.ToDictionary((SurvivorDef def) => SurvivorCatalog.GetBodyIndexFromSurvivorIndex(def.survivorIndex), (SurvivorDef def) => new ItemDisplayConfigSection(((BaseUnityPlugin)this).Config, Language.english.GetLocalizedStringByToken(def.displayNameToken)));
		InLobbyConfigIntegration.OnStart();
	}
}