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 System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; [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("NexusNamingEnabler")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("My first plugin")] [assembly: AssemblyTitle("NexusNamingEnabler")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NexusNamingEnabler { [BepInPlugin("NexusNamingEnabler", "My first plugin", "1.0.0")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(SaveMetadata), "IsCustomGame")] public class Techtonica_SaveMetadata_Tracker_Patch { private static void Postfix(SaveMetadata __instance) { if (__instance != null && !string.IsNullOrEmpty(__instance.worldName)) { lastWorldName = __instance.worldName; LoadModDataFromFile(lastWorldName); } } } [HarmonyPatch(typeof(NexusInstance), "GetDisplayName")] public class NexusInstance_GetDisplayName_Patch { private static bool Prefix(ref NexusInstance __instance, ref string __result) { try { int instanceId = (int)__instance.commonInfo.instanceId; foreach (KeyValuePair savedNexusName in SavedNexusNames) { if (savedNexusName.Key.EndsWith("_" + instanceId) && !string.IsNullOrEmpty(savedNexusName.Value)) { __result = savedNexusName.Value; return false; } } } catch (Exception) { } return true; } } [HarmonyPatch(typeof(NexusUI), "Init")] public class NexusUI_Init_Unlock_Patch { private static void Postfix(NexusUI __instance) { try { FieldInfo fieldInfo = AccessTools.Field(typeof(NexusUI), "_nameInputField"); if (fieldInfo == null) { return; } object nameInputFieldInstance = fieldInfo.GetValue(__instance); if (nameInputFieldInstance == null) { return; } object obj = AccessTools.Property(nameInputFieldInstance.GetType(), "Input")?.GetValue(nameInputFieldInstance); if (obj == null) { return; } AccessTools.Property(obj.GetType(), "readOnly")?.SetValue(obj, false); AccessTools.Property(obj.GetType(), "interactable")?.SetValue(obj, true); ApplyGlobalFontLocalizationOverrides(obj); object obj2 = AccessTools.Property(obj.GetType(), "onEndEdit")?.GetValue(obj); if (obj2 != null) { AccessTools.Method(obj2.GetType(), "RemoveAllListeners", (Type[])null, (Type[])null)?.Invoke(obj2, null); Action action = delegate(string submittedText) { try { string value = SanitizeInputText(submittedText); if (!string.IsNullOrEmpty(value)) { FieldInfo fieldInfo2 = AccessTools.Field(typeof(NexusUI), "_myMachineRef") ?? AccessTools.Field(((object)__instance).GetType().BaseType, "_myMachineRef"); if (fieldInfo2 != null) { object value2 = fieldInfo2.GetValue(__instance); if (value2 != null) { FieldInfo fieldInfo3 = AccessTools.Field(value2.GetType(), "_index"); if (fieldInfo3 != null) { string persistentKey = GetPersistentKey((int)fieldInfo3.GetValue(value2)); if (persistentKey != null) { SavedNexusNames[persistentKey] = value; AccessTools.Property(nameInputFieldInstance.GetType(), "Name")?.SetValue(nameInputFieldInstance, value); SaveModDataToFile(lastWorldName); Type type = AccessTools.TypeByName("FastTravelManager") ?? AccessTools.TypeByName("FastTravelNetwork") ?? AccessTools.TypeByName("FastTravelSystem"); if (type != null) { object obj3 = AccessTools.Field(type, "instance")?.GetValue(null) ?? AccessTools.Field(type, "Instance")?.GetValue(null) ?? AccessTools.Property(type, "instance")?.GetValue(null) ?? AccessTools.Property(type, "Instance")?.GetValue(null); if (obj3 != null) { AccessTools.Method(obj3.GetType(), "RefreshNetwork", (Type[])null, (Type[])null)?.Invoke(obj3, null); AccessTools.Method(obj3.GetType(), "MarkDirty", (Type[])null, (Type[])null)?.Invoke(obj3, null); } } Type type2 = AccessTools.TypeByName("UIManager"); if (type2 != null) { object obj4 = AccessTools.Field(type2, "instance")?.GetValue(null) ?? AccessTools.Field(type2, "Instance")?.GetValue(null) ?? AccessTools.Property(type2, "instance")?.GetValue(null) ?? AccessTools.Property(type2, "Instance")?.GetValue(null); if (obj4 != null) { AccessTools.Method(obj4.GetType(), "RefreshAll", (Type[])null, (Type[])null)?.Invoke(obj4, null); AccessTools.Method(obj4.GetType(), "SoftRefresh", (Type[])null, (Type[])null)?.Invoke(obj4, null); } } } } } } } } catch (Exception ex2) { Debug.LogError((object)("[NexusRenameMod] Event handle crash: " + ex2.Message)); } }; Delegate @delegate = Delegate.CreateDelegate(typeof(UnityAction<>).MakeGenericType(typeof(string)), action.Target, action.Method); MethodInfo methodInfo = null; MethodInfo[] methods = obj2.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name == "AddListener" && methodInfo2.GetParameters().Length == 1) { methodInfo = methodInfo2; break; } } if (methodInfo != null) { object[] parameters = new object[1] { @delegate }; methodInfo.Invoke(obj2, parameters); } } object[] parameters2 = new object[1] { 0 }; AccessTools.Method(obj.GetType(), "Rebuild", (Type[])null, (Type[])null)?.Invoke(obj, parameters2); AccessTools.Method(obj.GetType(), "UpdateLabel", (Type[])null, (Type[])null)?.Invoke(obj, null); } catch (Exception ex) { Debug.LogError((object)("[NexusRenameMod] Setup unlock error: " + ex.Message)); } } } [HarmonyPatch(typeof(NexusUI), "RefreshNexusLockState")] public class NexusUI_LockState_Patch { private static bool Prefix(NexusUI __instance) { try { FieldInfo fieldInfo = AccessTools.Field(typeof(NexusUI), "_nameInputField"); if (fieldInfo != null) { object value = fieldInfo.GetValue(__instance); if (value != null) { object obj = AccessTools.Property(value.GetType(), "Input")?.GetValue(value); if (obj != null) { AccessTools.Property(obj.GetType(), "readOnly")?.SetValue(obj, false); AccessTools.Property(obj.GetType(), "interactable")?.SetValue(obj, true); } FieldInfo fieldInfo2 = AccessTools.Field(typeof(NexusUI), "_myMachineRef") ?? AccessTools.Field(((object)__instance).GetType().BaseType, "_myMachineRef"); if (fieldInfo2 != null) { object value2 = fieldInfo2.GetValue(__instance); if (value2 != null) { FieldInfo fieldInfo3 = AccessTools.Field(value2.GetType(), "_index"); if (fieldInfo3 != null) { string persistentKey = GetPersistentKey((int)fieldInfo3.GetValue(value2)); if (persistentKey != null && SavedNexusNames.TryGetValue(persistentKey, out var value3) && (bool?)AccessTools.Property(value.GetType(), "IsFocused")?.GetValue(value, null) == false) { AccessTools.Property(value.GetType(), "Name")?.SetValue(value, value3); } } } } } } } catch (Exception) { } return false; } } internal static ManualLogSource Logger; private static string lastWorldName = "DefaultWorld"; public static Dictionary SavedNexusNames = new Dictionary(); private void Awake() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) new Harmony("com.Puppy_Dev.NexusNamingEnabler").PatchAll(); Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin NexusNamingEnabler is loaded with Localization fixes!"); } public static string GetPersistentKey(int targetIndex) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) try { MachineManager instance = MachineManager.instance; IMachineList val = ((instance != null) ? instance.GetMachineList((MachineTypeEnum)33) : null); if (val != null && val.IsValidIndex(ref targetIndex)) { int instanceId = (int)val.GetCommonInfo(targetIndex).instanceId; return "NEXUS_ID_" + targetIndex + "_" + instanceId; } } catch (Exception) { } return null; } public static string EncodeToUnicodeHex(string input) { if (string.IsNullOrEmpty(input)) { return input; } StringBuilder stringBuilder = new StringBuilder(); foreach (char c in input) { if (c > '\u007f') { stringBuilder.AppendFormat("\\u{0:X4}", (int)c); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } public static string DecodeFromUnicodeHex(string input) { if (string.IsNullOrEmpty(input)) { return input; } return Regex.Unescape(input); } public static string SanitizeInputText(string input) { if (string.IsNullOrEmpty(input)) { return ""; } return input.Replace("\n", "").Replace("\r", "").Replace("\t", "") .Trim(); } private static string GetSaveDirectory() { string text = Path.Combine(Path.Combine(Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)), "LocalLow"), "Fire Hose Games", "Techtonica", "Saves"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } return text; } public static void SaveModDataToFile(string worldName) { if (string.IsNullOrEmpty(worldName)) { return; } try { string text = string.Join("_", worldName.Split(Path.GetInvalidFileNameChars())); string path = Path.Combine(GetSaveDirectory(), text + ".modsave"); List list = new List(); foreach (KeyValuePair savedNexusName in SavedNexusNames) { string text2 = EncodeToUnicodeHex(savedNexusName.Value); list.Add(savedNexusName.Key + "||=" + text2); } File.WriteAllLines(path, list.ToArray()); } catch (Exception ex) { Logger.LogError((object)("[NexusRenameMod] Save err: " + ex.Message)); } } public static void LoadModDataFromFile(string worldName) { if (string.IsNullOrEmpty(worldName)) { return; } try { SavedNexusNames.Clear(); string text = string.Join("_", worldName.Split(Path.GetInvalidFileNameChars())); string path = Path.Combine(GetSaveDirectory(), text + ".modsave"); if (!File.Exists(path)) { return; } string[] array = File.ReadAllLines(path); foreach (string text2 in array) { if (!string.IsNullOrEmpty(text2)) { int num = text2.IndexOf("||="); if (num != -1) { string key = text2.Substring(0, num); string input = text2.Substring(num + 3); SavedNexusNames[key] = DecodeFromUnicodeHex(input); } } } } catch (Exception ex) { Logger.LogError((object)("[NexusRenameMod] Load err: " + ex.Message)); } } public static void ApplyGlobalFontLocalizationOverrides(object targetInputField) { if (targetInputField == null) { return; } try { object? obj = (targetInputField.GetType().GetProperty("textComponent") ?? targetInputField.GetType().GetProperty("TextComponent"))?.GetValue(targetInputField); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); if (!((Object)(object)val != (Object)null) || !((Object)(object)val.font != (Object)null)) { return; } TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll(); if (val.font.fallbackFontAssetTable == null) { val.font.fallbackFontAssetTable = new List(); } TMP_FontAsset[] array2 = array; foreach (TMP_FontAsset val2 in array2) { if ((Object)(object)val2 != (Object)(object)val.font && !val.font.fallbackFontAssetTable.Contains(val2)) { val.font.fallbackFontAssetTable.Add(val2); } } Logger.LogInfo((object)"[NexusRenameMod] Localization fallback font tables attached smoothly!"); } catch (Exception ex) { Logger.LogError((object)("[NexusRenameMod] Font lookup inject error: " + ex.Message)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "NexusNamingEnabler"; public const string PLUGIN_NAME = "My first plugin"; public const string PLUGIN_VERSION = "1.0.0"; } }