Decompiled source of Text Modder v1.0.2

SilkSongTextModder.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SilkSongTextModder")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+222f138ee05ecea42cb0923a89be01517b0b43bd")]
[assembly: AssemblyProduct("SilkSongTextModder")]
[assembly: AssemblyTitle("SilkSongTextModder")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.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]
	[Microsoft.CodeAnalysis.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;
		}
	}
	[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 SilkSongTextModder
{
	[BepInPlugin("TextModder", "TextModder", "1.0.0")]
	public class TextModderPlugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		private class Patch_Language_DoSwitch
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(typeof(Language), "DoSwitch", new Type[1] { typeof(LanguageCode) }, (Type[])null);
			}

			private static void Postfix()
			{
				//IL_00a4: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>> dictionary = ReadInCustomText();
				FieldInfo field = typeof(Language).GetField("_currentEntrySheets", BindingFlags.Static | BindingFlags.NonPublic);
				if (field == null)
				{
					TextModderLogger.LogError((object)"Failed to find '_currentEntrySheets' field");
					return;
				}
				if (!(field?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary2))
				{
					TextModderLogger.LogError((object)"Failed to get value of '_currentEntrySheets'");
					return;
				}
				FieldInfo field2 = typeof(Language).GetField("_currentLanguage", BindingFlags.Static | BindingFlags.NonPublic);
				if (field2 == null)
				{
					TextModderLogger.LogError((object)"Failed to find '_currentLanguage' field");
					return;
				}
				LanguageCode key = (LanguageCode)((field2.GetValue(null) is LanguageCode) ? ((int)(LanguageCode)field2.GetValue(null)) : 0);
				if (!dictionary.ContainsKey(key))
				{
					TextModderLogger.LogWarning((object)("There is no custom text for the game's current language code: '" + ((object)(LanguageCode)(ref key)).ToString() + "'"));
					return;
				}
				foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary[key])
				{
					if (!dictionary2.ContainsKey(item.Key))
					{
						dictionary2.Add(item.Key, item.Value);
					}
					foreach (KeyValuePair<string, string> item2 in item.Value)
					{
						dictionary2[item.Key][item2.Key] = item2.Value;
					}
				}
				field.SetValue(null, dictionary2);
				TextModderLogger.LogInfo((object)"Replaced all text entries");
			}

			private static Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>> ReadInCustomText()
			{
				Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>> dictionary = new Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>>();
				string pluginPath = Paths.PluginPath;
				string[] directories;
				if (Directory.Exists(pluginPath))
				{
					TextModderLogger.LogDebug((object)("BepInEx plugin directory found at: " + pluginPath));
					TextModderLogger.LogDebug((object)("PluginRoot (recursive):\n" + string.Join("\n", Directory.EnumerateFileSystemEntries(Paths.PluginPath, "*", SearchOption.AllDirectories))));
					directories = Directory.GetDirectories(pluginPath);
					foreach (string text in directories)
					{
						if (!File.Exists(Path.Combine(text, "TextModder")))
						{
							continue;
						}
						TextModderLogger.LogDebug((object)("Found TextModder Directory: " + text));
						string[] files = Directory.GetFiles(text, "*.txt", SearchOption.AllDirectories);
						foreach (string text2 in files)
						{
							TextModderLogger.LogInfo((object)("Reading Text From File: " + text2));
							string[] array = File.ReadAllLines(text2);
							for (int k = 0; k < array.Length; k++)
							{
								DeserializeCustomTextLine(array[k], dictionary);
							}
						}
					}
				}
				else
				{
					TextModderLogger.LogError((object)"No BepInEx plugin directory found.");
				}
				directories = Directory.GetFiles(ModDir);
				foreach (string text3 in directories)
				{
					TextModderLogger.LogInfo((object)("Reading Text From File: " + text3));
					string[] files = File.ReadAllLines(text3);
					for (int j = 0; j < files.Length; j++)
					{
						DeserializeCustomTextLine(files[j], dictionary);
					}
				}
				return dictionary;
			}

			private static void DeserializeCustomTextLine(string lineToDeserialize, Dictionary<LanguageCode, Dictionary<string, Dictionary<string, string>>> dictToAddTo)
			{
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: 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_0099: Unknown result type (might be due to invalid IL or missing references)
				TextModderLogger.LogDebug((object)lineToDeserialize);
				if (string.IsNullOrWhiteSpace(lineToDeserialize))
				{
					return;
				}
				string[] array = lineToDeserialize.Split(new char[1] { '>' }, 4);
				if (array.Length != 4)
				{
					TextModderLogger.LogWarning((object)("Invalid format: " + lineToDeserialize));
					return;
				}
				if (!Enum.TryParse<LanguageCode>(array[0], out LanguageCode result))
				{
					TextModderLogger.LogWarning((object)("Unknown language code: " + array[0]));
					return;
				}
				string key = array[1];
				string key2 = array[2];
				string value = array[3];
				if (!dictToAddTo.ContainsKey(result))
				{
					dictToAddTo[result] = new Dictionary<string, Dictionary<string, string>>();
				}
				if (!dictToAddTo[result].ContainsKey(key))
				{
					dictToAddTo[result][key] = new Dictionary<string, string>();
				}
				dictToAddTo[result][key][key2] = value;
			}
		}

		internal static ManualLogSource TextModderLogger = new ManualLogSource("TextModder");

		private static readonly string ModDir = Path.Combine(Application.dataPath, "Mods", "TextModder");

		private static bool _patched;

		private void Awake()
		{
			if (!Directory.Exists(ModDir))
			{
				Directory.CreateDirectory(ModDir);
			}
			Logger.Sources.Add((ILogSource)(object)TextModderLogger);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			if (!_patched)
			{
				DoPatch();
			}
		}

		private static void DoPatch()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			new Harmony("TextModder").PatchAll();
			_patched = true;
			TextModderLogger.LogInfo((object)"Harmony patching complete");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TextModder";

		public const string PLUGIN_NAME = "TextModder";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}