Decompiled source of LC Chinese Project v0.1.3

BepInEx/plugins/V81TestChn/V81TestChn.dll

Decompiled 2 hours ago
using System;
using System.Collections;
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.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore.LowLevel;
using UnityEngine.UI;
using UnityEngine.Video;

[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("V81TestChn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("V81TestChn")]
[assembly: AssemblyTitle("V81TestChn")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 V81TestChn
{
	internal static class AlertTextureReplacementService
	{
		[CompilerGenerated]
		private sealed class <WaitForFixedSceneLabels>d__35 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string stage;

			private float <elapsed>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForFixedSceneLabels>d__35(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<elapsed>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<elapsed>5__2 += 0.25f;
					break;
				}
				if (<elapsed>5__2 < 8f)
				{
					if (SyncFixedSceneLabelsInRelayScene(stage + ".relay-scene") > 0)
					{
						_fixedSceneLabelWatcher = null;
						return false;
					}
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 1;
					return true;
				}
				Plugin.Log.LogWarning((object)("NativeRelay[" + stage + ".relay-scene] target=FixedSceneLabel action=timeout"));
				_fixedSceneLabelWatcher = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <WaitForSystemOnlineTitle>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string stage;

			public HUDManager hudManager;

			private float <elapsed>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForSystemOnlineTitle>d__34(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<elapsed>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<elapsed>5__2 += 0.1f;
					break;
				}
				if ((Object)(object)hudManager != (Object)null && <elapsed>5__2 < 12f)
				{
					TMP_Text text = FindSystemOnlineTitleByFullPath();
					if (IsExactSystemOnlineTitle(text))
					{
						ApplySystemOnlineNativeTranslation(text, stage + ".watcher");
						_systemOnlineWatcher = null;
						return false;
					}
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				Plugin.Log.LogWarning((object)("NativeRelay[" + stage + ".watcher] target=SystemOnline action=timeout"));
				_systemOnlineWatcher = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const string SystemOnlineTitleObjectName = "TipLeft1";

		private const string SystemOnlineTitleFullPath = "Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/SystemsOnline/TipLeft1";

		private const string SystemOnlineTitlePathSuffix = "IngamePlayerHUD/BottomMiddle/SystemsOnline/TipLeft1";

		private const string SystemOnlineRelativePath = "BottomMiddle/SystemsOnline/TipLeft1";

		private const string EnteringAtmosphereTitleObjectName = "LoadText";

		private const string RelaySceneName = "SampleSceneRelay";

		private const string SystemOnlineLocalizedText = "系统在线";

		private const string EnteringAtmosphereLocalizedText = "正在进入大气层...";

		private const string HazardLevelLocalizedText = "危险等级:";

		private const string LifeSupportOfflineLocalizedText = "[生命维持:离线]";

		private static Coroutine? _systemOnlineWatcher;

		private static Coroutine? _fixedSceneLabelWatcher;

		private static readonly Dictionary<string, string> FixedSceneLabels = new Dictionary<string, string>(StringComparer.Ordinal)
		{
			["TO MEET PROFIT QUOTA"] = "以达到利润配额",
			["PERFORMANCE REPORT"] = "绩效报告",
			["EMPLOYEE RANK"] = "员工等级",
			["Fines"] = "罚款",
			["(Dead)"] = "(死亡)",
			["Deceased"] = "死亡",
			["[LIFE SUPPORT: OFFLINE]"] = "[生命维持:离线]",
			["You will keep your employee rank. Your ship and credits will be reset."] = "你的员工等级将被保留,但飞船和点数将被重置。"
		};

		public static void Initialize(string pluginDir)
		{
			Plugin.Log.LogInfo((object)"Native relay title translation enabled; SYSTEMS ONLINE uses original TMP object only.");
		}

		public static void ForceApplySystemOnlineOverlay(HUDManager? hudManager, string stage)
		{
			TMP_Text val = FindSystemOnlineTitle(hudManager, allowGlobalFallback: false);
			if ((Object)(object)val != (Object)null)
			{
				ApplySystemOnlineNativeTranslation(val, stage);
				return;
			}
			Plugin.Log.LogWarning((object)("NativeRelay[" + stage + "] target=SystemOnline action=not-found"));
			AuditSystemOnlineBranch(stage, hudManager);
		}

		public static void BeginSystemOnlineExactPathWatcher(HUDManager? hudManager, string stage)
		{
			if (!((Object)(object)hudManager == (Object)null) && _systemOnlineWatcher == null)
			{
				_systemOnlineWatcher = ((MonoBehaviour)hudManager).StartCoroutine(WaitForSystemOnlineTitle(hudManager, stage));
			}
		}

		public static void TryApplySystemOnlineDirect(HUDManager? hudManager, string stage)
		{
			TMP_Text val = FindSystemOnlineTitle(hudManager, allowGlobalFallback: true);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("NativeRelay[" + stage + "] target=SystemOnline action=not-found"));
			}
			else
			{
				ApplySystemOnlineNativeTranslation(val, stage);
			}
		}

		public static void QueueSystemOnlineSync(HUDManager? hudManager, string stage)
		{
		}

		public static void TryApplyEnteringAtmosphereOverlayFromLoadingScreen(HUDManager? hudManager, string stage)
		{
			TMP_Text val = FindEnteringAtmosphereTitle(hudManager);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("NativeRelay[" + stage + "] target=EnteringAtmosphere action=not-found"));
			}
			else
			{
				ApplyEnteringAtmosphereNativeTranslation(val, stage);
			}
		}

		public static void HideEnteringAtmosphereOverlayForHud(HUDManager? hudManager, string stage)
		{
			TMP_Text val = FindEnteringAtmosphereTitle(hudManager);
			if ((Object)(object)val != (Object)null)
			{
				ApplyEnteringAtmosphereNativeTranslation(val, stage);
			}
		}

		public static void SyncEnteringAtmosphereOverlayState(TMP_Text? text, string stage)
		{
			if (!((Object)(object)text == (Object)null) && IsEnteringAtmosphereTitleObject(text))
			{
				ApplyEnteringAtmosphereNativeTranslation(text, stage);
			}
		}

		public static void SyncHazardLevelRelay(HUDManager? hudManager, string stage)
		{
			TMP_Text val = FindHazardLevelTitle(hudManager);
			if ((Object)(object)val != (Object)null)
			{
				ApplyHazardLevelNativeTranslation(val, stage);
			}
		}

		public static void SyncLandingInfo(HUDManager? hudManager, string stage)
		{
			if (!((Object)(object)hudManager == (Object)null))
			{
				ApplyDynamicFieldTranslation((TMP_Text?)(object)hudManager.planetInfoHeaderText, stage, "PlanetInfoHeader");
				ApplyDynamicFieldTranslation((TMP_Text?)(object)hudManager.planetInfoSummaryText, stage, "PlanetInfoSummary");
				ApplyDynamicFieldTranslation((TMP_Text?)(object)hudManager.planetRiskLevelText, stage, "PlanetRiskLevel");
				SyncHazardLevelRelay(hudManager, stage);
			}
		}

		public static void SyncFixedSceneLabels(HUDManager? hudManager, string stage)
		{
			if (!((Object)(object)hudManager == (Object)null))
			{
				TMP_Text[] componentsInChildren = ((Component)hudManager).GetComponentsInChildren<TMP_Text>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					TryReplaceFixedSceneLabel(componentsInChildren[i], stage);
				}
			}
		}

		public static void BeginFixedSceneLabelWatcher(HUDManager? hudManager, string stage)
		{
			if (!((Object)(object)hudManager == (Object)null) && _fixedSceneLabelWatcher == null)
			{
				_fixedSceneLabelWatcher = ((MonoBehaviour)hudManager).StartCoroutine(WaitForFixedSceneLabels(stage));
			}
		}

		public static void TryReplaceSystemOnlineText(TMP_Text? text, string stage)
		{
			if (!((Object)(object)text == (Object)null))
			{
				if (IsSystemOnlineObject(text))
				{
					ApplySystemOnlineNativeTranslation(text, stage);
				}
				else if (IsEnteringAtmosphereTitleObject(text))
				{
					ApplyEnteringAtmosphereNativeTranslation(text, stage);
				}
				else if (IsHazardLevelTitle(text.text))
				{
					ApplyHazardLevelNativeTranslation(text, stage);
				}
				else
				{
					TryReplaceFixedSceneLabel(text, stage);
				}
			}
		}

		public static bool TryReplaceFixedSceneLabel(TMP_Text? text, string stage)
		{
			if ((Object)(object)text == (Object)null || string.IsNullOrWhiteSpace(text.text))
			{
				return false;
			}
			if (!TryResolveFixedSceneLabel(text.text, out string localized))
			{
				return false;
			}
			ApplyLocalizedText(text, localized, stage, "FixedSceneLabel");
			Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=FixedSceneLabel action=applied name=" + ((Object)text).name + " path=" + BuildPath(text.transform) + " text=" + text.text));
			return true;
		}

		public static void TryReplaceSystemOnlineText(Text? text, string stage)
		{
		}

		public static void TryReplaceSystemOnlineText(TextMesh? text, string stage)
		{
		}

		public static void TryReplace(Image? image, string stage)
		{
		}

		public static void TryReplace(RawImage? image, string stage)
		{
		}

		public static void TryReplace(SpriteRenderer? renderer, string stage)
		{
		}

		public static void TryReplace(Material? material, string stage)
		{
		}

		private static void ApplySystemOnlineNativeTranslation(TMP_Text text, string stage)
		{
			if (!((Behaviour)text).enabled)
			{
				((Behaviour)text).enabled = true;
			}
			ApplyLocalizedText(text, ResolveLocalizedText(text.text, "系统在线"), stage, "SystemOnline");
			Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=SystemOnline action=applied name=" + ((Object)text).name + " path=" + BuildPath(text.transform) + " text=" + text.text));
		}

		[IteratorStateMachine(typeof(<WaitForSystemOnlineTitle>d__34))]
		private static IEnumerator WaitForSystemOnlineTitle(HUDManager hudManager, string stage)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForSystemOnlineTitle>d__34(0)
			{
				hudManager = hudManager,
				stage = stage
			};
		}

		[IteratorStateMachine(typeof(<WaitForFixedSceneLabels>d__35))]
		private static IEnumerator WaitForFixedSceneLabels(string stage)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForFixedSceneLabels>d__35(0)
			{
				stage = stage
			};
		}

		private static void ApplyEnteringAtmosphereNativeTranslation(TMP_Text text, string stage)
		{
			ApplyLocalizedText(text, ResolveLocalizedText(text.text, "正在进入大气层..."), stage, "EnteringAtmosphere");
		}

		private static void ApplyHazardLevelNativeTranslation(TMP_Text text, string stage)
		{
			ApplyLocalizedText(text, "危险等级:", stage, "HazardLevel");
		}

		private static void ApplyLocalizedText(TMP_Text text, string localized, string stage, string target)
		{
			if (!string.IsNullOrWhiteSpace(localized))
			{
				if (!string.Equals(text.text, localized, StringComparison.Ordinal))
				{
					text.text = localized;
				}
				FontFallbackService.ApplyFallback(text, localized);
				ApplyLifeSupportOfflineTypography(text, localized);
			}
		}

		private static void ApplyLifeSupportOfflineTypography(TMP_Text text, string localized)
		{
			if (string.Equals(localized, "[生命维持:离线]", StringComparison.Ordinal))
			{
				text.richText = true;
				text.enableWordWrapping = false;
				text.overflowMode = (TextOverflowModes)0;
				text.fontStyle = (FontStyles)0;
				text.characterSpacing = Math.Max(text.characterSpacing, 6f);
				text.wordSpacing = Math.Max(text.wordSpacing, 8f);
			}
		}

		private static TMP_Text? FindSystemOnlineTitle(HUDManager? hudManager, bool allowGlobalFallback)
		{
			if ((Object)(object)hudManager != (Object)null)
			{
				if ((Object)(object)((Component)hudManager).transform != (Object)null)
				{
					Transform obj = ((Component)hudManager).transform.Find("BottomMiddle/SystemsOnline/TipLeft1");
					TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
					if (IsExactSystemOnlineTitle(val))
					{
						return val;
					}
				}
				TMP_Text[] componentsInChildren = ((Component)hudManager).GetComponentsInChildren<TMP_Text>(true);
				foreach (TMP_Text val2 in componentsInChildren)
				{
					if (IsExactSystemOnlineTitle(val2))
					{
						return val2;
					}
				}
			}
			if (allowGlobalFallback)
			{
				TMP_Text val3 = FindSystemOnlineTitleByFullPath();
				if (IsExactSystemOnlineTitle(val3))
				{
					return val3;
				}
				TMP_Text[] componentsInChildren = Resources.FindObjectsOfTypeAll<TMP_Text>();
				foreach (TMP_Text val4 in componentsInChildren)
				{
					if (IsExactSystemOnlineTitle(val4))
					{
						return val4;
					}
				}
			}
			return null;
		}

		private static TMP_Text? FindSystemOnlineTitleByFullPath()
		{
			GameObject val = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/SystemsOnline/TipLeft1");
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<TMP_Text>();
		}

		private static TMP_Text? FindEnteringAtmosphereTitle(HUDManager? hudManager)
		{
			if ((Object)(object)hudManager?.LoadingScreen == (Object)null)
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)hudManager.LoadingScreen).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (IsEnteringAtmosphereTitleObject(val))
				{
					return val;
				}
			}
			return null;
		}

		private static TMP_Text? FindHazardLevelTitle(HUDManager? hudManager)
		{
			if ((Object)(object)hudManager == (Object)null)
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)hudManager).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (IsHazardLevelTitle(val.text))
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsSystemOnlineObject(TMP_Text? text)
		{
			return IsExactSystemOnlineTitle(text);
		}

		private static bool IsSystemOnlinePath(Transform? transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			return BuildPath(transform).EndsWith("IngamePlayerHUD/BottomMiddle/SystemsOnline/TipLeft1", StringComparison.OrdinalIgnoreCase);
		}

		private static bool IsEnteringAtmosphereTitleObject(TMP_Text? text)
		{
			if ((Object)(object)text == (Object)null)
			{
				return false;
			}
			if (string.Equals(((Object)text).name, "LoadText", StringComparison.OrdinalIgnoreCase))
			{
				return HasNamedAncestor(text.transform, "LoadingText");
			}
			return false;
		}

		private static bool IsHazardLevelTitle(string? text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string a = text.Trim();
			if (!string.Equals(a, "HAZARD LEVEL:", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "危险等级:", StringComparison.Ordinal))
			{
				return string.Equals(a, "危险等级:", StringComparison.Ordinal);
			}
			return true;
		}

		private static string ResolveLocalizedText(string? current, string fallback)
		{
			if (!string.IsNullOrWhiteSpace(current) && TranslationService.TryTranslate(current, out string translated))
			{
				return translated;
			}
			return fallback;
		}

		private static bool TryResolveFixedSceneLabel(string? current, out string localized)
		{
			localized = string.Empty;
			if (string.IsNullOrWhiteSpace(current))
			{
				return false;
			}
			if (FixedSceneLabels.TryGetValue(current.Trim(), out localized) && !string.IsNullOrWhiteSpace(localized))
			{
				return true;
			}
			return false;
		}

		private static int SyncFixedSceneLabelsInRelayScene(string stage)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Scene sceneByName = SceneManager.GetSceneByName("SampleSceneRelay");
			if (!((Scene)(ref sceneByName)).IsValid() || !((Scene)(ref sceneByName)).isLoaded)
			{
				return 0;
			}
			int num = 0;
			GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
			for (int i = 0; i < rootGameObjects.Length; i++)
			{
				TMP_Text[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<TMP_Text>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					if (TryReplaceFixedSceneLabel(componentsInChildren[j], stage))
					{
						num++;
					}
				}
			}
			return num;
		}

		private static bool HasNamedAncestor(Transform? transform, string expectedName)
		{
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				if (string.Equals(((Object)val).name, expectedName, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void AuditSystemOnlineBranch(string stage, HUDManager? hudManager)
		{
			int num = 0;
			if ((Object)(object)hudManager != (Object)null)
			{
				TMP_Text[] componentsInChildren = ((Component)hudManager).GetComponentsInChildren<TMP_Text>(true);
				foreach (TMP_Text val in componentsInChildren)
				{
					if (HasNamedAncestor(val.transform, "SystemsOnline"))
					{
						num++;
						Plugin.Log.LogInfo((object)$"NativeRelay[{stage}] target=SystemOnline action=audit exact={IsExactSystemOnlineTitle(val)} name={((Object)val).name} path={BuildPath(val.transform)} text={val.text}");
					}
				}
			}
			_ = 0;
		}

		private static void ApplyDynamicFieldTranslation(TMP_Text? text, string stage, string target)
		{
			if (!((Object)(object)text == (Object)null) && !string.IsNullOrWhiteSpace(text.text) && TranslationService.TryTranslate(text.text, out string translated) && !string.IsNullOrWhiteSpace(translated))
			{
				if (!string.Equals(text.text, translated, StringComparison.Ordinal))
				{
					text.text = translated;
				}
				FontFallbackService.ApplyFallback(text, translated);
				Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=" + target + " action=applied name=" + ((Object)text).name + " path=" + BuildPath(text.transform) + " text=" + text.text));
			}
		}

		private static string BuildPath(Transform? transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "<null>";
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static bool IsExactSystemOnlineTitle(TMP_Text? text)
		{
			if ((Object)(object)text == (Object)null)
			{
				return false;
			}
			if (BuildPath(text.transform).EndsWith("IngamePlayerHUD/BottomMiddle/SystemsOnline/TipLeft1", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return false;
		}
	}
	internal static class EmbeddedFontPatcherService
	{
		private sealed class FontBundlePair
		{
			public string BundleName { get; set; } = string.Empty;


			public TMP_FontAsset? Normal { get; set; }

			public TMP_FontAsset? Transmit { get; set; }
		}

		[CompilerGenerated]
		private sealed class <ResolveCandidateDirectories>d__24 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private string <>2__current;

			private int <>l__initialThreadId;

			private string pluginDir;

			public string <>3__pluginDir;

			private string <relative>5__2;

			string IEnumerator<string>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ResolveCandidateDirectories>d__24(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<relative>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<relative>5__2 = NormalizePathSegment(_fontAssetsPath.Value);
					if (!string.IsNullOrWhiteSpace(<relative>5__2))
					{
						<>2__current = Path.Combine(pluginDir, "V81TestChn", <relative>5__2);
						<>1__state = 1;
						return true;
					}
					goto IL_00cd;
				case 1:
					<>1__state = -1;
					<>2__current = Path.Combine(pluginDir, <relative>5__2);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = Path.Combine(Paths.ConfigPath, <relative>5__2);
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					goto IL_00cd;
				case 4:
					<>1__state = -1;
					<>2__current = Path.Combine(pluginDir, "V81TestChn", "fonts", "fontpatcher", "default");
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					<>2__current = Path.Combine(Paths.ConfigPath, "FontPatcher", "default");
					<>1__state = 6;
					return true;
				case 6:
					{
						<>1__state = -1;
						return false;
					}
					IL_00cd:
					<>2__current = Path.Combine(pluginDir, "V81TestChn", "fontpatcher", "default");
					<>1__state = 4;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<string> IEnumerable<string>.GetEnumerator()
			{
				<ResolveCandidateDirectories>d__24 <ResolveCandidateDirectories>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ResolveCandidateDirectories>d__ = this;
				}
				else
				{
					<ResolveCandidateDirectories>d__ = new <ResolveCandidateDirectories>d__24(0);
				}
				<ResolveCandidateDirectories>d__.pluginDir = <>3__pluginDir;
				return <ResolveCandidateDirectories>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<string>)this).GetEnumerator();
			}
		}

		private static readonly List<FontBundlePair> LoadedBundles = new List<FontBundlePair>();

		private static readonly HashSet<int> PatchedFontIds = new HashSet<int>();

		private static readonly HashSet<string> ScannedDirectories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static ConfigEntry<bool>? _enabled;

		private static ConfigEntry<string>? _fontAssetsPath;

		private static ConfigEntry<string>? _normalRegexPattern;

		private static ConfigEntry<string>? _transmitRegexPattern;

		private static ConfigEntry<bool>? _useVanillaNormal;

		private static ConfigEntry<bool>? _useVanillaTransmit;

		private static ConfigEntry<bool>? _debugLog;

		private static ConfigEntry<bool>? _applyMaterialTweaks;

		private static ConfigEntry<string>? _bundleNameRegexPattern;

		private static Regex? _normalRegex;

		private static Regex? _transmitRegex;

		private static Regex? _bundleNameRegex;

		private static bool _initialized;

		private static int _patchLogBudget = 160;

		private static int _scanLogBudget = 60;

		private static bool _loggedNormalBundleBypass;

		public static void Initialize(string pluginDir, ConfigFile config)
		{
			if (!_initialized)
			{
				_enabled = config.Bind<bool>("EmbeddedFontPatcher", "Enable", true, "Enable embedded FontPatcher compatibility behavior.");
				_fontAssetsPath = config.Bind<string>("EmbeddedFontPatcher", "FontAssetsPath", "fontpatcher\\default", "Relative directory for font bundles.");
				_normalRegexPattern = config.Bind<string>("EmbeddedFontPatcher", "NormalFontNameRegex", "^(b|DialogueText).*$", "Regex used to detect normal UI fonts.");
				_transmitRegexPattern = config.Bind<string>("EmbeddedFontPatcher", "TransmitFontNameRegex", "^.*$", "Regex used to detect signal/transmit fonts.");
				_useVanillaNormal = config.Bind<bool>("EmbeddedFontPatcher", "UseVanillaNormalFont", true, "Keep vanilla normal font characters in addition to bundle fallback fonts.");
				_useVanillaTransmit = config.Bind<bool>("EmbeddedFontPatcher", "UseVanillaTransmitFont", true, "Keep vanilla transmit font characters in addition to bundle fallback fonts.");
				_debugLog = config.Bind<bool>("EmbeddedFontPatcher", "DebugLog", false, "Enable verbose embedded FontPatcher logs.");
				_applyMaterialTweaks = config.Bind<bool>("EmbeddedFontPatcher", "ApplyMaterialTweaks", false, "Apply FontPatcher-like material underlay tweaks.");
				_bundleNameRegexPattern = config.Bind<string>("EmbeddedFontPatcher", "BundleNameRegex", "^(00 default|cn|zh.*)$", "Only bundles whose file name matches this regex will be loaded. Prevents unintended style drift from unrelated language bundles.");
				UpgradeLegacyRegexDefaultsIfNeeded();
				_normalRegex = CreateRegex(_normalRegexPattern.Value, "^(b|DialogueText).*$");
				_transmitRegex = CreateRegex(_transmitRegexPattern.Value, "^.*$");
				_bundleNameRegex = CreateRegex(_bundleNameRegexPattern.Value, "^(00 default|cn|zh.*)$");
				_initialized = true;
				if (_enabled.Value)
				{
					LoadBundles(pluginDir);
					PatchLoadedFontAssets();
				}
				Plugin.Log.LogInfo((object)$"EmbeddedFontPatcher initialized: enabled={_enabled.Value}, bundles={LoadedBundles.Count}, assetsPath={_fontAssetsPath.Value}");
			}
		}

		public static void PatchFontAsset(TMP_FontAsset? fontAsset, string stage = "unknown")
		{
			if (!_initialized || !_enabled.Value || (Object)(object)fontAsset == (Object)null || _normalRegex == null || _transmitRegex == null)
			{
				return;
			}
			int instanceID = ((Object)fontAsset).GetInstanceID();
			string text = ((Object)fontAsset).name ?? string.Empty;
			bool flag = _normalRegex.IsMatch(text);
			bool flag2 = _transmitRegex.IsMatch(text);
			if ((!flag && !flag2) || !PatchedFontIds.Add(instanceID))
			{
				return;
			}
			if (fontAsset.fallbackFontAssetTable == null)
			{
				fontAsset.fallbackFontAssetTable = new List<TMP_FontAsset>();
			}
			if (flag)
			{
				DisableVanillaFont(fontAsset);
				if (!_loggedNormalBundleBypass)
				{
					_loggedNormalBundleBypass = true;
					Plugin.Log.LogWarning((object)"EmbeddedFontPatcher bypassed normal bundle fallbacks; relying on V81 dynamic Chinese fallback to avoid unreadable atlas stalls.");
				}
			}
			if (flag2 && !_useVanillaTransmit.Value)
			{
				DisableVanillaFont(fontAsset);
			}
			int num = 0;
			foreach (FontBundlePair loadedBundle in LoadedBundles)
			{
				if (!flag)
				{
					TMP_FontAsset val = (flag ? loadedBundle.Normal : loadedBundle.Transmit);
					if (!((Object)(object)val == (Object)null) && !fontAsset.fallbackFontAssetTable.Contains(val))
					{
						fontAsset.fallbackFontAssetTable.Add(val);
						num++;
					}
				}
			}
			if (_applyMaterialTweaks.Value)
			{
				ApplyMaterialTweaks(((TMP_Asset)fontAsset).material);
			}
			if (num > 0 && _patchLogBudget > 0)
			{
				_patchLogBudget--;
				Plugin.Log.LogWarning((object)string.Format("EmbeddedFontPatcher patched '{0}' at {1}: addedFallbacks={2}, mode={3}", text, stage, num, flag ? "Normal" : "Transmit"));
			}
			else if (_debugLog.Value)
			{
				Plugin.Log.LogInfo((object)string.Format("EmbeddedFontPatcher visited '{0}' at {1}: addedFallbacks={2}, mode={3}", text, stage, num, flag ? "Normal" : "Transmit"));
			}
		}

		public static void PatchTextComponent(TMP_Text? text, string stage = "unknown")
		{
			if (!((Object)(object)((text != null) ? text.font : null) == (Object)null))
			{
				PatchFontAsset(text.font, stage);
			}
		}

		private static void LoadBundles(string pluginDir)
		{
			LoadedBundles.Clear();
			ScannedDirectories.Clear();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in ResolveCandidateDirectories(pluginDir))
			{
				if (!Directory.Exists(item) || !ScannedDirectories.Add(item))
				{
					continue;
				}
				int num = 0;
				FileInfo[] files = new DirectoryInfo(item).GetFiles("*", SearchOption.TopDirectoryOnly);
				foreach (FileInfo fileInfo in files)
				{
					if (!hashSet.Add(fileInfo.Name))
					{
						continue;
					}
					if (_bundleNameRegex != null && !_bundleNameRegex.IsMatch(fileInfo.Name))
					{
						if (_debugLog.Value)
						{
							Plugin.Log.LogInfo((object)("EmbeddedFontPatcher skipped bundle '" + fileInfo.Name + "' by BundleNameRegex."));
						}
						continue;
					}
					try
					{
						AssetBundle val = AssetBundle.LoadFromFile(fileInfo.FullName);
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						TMP_FontAsset val2 = val.LoadAsset<TMP_FontAsset>("Normal");
						TMP_FontAsset val3 = val.LoadAsset<TMP_FontAsset>("Transmit");
						if (!((Object)(object)val2 == (Object)null) || !((Object)(object)val3 == (Object)null))
						{
							if ((Object)(object)val2 != (Object)null)
							{
								((Object)val2).name = fileInfo.Name + "(Normal)";
							}
							if ((Object)(object)val3 != (Object)null)
							{
								((Object)val3).name = fileInfo.Name + "(Transmit)";
							}
							LoadedBundles.Add(new FontBundlePair
							{
								BundleName = fileInfo.Name,
								Normal = val2,
								Transmit = val3
							});
							num++;
							if (_debugLog.Value)
							{
								Plugin.Log.LogInfo((object)$"EmbeddedFontPatcher loaded bundle '{fileInfo.Name}' from '{item}': normal={(Object)(object)val2 != (Object)null}, transmit={(Object)(object)val3 != (Object)null}");
							}
						}
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("EmbeddedFontPatcher failed loading '" + fileInfo.FullName + "': " + ex.GetType().Name + ": " + ex.Message));
					}
				}
				if (num > 0 && _scanLogBudget > 0)
				{
					_scanLogBudget--;
					Plugin.Log.LogInfo((object)$"EmbeddedFontPatcher loaded {num} bundles from '{item}'.");
				}
			}
		}

		[IteratorStateMachine(typeof(<ResolveCandidateDirectories>d__24))]
		private static IEnumerable<string> ResolveCandidateDirectories(string pluginDir)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ResolveCandidateDirectories>d__24(-2)
			{
				<>3__pluginDir = pluginDir
			};
		}

		private static void PatchLoadedFontAssets()
		{
			TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			for (int i = 0; i < array.Length; i++)
			{
				PatchFontAsset(array[i], "Resources.Scan");
			}
		}

		private static void DisableVanillaFont(TMP_FontAsset font)
		{
			if (font.characterLookupTable != null)
			{
				font.characterLookupTable.Clear();
			}
			font.atlasPopulationMode = (AtlasPopulationMode)0;
		}

		private static void ApplyMaterialTweaks(Material? material)
		{
			if (!((Object)(object)material == (Object)null))
			{
				if (material.HasProperty(ShaderUtilities.ID_UnderlayDilate))
				{
					material.SetFloat(ShaderUtilities.ID_UnderlayDilate, 1f);
				}
				if (material.HasProperty(ShaderUtilities.ID_UnderlayOffsetX))
				{
					material.SetFloat(ShaderUtilities.ID_UnderlayOffsetX, 0.1f);
				}
			}
		}

		private static void UpgradeLegacyRegexDefaultsIfNeeded()
		{
			if (_normalRegexPattern != null && _transmitRegexPattern != null)
			{
				string text = "^(b|DialogueText|3270.*)$";
				string text2 = "^edunline.*$";
				string text3 = "^(b|DialogueText).*$";
				string text4 = "^.*$";
				if (string.Equals(_normalRegexPattern.Value, text, StringComparison.Ordinal))
				{
					_normalRegexPattern.Value = text3;
					Plugin.Log.LogWarning((object)("EmbeddedFontPatcher auto-upgraded NormalFontNameRegex from legacy '" + text + "' to '" + text3 + "' to match FontPatcher behavior."));
				}
				if (string.Equals(_transmitRegexPattern.Value, text2, StringComparison.Ordinal))
				{
					_transmitRegexPattern.Value = text4;
					Plugin.Log.LogWarning((object)("EmbeddedFontPatcher auto-upgraded TransmitFontNameRegex from legacy '" + text2 + "' to '" + text4 + "' to match FontPatcher behavior."));
				}
			}
		}

		private static Regex CreateRegex(string source, string fallback)
		{
			try
			{
				return new Regex(source, RegexOptions.Compiled);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("EmbeddedFontPatcher invalid regex '" + source + "', fallback to '" + fallback + "'. Error: " + ex.Message));
				return new Regex(fallback, RegexOptions.Compiled);
			}
		}

		private static string NormalizePathSegment(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return string.Empty;
			}
			return value.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar).Trim();
		}
	}
	internal static class EndGameLocalizationService
	{
		private const string DeadLocalizedText = "(死亡)";

		private const string DeceasedLocalizedText = "死亡";

		private const string MissingLocalizedText = "失踪";

		private const string TextureSubfolder = "textures";

		private const string EndgameAllPlayersDeadTextureFile = "EndgameAllPlayersDeadOverlay.png";

		private const string EndgameStatsBoxesTextureFile = "EndgameStatsBoxesLocalized.png";

		private const string EndgameStatsDeceasedTextureFile = "EndgameStatsDeceased.png";

		private const string EndgameStatsMissingTextureFile = "EndgameStatsMissing.png";

		private static string? _textureDirectory;

		private static readonly Dictionary<string, Sprite?> SpriteCache = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase);

		public static void Initialize(string pluginDir)
		{
			_textureDirectory = Path.Combine(pluginDir, "textures");
		}

		public static void ApplyHudEndGameLocalization(HUDManager? hudManager, string stage)
		{
			if (hudManager?.statsUIElements != null)
			{
				CleanupLegacyEndGameOverlays(hudManager.statsUIElements);
				LocalizeRuntimeDeadTexts(stage);
				LocalizePlayerStateBadges(hudManager.statsUIElements, stage);
				LocalizeAllPlayersDeadOverlayImage(hudManager.statsUIElements, stage);
				LocalizeStatsBoxesImage(hudManager.statsUIElements, stage);
			}
		}

		public static void ApplySpectateUiLocalization(HUDManager? hudManager, string stage)
		{
			if (!((Object)(object)hudManager == (Object)null))
			{
				LocalizeSpectateDeadTexts(stage);
			}
		}

		public static void ApplyChallengeSlotLocalization(ChallengeLeaderboardSlot? slot, string stage)
		{
			if (!((Object)(object)slot?.scrapCollectedText == (Object)null) && string.Equals(((TMP_Text)slot.scrapCollectedText).text?.Trim(), "Deceased", StringComparison.OrdinalIgnoreCase))
			{
				((TMP_Text)slot.scrapCollectedText).text = "死亡";
				FontFallbackService.ApplyFallback((TMP_Text?)(object)slot.scrapCollectedText, "死亡");
				Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=ChallengeLeaderboard action=applied value=" + ((TMP_Text)slot.scrapCollectedText).text));
			}
		}

		private static void LocalizeRuntimeDeadTexts(string stage)
		{
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			foreach (TMP_Text val in array)
			{
				if (!((Object)(object)val == (Object)null) && !string.IsNullOrWhiteSpace(val.text))
				{
					string a = val.text.Trim();
					if (string.Equals(a, "(Dead)", StringComparison.Ordinal))
					{
						ApplyLocalizedText(val, "(死亡)", stage, "EndGameDeadLabel");
					}
					else if (string.Equals(a, "Deceased", StringComparison.OrdinalIgnoreCase))
					{
						ApplyLocalizedText(val, "死亡", stage, "EndGameDeceasedLabel");
					}
				}
			}
		}

		public static void TryRewriteSpectateDeadValue(TMP_Text? text, ref string value, string stage)
		{
			if (!((Object)(object)text == (Object)null) && !string.IsNullOrWhiteSpace(value) && IsSpectateDeadLabel(text.transform))
			{
				string a = value.Trim();
				if (string.Equals(a, "(Dead)", StringComparison.Ordinal))
				{
					value = "(死亡)";
					Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=SpectateDeadLabel action=rewrite path=" + BuildPath(text.transform) + " value=" + value));
				}
				else if (string.Equals(a, "Deceased", StringComparison.OrdinalIgnoreCase))
				{
					value = "死亡";
					Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=SpectateDeceasedLabel action=rewrite path=" + BuildPath(text.transform) + " value=" + value));
				}
			}
		}

		public static void TryLocalizeSpectateDeadLabel(TMP_Text? text, string stage)
		{
			if (!((Object)(object)text == (Object)null) && !string.IsNullOrWhiteSpace(text.text) && IsSpectateDeadLabel(text.transform))
			{
				string a = text.text.Trim();
				if (string.Equals(a, "(Dead)", StringComparison.Ordinal))
				{
					ApplyLocalizedText(text, "(死亡)", stage, "SpectateDeadLabel");
				}
				else if (string.Equals(a, "Deceased", StringComparison.OrdinalIgnoreCase))
				{
					ApplyLocalizedText(text, "死亡", stage, "SpectateDeceasedLabel");
				}
			}
		}

		private static void LocalizeSpectateDeadTexts(string stage)
		{
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			for (int i = 0; i < array.Length; i++)
			{
				TryLocalizeSpectateDeadLabel(array[i], stage);
			}
		}

		private static void LocalizePlayerStateBadges(EndOfGameStatUIElements elements, string stage)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text template = PickTemplate(elements);
			if (elements.playerStates == null)
			{
				return;
			}
			Image[] playerStates = elements.playerStates;
			foreach (Image val in playerStates)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (!((Behaviour)val).enabled || (Object)(object)val.sprite == (Object)null)
				{
					SetOverlayActive(((Component)val).transform, "__V81_EndgameStateOverlay", active: false);
				}
				else if (val.sprite == elements.deceasedIcon)
				{
					if (!TryApplyLocalizedStateSprite(val, "EndgameStatsDeceased.png", stage, "deceased"))
					{
						((Behaviour)val).enabled = false;
						((Component)EnsureOverlayLabel(((Component)val).transform, "__V81_EndgameStateOverlay", template, new Vector2(220f, 90f), Vector2.zero, "死亡", 24f, new Color(1f, 0.22f, 0.22f, 1f), (TextAlignmentOptions)514)).gameObject.SetActive(true);
						Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=EndGameState action=fallback-label state=deceased path=" + BuildPath(((Component)val).transform)));
					}
				}
				else if (val.sprite == elements.missingIcon)
				{
					if (!TryApplyLocalizedStateSprite(val, "EndgameStatsMissing.png", stage, "missing"))
					{
						((Behaviour)val).enabled = false;
						((Component)EnsureOverlayLabel(((Component)val).transform, "__V81_EndgameStateOverlay", template, new Vector2(220f, 90f), Vector2.zero, "失踪", 24f, new Color(1f, 0.22f, 0.22f, 1f), (TextAlignmentOptions)514)).gameObject.SetActive(true);
						Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=EndGameState action=fallback-label state=missing path=" + BuildPath(((Component)val).transform)));
					}
				}
				else
				{
					SetOverlayActive(((Component)val).transform, "__V81_EndgameStateOverlay", active: false);
				}
			}
		}

		private static void LocalizeAllPlayersDeadOverlayImage(EndOfGameStatUIElements elements, string stage)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			Image allPlayersDeadOverlay = elements.allPlayersDeadOverlay;
			if ((Object)(object)allPlayersDeadOverlay == (Object)null)
			{
				return;
			}
			if (!((Behaviour)allPlayersDeadOverlay).enabled)
			{
				DestroyChildIfExists(((Component)allPlayersDeadOverlay).transform, "__V81_EndgameNoSurvivorsOverlay");
				DestroyChildIfExists(((Component)allPlayersDeadOverlay).transform, "__V81_EndgameAllPlayersDeadTexture");
				return;
			}
			DestroyChildIfExists(((Component)allPlayersDeadOverlay).transform, "__V81_EndgameNoSurvivorsOverlay");
			DestroyChildIfExists(((Component)allPlayersDeadOverlay).transform, "__V81_EndgameAllScrapLostOverlay");
			DestroyChildIfExists(((Component)allPlayersDeadOverlay).transform, "__V81_EndgameAllPlayersDeadTexture");
			Sprite sprite = allPlayersDeadOverlay.sprite;
			Type type = allPlayersDeadOverlay.type;
			bool preserveAspect = allPlayersDeadOverlay.preserveAspect;
			Sprite val = LoadSprite("EndgameAllPlayersDeadOverlay.png", sprite);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("NativeRelay[" + stage + "] target=EndGameOverlay action=texture-missing file=EndgameAllPlayersDeadOverlay.png"));
				return;
			}
			allPlayersDeadOverlay.sprite = val;
			allPlayersDeadOverlay.preserveAspect = preserveAspect;
			allPlayersDeadOverlay.type = type;
			((Graphic)allPlayersDeadOverlay).color = Color.white;
			Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=EndGameOverlay action=applied path=" + BuildPath(((Component)allPlayersDeadOverlay).transform) + " " + $"type={allPlayersDeadOverlay.type} preserveAspect={allPlayersDeadOverlay.preserveAspect} imageRect={DescribeRect(((Graphic)allPlayersDeadOverlay).rectTransform.rect)} " + "templateSprite=" + DescribeSprite(sprite) + " localizedSprite=" + DescribeSprite(val)));
		}

		private static void LocalizeStatsBoxesImage(EndOfGameStatUIElements elements, string stage)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			Image val = FindStatsBoxesImage(elements);
			if (!((Object)(object)val == (Object)null))
			{
				DestroyChildIfExists(((Component)val).transform, "__V81_EndgameGradeLabel");
				DestroyChildIfExists(((Component)val).transform, "__V81_EndgameGradeTexture");
				DestroyChildIfExists(((Component)val).transform, "__V81_EndgameCollectedTexture");
				Sprite sprite = val.sprite;
				Type type = val.type;
				bool preserveAspect = val.preserveAspect;
				Sprite val2 = LoadSprite("EndgameStatsBoxesLocalized.png", sprite);
				if ((Object)(object)val2 == (Object)null)
				{
					Plugin.Log.LogWarning((object)("NativeRelay[" + stage + "] target=EndGameStatsBoxes action=texture-missing file=EndgameStatsBoxesLocalized.png"));
					return;
				}
				val.sprite = val2;
				val.preserveAspect = preserveAspect;
				val.type = type;
				((Graphic)val).color = Color.white;
				Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=EndGameStatsBoxes action=applied path=" + BuildPath(((Component)val).transform) + " " + $"type={val.type} preserveAspect={val.preserveAspect} imageRect={DescribeRect(((Graphic)val).rectTransform.rect)} " + "templateSprite=" + DescribeSprite(sprite) + " localizedSprite=" + DescribeSprite(val2)));
			}
		}

		private static TMP_Text? PickTemplate(EndOfGameStatUIElements elements)
		{
			return (TMP_Text?)(object)(elements.playerNamesText?.FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI text) => (Object)(object)text != (Object)null)) ?? elements.gradeLetter);
		}

		private static Image? FindStatsBoxesImage(EndOfGameStatUIElements elements)
		{
			Image bestCandidate = null;
			int bestScore = int.MinValue;
			TextMeshProUGUI quotaNumerator = elements.quotaNumerator;
			ConsiderCandidate(ref bestCandidate, ref bestScore, FindBestImageOnAncestorChain((quotaNumerator != null) ? ((TMP_Text)quotaNumerator).transform : null, elements), elements);
			TextMeshProUGUI gradeLetter = elements.gradeLetter;
			ConsiderCandidate(ref bestCandidate, ref bestScore, FindBestImageOnAncestorChain((gradeLetter != null) ? ((TMP_Text)gradeLetter).transform : null, elements), elements);
			TextMeshProUGUI gradeLetter2 = elements.gradeLetter;
			object obj;
			if (gradeLetter2 == null)
			{
				obj = null;
			}
			else
			{
				Canvas canvas = ((Graphic)gradeLetter2).canvas;
				obj = ((canvas != null) ? ((Component)canvas).transform : null);
			}
			if (obj == null)
			{
				TextMeshProUGUI quotaNumerator2 = elements.quotaNumerator;
				if (quotaNumerator2 == null)
				{
					obj = null;
				}
				else
				{
					Canvas canvas2 = ((Graphic)quotaNumerator2).canvas;
					obj = ((canvas2 != null) ? ((Component)canvas2).transform : null);
				}
			}
			Transform val = (Transform)obj;
			if ((Object)(object)val != (Object)null)
			{
				Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
				foreach (Image val2 in componentsInChildren)
				{
					if (!((Object)(object)val2 == (Object)null) && val2 != elements.allPlayersDeadOverlay)
					{
						Sprite sprite = val2.sprite;
						string text = ((sprite != null) ? ((Object)sprite).name : null);
						if (!string.IsNullOrWhiteSpace(text) && text.IndexOf("endgameStatsBoxes", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return val2;
						}
						ConsiderCandidate(ref bestCandidate, ref bestScore, val2, elements);
					}
				}
				if ((Object)(object)bestCandidate != (Object)null)
				{
					ManualLogSource log = Plugin.Log;
					string arg = BuildPath(((Component)bestCandidate).transform);
					object arg2 = bestScore;
					Sprite sprite2 = bestCandidate.sprite;
					log.LogInfo((object)string.Format("NativeRelay[EndGameStatsBoxes] action=fallback-candidate path={0} score={1} sprite={2}", arg, arg2, ((sprite2 != null) ? ((Object)sprite2).name : null) ?? "<null>"));
					return bestCandidate;
				}
			}
			TextMeshProUGUI quotaNumerator3 = elements.quotaNumerator;
			object obj2;
			if (quotaNumerator3 == null)
			{
				obj2 = null;
			}
			else
			{
				Transform parent = ((TMP_Text)quotaNumerator3).transform.parent;
				obj2 = ((parent != null) ? ((Component)parent).GetComponent<Image>() : null);
			}
			if (obj2 == null)
			{
				TextMeshProUGUI gradeLetter3 = elements.gradeLetter;
				if (gradeLetter3 == null)
				{
					return null;
				}
				Transform parent2 = ((TMP_Text)gradeLetter3).transform.parent;
				if (parent2 == null)
				{
					return null;
				}
				obj2 = ((Component)parent2).GetComponent<Image>();
			}
			return (Image?)obj2;
		}

		private static Image? FindBestImageOnAncestorChain(Transform? start, EndOfGameStatUIElements elements)
		{
			Transform val = start;
			Image result = null;
			int num = int.MinValue;
			while ((Object)(object)val != (Object)null)
			{
				Image component = ((Component)val).GetComponent<Image>();
				if ((Object)(object)component != (Object)null && component != elements.allPlayersDeadOverlay && (Object)(object)component.sprite != (Object)null)
				{
					int num2 = ScoreStatsBoxesCandidate(component, elements);
					Plugin.Log.LogInfo((object)$"NativeRelay[EndGameStatsBoxes] action=ancestor-candidate path={BuildPath(((Component)component).transform)} sprite={((Object)component.sprite).name} score={num2}");
					if (num2 > num)
					{
						num = num2;
						result = component;
					}
				}
				val = val.parent;
			}
			return result;
		}

		private static void ConsiderCandidate(ref Image? bestCandidate, ref int bestScore, Image? image, EndOfGameStatUIElements elements)
		{
			if (!((Object)(object)image == (Object)null))
			{
				int num = ScoreStatsBoxesCandidate(image, elements);
				if (num > bestScore)
				{
					bestScore = num;
					bestCandidate = image;
				}
			}
		}

		private static int ScoreStatsBoxesCandidate(Image image, EndOfGameStatUIElements elements)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			Sprite sprite = image.sprite;
			string obj = ((sprite != null) ? ((Object)sprite).name : null) ?? string.Empty;
			string text = BuildPath(((Component)image).transform);
			Rect rect = ((Graphic)image).rectTransform.rect;
			if (obj.IndexOf("statsboxes", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num += 1000;
			}
			if (obj.IndexOf("endgamestats", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num += 120;
			}
			if (obj.IndexOf("statsbg", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num -= 120;
			}
			if (text.IndexOf("/EndgameStats/", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num += 40;
			}
			if (text.IndexOf("/Text/", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				num += 60;
			}
			if (((Rect)(ref rect)).width >= 400f && ((Rect)(ref rect)).height >= 180f)
			{
				num += 25;
			}
			if (((Rect)(ref rect)).width >= 700f && ((Rect)(ref rect)).height >= 500f)
			{
				num += 25;
			}
			Transform transform = ((Component)image).transform;
			TextMeshProUGUI quotaNumerator = elements.quotaNumerator;
			if ((Object)(object)transform == (Object)(object)((quotaNumerator != null) ? ((TMP_Text)quotaNumerator).transform.parent : null))
			{
				num += 180;
			}
			Transform transform2 = ((Component)image).transform;
			TextMeshProUGUI gradeLetter = elements.gradeLetter;
			if ((Object)(object)transform2 == (Object)(object)((gradeLetter != null) ? ((TMP_Text)gradeLetter).transform.parent : null))
			{
				num += 180;
			}
			Rect rect2;
			if ((Object)(object)elements.quotaNumerator != (Object)null)
			{
				rect2 = ((Graphic)image).rectTransform.rect;
				float width = ((Rect)(ref rect2)).width;
				rect2 = ((TMP_Text)elements.quotaNumerator).rectTransform.rect;
				if (width > ((Rect)(ref rect2)).width * 2f)
				{
					num += 70;
				}
			}
			if ((Object)(object)elements.gradeLetter != (Object)null)
			{
				rect2 = ((Graphic)image).rectTransform.rect;
				float height = ((Rect)(ref rect2)).height;
				rect2 = ((TMP_Text)elements.gradeLetter).rectTransform.rect;
				if (height > ((Rect)(ref rect2)).height * 2f)
				{
					num += 40;
				}
			}
			return num;
		}

		private static void CleanupLegacyEndGameOverlays(EndOfGameStatUIElements elements)
		{
			TextMeshProUGUI gradeLetter = elements.gradeLetter;
			object obj;
			if (gradeLetter == null)
			{
				obj = null;
			}
			else
			{
				Canvas canvas = ((Graphic)gradeLetter).canvas;
				obj = ((canvas != null) ? ((Component)canvas).transform : null);
			}
			if (obj == null)
			{
				TextMeshProUGUI quotaNumerator = elements.quotaNumerator;
				if (quotaNumerator == null)
				{
					obj = null;
				}
				else
				{
					Canvas canvas2 = ((Graphic)quotaNumerator).canvas;
					obj = ((canvas2 != null) ? ((Component)canvas2).transform : null);
				}
			}
			Transform val = (Transform)obj;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string[] source = new string[6] { "__V81_EndgameNoSurvivorsOverlay", "__V81_EndgameAllScrapLostOverlay", "__V81_EndgameAllPlayersDeadTexture", "__V81_EndgameGradeLabel", "__V81_EndgameGradeTexture", "__V81_EndgameCollectedTexture" };
			Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && source.Contains<string>(((Object)val2).name, StringComparer.Ordinal))
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
		}

		private static TextMeshProUGUI EnsureOverlayLabel(Transform parent, string objectName, TMP_Text? template, Vector2 sizeDelta, Vector2 anchoredPosition, string localizedText, float fontSize, Color color, TextAlignmentOptions alignment)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			Transform val = parent.Find(objectName);
			TextMeshProUGUI val3;
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = new GameObject(objectName, new Type[1] { typeof(RectTransform) });
				val2.transform.SetParent(parent, false);
				val3 = val2.AddComponent<TextMeshProUGUI>();
				((Graphic)val3).raycastTarget = false;
			}
			else
			{
				val3 = ((Component)val).GetComponent<TextMeshProUGUI>() ?? ((Component)val).gameObject.AddComponent<TextMeshProUGUI>();
			}
			RectTransform rectTransform = ((TMP_Text)val3).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = sizeDelta;
			rectTransform.anchoredPosition = anchoredPosition;
			if ((Object)(object)template != (Object)null)
			{
				((TMP_Text)val3).font = template.font;
				((TMP_Text)val3).fontSharedMaterial = template.fontSharedMaterial;
				((TMP_Text)val3).characterSpacing = template.characterSpacing;
				((TMP_Text)val3).wordSpacing = template.wordSpacing;
				((TMP_Text)val3).lineSpacing = template.lineSpacing;
			}
			((TMP_Text)val3).fontSize = fontSize;
			((TMP_Text)val3).alignment = alignment;
			((TMP_Text)val3).enableWordWrapping = false;
			((Graphic)val3).color = color;
			((TMP_Text)val3).text = localizedText;
			FontFallbackService.ApplyFallback((TMP_Text?)(object)val3, localizedText);
			return val3;
		}

		private static void SetOverlayActive(Transform parent, string objectName, bool active)
		{
			Transform val = parent.Find(objectName);
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(active);
			}
		}

		private static void DestroyChildIfExists(Transform parent, string objectName)
		{
			Transform val = parent.Find(objectName);
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private static void ApplyLocalizedText(TMP_Text text, string localized, string stage, string target)
		{
			if (!string.Equals(text.text, localized, StringComparison.Ordinal))
			{
				text.text = localized;
			}
			FontFallbackService.ApplyFallback(text, localized);
			Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=" + target + " action=applied path=" + BuildPath(text.transform) + " text=" + text.text));
		}

		private static bool TryApplyLocalizedStateSprite(Image stateImage, string textureFileName, string stage, string state)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			Sprite sprite = stateImage.sprite;
			Type type = stateImage.type;
			bool preserveAspect = stateImage.preserveAspect;
			Sprite val = LoadSprite(textureFileName, sprite);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("NativeRelay[" + stage + "] target=EndGameState action=texture-missing state=" + state + " file=" + textureFileName));
				return false;
			}
			((Behaviour)stateImage).enabled = true;
			stateImage.sprite = val;
			stateImage.type = type;
			stateImage.preserveAspect = preserveAspect;
			((Graphic)stateImage).color = Color.white;
			SetOverlayActive(((Component)stateImage).transform, "__V81_EndgameStateOverlay", active: false);
			Plugin.Log.LogInfo((object)("NativeRelay[" + stage + "] target=EndGameState action=applied-sprite state=" + state + " path=" + BuildPath(((Component)stateImage).transform) + " " + $"type={stateImage.type} preserveAspect={stateImage.preserveAspect} imageRect={DescribeRect(((Graphic)stateImage).rectTransform.rect)} " + "templateSprite=" + DescribeSprite(sprite) + " localizedSprite=" + DescribeSprite(val)));
			return true;
		}

		private static Sprite? LoadSprite(string fileName, Sprite? templateSprite = null)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			string key = BuildSpriteCacheKey(fileName, templateSprite);
			if (SpriteCache.TryGetValue(key, out Sprite value))
			{
				return value;
			}
			if (string.IsNullOrWhiteSpace(_textureDirectory))
			{
				return null;
			}
			string path = Path.Combine(_textureDirectory, fileName);
			if (!File.Exists(path))
			{
				SpriteCache[key] = null;
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(path);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array, false))
				{
					Object.Destroy((Object)(object)val);
					SpriteCache[key] = null;
					return null;
				}
				((Object)val).name = fileName;
				((Texture)val).wrapMode = (TextureWrapMode)1;
				Vector2Int val2 = ResolveSpriteRectSize(templateSprite, ((Texture)val).width, ((Texture)val).height);
				Rect val3 = default(Rect);
				((Rect)(ref val3))..ctor(0f, 0f, (float)((Vector2Int)(ref val2)).x, (float)((Vector2Int)(ref val2)).y);
				Vector2 val4 = ResolveSpritePivot(templateSprite, val3);
				Vector4 val5 = ResolveSpriteBorder(templateSprite, val3);
				float num = ((templateSprite != null) ? templateSprite.pixelsPerUnit : 100f);
				Sprite val6 = Sprite.Create(val, val3, val4, num, 0u, (SpriteMeshType)0, val5);
				((Object)val6).name = Path.GetFileNameWithoutExtension(fileName);
				SpriteCache[key] = val6;
				return val6;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("NativeRelay[EndGameTexture] action=load-failed file=" + fileName + " error=" + ex.GetType().Name + ": " + ex.Message));
				SpriteCache[key] = null;
				return null;
			}
		}

		private static string BuildSpriteCacheKey(string fileName, Sprite? templateSprite)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)templateSprite == (Object)null)
			{
				return fileName;
			}
			Rect rect = templateSprite.rect;
			Vector2 pivot = templateSprite.pivot;
			Vector4 border = templateSprite.border;
			return $"{fileName}|rect={Mathf.RoundToInt(((Rect)(ref rect)).width)}x{Mathf.RoundToInt(((Rect)(ref rect)).height)}|pivot={Mathf.RoundToInt(pivot.x)},{Mathf.RoundToInt(pivot.y)}|ppu={Mathf.RoundToInt(templateSprite.pixelsPerUnit * 1000f)}|border={Mathf.RoundToInt(border.x)},{Mathf.RoundToInt(border.y)},{Mathf.RoundToInt(border.z)},{Mathf.RoundToInt(border.w)}";
		}

		private static Vector2Int ResolveSpriteRectSize(Sprite? templateSprite, int textureWidth, int textureHeight)
		{
			//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)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)templateSprite == (Object)null)
			{
				return new Vector2Int(textureWidth, textureHeight);
			}
			Rect rect = templateSprite.rect;
			int num = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref rect)).width), 1, textureWidth);
			int num2 = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref rect)).height), 1, textureHeight);
			return new Vector2Int(num, num2);
		}

		private static Vector2 ResolveSpritePivot(Sprite? templateSprite, Rect spriteRect)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)templateSprite == (Object)null || ((Rect)(ref spriteRect)).width <= 0f || ((Rect)(ref spriteRect)).height <= 0f)
			{
				return new Vector2(0.5f, 0.5f);
			}
			float x = templateSprite.pivot.x;
			Rect rect = templateSprite.rect;
			float num = Mathf.Clamp01(x / Mathf.Max(((Rect)(ref rect)).width, 1f));
			float y = templateSprite.pivot.y;
			rect = templateSprite.rect;
			return new Vector2(num, Mathf.Clamp01(y / Mathf.Max(((Rect)(ref rect)).height, 1f)));
		}

		private static Vector4 ResolveSpriteBorder(Sprite? templateSprite, Rect spriteRect)
		{
			//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)
			//IL_0016: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)templateSprite == (Object)null)
			{
				return Vector4.zero;
			}
			Vector4 border = templateSprite.border;
			return new Vector4(Mathf.Clamp(border.x, 0f, ((Rect)(ref spriteRect)).width), Mathf.Clamp(border.y, 0f, ((Rect)(ref spriteRect)).height), Mathf.Clamp(border.z, 0f, ((Rect)(ref spriteRect)).width), Mathf.Clamp(border.w, 0f, ((Rect)(ref spriteRect)).height));
		}

		private static string DescribeSprite(Sprite? sprite)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite == (Object)null)
			{
				return "<null>";
			}
			return $"{((Object)sprite).name}|rect={DescribeRect(sprite.rect)}|pivot={DescribeVector2(sprite.pivot)}|ppu={sprite.pixelsPerUnit:0.###}|border={DescribeVector4(sprite.border)}";
		}

		private static string DescribeRect(Rect rect)
		{
			return $"{((Rect)(ref rect)).x:0.###},{((Rect)(ref rect)).y:0.###},{((Rect)(ref rect)).width:0.###},{((Rect)(ref rect)).height:0.###}";
		}

		private static string DescribeVector2(Vector2 vector)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return $"{vector.x:0.###},{vector.y:0.###}";
		}

		private static string DescribeVector4(Vector4 vector)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			return $"{vector.x:0.###},{vector.y:0.###},{vector.z:0.###},{vector.w:0.###}";
		}

		private static string BuildPath(Transform? transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "<null>";
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static bool IsSpectateDeadLabel(Transform? transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			string text = BuildPath(transform);
			if (text.IndexOf("DeathScreen/SpectateUI/", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return false;
			}
			if (((Object)transform).name.IndexOf("DeadOrAlive", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.EndsWith("/DeadOrAlive", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}
	}
	internal static class FocusedTextAuditService
	{
		private static int _logBudget = 180;

		public static void AuditLoadedScene(string stage)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			if (_logBudget <= 0)
			{
				return;
			}
			TMP_Text[] array = Object.FindObjectsOfType<TMP_Text>(true);
			foreach (TMP_Text val in array)
			{
				if (!((Object)(object)val == (Object)null) && ShouldAudit(val.text))
				{
					string sharedFace = "N/A";
					Material fontSharedMaterial = val.fontSharedMaterial;
					Color color;
					if ((Object)(object)fontSharedMaterial != (Object)null && fontSharedMaterial.HasProperty(ShaderUtilities.ID_FaceColor))
					{
						color = fontSharedMaterial.GetColor(ShaderUtilities.ID_FaceColor);
						sharedFace = ((object)(Color)(ref color)).ToString();
					}
					string fontFace = "N/A";
					Material fontMaterial = val.fontMaterial;
					if ((Object)(object)fontMaterial != (Object)null && fontMaterial.HasProperty(ShaderUtilities.ID_FaceColor))
					{
						color = fontMaterial.GetColor(ShaderUtilities.ID_FaceColor);
						fontFace = ((object)(Color)(ref color)).ToString();
					}
					Log(stage, "TMP", ((Object)val).name, ((Graphic)val).color, sharedFace, fontFace, val.text);
					if (_logBudget <= 0)
					{
						return;
					}
				}
			}
			Text[] array2 = Object.FindObjectsOfType<Text>(true);
			foreach (Text val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null) && ShouldAudit(val2.text))
				{
					Log(stage, "UGUI.Text", ((Object)val2).name, ((Graphic)val2).color, "N/A", "N/A", val2.text);
					if (_logBudget <= 0)
					{
						return;
					}
				}
			}
			TextMesh[] array3 = Object.FindObjectsOfType<TextMesh>(true);
			foreach (TextMesh val3 in array3)
			{
				if (!((Object)(object)val3 == (Object)null) && ShouldAudit(val3.text))
				{
					Log(stage, "TextMesh", ((Object)val3).name, val3.color, "N/A", "N/A", val3.text);
					if (_logBudget <= 0)
					{
						break;
					}
				}
			}
		}

		private static void Log(string stage, string type, string name, Color color, string sharedFace, string fontFace, string text)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (_logBudget > 0)
			{
				_logBudget--;
				Plugin.Log.LogWarning((object)$"FocusedSceneAudit[{stage}] type={type}, name={name}, color={color}, sharedFace={sharedFace}, fontFace={fontFace}, text='{Trim(text)}'");
			}
		}

		private static bool ShouldAudit(string? text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			if (!ContainsOrdinalIgnoreCase(text, "SYSTEMS ONLINE") && !ContainsOrdinalIgnoreCase(text, "joined the ship") && !ContainsOrdinalIgnoreCase(text, "started the ship") && !ContainsOrdinalIgnoreCase(text, "ENTERING THE ATMOSPHERE") && !ContainsOrdinalIgnoreCase(text, "系统在线") && !ContainsOrdinalIgnoreCase(text, "系统上线") && !ContainsOrdinalIgnoreCase(text, "正在进入大气层"))
			{
				return ContainsOrdinalIgnoreCase(text, "进入大气层");
			}
			return true;
		}

		private static bool ContainsOrdinalIgnoreCase(string source, string needle)
		{
			return source.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static string Trim(string input)
		{
			input = input.Replace('\n', ' ');
			if (input.Length > 120)
			{
				return input.Substring(0, 120);
			}
			return input;
		}
	}
	internal static class FontFallbackService
	{
		private static readonly Regex CjkRegex = new Regex("[\\u3400-\\u9FFF]", RegexOptions.Compiled);

		private static readonly Dictionary<int, Color> BaselineColorByInstance = new Dictionary<int, Color>();

		private static readonly HashSet<int> FinalRenderSubscribedIds = new HashSet<int>();

		private static readonly HashSet<int> SpecialCaseTextIds = new HashSet<int>();

		private static readonly HashSet<int> FinalRenderRepairLoggedIds = new HashSet<int>();

		private static readonly HashSet<int> RenderAuditLoggedIds = new HashSet<int>();

		private static int _renderAuditBudget = 80;

		private static int _finalRenderRepairLogBudget = 80;

		private static int _specialCaseLogBudget = 60;

		private static int _focusedAuditBudget = 120;

		private static int _systemOnlineProbeLogBudget = 120;

		private static int _postTranslationProbeLogBudget = 160;

		private static int _runtimeCjkSweepLogBudget = 180;

		private static int _canvasGroupBypassLogBudget = 80;

		private static TMP_FontAsset? _fallbackFont;

		private static string? _pluginDir;

		private static bool _globalFallbackApplied;

		public static bool HasFallbackFont => (Object)(object)_fallbackFont != (Object)null;

		public static void TryLoadFontAsset(string pluginDir)
		{
			_pluginDir = pluginDir;
			if (TryLoadFontFileAsset(pluginDir))
			{
				ApplyFallbackGlobally();
				return;
			}
			string text = Path.Combine(pluginDir, "V81TestChn", "fonts", "zh-cn-tmp-font");
			if (!File.Exists(text))
			{
				text = Path.Combine(pluginDir, "fonts", "zh-cn-tmp-font");
			}
			if (!File.Exists(text))
			{
				Plugin.Log.LogWarning((object)("Chinese TMP font bundle not found: " + text));
				TryLoadSystemFontAsset();
				return;
			}
			try
			{
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Failed to load Chinese TMP font bundle.");
					TryLoadSystemFontAsset();
					return;
				}
				string[] allAssetNames = val.GetAllAssetNames();
				foreach (string text2 in allAssetNames)
				{
					_fallbackFont = val.LoadAsset<TMP_FontAsset>(text2);
					if ((Object)(object)_fallbackFont != (Object)null)
					{
						NormalizeFallbackFontMaterials();
						Plugin.Log.LogInfo((object)("Loaded Chinese fallback font: " + ((Object)_fallbackFont).name + " from " + text));
						ApplyFallbackGlobally();
						return;
					}
				}
				Plugin.Log.LogWarning((object)("No TMP_FontAsset found in Chinese font bundle: " + text));
				TryLoadSystemFontAsset();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to load Chinese font bundle: {arg}");
				TryLoadSystemFontAsset();
			}
		}

		private static bool TryLoadFontFileAsset(string pluginDir)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			string[] array = new string[6]
			{
				Path.Combine(pluginDir, "V81TestChn", "fonts", "NotoSansSC-VF.ttf"),
				Path.Combine(pluginDir, "fonts", "NotoSansSC-VF.ttf"),
				"C:\\Windows\\Fonts\\NotoSansSC-VF.ttf",
				"C:\\Windows\\Fonts\\msyh.ttc",
				"C:\\Windows\\Fonts\\msyhbd.ttc",
				"C:\\Windows\\Fonts\\simsun.ttc"
			};
			foreach (string text in array)
			{
				if (!File.Exists(text))
				{
					continue;
				}
				try
				{
					if (TryCreateTmpFontAsset(new Font(text), Path.GetFileNameWithoutExtension(text)))
					{
						Plugin.Log.LogInfo((object)("Loaded Chinese fallback font from font file: " + text));
						return true;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogDebug((object)("Font file fallback failed for " + text + ": " + ex.Message));
				}
			}
			return false;
		}

		private static void TryLoadSystemFontAsset()
		{
			if ((Object)(object)_fallbackFont != (Object)null)
			{
				return;
			}
			string[] array = new string[4] { "Noto Sans SC", "Source Han Sans SC", "Microsoft YaHei UI", "Microsoft YaHei" };
			foreach (string text in array)
			{
				try
				{
					if (TryCreateTmpFontAsset(Font.CreateDynamicFontFromOSFont(text, 18), text))
					{
						Plugin.Log.LogInfo((object)("Loaded Chinese fallback font from system font: " + text));
						ApplyFallbackGlobally();
						return;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogDebug((object)("System font fallback failed for " + text + ": " + ex.Message));
				}
			}
			Plugin.Log.LogWarning((object)"No compatible Chinese system font fallback was loaded.");
		}

		private static bool TryCreateTmpFontAsset(Font? font, string label)
		{
			if ((Object)(object)font == (Object)null)
			{
				return false;
			}
			_fallbackFont = TMP_FontAsset.CreateFontAsset(font, 90, 9, (GlyphRenderMode)4165, 4096, 4096, (AtlasPopulationMode)1, true);
			if ((Object)(object)_fallbackFont == (Object)null)
			{
				return false;
			}
			((Object)_fallbackFont).name = "V81TestChn_SystemFallback_" + label;
			_fallbackFont.atlasPopulationMode = (AtlasPopulationMode)1;
			NormalizeFallbackFontMaterials();
			WarmFallbackCharacters();
			return true;
		}

		public static void ApplyFallback(TMP_Text? text, string? candidateText = null)
		{
			if (!((Object)(object)_fallbackFont == (Object)null) && !((Object)(object)((text != null) ? text.font : null) == (Object)null))
			{
				CaptureHealthyBaseline(text);
				ApplyFallbackToFont(text.font);
			}
		}

		public static void RegisterTextInstance(TMP_Text? text, string stage)
		{
			if (!((Object)(object)text == (Object)null))
			{
				if (IsCriticalTextForRepair(text, text.text))
				{
					EnsureFinalRenderRepair(text);
				}
				if (ShouldFocusAudit(text.text))
				{
					LogFocusedAudit(stage, text, text.textInfo);
				}
			}
		}

		public static void ReconcileRenderedText(TMP_Text? text)
		{
		}

		public static void ApplySystemOnlineProbeFix(TMP_Text? text, string stage, string? candidateText = null)
		{
		}

		public static void RepairPostTranslationText(TMP_Text? text, string stage)
		{
			if ((Object)(object)text == (Object)null || string.IsNullOrWhiteSpace(text.text))
			{
				return;
			}
			if (IsAtmosphereRelayObject((Component?)(object)text))
			{
				ApplyFallbackToFont(text.font);
			}
			else if (!IsSystemOnlineRelayObject((Component?)(object)text) && CjkRegex.IsMatch(text.text))
			{
				ApplyFallbackToFont(text.font);
				if (ShouldRepairReadableCjkTextLight(text))
				{
					RepairReadableCjkTextLight(text, stage);
				}
			}
		}

		public static void RepairLoadedCjkTextObjects(string stage)
		{
		}

		public static void ApplySystemOnlineProbeFix(Text? text, string stage, string? candidateText = null)
		{
		}

		public static void ApplySystemOnlineProbeFix(TextMesh? text, string stage, string? candidateText = null)
		{
		}

		public static void SanitizeSystemOnlineAssignedColor(TMP_Text? text, ref Color value, string stage)
		{
		}

		public static void RepairSystemOnlineRelayAppearance(TMP_Text? text)
		{
		}

		public static void OnFontAssetAwake(TMP_FontAsset? fontAsset)
		{
			if (!((Object)(object)fontAsset == (Object)null))
			{
				ApplyFallbackToFont(fontAsset);
				NormalizeMaterial(((TMP_Asset)fontAsset).material);
			}
		}

		public static void ReconcileSubMeshMaterial(TMP_SubMeshUI? subMesh)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)subMesh == (Object)null)
			{
				return;
			}
			TMP_Text textComponent = subMesh.textComponent;
			if (!((Object)(object)textComponent == (Object)null) && !string.IsNullOrWhiteSpace(textComponent.text) && CjkRegex.IsMatch(textComponent.text))
			{
				EnsureFinalRenderRepair(textComponent);
				Material fontSharedMaterial = textComponent.fontSharedMaterial;
				Material sharedMaterial = subMesh.sharedMaterial;
				Material val = TryGetSubMeshUiMaterial(subMesh, "ReconcileSubMeshMaterial(UI)");
				if ((Object)(object)fontSharedMaterial != (Object)null)
				{
					SyncMaterialWithPrimary(sharedMaterial, fontSharedMaterial);
					SyncMaterialWithPrimary(val, fontSharedMaterial);
				}
				ApplyFaceColorFromOwner(sharedMaterial, textComponent);
				ApplyFaceColorFromOwner(val, textComponent);
				((Graphic)subMesh).color = ((Graphic)textComponent).color;
				AuditIfStillDark("ReconcileSubMeshMaterial(UI)", textComponent);
			}
		}

		public static void ReconcileSubMeshMaterial(TMP_SubMesh? subMesh)
		{
			if ((Object)(object)subMesh == (Object)null)
			{
				return;
			}
			TMP_Text textComponent = subMesh.textComponent;
			if (!((Object)(object)textComponent == (Object)null) && !string.IsNullOrWhiteSpace(textComponent.text) && CjkRegex.IsMatch(textComponent.text))
			{
				EnsureFinalRenderRepair(textComponent);
				Material fontSharedMaterial = textComponent.fontSharedMaterial;
				if ((Object)(object)fontSharedMaterial != (Object)null)
				{
					SyncMaterialWithPrimary(subMesh.sharedMaterial, fontSharedMaterial);
					SyncMaterialWithPrimary(subMesh.material, fontSharedMaterial);
				}
				ApplyFaceColorFromOwner(subMesh.sharedMaterial, textComponent);
				ApplyFaceColorFromOwner(subMesh.material, textComponent);
				AuditIfStillDark("ReconcileSubMeshMaterial(3D)", textComponent);
			}
		}

		public static void SanitizeAssignedColor(TMP_Text? text, ref Color value, string? candidateText = null)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)text == (Object)null)
			{
				return;
			}
			string text2 = (string.IsNullOrWhiteSpace(candidateText) ? text.text : candidateText);
			if (string.IsNullOrWhiteSpace(text2) || IsAtmosphereRelayObject((Component?)(object)text))
			{
				return;
			}
			int instanceID = ((Object)text).GetInstanceID();
			if (!BaselineColorByInstance.ContainsKey(instanceID))
			{
				TryStoreHealthyBaseline(instanceID, ((Graphic)text).color);
			}
			if (!CjkRegex.IsMatch(text2))
			{
				TryStoreHealthyBaseline(instanceID, value);
			}
			else
			{
				if (!ShouldRepairReadableCjkTextLight(text))
				{
					return;
				}
				EnsureFinalRenderRepair(text);
				if (TryGetHealthyBaseline(instanceID, out var baseline))
				{
					if (value.a < 0.999f || IsNearlyBlack(value))
					{
						value = new Color(baseline.r, baseline.g, baseline.b, baseline.a);
					}
				}
				else if (value.a < 0.35f || IsNearlyBlack(value))
				{
					value = new Color(1f, 1f, 1f, 1f);
				}
			}
		}

		public static void ApplyFallbackGlobally()
		{
			if (!((Object)(object)_fallbackFont == (Object)null) && !_globalFallbackApplied)
			{
				List<TMP_FontAsset> fallbackFontAssets = TMP_Settings.fallbackFontAssets;
				if (fallbackFontAssets != null && !fallbackFontAssets.Contains(_fallbackFont))
				{
					fallbackFontAssets.Add(_fallbackFont);
				}
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				for (int i = 0; i < array.Length; i++)
				{
					ApplyFallbackToFont(array[i]);
				}
				_globalFallbackApplied = true;
				Plugin.Log.LogInfo((object)("Applied Chinese fallback font globally: " + ((Object)_fallbackFont).name));
			}
		}

		private static void ApplyFallbackToFont(TMP_FontAsset? fontAsset)
		{
			if (!((Object)(object)_fallbackFont == (Object)null) && !((Object)(object)fontAsset == (Object)null) && fontAsset != _fallbackFont)
			{
				if (fontAsset.fallbackFontAssetTable == null)
				{
					fontAsset.fallbackFontAssetTable = new List<TMP_FontAsset>();
				}
				if (!fontAsset.fallbackFontAssetTable.Contains(_fallbackFont))
				{
					fontAsset.fallbackFontAssetTable.Add(_fallbackFont);
				}
			}
		}

		private static void WarmFallbackCharacters()
		{
			if ((Object)(object)_fallbackFont == (Object)null)
			{
				return;
			}
			string text = ((_pluginDir == null) ? null : Path.Combine(_pluginDir, "V81TestChn", "fonts", "zh-cn-charset.txt"));
			if (text == null || !File.Exists(text))
			{
				text = Path.Combine(PathsRelativePluginRoot(), "fonts", "zh-cn-charset.txt");
			}
			if (!File.Exists(text))
			{
				return;
			}
			try
			{
				string source = File.ReadAllText(text);
				source = new string(source.Where((char c) => !char.IsControl(c)).Distinct().ToArray());
				string text2 = default(string);
				if (_fallbackFont.TryAddCharacters(source, ref text2, false) && string.IsNullOrEmpty(text2))
				{
					Plugin.Log.LogInfo((object)$"Prewarmed Chinese fallback font characters: {source.Length}");
				}
				else if (!string.IsNullOrEmpty(text2))
				{
					Plugin.Log.LogWarning((object)$"Chinese fallback font missing {text2.Length} prewarm characters.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Failed to prewarm Chinese fallback characters: " + ex.Message));
			}
		}

		private static string PathsRelativePluginRoot()
		{
			return _pluginDir ?? Paths.PluginPath;
		}

		private static void NormalizeFallbackFontMaterials()
		{
			if (!((Object)(object)_fallbackFont == (Object)null))
			{
				NormalizeMaterial(((TMP_Asset)_fallbackFont).material);
			}
		}

		private static void NormalizeMaterial(Material? material)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)material == (Object)null))
			{
				if (material.HasProperty(ShaderUtilities.ID_FaceColor))
				{
					material.SetColor(ShaderUtilities.ID_FaceColor, Color.white);
				}
				if (material.HasProperty(ShaderUtilities.ID_OutlineWidth))
				{
					material.SetFloat(ShaderUtilities.ID_OutlineWidth, 0f);
				}
				if (material.HasProperty(ShaderUtilities.ID_OutlineColor))
				{
					Color color = material.GetColor(ShaderUtilities.ID_OutlineColor);
					material.SetColor(ShaderUtilities.ID_OutlineColor, new Color(color.r, color.g, color.b, 0f));
				}
				if (material.HasProperty(ShaderUtilities.ID_FaceDilate))
				{
					material.SetFloat(ShaderUtilities.ID_FaceDilate, 0f);
				}
				if (material.HasProperty(ShaderUtilities.ID_UnderlayColor))
				{
					Color color2 = material.GetColor(ShaderUtilities.ID_UnderlayColor);
					material.SetColor(ShaderUtilities.ID_UnderlayColor, new Color(color2.r, color2.g, color2.b, 0f));
				}
				if (material.HasProperty(ShaderUtilities.ID_UnderlaySoftness))
				{
					material.SetFloat(ShaderUtilities.ID_UnderlaySoftness, 0f);
				}
				if (material.HasProperty(ShaderUtilities.ID_UnderlayDilate))
				{
					material.SetFloat(ShaderUtilities.ID_UnderlayDilate, 0f);
				}
				material.DisableKeyword("UNDERLAY_ON");
				material.DisableKeyword("UNDERLAY_INNER");
				material.DisableKeyword("OUTLINE_ON");
			}
		}

		private static void ImproveReadabilityForOverlayChinese(TMP_Text text, string? candidateText)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)text == (Object)null)
			{
				return;
			}
			string text2 = (string.IsNullOrWhiteSpace(candidateText) ? text.text : candidateText);
			if (string.IsNullOrWhiteSpace(text2))
			{
				return;
			}
			int instanceID = ((Object)text).GetInstanceID();
			if (!BaselineColorByInstance.ContainsKey(instanceID))
			{
				TryStoreHealthyBaseline(instanceID, ((Graphic)text).color);
			}
			if (!CjkRegex.IsMatch(text2))
			{
				TryStoreHealthyBaseline(instanceID, ((Graphic)text).color);
				return;
			}
			if (IsAtmosphereHeader(text2))
			{
				ApplyAtmosphereHeaderStyle(text);
				return;
			}
			SyncSubMeshMaterials(text);
			Color color = ((Graphic)text).color;
			if (color.a < 0.999f || IsNearlyBlack(color))
			{
				if (TryGetHealthyBaseline(instanceID, out var baseline))
				{
					((Graphic)text).color = new Color(baseline.r, baseline.g, baseline.b, baseline.a);
				}
				else
				{
					((Graphic)text).color = ((color.a < 0.999f || IsNearlyBlack(color)) ? new Color(1f, 1f, 1f, 1f) : new Color(color.r, color.g, color.b, 1f));
				}
			}
		}

		private static void RepairReadableCjkTextLight(TMP_Text text, string stage)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)text == (Object)null) && !string.IsNullOrWhiteSpace(text.text) && CjkRegex.IsMatch(text.text))
			{
				CaptureHealthyBaseline(text);
				Color val = ResolveExpectedColor(text);
				if (val.a < 0.999f)
				{
					val.a = 1f;
				}
				bool flag = false;
				if (NeedsGraphicColorRepair(((Graphic)text).color, val))
				{
					((Graphic)text).color = val;
					flag = true;
				}
				bool flag2 = RepairReadableFaceMaterials(text, val);
				if (HasAnomalousCjkVertex(text))
				{
					FixCjkVertexColors(text);
				}
				if ((flag || flag2) && _postTranslationProbeLogBudget > 0)
				{
					_postTranslationProbeLogBudget--;
					string text2 = (((Object)(object)text.font != (Object)null) ? ((Object)text.font).name : string.Empty);
					Plugin.Log.LogWarning((object)$"PostTranslationCjkRepairLight[{stage}] name={((Object)text).name}, font='{text2}', after={((Graphic)text).color}, text='{TrimAuditText(text.text)}'");
				}
			}
		}

		private static bool ShouldRepairReadableCjkTextLight(TMP_Text? text)
		{
			if ((Object)(object)text == (Object)null)
			{
				return false;
			}
			if (!IsSystemOnlineRelayObject((Component?)(object)text))
			{
				IsAtmosphereRelayObject((Component?)(object)text);
			}
			return false;
		}

		private static bool IsNearlyBlack(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			if (color.r < 0.08f && color.g < 0.08f)
			{
				return color.b < 0.08f;
			}
			return false;
		}

		private static bool IsHealthyColor(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!IsNearlyBlack(color))
			{
				return color.a >= 0.35f;
			}
			return false;
		}

		private static bool TryGetHealthyBaseline(int textId, out Color baseline)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (BaselineColorByInstance.TryGetValue(textId, out baseline) && IsHealthyColor(baseline))
			{
				return true;
			}
			baseline = default(Color);
			return false;
		}

		private static void TryStoreHealthyBaseline(int textId, Color candidate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (IsHealthyColor(candidate))
			{
				BaselineColorByInstance[textId] = candidate;
			}
		}

		private static void SyncSubMeshMaterials(TMP_Text text)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Material fontSharedMaterial = text.fontSharedMaterial;
			if (!((Object)(object)fontSharedMaterial == (Object)null))
			{
				TMP_SubMeshUI[] componentsInChildren = ((Component)text).GetComponentsInChildren<TMP_SubMeshUI>(true);
				foreach (TMP_SubMeshUI obj in componentsInChildren)
				{
					SyncMaterialWithPrimary(obj.sharedMaterial, fontSharedMaterial);
					SyncMaterialWithPrimary(TryGetSubMeshUiMaterial(obj, "SyncSubMeshMaterials"), fontSharedMaterial);
					((Graphic)obj).color = ((Graphic)text).color;
				}
				TMP_SubMesh[] componentsInChildren2 = ((Component)text).GetComponentsInChildren<TMP_SubMesh>(true);
				foreach (TMP_SubMesh obj2 in componentsInChildren2)
				{
					SyncMaterialWithPrimary(obj2.sharedMaterial, fontSharedMaterial);
					SyncMaterialWithPrimary(obj2.material, fontSharedMaterial);
				}
			}
		}

		private static void FixCjkVertexColors(TMP_Text text)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if (text.textInfo == null || string.IsNullOrEmpty(text.text) || !CjkRegex.IsMatch(text.text))
			{
				return;
			}
			Color32 val = Color32.op_Implicit(ResolveExpectedColor(text));
			TMP_TextInfo textInfo = text.textInfo;
			bool flag = false;
			for (int i = 0; i < textInfo.cha