Decompiled source of ZetAspects zh v1.0.0

plugins/ZetAspects_zh/ZetAspects_zh.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using HarmonyLib;
using Newtonsoft.Json;
using On.RoR2;
using R2API.Utils;
using RoR2;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ZetAspectsZh;

[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("local.zetaspects.zh", "ZetAspects_zh", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin
{
	private sealed class Rule
	{
		public Regex Pattern;

		public string Template;
	}

	public const string Guid = "local.zetaspects.zh";

	private static Plugin instance;

	private Harmony harmony;

	private Dictionary<string, string> translations;

	private readonly Dictionary<string, string> tokenTranslations = new Dictionary<string, string>(StringComparer.Ordinal);

	private readonly List<Rule> rules = new List<Rule>();

	private bool hooked;

	private static readonly Regex Han = new Regex("[\\u3400-\\u9fff]");

	private static readonly Regex Parameter = new Regex("\\{(\\d+)\\}");

	private static bool Chinese
	{
		get
		{
			if ((Object)(object)instance != (Object)null && Language.currentLanguage != null)
			{
				return Language.currentLanguage.name == "zh-CN";
			}
			return false;
		}
	}

	private void Awake()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Expected O, but got Unknown
		instance = this;
		try
		{
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "translations.json");
			translations = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(path, Encoding.UTF8));
			BuildRules();
			BuildTokenTranslations();
			harmony = new Harmony("local.zetaspects.zh");
			Language.GetLocalizedStringByToken += new hook_GetLocalizedStringByToken(Lookup);
			hooked = true;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AfterGameLoad));
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ZetAspects_zh ready: " + translations.Count + " fragment translations, " + tokenTranslations.Count + " registered tokens."));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("ZetAspects_zh disabled: " + ex));
		}
	}

	private void BuildRules()
	{
		foreach (KeyValuePair<string, string> item in translations.OrderByDescending((KeyValuePair<string, string> p) => p.Key.Length))
		{
			if (string.IsNullOrEmpty(item.Key) || item.Key.Contains("<style=cStack>(???)</style>"))
			{
				continue;
			}
			StringBuilder stringBuilder = new StringBuilder("(?<![A-Za-z])");
			int num = 0;
			foreach (Match item2 in Parameter.Matches(item.Key))
			{
				stringBuilder.Append(Regex.Escape(item.Key.Substring(num, item2.Index - num)));
				stringBuilder.Append("(?<p" + item2.Groups[1].Value + ">[-+]?\\d[\\d.,]*%?(?:\\s*\\w+)?)");
				num = item2.Index + item2.Length;
			}
			stringBuilder.Append(Regex.Escape(item.Key.Substring(num))).Append("(?![A-Za-z])");
			try
			{
				rules.Add(new Rule
				{
					Pattern = new Regex(stringBuilder.ToString(), RegexOptions.CultureInvariant, TimeSpan.FromMilliseconds(35.0)),
					Template = item.Value
				});
			}
			catch
			{
			}
		}
	}

	private void BuildTokenTranslations()
	{
		Type type = AccessTools.TypeByName("TPDespair.ZetAspects.Language");
		if (type == null)
		{
			throw new InvalidOperationException("ZetAspects.Language not found");
		}
		FieldInfo fieldInfo = AccessTools.Field(type, "tokens");
		IDictionary dictionary = ((fieldInfo == null) ? null : (fieldInfo.GetValue(null) as IDictionary));
		if (dictionary == null || !(dictionary["default"] is IDictionary dictionary2))
		{
			return;
		}
		foreach (DictionaryEntry item in dictionary2)
		{
			string text = item.Key as string;
			string text2 = item.Value as string;
			if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2))
			{
				string text3 = Translate(text2);
				if (text3 != text2 && Han.IsMatch(text3))
				{
					tokenTranslations[text] = text3;
				}
			}
		}
	}

	private static string Lookup(orig_GetLocalizedStringByToken orig, Language self, string token)
	{
		string text = orig.Invoke(self, token);
		if (!Chinese || self == null || self.name != "zh-CN" || (Object)(object)instance == (Object)null)
		{
			return text;
		}
		if (instance.tokenTranslations.TryGetValue(token, out var value))
		{
			return value;
		}
		return instance.Translate(text);
	}

	private string Translate(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return value;
		}
		string text = value;
		foreach (Rule rule in rules)
		{
			text = rule.Pattern.Replace(text, (Match match) => Parameter.Replace(rule.Template, (Match p) => match.Groups["p" + p.Groups[1].Value].Value));
		}
		return text;
	}

	private void AfterGameLoad()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		if (hooked)
		{
			Language.GetLocalizedStringByToken -= new hook_GetLocalizedStringByToken(Lookup);
			Language.GetLocalizedStringByToken += new hook_GetLocalizedStringByToken(Lookup);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ZetAspects_zh language chain attached after game language load.");
		}
	}

	private void OnDestroy()
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		if (hooked)
		{
			Language.GetLocalizedStringByToken -= new hook_GetLocalizedStringByToken(Lookup);
		}
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(AfterGameLoad));
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if ((Object)(object)instance == (Object)(object)this)
		{
			instance = null;
		}
	}
}