Decompiled source of LocalizationCache v0.3.0

LocalizationCache.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HarmonyLib.Public.Patching;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LocalizationCache")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LocalizationCache")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("FE8B42E3-7082-4DFF-A5CC-6B62B0315ACA")]
[assembly: AssemblyFileVersion("0.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
[module: UnverifiableCode]
namespace LocalizationCache;

public static class DebugTimingPatch
{
	[HarmonyPatch(typeof(Localization), "SetupLanguage")]
	[HarmonyPrefix]
	[HarmonyPriority(800)]
	public static void SetupLanguage_Prefix(Localization __instance, ref Stopwatch __state)
	{
		__state = Stopwatch.StartNew();
	}

	[HarmonyPatch(typeof(Localization), "SetupLanguage")]
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	public static void SetupLanguage_Postfix(Localization __instance, ref Stopwatch __state)
	{
		__state.Stop();
		if (Plugin.DebugTiming.Value)
		{
			Plugin.Log.LogInfo((object)$"Localization.SetupLanguage took {__state.ElapsedMilliseconds}ms");
		}
		if (Plugin.DebugStacktrace.Value)
		{
			Plugin.Log.LogInfo((object)$"Localization.SetupLanguage was called\n{new StackTrace()}");
		}
	}
}
[HarmonyPatch]
public static class LocalizationPatches
{
	private static Dictionary<Tuple<string, string>, Dictionary<string, string>> languageTranslations = new Dictionary<Tuple<string, string>, Dictionary<string, string>>();

	private static List<Patch> patchedMods = new List<Patch>();

	private static MethodInfo LoadCSVMethod { get; } = AccessTools.Method(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null);


	[HarmonyPatch(typeof(Localization), "LoadCSV")]
	[HarmonyPrefix]
	[HarmonyPriority(800)]
	public static bool SetupLanguage_Prefix(Localization __instance, TextAsset file, string language, ref bool __result)
	{
		if (!Object.op_Implicit((Object)(object)file))
		{
			return true;
		}
		Tuple<string, string> key = new Tuple<string, string>(((Object)file).name, language);
		if (!languageTranslations.TryGetValue(key, out var value))
		{
			return true;
		}
		__instance.m_translations = value;
		__result = true;
		return false;
	}

	[HarmonyPatch(typeof(Localization), "LoadCSV")]
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	public static void SetupLanguage_Postfix(Localization __instance, TextAsset file, string language, bool __result)
	{
		if (__result && Object.op_Implicit((Object)(object)file))
		{
			Tuple<string, string> key = new Tuple<string, string>(((Object)file).name, language);
			languageTranslations[key] = __instance.m_translations;
			CacheOtherMods();
		}
	}

	private static void CacheOtherMods()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		if (!Plugin.CacheMods.Value)
		{
			return;
		}
		Patch[] postfixes = PatchManager.ToPatchInfo((MethodBase)LoadCSVMethod).postfixes;
		foreach (Patch val in postfixes)
		{
			if (!(val.owner == "com.maxsch.valheim.LocalizationCache") && !patchedMods.Contains(val))
			{
				Plugin.harmony.Patch((MethodBase)val.PatchMethod, new HarmonyMethod(typeof(LocalizationPatches), "SkipLoad", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				patchedMods.Add(val);
			}
		}
	}

	private static bool SkipLoad()
	{
		return false;
	}
}
[BepInPlugin("com.maxsch.valheim.LocalizationCache", "LocalizationCache", "0.3.0")]
public class Plugin : BaseUnityPlugin
{
	public const string ModName = "LocalizationCache";

	public const string ModGuid = "com.maxsch.valheim.LocalizationCache";

	public const string ModVersion = "0.3.0";

	public static ConfigEntry<bool> EnableCache;

	public static ConfigEntry<bool> CacheMods;

	public static ConfigEntry<bool> DebugTiming;

	public static ConfigEntry<bool> DebugStacktrace;

	internal static Harmony harmony;

	internal static ManualLogSource Log { get; private set; }

	private void Awake()
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		EnableCache = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enable Cache", true, "Enable caching of localization files. Disable to compare loading times. Requires a restart to take effect");
		CacheMods = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Cache Mods", true, "Cache localization calls from some mods. Breaks switching the language at runtime but can drastically improve loading time. Requires a restart to take effect");
		DebugTiming = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Debug", "Log Timing", false, "Log timing information for Localization.SetupLanguage. Requires a restart to take effect");
		DebugStacktrace = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Debug", "Log Stacktrace", false, "Log stacktrace for each Localization.SetupLanguage call. Requires a restart to take effect");
		harmony = new Harmony("com.maxsch.valheim.LocalizationCache");
		if (EnableCache.Value)
		{
			harmony.PatchAll(typeof(LocalizationPatches));
		}
		if (DebugTiming.Value || DebugStacktrace.Value)
		{
			harmony.PatchAll(typeof(DebugTimingPatch));
		}
	}
}