using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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
{
private enum NativeTextRole
{
None,
SystemOnline,
EnteringAtmosphere
}
private readonly struct CachedNativeTextRole
{
public int ParentId { get; }
public NativeTextRole Role { get; }
public CachedNativeTextRole(int parentId, NativeTextRole role)
{
ParentId = parentId;
Role = role;
}
}
[CompilerGenerated]
private sealed class <WaitForFixedSceneLabels>d__39 : 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__39(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__38 : 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__38(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 int NativeTextRoleCacheLimit = 4096;
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<int, CachedNativeTextRole> NativeTextRoleCache = new Dictionary<int, CachedNativeTextRole>();
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) && GetNativeTextRole(text) == NativeTextRole.EnteringAtmosphere)
{
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)
{
return;
}
switch (GetNativeTextRole(text))
{
case NativeTextRole.SystemOnline:
ApplySystemOnlineNativeTranslation(text, stage);
return;
case NativeTextRole.EnteringAtmosphere:
ApplyEnteringAtmosphereNativeTranslation(text, stage);
return;
}
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__38))]
private static IEnumerator WaitForSystemOnlineTitle(HUDManager hudManager, string stage)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForSystemOnlineTitle>d__38(0)
{
hudManager = hudManager,
stage = stage
};
}
[IteratorStateMachine(typeof(<WaitForFixedSceneLabels>d__39))]
private static IEnumerator WaitForFixedSceneLabels(string stage)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForFixedSceneLabels>d__39(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 GetNativeTextRole(text) == NativeTextRole.SystemOnline;
}
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)
{
return GetNativeTextRole(text) == NativeTextRole.EnteringAtmosphere;
}
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)
{
return GetNativeTextRole(text) == NativeTextRole.SystemOnline;
}
private static NativeTextRole GetNativeTextRole(TMP_Text? text)
{
if ((Object)(object)text == (Object)null)
{
return NativeTextRole.None;
}
if (TryGetCachedNativeTextRole(text, out var role))
{
return role;
}
role = ResolveNativeTextRole(text);
CacheNativeTextRole(text, role);
return role;
}
private static bool TryGetCachedNativeTextRole(TMP_Text text, out NativeTextRole role)
{
int parentInstanceId = GetParentInstanceId(text.transform);
if (NativeTextRoleCache.TryGetValue(((Object)text).GetInstanceID(), out var value) && value.ParentId == parentInstanceId)
{
role = value.Role;
return true;
}
role = NativeTextRole.None;
return false;
}
private static NativeTextRole ResolveNativeTextRole(TMP_Text text)
{
if (string.Equals(((Object)text).name, "LoadText", StringComparison.OrdinalIgnoreCase) && HasNamedAncestor(text.transform, "LoadingText"))
{
return NativeTextRole.EnteringAtmosphere;
}
if (string.Equals(((Object)text).name, "TipLeft1", StringComparison.OrdinalIgnoreCase) && IsSystemOnlinePath(text.transform))
{
return NativeTextRole.SystemOnline;
}
return NativeTextRole.None;
}
private static void CacheNativeTextRole(TMP_Text text, NativeTextRole role)
{
if (NativeTextRoleCache.Count >= 4096)
{
NativeTextRoleCache.Clear();
}
NativeTextRoleCache[((Object)text).GetInstanceID()] = new CachedNativeTextRole(GetParentInstanceId(text.transform), role);
}
private static int GetParentInstanceId(Transform? transform)
{
if (!((Object)(object)((transform != null) ? transform.parent : null) == (Object)null))
{
return ((Object)transform.parent).GetInstanceID();
}
return 0;
}
}
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 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 readonly HashSet<int> AppliedFallbackFontIds = 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) && ContainsCjk(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_007c: 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) && ContainsCjk(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) && ContainsCjk(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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: 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_00c8: 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_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: 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_008a: 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 (!ContainsCjk(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)
{
return;
}
int instanceID = ((Object)fontAsset).GetInstanceID();
if (!AppliedFallbackFontIds.Contains(instanceID))
{
if (fontAsset.fallbackFontAssetTable == null)
{
fontAsset.fallbackFontAssetTable = new List<TMP_FontAsset>();
}
if (!fontAsset.fallbackFontAssetTable.Contains(_fallbackFont))
{
fontAsset.fallbackFontAssetTable.Add(_fallbackFont);
}
AppliedFallbackFontIds.Add(instanceID);
}
}
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_004f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: 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)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: 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 (!ContainsCjk(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_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: 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_0064: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)text == (Object)null) && !string.IsNullOrWhiteSpace(text.text) && ContainsCjk(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_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_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown