Decompiled source of WKTranslator v0.1.0

plugins/galfarious.WKTranslator.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("galfarious.WKTranslator")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+58155c789f39ff65e59abdf7b6f90184468d5492")]
[assembly: AssemblyProduct("WKTranslator")]
[assembly: AssemblyTitle("galfarious.WKTranslator")]
[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 WKTranslator
{
	public static class FontLoader
	{
		public static TMP_FontAsset CustomFont;

		public static void LoadCustomFont(string folderPath)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.TopDirectoryOnly);
			string text = null;
			string[] array = files;
			foreach (string text2 in array)
			{
				if (text2.EndsWith(".ttf") || text2.EndsWith(".otf"))
				{
					text = text2;
					break;
				}
			}
			if (!string.IsNullOrEmpty(text))
			{
				byte[] array2 = File.ReadAllBytes(text);
				Font val = new Font();
				val = new Font(text);
				CustomFont = TMP_FontAsset.CreateFontAsset(val);
				((Object)CustomFont).name = "WK_CustomFont";
				LogManager.Info("Loaded custom font: " + Path.GetFileName(text));
			}
		}
	}
	public static class LogManager
	{
		private static ManualLogSource _logSource;

		public static void Initialize(ManualLogSource logger)
		{
			_logSource = logger;
		}

		public static void Info(object message)
		{
			_logSource.LogInfo(message);
		}

		public static void Warn(object message)
		{
			_logSource.LogWarning(message);
		}

		public static void Error(object message)
		{
			_logSource.LogError(message);
		}

		public static void Debug(object message)
		{
			_logSource.LogDebug(message);
		}
	}
	[BepInPlugin("galfarious.WKTranslator", "WKTranslator", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPriority(800)]
		[HarmonyPatch(typeof(Resources))]
		public static class ResourcesPatches
		{
			[HarmonyPatch("Load", new Type[]
			{
				typeof(string),
				typeof(Type)
			})]
			public static bool LoadPatch(string path, Type systemTypeInstance, ref Object __result)
			{
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Expected O, but got Unknown
				if (systemTypeInstance == typeof(TextAsset) && path.Contains("en") && CustomSubtitleAsset != null)
				{
					__result = (Object)(object)CustomSubtitleAsset;
					return false;
				}
				if (systemTypeInstance == typeof(Material))
				{
					LogManager.Warn($"this is spriteRegistry Keys: {TextureRegistry.Keys}");
					Material val = (Material)__result;
					LogManager.Warn("This is the material that was loaded: " + ((Object)val).name);
					if (TextureRegistry.TryGetValue(((Object)val.mainTexture).name, out var value))
					{
						LogManager.Error("Trying to replace the texture with new material idk...");
						val.mainTexture = (Texture)(object)value;
						__result = (Object)(object)val;
						return false;
					}
				}
				return true;
			}
		}

		public static Plugin Instance;

		private ConfigEntry<string> _langKey;

		public static readonly Dictionary<string, string> Translations = new Dictionary<string, string>();

		public static readonly Dictionary<string, Texture2D> TextureRegistry = new Dictionary<string, Texture2D>();

		public static readonly Dictionary<string, AudioClip> AudioRegistry = new Dictionary<string, AudioClip>();

		public static Dictionary<Regex, string> RegexTranslations = new Dictionary<Regex, string>();

		public static TMP_FontAsset CustomFontAsset;

		public static TextAsset CustomSubtitleAsset;

		private List<TranslationFolder> _translationFolders = new List<TranslationFolder>();

		private List<string> _allowedImageTypes = new List<string>(1) { "png" };

		private List<string> _allowedAudioTypes = new List<string>(3) { "wav", "ogg", "mp3" };

		private string PluginDir => Path.Combine(Paths.PluginPath, "WKTranslator");

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null || (Object)(object)Instance != (Object)(object)this)
			{
				Instance = this;
			}
			LogManager.Initialize(((BaseUnityPlugin)this).Logger);
			_langKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "LanguageKey", "en", "Select the language corresponding to the translation JSON\ne.g.: cz");
			_langKey.SettingChanged += delegate
			{
				ReloadLanguage();
			};
			_translationFolders = TranslationScanner.Scan(Paths.PluginPath);
			ReloadLanguage();
			ApplyHarmonyPatches();
			LogManager.Info("Plugin galfarious.WKTranslator v1.0.0 is loaded!");
			CreateWKTranslationManagerObject();
			LogManager.Info("Added command for dumping text!");
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			CreateWKTranslationManagerObject();
		}

		public void ReloadLanguage()
		{
			ClearAll();
			_translationFolders = TranslationScanner.Scan(Paths.PluginPath);
			TranslationFolder translationFolder = _translationFolders.FirstOrDefault((TranslationFolder t) => t.Config.LanguageKey == _langKey.Value);
			LogManager.Info(translationFolder);
			if (translationFolder == null)
			{
				LogManager.Error("Translation '" + _langKey.Value + "' not found or invalid.");
				return;
			}
			string text = Path.Combine(translationFolder.FolderPath, translationFolder.Config.ConfigFileName);
			FontLoader.LoadCustomFont(translationFolder.FolderPath);
			CustomFontAsset = FontLoader.CustomFont;
			if (CustomFontAsset == null)
			{
				LogManager.Info("No Custom Font Loaded!");
			}
			else
			{
				LogManager.Info("Loaded Custom font!");
			}
			LoadTranslations(translationFolder.FolderPath, translationFolder.Config);
			LoadTextures(Path.Combine(translationFolder.FolderPath, "Textures"));
			LoadAudio(Path.Combine(translationFolder.FolderPath, "Audio"));
			LogManager.Info("Loaded translation '" + translationFolder.Config.LanguageName + "' by " + string.Join(", ", translationFolder.Config.Authors) + ".");
		}

		private static void CreateWKTranslationManagerObject()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("WKTranslationManager");
			val.AddComponent<WKTranslationManager>();
		}

		private void ClearAll()
		{
			Translations.Clear();
			TextureRegistry.Clear();
			AudioRegistry.Clear();
		}

		private void LoadTranslations(string filepath, TranslationConfig config)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Invalid comparison between Unknown and I4
			LogManager.Info("Loading translations from '" + filepath + "'.");
			string text = Path.Combine(filepath, config.LanguageKey + ".json");
			Translations.Clear();
			if (!File.Exists(text))
			{
				LogManager.Error("Translation '" + text + "' not found or invalid.");
				return;
			}
			try
			{
				string text2 = File.ReadAllText(text);
				JObject val = JObject.Parse(text2);
				foreach (JProperty item in val.Properties())
				{
					JTokenType type = item.Value.Type;
					JTokenType val2 = type;
					if ((int)val2 != 1)
					{
						if ((int)val2 == 8)
						{
							string name = item.Name;
							string value = ((object)item.Value).ToString();
							Translations.TryAdd(name, value);
						}
						continue;
					}
					JObject val3 = (JObject)item.Value;
					foreach (JProperty item2 in val3.Properties())
					{
						string name2 = item2.Name;
						string value2 = ((object)item2.Value).ToString();
						Translations.TryAdd(name2, value2);
					}
				}
				LogManager.Info($"Loaded {Translations.Count} translations from {Path.GetFileName(text)}");
			}
			catch (Exception ex)
			{
				LogManager.Error("Failed to load translations from '" + text + "': " + ex.Message);
			}
		}

		private void LoadTextures(string dir)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			TextureRegistry.Clear();
			if (!Directory.Exists(dir))
			{
				return;
			}
			string[] files = Directory.GetFiles(dir);
			foreach (string path in files)
			{
				List<string> allowedImageTypes = _allowedImageTypes;
				string extension = Path.GetExtension(path);
				if (allowedImageTypes.Contains(extension.Substring(1, extension.Length - 1)))
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					byte[] array = File.ReadAllBytes(path);
					Texture2D val = new Texture2D(2, 2);
					ImageConversion.LoadImage(val, array);
					TextureRegistry.Add(fileNameWithoutExtension, val);
				}
			}
		}

		private async void LoadAudio(string dir)
		{
			try
			{
				AudioRegistry.Clear();
				if (!Directory.Exists(dir))
				{
					return;
				}
				string[] files = Directory.GetFiles(dir);
				foreach (string file in files)
				{
					string extension = Path.GetExtension(file);
					string ext = extension.Substring(1, extension.Length - 1);
					if (_allowedAudioTypes.Contains(ext))
					{
						string key = Path.GetFileNameWithoutExtension(file);
						string key2 = key;
						AudioClip value = await LoadSound(file, ext);
						AudioRegistry.TryAdd(key2, value);
					}
				}
			}
			catch
			{
			}
		}

		private void ApplyHarmonyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			Harmony val = new Harmony("galfarious.WKTranslator.patches");
			val.PatchAll();
		}

		private static async Task<AudioClip> LoadSound(string filename, string type)
		{
			AudioClip audioClip = null;
			string text = type.ToLower();
			if (1 == 0)
			{
			}
			AudioType val = (AudioType)(text switch
			{
				"wav" => 20, 
				"ogg" => 14, 
				"mp3" => 13, 
				_ => 0, 
			});
			if (1 == 0)
			{
			}
			AudioType audioType = val;
			if ((int)audioType == 0)
			{
				return null;
			}
			UnityWebRequest uwr = new UnityWebRequest(filename, "GET")
			{
				downloadHandler = (DownloadHandler)new DownloadHandlerAudioClip(filename, audioType)
			};
			DownloadHandlerAudioClip dh = (DownloadHandlerAudioClip)uwr.downloadHandler;
			dh.streamAudio = false;
			dh.compressed = true;
			uwr.SendWebRequest();
			try
			{
				while (!uwr.isDone)
				{
					await Task.Delay(5);
				}
				if ((int)uwr.result == 2 || (int)uwr.result == 3)
				{
					LogManager.Error(uwr.error);
				}
				else
				{
					audioClip = dh.audioClip;
				}
			}
			catch (Exception e)
			{
				LogManager.Error(e.Message + "\n" + e.StackTrace);
			}
			return audioClip;
		}
	}
	public static class TextScanner
	{
		private class ScannerBehaviour : MonoBehaviour
		{
			private float _timer;

			private const float ScanInterval = 3f;

			private void Update()
			{
				_timer += Time.unscaledDeltaTime;
				if (_timer >= 3f)
				{
					_timer = 0f;
					ScanUI();
				}
			}

			private void ScanUI()
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				Text[] array = Resources.FindObjectsOfTypeAll<Text>();
				Scene scene;
				foreach (Text val in array)
				{
					scene = ((Component)val).gameObject.scene;
					if (!((Scene)(ref scene)).isLoaded)
					{
						scene = ((Component)val).gameObject.scene;
						if (!(((Scene)(ref scene)).name == "DontDestroyOnLoad"))
						{
							continue;
						}
					}
					AddFoundString(val.text);
				}
				TMP_Text[] array2 = Resources.FindObjectsOfTypeAll<TMP_Text>();
				foreach (TMP_Text val2 in array2)
				{
					scene = ((Component)val2).gameObject.scene;
					if (!((Scene)(ref scene)).isLoaded)
					{
						scene = ((Component)val2).gameObject.scene;
						if (!(((Scene)(ref scene)).name == "DontDestroyOnLoad"))
						{
							continue;
						}
					}
					AddFoundString(val2.text);
				}
			}
		}

		private static Dictionary<string, HashSet<string>> _categorizedStrings = new Dictionary<string, HashSet<string>>();

		private static bool _isActive;

		private static GameObject _scannerGo;

		private static readonly Regex GarbageFilter = new Regex("^<[^>]+>[\\d\\.,\\s]+<\\/[^>]+>$|^Time Since Last Hit:|^<color=[^>]+>null</color>|^[\\d\\W]+$|<sprite=", RegexOptions.IgnoreCase);

		public static void RunScanner()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (!_isActive)
			{
				_isActive = true;
				_categorizedStrings.Clear();
				_scannerGo = new GameObject("WK_TextScanner");
				_scannerGo.AddComponent<ScannerBehaviour>();
				Object.DontDestroyOnLoad((Object)(object)_scannerGo);
			}
		}

		public static void StopScanner()
		{
			if (_isActive)
			{
				_isActive = false;
				if ((Object)(object)_scannerGo != (Object)null)
				{
					Object.Destroy((Object)(object)_scannerGo);
				}
				SaveToFile();
			}
		}

		private static void AddFoundString(string text)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (IsValidText(text))
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string text2 = ((Scene)(ref activeScene)).name;
				if (string.IsNullOrEmpty(text2))
				{
					text2 = "Unknown";
				}
				if (!_categorizedStrings.ContainsKey(text2))
				{
					_categorizedStrings[text2] = new HashSet<string>();
				}
				if (!_categorizedStrings[text2].Contains(text))
				{
					_categorizedStrings[text2].Add(text);
					LogManager.Debug("Found text: " + text);
				}
			}
		}

		private static bool IsValidText(string s)
		{
			if (string.IsNullOrWhiteSpace(s))
			{
				return false;
			}
			if (s.Contains("UnityEngine") || s.Contains("System."))
			{
				return false;
			}
			if (GarbageFilter.IsMatch(s))
			{
				return false;
			}
			if (s.Length == 1 && s != "I" && s != "A" && s != "a")
			{
				return false;
			}
			return true;
		}

		private static void SaveToFile()
		{
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (HashSet<string> value in _categorizedStrings.Values)
			{
				foreach (string item in value)
				{
					if (!dictionary.ContainsKey(item))
					{
						dictionary[item] = 0;
					}
					dictionary[item]++;
				}
			}
			Dictionary<string, HashSet<string>> dictionary2 = new Dictionary<string, HashSet<string>>();
			HashSet<string> hashSet = new HashSet<string>();
			foreach (KeyValuePair<string, HashSet<string>> categorizedString in _categorizedStrings)
			{
				string key = categorizedString.Key;
				dictionary2[key] = new HashSet<string>();
				foreach (string item2 in categorizedString.Value)
				{
					if (dictionary[item2] > 1)
					{
						hashSet.Add(item2);
					}
					else
					{
						dictionary2[key].Add(item2);
					}
				}
			}
			if (hashSet.Count > 0)
			{
				dictionary2["_Common"] = hashSet;
			}
			JObject val = new JObject();
			foreach (string item3 in dictionary2.Keys.OrderBy((string k) => k))
			{
				HashSet<string> hashSet2 = dictionary2[item3];
				if (hashSet2.Count == 0)
				{
					continue;
				}
				JObject val2 = new JObject();
				foreach (string item4 in hashSet2.OrderBy((string x) => x))
				{
					val2[item4] = JToken.op_Implicit(item4);
				}
				val[item3] = (JToken)(object)val2;
			}
			string text = Path.Combine(Paths.PluginPath, "WKTranslator");
			Directory.CreateDirectory(text);
			string text2 = Path.Combine(text, "scan_output_categorized.json");
			File.WriteAllText(text2, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>()));
			Debug.Log((object)("[WKTranslator] Scan saved to " + text2));
		}
	}
	public class TranslationConfig
	{
		[JsonProperty("languageKey")]
		public string LanguageKey { get; set; }

		[JsonProperty("languageName")]
		public string LanguageName { get; set; }

		[JsonProperty("authors")]
		public List<string> Authors { get; set; }

		[JsonIgnore]
		public string ConfigFileName { get; set; }

		[JsonIgnore]
		[JsonProperty("fontFile")]
		public string FontFileName { get; set; }
	}
	public class TranslationFolder
	{
		public string FolderPath { get; }

		public TranslationConfig Config { get; }

		public TranslationFolder(string path, TranslationConfig config)
		{
			FolderPath = path;
			Config = config;
		}
	}
	public static class TranslationScanner
	{
		public static List<TranslationFolder> Scan(string rootPluginPath)
		{
			List<TranslationFolder> list = new List<TranslationFolder>();
			string[] directories = Directory.GetDirectories(rootPluginPath);
			foreach (string path in directories)
			{
				IEnumerable<string> enumerable = from x in Directory.GetFiles(path, "*.json")
					where !string.IsNullOrEmpty(x)
					select x;
				foreach (string item in enumerable)
				{
					LogManager.Debug(item);
					try
					{
						TranslationConfig translationConfig = JsonConvert.DeserializeObject<TranslationConfig>(File.ReadAllText(item));
						translationConfig.ConfigFileName = Path.GetFileName(item);
						list.Add(new TranslationFolder(path, translationConfig));
					}
					catch (Exception arg)
					{
						LogManager.Error($"Failed to load {item}\n{arg}");
					}
				}
			}
			return list;
		}
	}
	public class WKTranslationManager : MonoBehaviour
	{
		[HarmonyPatch(typeof(TMP_Text))]
		public static class TMPTextPatches
		{
			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPrefix]
			public static bool PrefixText(TMP_Text __instance, ref string __0)
			{
				if (string.IsNullOrEmpty(__0))
				{
					return true;
				}
				if (Plugin.Translations.TryGetValue(__0, out var value))
				{
					__0 = value;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Text))]
		public static class LegacyTextPatches
		{
			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPrefix]
			public static bool PrefixText(Text __instance, ref string __0)
			{
				if (string.IsNullOrEmpty(__0))
				{
					return true;
				}
				if (Plugin.Translations.TryGetValue(__0, out var value))
				{
					__0 = value;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Sprite))]
		private static class SpritePatches
		{
			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void PostFix_texture(ref Texture2D __result)
			{
				if (__result != null && Plugin.TextureRegistry.TryGetValue(((Object)__result).name, out var value))
				{
					__result = value;
				}
			}
		}

		[HarmonyPatch(typeof(SpriteRenderer))]
		private static class SpriteRendererTextureOverridePatch
		{
			[HarmonyPatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPostfix]
			private static void Postfix_SetSprite(SpriteRenderer __instance)
			{
				try
				{
					if (__instance != null)
					{
						Sprite sprite = __instance.sprite;
						object obj;
						if (sprite == null)
						{
							obj = null;
						}
						else
						{
							Texture2D texture = sprite.texture;
							obj = ((texture != null) ? ((Object)texture).name : null);
						}
						string text = (string)obj;
						if (text != null && Plugin.TextureRegistry.TryGetValue(text, out var value) && value != null)
						{
							OverrideRendererTexture(__instance, value);
						}
					}
				}
				catch (Exception arg)
				{
					LogManager.Debug($"[MaterialOverride] failed on {((Object)__instance).name}: {arg}");
				}
			}
		}

		[HarmonyPatch]
		private static class AudioSourcePatches
		{
			[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { })]
			[HarmonyPrefix]
			private static void Play_NoArgs_Postfix(AudioSource __instance)
			{
				SwapClip(__instance);
			}

			[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { typeof(double) })]
			[HarmonyPrefix]
			private static void Play_DelayDouble_Postfix(AudioSource __instance)
			{
				SwapClip(__instance);
			}

			[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { typeof(ulong) })]
			[HarmonyPrefix]
			private static void Play_DelayUlong_Postfix(AudioSource __instance)
			{
				SwapClip(__instance);
			}

			[HarmonyPatch(typeof(AudioSource), "PlayOneShot", new Type[] { typeof(AudioClip) })]
			[HarmonyPrefix]
			private static void PlayOneShot_ClipOnly_Postfix(AudioSource __instance, ref AudioClip __0)
			{
				if (Plugin.AudioRegistry.TryGetValue(((Object)__0).name, out var value))
				{
					__0 = value;
				}
			}

			[HarmonyPatch(typeof(AudioSource), "PlayOneShot", new Type[]
			{
				typeof(AudioClip),
				typeof(float)
			})]
			[HarmonyPrefix]
			private static void PlayOneShot_ClipAndVolume_Postfix(AudioSource __instance, ref AudioClip __0)
			{
				if (Plugin.AudioRegistry.TryGetValue(((Object)__0).name, out var value))
				{
					__0 = value;
				}
			}

			private static void SwapClip(AudioSource src)
			{
				if (((src != null) ? src.clip : null) != null)
				{
					string name = ((Object)src.clip).name;
					if (Plugin.AudioRegistry.TryGetValue(name, out var value))
					{
						src.clip = value;
					}
				}
			}
		}

		public static WKTranslationManager Instance;

		private static readonly int MainTexture = Shader.PropertyToID("_MainTex");

		public void Awake()
		{
			if (Instance != null && (Object)(object)Instance != (Object)(object)this)
			{
				LogManager.Warn("Destroying duplicate WKTranslationManager");
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			LogManager.Info("WKTranslationManager Awake");
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		public async void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (CanContinueScene(((Scene)(ref scene)).name))
			{
				await PrepareAsync();
				ReplaceAllMaterial();
				ReplaceTextures();
				ReplaceAllMaterial();
				ReplaceOnSources();
				CommandConsole.AddCommand("startscanner", (Action<string[]>)delegate
				{
					TextScanner.RunScanner();
				}, false);
				CommandConsole.AddCommand("endscanner", (Action<string[]>)delegate
				{
					TextScanner.StopScanner();
				}, false);
				CommandConsole.AddCommand("reloadtranslation", (Action<string[]>)delegate
				{
					Plugin.Instance.ReloadLanguage();
				}, false);
				LogManager.Warn("Added commands");
			}
		}

		private async Task PrepareAsync()
		{
			Scene activeScene = SceneManager.GetActiveScene();
			LogManager.Info("Scanning scene: " + ((Scene)(ref activeScene)).name + " for static text...");
			TMP_Text[] allTmp = Resources.FindObjectsOfTypeAll<TMP_Text>();
			TMP_Text[] array = allTmp;
			foreach (TMP_Text txt in array)
			{
				if (ValidForTranslation(((Component)txt).gameObject))
				{
					TryTranslate(txt);
				}
			}
			Text[] allLegacy = Resources.FindObjectsOfTypeAll<Text>();
			Text[] array2 = allLegacy;
			foreach (Text txt2 in array2)
			{
				if (ValidForTranslation(((Component)txt2).gameObject))
				{
					TryTranslateLegacy(txt2);
				}
			}
			RectTransform[] rectTransforms = Resources.FindObjectsOfTypeAll<RectTransform>();
			RectTransform[] array3 = rectTransforms;
			foreach (RectTransform rectTransform in array3)
			{
				rectTransform.ForceUpdateRectTransforms();
			}
		}

		private bool ValidForTranslation(GameObject go)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Scene scene = go.scene;
			int result;
			if (!((Scene)(ref scene)).isLoaded)
			{
				scene = go.scene;
				result = ((((Scene)(ref scene)).name == "DontDestroyOnLoad") ? 1 : 0);
			}
			else
			{
				result = 1;
			}
			return (byte)result != 0;
		}

		public static void TryTranslate(TMP_Text txtComponent)
		{
			if (!((Object)(object)txtComponent == (Object)null) && !string.IsNullOrEmpty(txtComponent.text) && Plugin.Translations.TryGetValue(txtComponent.text, out var value))
			{
				txtComponent.text = value;
				txtComponent.autoSizeTextContainer = true;
				txtComponent.alignment = (TextAlignmentOptions)4098;
				RectTransform component = ((Component)txtComponent.transform.parent).GetComponent<RectTransform>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.ForceUpdateRectTransforms();
				}
			}
		}

		public static void TryTranslateLegacy(Text txtComponent)
		{
			if (!((Object)(object)txtComponent == (Object)null) && !string.IsNullOrEmpty(txtComponent.text) && Plugin.Translations.TryGetValue(txtComponent.text, out var value))
			{
				txtComponent.text = value;
				RectTransform component = ((Component)((Component)txtComponent).transform.parent).GetComponent<RectTransform>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.ForceUpdateRectTransforms();
				}
			}
		}

		private void ReplaceAllMaterial()
		{
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			foreach (Material val in array)
			{
				if (val.HasProperty(MainTexture) && ((val != null) ? val.mainTexture : null) != null)
				{
					LogManager.Debug("Found " + ((Object)val.mainTexture).name);
					if (Plugin.TextureRegistry.TryGetValue(((Object)val.mainTexture).name, out var value))
					{
						LogManager.Debug("Replacing " + ((Object)val.mainTexture).name);
						val.mainTexture = (Texture)(object)value;
					}
				}
			}
		}

		private void ReplaceTextures()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Image[] array = Resources.FindObjectsOfTypeAll<Image>();
			Rect val2 = default(Rect);
			foreach (Image val in array)
			{
				if (val.sprite != null && Plugin.TextureRegistry.TryGetValue(((Object)val.sprite).name, out var value))
				{
					Sprite sprite = val.sprite;
					((Rect)(ref val2))..ctor(0f, 0f, (float)((Texture)value).width, (float)((Texture)value).height);
					Sprite overrideSprite = (val.sprite = Sprite.Create(value, val2, new Vector2(0.5f, 0.5f), sprite.pixelsPerUnit, 0u, (SpriteMeshType)0, sprite.border));
					val.overrideSprite = overrideSprite;
					if (((Graphic)val).rectTransform != null)
					{
						LayoutRebuilder.ForceRebuildLayoutImmediate(((Graphic)val).rectTransform);
					}
				}
			}
		}

		private static void OverrideRendererTexture(SpriteRenderer sr, Texture2D newTex)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			MaterialPropertyBlock val = new MaterialPropertyBlock();
			((Renderer)sr).GetPropertyBlock(val);
			val.SetTexture(MainTexture, (Texture)(object)newTex);
			((Renderer)sr).SetPropertyBlock(val);
		}

		private void ReplaceOnSources()
		{
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true);
			foreach (AudioSource val in array)
			{
				if (val.clip == null)
				{
					continue;
				}
				string name = val.clip.GetName();
				if (Plugin.AudioRegistry.TryGetValue(name, out var value) && value != null)
				{
					bool isPlaying = val.isPlaying;
					bool playOnAwake = val.playOnAwake;
					val.clip = value;
					if (isPlaying || playOnAwake)
					{
						val.Play();
					}
					LogManager.Debug("Replaced AudioSource Clip on " + ((Object)((Component)val).gameObject).name + " (" + name + ")");
				}
			}
		}

		private bool CanContinueScene(string sceneName)
		{
			if (1 == 0)
			{
			}
			bool result = true;
			if (1 == 0)
			{
			}
			return result;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "galfarious.WKTranslator";

		public const string PLUGIN_NAME = "WKTranslator";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}