Decompiled source of CoronerCustomMessages v1.2.0

BepInEx\plugins\CoronerCustomMessages\CoronerCustomMessages.dll

Decompiled a month 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 System.Security;
using System.Text;
using System.Xml.Linq;
using BepInEx;
using BepInEx.Configuration;
using Coroner;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CoronerCustomMessages")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CoronerCustomMessages")]
[assembly: AssemblyTitle("CoronerCustomMessages")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CoronerCustomMessages
{
	[BepInPlugin("dowompi.coronercustommessages", "Coroner Custom Messages", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "dowompi.coronercustommessages";

		public const string PluginName = "Coroner Custom Messages";

		public const string PluginVersion = "1.2.0";

		private const string LanguageCode = "en-us";

		private const string OutputFileName = "Strings_en-us_custom.xml";

		private const string DiscoveryReportFileName = "dowompi.coronercustommessages.discovered-tags.txt";

		private const string Separator = "||";

		private ConfigEntry<bool> pluginEnabled;

		private readonly Dictionary<string, ConfigEntry<string>> messageEntries = new Dictionary<string, ConfigEntry<string>>(StringComparer.Ordinal);

		private readonly Dictionary<string, string> defaultMessages = new Dictionary<string, string>(StringComparer.Ordinal)
		{
			["DeathEnemyBracken"] = "Was folded into a portable shape by a Bracken.||Learned too late that the Bracken wanted privacy.",
			["DeathEnemyCoilHead"] = "Lost a staring contest with a Coil-Head.||Blinking was the last mistake they made.",
			["DeathEnemyJester"] = "Stayed for the punchline. There was no survival after it.||Heard the music and still did not leave.",
			["DeathOtherLandmine"] = "Conducted an unscheduled landmine inspection.||Proved the mine was active.",
			["DeathPlayerJetpackBlast"] = "Turned the jetpack into a very brief career.||Misunderstood which end of the jetpack was the dangerous one.",
			["DeathPlayerCruiserRanOver"] = "Became a speed bump for company transport.||Lost an argument with several tons of cruiser.",
			["DeathOtherSpikeTrap"] = "Tested the spike trap so the team would not have to.||Found the trap the fast way.",
			["DeathUnknown"] = "Died under unclear but probably embarrassing circumstances."
		};

		private List<string> discoveredTags = new List<string>();

		private void Awake()
		{
			BindGeneralConfig();
		}

		private void Start()
		{
			DiscoverAndBindMessageConfig();
			WriteLanguageFile();
			WriteDiscoveryReport();
			ReloadCoronerLanguage();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Coroner Custom Messages loaded.");
		}

		private void BindGeneralConfig()
		{
			pluginEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable writing the custom Coroner language file.");
		}

		private void DiscoverAndBindMessageConfig()
		{
			messageEntries.Clear();
			discoveredTags = AdvancedCauseOfDeath.Registry.Keys.Where(IsDeathTag).OrderBy<string, string>((string tag) => tag, StringComparer.Ordinal).ToList();
			foreach (string discoveredTag in discoveredTags)
			{
				string defaultValue = (defaultMessages.ContainsKey(discoveredTag) ? defaultMessages[discoveredTag] : string.Empty);
				messageEntries[discoveredTag] = BindMessageList(discoveredTag, defaultValue);
			}
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Discovered {discoveredTags.Count} Coroner death tags and created config entries for them.");
		}

		private ConfigEntry<string> BindMessageList(string tag, string defaultValue)
		{
			return ((BaseUnityPlugin)this).Config.Bind<string>("Messages", tag, defaultValue, "Messages for " + tag + ". Separate multiple variants with '||'. This entry was created from Coroner's registered death tags.");
		}

		private void WriteLanguageFile()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_0158: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Paths.ConfigPath, "EliteMasterEric-Coroner");
			Directory.CreateDirectory(text);
			string text2 = Path.Combine(text, "Strings_en-us_custom.xml");
			if (!pluginEnabled.Value)
			{
				if (File.Exists(text2))
				{
					File.Delete(text2);
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Deleted Strings_en-us_custom.xml because the plugin is disabled.");
				}
				return;
			}
			KeyValuePair<string, string>[] source = (from entry in messageEntries.OrderBy<KeyValuePair<string, ConfigEntry<string>>, string>((KeyValuePair<string, ConfigEntry<string>> entry) => entry.Key, StringComparer.Ordinal)
				select CreateEntry(entry.Key, entry.Value.Value)).ToArray();
			new XDocument(new XDeclaration("1.0", "utf-8", (string)null), new object[1] { (object)new XElement(XName.op_Implicit("base"), new object[3]
			{
				(object)new XAttribute(XName.op_Implicit("type"), (object)"string"),
				(object)new XElement(XName.op_Implicit("tags"), (object)new XElement(XName.op_Implicit("tag"), (object)new XAttribute(XName.op_Implicit("language"), (object)"en-us"))),
				(object)new XElement(XName.op_Implicit("strings"), (object)source.SelectMany(BuildElementsForEntry))
			}) }).Save(text2);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Wrote " + text2));
		}

		private void WriteDiscoveryReport()
		{
			List<string> list = new List<string>
			{
				"Coroner Custom Messages discovery report",
				$"Generated: {DateTime.Now:yyyy-MM-dd HH:mm:ss}",
				$"Discovered tags: {discoveredTags.Count}",
				string.Empty,
				"These are Coroner death tags that were registered when the game loaded.",
				"This does not guarantee a separate source mod per tag; it only shows what Coroner exposed to this plugin.",
				string.Empty
			};
			foreach (string discoveredTag in discoveredTags)
			{
				int num = SplitMessages(messageEntries.ContainsKey(discoveredTag) ? messageEntries[discoveredTag].Value : string.Empty).Count();
				list.Add($"{discoveredTag} | variants={num}");
			}
			string text = Path.Combine(Paths.ConfigPath, "dowompi.coronercustommessages.discovered-tags.txt");
			File.WriteAllLines(text, list, Encoding.UTF8);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Wrote discovery report to " + text));
		}

		private static KeyValuePair<string, string> CreateEntry(string tag, string rawValue)
		{
			return new KeyValuePair<string, string>(tag, rawValue ?? string.Empty);
		}

		private static IEnumerable<XElement> BuildElementsForEntry(KeyValuePair<string, string> entry)
		{
			foreach (string item in SplitMessages(entry.Value))
			{
				yield return new XElement(XName.op_Implicit(entry.Key), (object)new XAttribute(XName.op_Implicit("text"), (object)item));
			}
		}

		private static IEnumerable<string> SplitMessages(string rawValue)
		{
			return (from message in (rawValue ?? string.Empty).Split(new string[1] { "||" }, StringSplitOptions.None)
				select message.Trim() into message
				where !string.IsNullOrWhiteSpace(message)
				select message).Distinct<string>(StringComparer.Ordinal);
		}

		private static bool IsDeathTag(string tag)
		{
			if (!string.IsNullOrWhiteSpace(tag))
			{
				return tag.StartsWith("Death", StringComparison.Ordinal);
			}
			return false;
		}

		private void ReloadCoronerLanguage()
		{
			try
			{
				if ((Object)(object)Plugin.Instance == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Coroner instance was not available; custom messages will apply next launch.");
					return;
				}
				Plugin.Instance.LoadLanguageHandlers();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Reloaded Coroner language handlers.");
			}
			catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is SecurityException)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to reload Coroner language handlers: {ex}");
			}
		}
	}
}