Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Text Modder v1.0.2
SilkSongTextModder.dll
Decompiled 5 months agousing 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"; } }