Decompiled source of Bielarusizatar Valheim Belarusian Translation v2.0.0

plugins/Bielarusizatar_Valheim.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using TMPro;
using UnityEngine;

[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("Bielarusizatar_Valheim")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+6f269b6857415108b3265dff3fd8426619a2f716")]
[assembly: AssemblyProduct("Bielarusizatar_Valheim")]
[assembly: AssemblyTitle("Bielarusizatar_Valheim")]
[assembly: AssemblyVersion("2.0.0.0")]
namespace Bielarusizatar.Valheim;

[BepInPlugin("lokar.Bielarusizatar_Valheim", "Bielarusizatar Valheim", "2.0.0")]
public class BielarusizatarPlugin : BaseUnityPlugin
{
	internal const char ShortU = 'ў';

	internal const char ShortUUpper = 'Ў';

	internal const char ShortUSub = 'ý';

	internal const char ShortUSubUpper = 'Ý';

	private const float SweepDelay = 3f;

	private bool _swept;

	internal static readonly PropertyInfo LocalizationMap = typeof(CustomLocalization).GetProperty("Map", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	internal static readonly FieldInfo LocalizationList = typeof(LocalizationManager).GetField("Localizations", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

	internal static BielarusizatarPlugin Instance { get; private set; }

	internal string PluginDir { get; private set; }

	internal ManualLogSource Log => ((BaseUnityPlugin)this).Logger;

	private void Awake()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		PluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".";
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Bielarusizatar Valheim started (plugin dir: " + PluginDir + ")"));
		try
		{
			new Harmony("lokar.Bielarusizatar_Valheim").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Localization substitution patch applied.");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Localization patch failed: " + ex));
		}
	}

	private void Update()
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		if (_swept || Time.realtimeSinceStartup < 3f)
		{
			return;
		}
		_swept = true;
		try
		{
			if (!(LocalizationList?.GetValue(null) is IEnumerable enumerable))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Localization list unavailable; AddTranslation hook is the only path.");
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (CustomLocalization item in enumerable)
			{
				CustomLocalization val = item;
				if (val == null || !(LocalizationMap?.GetValue(val) is Dictionary<string, Dictionary<string, string>> dictionary))
				{
					continue;
				}
				num++;
				foreach (string item2 in new List<string>(dictionary.Keys))
				{
					if (!IsBelarusian(item2))
					{
						continue;
					}
					Dictionary<string, string> dictionary2 = dictionary[item2];
					if (dictionary2 == null)
					{
						continue;
					}
					foreach (string item3 in new List<string>(dictionary2.Keys))
					{
						string text = dictionary2[item3];
						if (!string.IsNullOrEmpty(text))
						{
							string text2 = Substitute(text);
							if (!(text2 == text))
							{
								dictionary2[item3] = text2;
								num2++;
							}
						}
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Map sweep visited " + num + " localization(s), rewrote " + num2 + " string(s)."));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Localization map sweep failed: " + ex));
		}
	}

	internal static string Substitute(string text)
	{
		if (string.IsNullOrEmpty(text))
		{
			return text;
		}
		if (text.IndexOf('ў') < 0 && text.IndexOf('Ў') < 0)
		{
			return text;
		}
		StringBuilder stringBuilder = new StringBuilder(text.Length);
		foreach (char c in text)
		{
			switch (c)
			{
			case 'ў':
				stringBuilder.Append('ý');
				break;
			case 'Ў':
				stringBuilder.Append('Ý');
				break;
			default:
				stringBuilder.Append(c);
				break;
			}
		}
		return stringBuilder.ToString();
	}

	internal static bool IsBelarusian(string language)
	{
		if (string.IsNullOrEmpty(language))
		{
			return false;
		}
		if (language.IndexOf("belarus", StringComparison.OrdinalIgnoreCase) < 0)
		{
			return language.IndexOf("Белар", StringComparison.Ordinal) >= 0;
		}
		return true;
	}
}
[HarmonyPatch]
internal static class AddTranslationPatch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		yield return AccessTools.Method(typeof(CustomLocalization), "AddTranslation", new Type[3]
		{
			typeof(string).MakeByRefType(),
			typeof(string).MakeByRefType(),
			typeof(string)
		}, (Type[])null);
		yield return AccessTools.Method(typeof(CustomLocalization), "AddTranslation", new Type[2]
		{
			typeof(string).MakeByRefType(),
			typeof(string)
		}, (Type[])null);
	}

	private static void Postfix(ref string translation)
	{
		if (!string.IsNullOrEmpty(translation))
		{
			string text = BielarusizatarPlugin.Substitute(translation);
			if ((object)text != translation && text != translation)
			{
				translation = text;
			}
		}
	}
}
[HarmonyPatch(typeof(TMP_Text), "set_text")]
internal static class TmpTextSetterPatch
{
	private static void Prefix(ref string value)
	{
		if (!string.IsNullOrEmpty(value) && (value.IndexOf('ў') >= 0 || value.IndexOf('Ў') >= 0))
		{
			value = BielarusizatarPlugin.Substitute(value);
		}
	}
}
[HarmonyPatch(typeof(CinematicsManager), "GetSubtitle")]
internal static class SubtitlePatch
{
	private static readonly FieldInfo CurrentVideo = typeof(CinematicsManager).GetField("m_currentVideo", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo VideoName = typeof(VideoEntry).GetField("m_name", BindingFlags.Instance | BindingFlags.Public);

	private static TextAsset _intro;

	private static TextAsset _outro;

	private static bool _loaded;

	private static void Postfix(string language, ref TextAsset __result)
	{
		try
		{
			if (IsBelarusian(language))
			{
				if (!_loaded)
				{
					_loaded = true;
					_intro = LoadAsset("Valheim_intro_subtitles_be.srt");
					_outro = LoadAsset("Valheim_outro_subtitles_be.srt");
				}
				CinematicsManager s_instance = CinematicsManager.s_instance;
				object obj = (((Object)(object)s_instance == (Object)null) ? null : CurrentVideo?.GetValue(s_instance));
				string text = ((obj == null) ? null : (VideoName?.GetValue(obj) as string));
				TextAsset val = ((text != null && text.IndexOf("outro", StringComparison.OrdinalIgnoreCase) >= 0) ? _outro : _intro);
				if ((Object)(object)val != (Object)null)
				{
					__result = val;
				}
			}
		}
		catch (Exception ex)
		{
			BielarusizatarPlugin instance = BielarusizatarPlugin.Instance;
			if (instance != null)
			{
				instance.Log.LogError((object)("Subtitle injection failed: " + ex));
			}
		}
	}

	private static TextAsset LoadAsset(string file)
	{
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		try
		{
			BielarusizatarPlugin instance = BielarusizatarPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			string text = Path.Combine(instance.PluginDir, "Assets", "Subtitles", file);
			if (!File.Exists(text))
			{
				instance.Log.LogWarning((object)("Subtitle file not found: " + text));
				return null;
			}
			string text2 = BielarusizatarPlugin.Substitute(File.ReadAllText(text));
			instance.Log.LogInfo((object)("Subtitles loaded: " + file + " (" + text2.Length + " chars)"));
			return new TextAsset(text2);
		}
		catch (Exception ex)
		{
			BielarusizatarPlugin instance2 = BielarusizatarPlugin.Instance;
			if (instance2 != null)
			{
				instance2.Log.LogError((object)("Failed to load " + file + ": " + ex));
			}
			return null;
		}
	}

	private static bool IsBelarusian(string language)
	{
		if (BielarusizatarPlugin.IsBelarusian(language))
		{
			return true;
		}
		return BielarusizatarPlugin.IsBelarusian(PlayerPrefs.GetString("language", "English"));
	}
}