Decompiled source of Provenance v1.0.0

plugins/Provenance.dll

Decompiled 18 hours ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG;
using HarmonyLib;
using RoR2;
using RoR2.ContentManagement;
using RoR2.ExpansionManagement;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace FluxSquido.Provenance;

[BepInPlugin("FluxSquido.Provenance", "Provenance", "1.0.0")]
public class ProvenancePlugin : BaseUnityPlugin
{
	public const string GUID = "FluxSquido.Provenance";

	public const string NAME = "Provenance";

	public const string VERSION = "1.0.0";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> CfgEnabled;

	internal static ConfigEntry<bool> CfgShowVanilla;

	internal static ConfigEntry<string> CfgColorHex;

	internal static ConfigFile Cfg;

	internal static readonly Dictionary<string, string> TokenToSource = new Dictionary<string, string>();

	internal static readonly Dictionary<string, ConfigEntry<string>> SourceColor = new Dictionary<string, ConfigEntry<string>>();

	internal static readonly Dictionary<string, ConfigEntry<string>> SourceDisplay = new Dictionary<string, ConfigEntry<string>>();

	private static readonly Dictionary<string, string> BakedColors = new Dictionary<string, string>
	{
		["StandaloneAncientScepter"] = "902a7a",
		["Sandswept"] = "a6d7d6",
		["vanillaVoid"] = "e15d9a",
		["EXPEDITION"] = "cee7fc",
		["com.Viliger.EnemiesReturns.ContentProvider"] = "f8ffb2",
		["Dante"] = "9e292f",
		["Hunk"] = "7c0e0e",
		["Starstorm 2"] = "e05d58",
		["viliger.ReliableAncientScepterPlugin.ContentPack"] = "902a7a",
		["Survivors of the Void"] = "e15d9a",
		["Seekers of the Storm"] = "6cb28a",
		["Alloyed Collective"] = "65b4d6"
	};

	private static readonly Dictionary<string, string> BakedNames = new Dictionary<string, string>
	{
		["StandaloneAncientScepter"] = "Standalone Ancient Scepter",
		["vanillaVoid"] = "Vanilla Void",
		["EXPEDITION"] = "Expedition",
		["WolfoQoL_Extras"] = "WolfoQoL",
		["com.Viliger.EnemiesReturns.ContentProvider"] = "EnemiesReturns",
		["viliger.ReliableAncientScepterPlugin.ContentPack"] = "Reliable Ancient Scepter"
	};

	private void Awake()
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		Cfg = ((BaseUnityPlugin)this).Config;
		CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for appending the origin to item and equipment descriptions.");
		CfgShowVanilla = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Origin For Vanilla Items", true, "Append the origin for base-game and DLC items too. Base items are labelled Risk of Rain 2 and DLC items are labelled with their DLC's name. Turn off to only label modded items.");
		CfgColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "Default Label Color", "6B93D6", "Default hex color (RRGGBB) for an origin's label. Each origin also gets its own entry under [Label Colors] that overrides this.");
		new Harmony("FluxSquido.Provenance").PatchAll();
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(BuildMap));
		Log.LogInfo((object)"Provenance 1.0.0 loaded.");
	}

	private static void BuildMap()
	{
		//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_001d: 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)
		//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)
		//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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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)
		//IL_0121: 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)
		try
		{
			TokenToSource.Clear();
			bool value = CfgShowVanilla.Value;
			Enumerator<ReadOnlyContentPack> enumerator = ContentManager.allLoadedContentPacks.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ReadOnlyContentPack current = enumerator.Current;
					if (!((ReadOnlyContentPack)(ref current)).isValid)
					{
						continue;
					}
					string identifier = ((ReadOnlyContentPack)(ref current)).identifier;
					bool flag = identifier?.StartsWith("RoR2.") ?? false;
					if (flag && !value)
					{
						continue;
					}
					string text = ((!flag) ? ModName(identifier) : null);
					AssetEnumerator<ItemDef> enumerator2 = ((ReadOnlyContentPack)(ref current)).itemDefs.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							ItemDef current2 = enumerator2.Current;
							if (!((Object)(object)current2 == (Object)null))
							{
								string descriptionToken = current2.descriptionToken;
								if (!string.IsNullOrEmpty(descriptionToken))
								{
									Register(descriptionToken, (!flag) ? text : VanillaSource(current2.requiredExpansion));
								}
							}
						}
					}
					finally
					{
						((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
					AssetEnumerator<EquipmentDef> enumerator3 = ((ReadOnlyContentPack)(ref current)).equipmentDefs.GetEnumerator();
					try
					{
						while (enumerator3.MoveNext())
						{
							EquipmentDef current3 = enumerator3.Current;
							if (!((Object)(object)current3 == (Object)null))
							{
								string descriptionToken2 = current3.descriptionToken;
								if (!string.IsNullOrEmpty(descriptionToken2))
								{
									Register(descriptionToken2, (!flag) ? text : VanillaSource(current3.requiredExpansion));
								}
							}
						}
					}
					finally
					{
						((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Log.LogInfo((object)("Mapped " + TokenToSource.Count + " descriptions across " + SourceColor.Count + " sources."));
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Failed to build source map: " + ex));
		}
	}

	private static void Register(string token, string source)
	{
		if (!string.IsNullOrEmpty(source))
		{
			TokenToSource[token] = source;
			ColorEntryFor(source);
			DisplayEntryFor(source);
		}
	}

	private static string VanillaSource(ExpansionDef exp)
	{
		if ((Object)(object)exp == (Object)null)
		{
			return "Risk of Rain 2";
		}
		string nameToken = exp.nameToken;
		if (!string.IsNullOrEmpty(nameToken))
		{
			string text = Language.GetString(nameToken);
			if (!string.IsNullOrEmpty(text) && text != nameToken)
			{
				return text;
			}
		}
		if (!string.IsNullOrEmpty(((Object)exp).name))
		{
			return ((Object)exp).name;
		}
		return "Risk of Rain 2";
	}

	private static string ModName(string identifier)
	{
		if (string.IsNullOrEmpty(identifier))
		{
			return null;
		}
		try
		{
			if (Chainloader.PluginInfos.TryGetValue(identifier, out var value) && value != null && value.Metadata != null && !string.IsNullOrEmpty(value.Metadata.Name))
			{
				return value.Metadata.Name;
			}
		}
		catch
		{
		}
		return identifier;
	}

	private static ConfigEntry<string> ColorEntryFor(string source)
	{
		if (SourceColor.TryGetValue(source, out var value))
		{
			return value;
		}
		string value2;
		string text = ((!BakedColors.TryGetValue(source, out value2)) ? CfgColorHex.Value : value2);
		ConfigEntry<string> val = Cfg.Bind<string>("Label Colors", SanitizeKey(source), text, "Text color (RRGGBB) of the \"" + source + "\" label.");
		SourceColor[source] = val;
		return val;
	}

	private static ConfigEntry<string> DisplayEntryFor(string source)
	{
		if (SourceDisplay.TryGetValue(source, out var value))
		{
			return value;
		}
		string value2;
		string text = ((!BakedNames.TryGetValue(source, out value2)) ? source : value2);
		ConfigEntry<string> val = Cfg.Bind<string>("Display Names", SanitizeKey(source), text, "Text shown for the \"" + source + "\" label. Change it to rename how this origin appears.");
		SourceDisplay[source] = val;
		return val;
	}

	private static string SanitizeKey(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return "Unknown";
		}
		StringBuilder stringBuilder = new StringBuilder(s.Length);
		foreach (char c in s)
		{
			if (c != '=' && c != '\n' && c != '\r' && c != '\t')
			{
				stringBuilder.Append(c);
			}
		}
		string text = stringBuilder.ToString().Trim();
		return (!string.IsNullOrEmpty(text)) ? text : "Unknown";
	}

	internal static string SuffixFor(string source)
	{
		ConfigEntry<string> value;
		string text = ((!SourceDisplay.TryGetValue(source, out value) || string.IsNullOrEmpty(value.Value)) ? source : value.Value);
		ConfigEntry<string> value2;
		string text2 = ((!SourceColor.TryGetValue(source, out value2)) ? CfgColorHex.Value : value2.Value);
		return "\n\n<color=#" + text2 + ">" + text + "</color>";
	}

	internal static void TryAppend(string token, ref string result)
	{
		if (CfgEnabled.Value && result != null && token != null && TokenToSource.TryGetValue(token, out var value))
		{
			string text = SuffixFor(value);
			if (!result.EndsWith(text, StringComparison.Ordinal))
			{
				result += text;
			}
		}
	}
}
[HarmonyPatch(typeof(Language), "GetString", new Type[] { typeof(string) })]
internal static class Language_GetString_Patch
{
	private static void Postfix(string token, ref string __result)
	{
		ProvenancePlugin.TryAppend(token, ref __result);
	}
}
[HarmonyPatch(typeof(Language), "GetStringFormatted", new Type[]
{
	typeof(string),
	typeof(object[])
})]
internal static class Language_GetStringFormatted_Patch
{
	private static void Postfix(string token, ref string __result)
	{
		ProvenancePlugin.TryAppend(token, ref __result);
	}
}
[HarmonyPatch(typeof(Language), "GetLocalizedStringByToken")]
internal static class Language_GetLocalizedStringByToken_Patch
{
	private static void Postfix(string token, ref string __result)
	{
		ProvenancePlugin.TryAppend(token, ref __result);
	}
}