using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("GWYFTmpPatcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a9d3046b810a7bd0dd1013e2f8e0683442b198ae")]
[assembly: AssemblyProduct("GWYFTmpPatcher")]
[assembly: AssemblyTitle("GWYFTmpPatcher")]
[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 GWYFTmpPatcher
{
[BepInPlugin("codex.gwyf.tmppatcher", "GWYF TMP Patcher", "0.1.15")]
public sealed class TmpPatcherPlugin : BaseUnityPlugin
{
private sealed class TextureReplacement
{
public string Name { get; set; } = string.Empty;
public Texture2D Texture { get; set; }
public HashSet<int> PatchedTextures { get; } = new HashSet<int>();
public Dictionary<int, Sprite> SpriteCache { get; } = new Dictionary<int, Sprite>();
}
private sealed class RegexRule
{
public Regex Regex { get; }
public string Replacement { get; }
public RegexRule(Regex regex, string replacement)
{
Regex = regex;
Replacement = replacement;
}
}
[CompilerGenerated]
private sealed class <PatchSceneTexturesBatched>d__40 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float delaySeconds;
public TmpPatcherPlugin <>4__this;
public string reason;
private int <textures>5__2;
private int <images>5__3;
private int <spriteRenderers>5__4;
private int <materials>5__5;
private int <processedThisFrame>5__6;
private int <batchSize>5__7;
private Texture2D[] <>7__wrap7;
private int <>7__wrap8;
private Image[] <>7__wrap9;
private SpriteRenderer[] <>7__wrap10;
private Renderer[] <>7__wrap11;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PatchSceneTexturesBatched>d__40(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>7__wrap7 = null;
<>7__wrap9 = null;
<>7__wrap10 = null;
<>7__wrap11 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
int num = <>1__state;
TmpPatcherPlugin tmpPatcherPlugin = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
if (delaySeconds > 0f)
{
<>2__current = (object)new WaitForSecondsRealtime(delaySeconds);
<>1__state = 1;
return true;
}
goto IL_0063;
case 1:
<>1__state = -1;
goto IL_0063;
case 2:
<>1__state = -1;
goto IL_0122;
case 3:
<>1__state = -1;
goto IL_01da;
case 4:
<>1__state = -1;
goto IL_0292;
case 5:
{
<>1__state = -1;
goto IL_0333;
}
IL_0341:
if (<>7__wrap8 < <>7__wrap11.Length)
{
Renderer val = <>7__wrap11[<>7__wrap8];
if ((Object)(object)val != (Object)null)
{
<materials>5__5 += tmpPatcherPlugin.PatchRendererMaterials(val);
}
if (++<processedThisFrame>5__6 >= <batchSize>5__7)
{
<processedThisFrame>5__6 = 0;
<>2__current = null;
<>1__state = 5;
return true;
}
goto IL_0333;
}
<>7__wrap11 = null;
if (tmpPatcherPlugin._logChanges.Value && (<textures>5__2 > 0 || <images>5__3 > 0 || <spriteRenderers>5__4 > 0 || <materials>5__5 > 0))
{
((BaseUnityPlugin)tmpPatcherPlugin).Logger.LogInfo((object)$"Texture patch complete ({reason}). Textures={<textures>5__2}, images={<images>5__3}, spriteRenderers={<spriteRenderers>5__4}, materials={<materials>5__5}.");
}
return false;
IL_0063:
if (!tmpPatcherPlugin.LoadEmbeddedTextureReplacements())
{
return false;
}
<textures>5__2 = 0;
<images>5__3 = 0;
<spriteRenderers>5__4 = 0;
<materials>5__5 = 0;
<processedThisFrame>5__6 = 0;
<batchSize>5__7 = Mathf.Max(1, tmpPatcherPlugin._textureBatchSize.Value);
<>7__wrap7 = Resources.FindObjectsOfTypeAll<Texture2D>();
<>7__wrap8 = 0;
goto IL_0130;
IL_0292:
<>7__wrap8++;
goto IL_02a0;
IL_01da:
<>7__wrap8++;
goto IL_01e8;
IL_0130:
if (<>7__wrap8 < <>7__wrap7.Length)
{
Texture2D val2 = <>7__wrap7[<>7__wrap8];
if ((Object)(object)val2 != (Object)null && tmpPatcherPlugin.PatchLoadedTextureObject(val2))
{
<textures>5__2++;
}
if (++<processedThisFrame>5__6 >= <batchSize>5__7)
{
<processedThisFrame>5__6 = 0;
<>2__current = null;
<>1__state = 2;
return true;
}
goto IL_0122;
}
<>7__wrap7 = null;
<>7__wrap9 = Resources.FindObjectsOfTypeAll<Image>();
<>7__wrap8 = 0;
goto IL_01e8;
IL_01e8:
if (<>7__wrap8 < <>7__wrap9.Length)
{
Image val3 = <>7__wrap9[<>7__wrap8];
if ((Object)(object)val3 != (Object)null && (Object)(object)val3.sprite != (Object)null && tmpPatcherPlugin.PatchImage(val3))
{
<images>5__3++;
}
if (++<processedThisFrame>5__6 >= <batchSize>5__7)
{
<processedThisFrame>5__6 = 0;
<>2__current = null;
<>1__state = 3;
return true;
}
goto IL_01da;
}
<>7__wrap9 = null;
<>7__wrap10 = Resources.FindObjectsOfTypeAll<SpriteRenderer>();
<>7__wrap8 = 0;
goto IL_02a0;
IL_0122:
<>7__wrap8++;
goto IL_0130;
IL_02a0:
if (<>7__wrap8 < <>7__wrap10.Length)
{
SpriteRenderer val4 = <>7__wrap10[<>7__wrap8];
if ((Object)(object)val4 != (Object)null && (Object)(object)val4.sprite != (Object)null && tmpPatcherPlugin.PatchSpriteRenderer(val4))
{
<spriteRenderers>5__4++;
}
if (++<processedThisFrame>5__6 >= <batchSize>5__7)
{
<processedThisFrame>5__6 = 0;
<>2__current = null;
<>1__state = 4;
return true;
}
goto IL_0292;
}
<>7__wrap10 = null;
<>7__wrap11 = Resources.FindObjectsOfTypeAll<Renderer>();
<>7__wrap8 = 0;
goto IL_0341;
IL_0333:
<>7__wrap8++;
goto IL_0341;
}
}
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 <PatchSceneTmpObjectsBatched>d__38 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float delaySeconds;
public TmpPatcherPlugin <>4__this;
public string reason;
private TMP_Text[] <texts>5__2;
private HashSet<int> <seen>5__3;
private int <fontPatched>5__4;
private int <translated>5__5;
private int <processedThisFrame>5__6;
private int <batchSize>5__7;
private TMP_FontAsset[] <>7__wrap7;
private int <>7__wrap8;
private TMP_Text[] <>7__wrap9;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PatchSceneTmpObjectsBatched>d__38(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<texts>5__2 = null;
<seen>5__3 = null;
<>7__wrap7 = null;
<>7__wrap9 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
int num = <>1__state;
TmpPatcherPlugin tmpPatcherPlugin = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
if (delaySeconds > 0f)
{
<>2__current = (object)new WaitForSecondsRealtime(delaySeconds);
<>1__state = 1;
return true;
}
goto IL_005b;
case 1:
<>1__state = -1;
goto IL_005b;
case 2:
<>1__state = -1;
goto IL_0118;
case 3:
{
<>1__state = -1;
goto IL_022d;
}
IL_022d:
<>7__wrap8++;
goto IL_023b;
IL_005b:
<texts>5__2 = Resources.FindObjectsOfTypeAll<TMP_Text>();
<seen>5__3 = new HashSet<int>();
<fontPatched>5__4 = 0;
<translated>5__5 = 0;
<processedThisFrame>5__6 = 0;
<batchSize>5__7 = Mathf.Max(1, tmpPatcherPlugin._fontBatchSize.Value);
<>7__wrap7 = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
<>7__wrap8 = 0;
goto IL_0126;
IL_0126:
if (<>7__wrap8 < <>7__wrap7.Length)
{
TMP_FontAsset val = <>7__wrap7[<>7__wrap8];
if ((Object)(object)val != (Object)null && tmpPatcherPlugin.PatchChineseFontAsset(val))
{
<fontPatched>5__4++;
}
if (++<processedThisFrame>5__6 >= <batchSize>5__7)
{
<processedThisFrame>5__6 = 0;
<>2__current = null;
<>1__state = 2;
return true;
}
goto IL_0118;
}
<>7__wrap7 = null;
<>7__wrap9 = <texts>5__2;
<>7__wrap8 = 0;
goto IL_023b;
IL_0118:
<>7__wrap8++;
goto IL_0126;
IL_023b:
if (<>7__wrap8 < <>7__wrap9.Length)
{
TMP_Text val2 = <>7__wrap9[<>7__wrap8];
if (!((Object)(object)val2 == (Object)null) && !IsEditorOrAssetObject((Component)(object)val2) && <seen>5__3.Add(((Object)val2).GetInstanceID()))
{
tmpPatcherPlugin.PatchTmpText(val2, reason, allowTranslate: false, allowFont: true, out var fontChanged, out var textTranslated);
<fontPatched>5__4 += (fontChanged ? 1 : 0);
<translated>5__5 += (textTranslated ? 1 : 0);
if (textTranslated && tmpPatcherPlugin._forceMeshUpdate.Value)
{
((Graphic)val2).SetAllDirty();
val2.ForceMeshUpdate(true, true);
}
<processedThisFrame>5__6++;
if (<processedThisFrame>5__6 >= <batchSize>5__7)
{
<processedThisFrame>5__6 = 0;
<>2__current = null;
<>1__state = 3;
return true;
}
}
goto IL_022d;
}
<>7__wrap9 = null;
tmpPatcherPlugin.LogPatchSummary(reason, <fontPatched>5__4, <translated>5__5);
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 ConfigEntry<bool> _enabled;
private ConfigEntry<bool> _patchOnlyUi;
private ConfigEntry<bool> _translateTmpText;
private ConfigEntry<bool> _forceMeshUpdate;
private ConfigEntry<bool> _logChanges;
private ConfigEntry<int> _fontBatchSize;
private ConfigEntry<bool> _replaceFontWithExternalFile;
private ConfigEntry<string> _externalFontPath;
private ConfigEntry<string> _assetBundleFontAssetName;
private ConfigEntry<bool> _replaceBuiltInTextures;
private ConfigEntry<int> _textureBatchSize;
private ConfigEntry<string> _translationTextPath;
private const string TargetTmpFontName = "ChineseFont";
private const string LogoTextureName = "GWYF_LOGO_1280x720";
private const string MainTexPropertyName = "_MainTex";
private const string ReplacerTargetPath = "/LocalManager/UI/InteractionUIPanel/TextPanel/ItemNameText";
private const string EmbeddedFontResourceName = "GWYFTmpPatcher.Assets.notosanstc-medium-sdf.bundle";
private const string EmbeddedLogoResourceName = "GWYFTmpPatcher.Assets.GWYFTW_LOGO.png";
private static readonly string[] TmpFontAssetCopyFields = new string[24]
{
"m_Version", "m_FaceInfo", "m_GlyphTable", "m_CharacterTable", "m_AtlasTexture", "m_AtlasTextures", "m_AtlasTextureIndex", "m_UsedGlyphRects", "m_FreeGlyphRects", "m_GlyphIndexList",
"m_GlyphIndexListNewlyAdded", "m_GlyphsToRender", "m_GlyphsRendered", "m_AtlasWidth", "m_AtlasHeight", "m_AtlasPadding", "m_AtlasRenderMode", "m_AtlasPopulationMode", "m_FontFeatureTable", "m_fontInfo",
"m_glyphInfoList", "m_KerningTable", "m_kerningInfo", "fallbackFontAssets"
};
private readonly HashSet<int> _patchedFontAssetIds = new HashSet<int>();
private readonly List<AssetBundle> _loadedFontBundles = new List<AssetBundle>();
private readonly Dictionary<string, TextureReplacement> _textureReplacements = new Dictionary<string, TextureReplacement>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string> _exactRules = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string> _postRules = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly List<RegexRule> _regexRules = new List<RegexRule>();
private readonly Dictionary<int, string> _lastAppliedText = new Dictionary<int, string>();
private readonly Dictionary<string, DateTime> _translationFileTimes = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);
private string _translationTextDirectory;
private TMP_FontAsset? _externalFontAsset;
private bool _embeddedFontLoadAttempted;
private bool _textureReplacementsLoaded;
private static readonly MethodInfo? LoadImageMethod = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
{
typeof(Texture2D),
typeof(byte[]),
typeof(bool)
}, null);
private void Awake()
{
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable TMP patching.");
_patchOnlyUi = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PatchOnlyUi", true, "Only patch UI text under Canvas/TextMeshProUGUI.");
_translateTmpText = ((BaseUnityPlugin)this).Config.Bind<bool>("Translation", "TranslateTmpText", true, "Apply XUnity translation files to TMP_Text objects missed by XUnity hooks.");
_forceMeshUpdate = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ForceMeshUpdate", false, "Force TMP meshes to redraw after text replacement.");
_logChanges = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "LogChanges", true, "Log applied font and translation changes.");
_fontBatchSize = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "FontBatchSize", 32, "How many TMP objects to font patch per frame during scene scans.");
_replaceFontWithExternalFile = ((BaseUnityPlugin)this).Config.Bind<bool>("Font", "ReplaceFontWithExternalFile", true, "Patch only the game's ChineseFont TMP font asset.");
_externalFontPath = ((BaseUnityPlugin)this).Config.Bind<string>("Font", "ExternalFontPath", "notosanstc-medium sdf", "External TMP font AssetBundle path. Relative paths are searched from the game root and BepInEx/config.");
_assetBundleFontAssetName = ((BaseUnityPlugin)this).Config.Bind<string>("Font", "AssetBundleFontAssetName", "", "TMP_FontAsset name inside the AssetBundle. Leave blank to use the first TMP_FontAsset.");
_replaceBuiltInTextures = ((BaseUnityPlugin)this).Config.Bind<bool>("Texture", "ReplaceBuiltInTextures", true, "Replace selected game textures from resources embedded in this patcher.");
_textureBatchSize = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "TextureBatchSize", 64, "How many texture related objects to inspect per frame during texture replacement scans.");
_translationTextPath = ((BaseUnityPlugin)this).Config.Bind<string>("Paths", "TranslationTextPath", "Translation\\zh-TW\\Text", "Translation text directory relative to BepInEx. Use config\\Translation\\zh-TW\\Text for Thunderstore profiles.");
_translationTextDirectory = ResolveBepInExRelativePath(_translationTextPath.Value);
ReloadTranslationsIfNeeded(force: true);
TryLoadExternalFont();
LoadEmbeddedTextureReplacements();
SceneManager.sceneLoaded += OnSceneLoaded;
TMPro_EventManager.TEXT_CHANGED_EVENT.Add((Action<Object>)OnTextChanged);
QueueSceneFontScans("startup");
QueueTextureScans("startup");
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove((Action<Object>)OnTextChanged);
foreach (AssetBundle loadedFontBundle in _loadedFontBundles)
{
loadedFontBundle.Unload(false);
}
_loadedFontBundles.Clear();
foreach (TextureReplacement item in _textureReplacements.Values.Distinct())
{
if ((Object)(object)item.Texture != (Object)null)
{
Object.Destroy((Object)(object)item.Texture);
}
}
_textureReplacements.Clear();
}
private void OnTextChanged(Object changedObject)
{
if (!_enabled.Value)
{
return;
}
TMP_Text val = (TMP_Text)(object)((changedObject is TMP_Text) ? changedObject : null);
if (val != null && !((Object)(object)val == (Object)null) && !IsEditorOrAssetObject((Component)(object)val))
{
ReloadTranslationsIfNeeded(force: false);
PatchTmpText(val, "text-changed", allowTranslate: true, allowFont: true, out var _, out var textTranslated);
if (textTranslated && _forceMeshUpdate.Value)
{
((Graphic)val).SetAllDirty();
val.ForceMeshUpdate(true, true);
}
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (_enabled.Value)
{
ReloadTranslationsIfNeeded(force: false);
QueueSceneFontScans("scene:" + ((Scene)(ref scene)).name);
QueueTextureScans("scene:" + ((Scene)(ref scene)).name);
}
}
private void QueueSceneFontScans(string reason)
{
if (_replaceFontWithExternalFile.Value)
{
((MonoBehaviour)this).StartCoroutine(PatchSceneTmpObjectsBatched(reason, 0f));
((MonoBehaviour)this).StartCoroutine(PatchSceneTmpObjectsBatched(reason + ":delayed1", 1f));
((MonoBehaviour)this).StartCoroutine(PatchSceneTmpObjectsBatched(reason + ":delayed3", 3f));
}
}
[IteratorStateMachine(typeof(<PatchSceneTmpObjectsBatched>d__38))]
private IEnumerator PatchSceneTmpObjectsBatched(string reason, float delaySeconds)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PatchSceneTmpObjectsBatched>d__38(0)
{
<>4__this = this,
reason = reason,
delaySeconds = delaySeconds
};
}
private void QueueTextureScans(string reason)
{
if (_replaceBuiltInTextures.Value)
{
((MonoBehaviour)this).StartCoroutine(PatchSceneTexturesBatched(reason, 0f));
((MonoBehaviour)this).StartCoroutine(PatchSceneTexturesBatched(reason + ":delayed1", 1f));
((MonoBehaviour)this).StartCoroutine(PatchSceneTexturesBatched(reason + ":delayed3", 3f));
}
}
[IteratorStateMachine(typeof(<PatchSceneTexturesBatched>d__40))]
private IEnumerator PatchSceneTexturesBatched(string reason, float delaySeconds)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PatchSceneTexturesBatched>d__40(0)
{
<>4__this = this,
reason = reason,
delaySeconds = delaySeconds
};
}
private bool PatchTmpText(TMP_Text text, string reason, bool allowTranslate, bool allowFont, out bool fontChanged, out bool textTranslated)
{
TMP_Text text2 = text;
fontChanged = false;
textTranslated = false;
bool result = false;
if (allowTranslate && _translateTmpText.Value && ShouldPatchTextComponent((Component)(object)text2) && IsReplacerTarget(text2) && TryTranslateText((Component)(object)text2, text2.text, delegate(string value)
{
text2.text = value;
}, reason, "TMP"))
{
result = true;
textTranslated = true;
}
if (allowFont && _replaceFontWithExternalFile.Value)
{
TryLoadExternalFont();
if (PatchChineseFontAsset(text2.font))
{
result = true;
fontChanged = true;
}
}
return result;
}
private bool PatchChineseFontAsset(TMP_FontAsset? targetFont)
{
TMP_FontAsset externalFontAsset = _externalFontAsset;
if (!_replaceFontWithExternalFile.Value || (Object)(object)externalFontAsset == (Object)null)
{
return false;
}
if ((Object)(object)targetFont == (Object)null || !IsTargetTmpFontAsset(targetFont) || targetFont == externalFontAsset)
{
return false;
}
int instanceID = ((Object)targetFont).GetInstanceID();
if (_patchedFontAssetIds.Contains(instanceID))
{
return false;
}
PatchTmpFontAssetInPlace(targetFont, externalFontAsset);
_patchedFontAssetIds.Add(instanceID);
return true;
}
private void LogPatchSummary(string reason, int fontPatched, int translated)
{
if (_logChanges.Value && (fontPatched > 0 || translated > 0))
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"TMP patch complete ({reason}). Fonts={fontPatched}, translated={translated}.");
}
}
private bool LoadEmbeddedTextureReplacements()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
if (_textureReplacementsLoaded)
{
return _textureReplacements.Count > 0;
}
_textureReplacementsLoaded = true;
if (!_replaceBuiltInTextures.Value)
{
return false;
}
byte[] array = ReadEmbeddedResourceBytes("GWYFTmpPatcher.Assets.GWYFTW_LOGO.png");
if (array == null || array.Length == 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Embedded logo PNG was not found in patcher resources.");
return false;
}
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!TryLoadPng(val, array))
{
Object.Destroy((Object)(object)val);
((BaseUnityPlugin)this).Logger.LogWarning((object)"Embedded logo PNG could not be decoded.");
return false;
}
((Object)val).name = "GWYF_LOGO_1280x720";
((Texture)val).wrapMode = (TextureWrapMode)1;
((Texture)val).filterMode = (FilterMode)1;
TextureReplacement value = new TextureReplacement
{
Name = "GWYF_LOGO_1280x720",
Texture = val
};
_textureReplacements["GWYF_LOGO_1280x720"] = value;
if (_logChanges.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded embedded texture replacements: {_textureReplacements.Count} aliases, logo={((Texture)val).width}x{((Texture)val).height}");
}
return _textureReplacements.Count > 0;
}
private bool PatchLoadedTextureObject(Texture2D texture)
{
if (!TryGetTextureReplacement(((Object)texture).name, out TextureReplacement replacement))
{
return false;
}
int instanceID = ((Object)texture).GetInstanceID();
if (replacement.PatchedTextures.Contains(instanceID) || texture == replacement.Texture || ((Texture)texture).width != ((Texture)replacement.Texture).width || ((Texture)texture).height != ((Texture)replacement.Texture).height)
{
return false;
}
try
{
Graphics.CopyTexture((Texture)(object)replacement.Texture, (Texture)(object)texture);
replacement.PatchedTextures.Add(instanceID);
return true;
}
catch (Exception ex)
{
replacement.PatchedTextures.Add(instanceID);
((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not copy replacement into Texture2D '" + ((Object)texture).name + "'; sprite/material replacement may still work. " + ex.Message));
return false;
}
}
private bool PatchImage(Image image)
{
TextureReplacement textureReplacement = FindReplacementForSprite(image.sprite);
if (textureReplacement == null)
{
return false;
}
Sprite replacementSprite = GetReplacementSprite(textureReplacement, image.sprite);
if (image.sprite == replacementSprite)
{
return false;
}
image.sprite = replacementSprite;
((Graphic)image).SetAllDirty();
return true;
}
private bool PatchSpriteRenderer(SpriteRenderer renderer)
{
TextureReplacement textureReplacement = FindReplacementForSprite(renderer.sprite);
if (textureReplacement == null)
{
return false;
}
Sprite replacementSprite = GetReplacementSprite(textureReplacement, renderer.sprite);
if (renderer.sprite == replacementSprite)
{
return false;
}
renderer.sprite = replacementSprite;
return true;
}
private int PatchRendererMaterials(Renderer renderer)
{
int num = 0;
Material[] array = renderer.sharedMaterials ?? Array.Empty<Material>();
foreach (Material val in array)
{
if (!((Object)(object)val == (Object)null) && HasMainTextureProperty(val))
{
Texture mainTexture = val.mainTexture;
if (!((Object)(object)mainTexture == (Object)null) && TryGetTextureReplacement(((Object)mainTexture).name, out TextureReplacement replacement) && mainTexture != replacement.Texture)
{
val.mainTexture = (Texture)(object)replacement.Texture;
num++;
}
}
}
return num;
}
private TextureReplacement? FindReplacementForSprite(Sprite sprite)
{
if (TryGetTextureReplacement(((Object)sprite).name, out TextureReplacement replacement))
{
return replacement;
}
Texture2D texture = sprite.texture;
if ((Object)(object)texture != (Object)null && TryGetTextureReplacement(((Object)texture).name, out replacement))
{
return replacement;
}
return null;
}
private static bool HasMainTextureProperty(Material material)
{
return material.HasProperty("_MainTex");
}
private bool TryGetTextureReplacement(string objectName, out TextureReplacement replacement)
{
if (_textureReplacements.TryGetValue(objectName, out replacement))
{
return true;
}
string text = NormalizeUnityObjectName(objectName);
if (!string.Equals(text, objectName, StringComparison.Ordinal) && _textureReplacements.TryGetValue(text, out replacement))
{
return true;
}
replacement = null;
return false;
}
private static string NormalizeUnityObjectName(string objectName)
{
string text = (objectName ?? string.Empty).Trim();
string[] array = new string[2] { "(Clone)", "(Instance)" };
foreach (string value in array)
{
int num = text.IndexOf(value, StringComparison.OrdinalIgnoreCase);
if (num >= 0)
{
text = text.Substring(0, num).Trim();
}
}
return text;
}
private static Sprite GetReplacementSprite(TextureReplacement replacement, Sprite source)
{
//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_0085: 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)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: 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)
//IL_009b: 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_00b3: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: 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_00de: Unknown result type (might be due to invalid IL or missing references)
int instanceID = ((Object)source).GetInstanceID();
if (replacement.SpriteCache.TryGetValue(instanceID, out Sprite value))
{
return value;
}
Rect rect = source.rect;
if (((Rect)(ref rect)).xMax > (float)((Texture)replacement.Texture).width || ((Rect)(ref rect)).yMax > (float)((Texture)replacement.Texture).height)
{
((Rect)(ref rect))..ctor(0f, 0f, (float)((Texture)replacement.Texture).width, (float)((Texture)replacement.Texture).height);
}
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0.5f, 0.5f);
Rect rect2 = source.rect;
if (((Rect)(ref rect2)).width > 0f)
{
rect2 = source.rect;
if (((Rect)(ref rect2)).height > 0f)
{
float x = source.pivot.x;
rect2 = source.rect;
float num = x / ((Rect)(ref rect2)).width;
float y = source.pivot.y;
rect2 = source.rect;
((Vector2)(ref val))..ctor(num, y / ((Rect)(ref rect2)).height);
}
}
Sprite val2 = Sprite.Create(replacement.Texture, rect, val, source.pixelsPerUnit, 0u, (SpriteMeshType)0, source.border);
((Object)val2).name = replacement.Name;
replacement.SpriteCache[instanceID] = val2;
return val2;
}
private static IEnumerable<string> SplitAliases(string aliases)
{
return from alias in (aliases ?? string.Empty).Split(new char[5] { '|', ',', ';', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
select alias.Trim() into alias
where alias.Length > 0
select alias;
}
private static byte[]? ReadEmbeddedResourceBytes(string resourceName)
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
if (stream == null)
{
return null;
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
private static bool TryLoadPng(Texture2D texture, byte[] bytes)
{
if (LoadImageMethod == null)
{
return false;
}
object obj = LoadImageMethod.Invoke(null, new object[3] { texture, bytes, false });
bool flag = default(bool);
int num;
if (obj is bool)
{
flag = (bool)obj;
num = 1;
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
private void TryLoadExternalFont()
{
if (!_replaceFontWithExternalFile.Value || (Object)(object)_externalFontAsset != (Object)null || TryLoadEmbeddedFont())
{
return;
}
string text = ResolveExternalFontPath(_externalFontPath.Value);
if (text == null)
{
if (_logChanges.Value)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("External TMP font file was not found: " + _externalFontPath.Value));
}
return;
}
try
{
AssetBundle val = AssetBundle.LoadFromFile(text);
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("External TMP font file is not a readable AssetBundle: " + text));
return;
}
_loadedFontBundles.Add(val);
TryLoadFontFromBundle(val, text);
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to load external TMP font '" + text + "': " + ex.Message));
}
}
private bool TryLoadEmbeddedFont()
{
if (_embeddedFontLoadAttempted)
{
return (Object)(object)_externalFontAsset != (Object)null;
}
_embeddedFontLoadAttempted = true;
try
{
byte[] array = ReadEmbeddedResourceBytes("GWYFTmpPatcher.Assets.notosanstc-medium-sdf.bundle");
if (array == null || array.Length == 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Embedded TMP font AssetBundle was not found in patcher resources.");
return false;
}
AssetBundle val = AssetBundle.LoadFromMemory(array);
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Embedded TMP font AssetBundle could not be loaded.");
return false;
}
_loadedFontBundles.Add(val);
if (!TryLoadFontFromBundle(val, "embedded patcher resource"))
{
return false;
}
return true;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to load embedded TMP font AssetBundle: " + ex.Message));
return false;
}
}
private static string? ResolveExternalFontPath(string configuredPath)
{
string text = (configuredPath ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(text))
{
return null;
}
if (Path.IsPathRooted(text) && File.Exists(text))
{
return Path.GetFullPath(text);
}
string[] array = new string[5]
{
Paths.GameRootPath,
Paths.ConfigPath,
Path.Combine(Paths.ConfigPath, "TMPFonts"),
Path.Combine(Paths.ConfigPath, "ConfigTMP"),
Paths.PluginPath
};
for (int i = 0; i < array.Length; i++)
{
string path = Path.Combine(array[i], text);
if (File.Exists(path))
{
return Path.GetFullPath(path);
}
}
return null;
}
private static string ResolveBepInExRelativePath(string configuredPath)
{
string text = (configuredPath ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(text))
{
text = "Translation";
}
if (Path.IsPathRooted(text))
{
return Path.GetFullPath(text);
}
string text2 = text.Replace('\\', '/');
if (text2.Equals("config", StringComparison.OrdinalIgnoreCase))
{
return Paths.ConfigPath;
}
if (text2.StartsWith("config/", StringComparison.OrdinalIgnoreCase))
{
string path = text2.Substring("config/".Length).Replace('/', Path.DirectorySeparatorChar);
return Path.GetFullPath(Path.Combine(Paths.ConfigPath, path));
}
return Path.GetFullPath(Path.Combine(Paths.GameRootPath, "BepInEx", text2.Replace('/', Path.DirectorySeparatorChar)));
}
private static bool IsTargetTmpFontAsset(TMP_FontAsset? fontAsset)
{
if ((Object)(object)fontAsset != (Object)null)
{
return string.Equals(NormalizeUnityObjectName(((Object)fontAsset).name), "ChineseFont", StringComparison.OrdinalIgnoreCase);
}
return false;
}
private void PatchTmpFontAssetInPlace(TMP_FontAsset targetFont, TMP_FontAsset sourceFont)
{
Material material = ((TMP_Asset)targetFont).material;
Material material2 = ((TMP_Asset)sourceFont).material;
string[] tmpFontAssetCopyFields = TmpFontAssetCopyFields;
foreach (string fieldName in tmpFontAssetCopyFields)
{
CopyFieldValue(sourceFont, targetFont, fieldName);
}
if ((Object)(object)material != (Object)null && (Object)(object)material2 != (Object)null)
{
string name = ((Object)material).name;
material.CopyPropertiesFromMaterial(material2);
((Object)material).name = name;
CopyFieldValue(sourceFont, targetFont, "m_Material", material);
}
else if ((Object)(object)material2 != (Object)null)
{
CopyFieldValue(sourceFont, targetFont, "m_Material");
}
RefreshTmpFontAsset(targetFont);
if (_logChanges.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Patched TMP font asset 'ChineseFont' with '" + ((Object)sourceFont).name + "'."));
}
}
private static void CopyFieldValue(TMP_FontAsset source, TMP_FontAsset target, string fieldName)
{
FieldInfo field = typeof(TMP_FontAsset).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (!(field == null))
{
field.SetValue(target, field.GetValue(source));
}
}
private static void CopyFieldValue(TMP_FontAsset source, TMP_FontAsset target, string fieldName, object value)
{
typeof(TMP_FontAsset).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(target, value);
}
private static void RefreshTmpFontAsset(TMP_FontAsset fontAsset)
{
MethodInfo method = typeof(TMP_FontAsset).GetMethod("ReadFontAssetDefinition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method != null)
{
method.Invoke(fontAsset, null);
}
else
{
typeof(TMP_FontAsset).GetMethod("InitializeDictionaryLookupTables", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(fontAsset, null);
}
}
private static bool IsReplacerTarget(TMP_Text text)
{
string hierarchyPath = GetHierarchyPath(text.transform);
string text2 = NormalizeHierarchyPath("/LocalManager/UI/InteractionUIPanel/TextPanel/ItemNameText");
if (!string.Equals(hierarchyPath, text2, StringComparison.OrdinalIgnoreCase))
{
return hierarchyPath.EndsWith(text2, StringComparison.OrdinalIgnoreCase);
}
return true;
}
private bool ShouldPatchTextComponent(Component component)
{
if (!_patchOnlyUi.Value)
{
return true;
}
if (!(component is TextMeshProUGUI))
{
return (Object)(object)component.GetComponentInParent<Canvas>(true) != (Object)null;
}
return true;
}
private static string GetHierarchyPath(Transform transform)
{
Stack<string> stack = new Stack<string>();
Transform val = transform;
while ((Object)(object)val != (Object)null)
{
stack.Push(((Object)val).name);
val = val.parent;
}
return "/" + string.Join("/", stack.Select(NormalizePathSegment));
}
private static string NormalizeHierarchyPath(string path)
{
string text = path.Replace('\\', '/').Trim();
if (!text.StartsWith("/", StringComparison.Ordinal))
{
text = "/" + text;
}
return string.Join("/", text.Split(new char[1] { '/' }, StringSplitOptions.RemoveEmptyEntries).Select(NormalizePathSegment).Prepend(string.Empty));
}
private static string NormalizePathSegment(string segment)
{
int num = segment.IndexOf("(Clone)", StringComparison.OrdinalIgnoreCase);
if (num >= 0)
{
segment = segment.Remove(num);
}
return segment.Trim();
}
private bool TryTranslateText(Component component, string original, Action<string> setText, string reason, string kind)
{
if (string.IsNullOrWhiteSpace(original) || IsMostlyCjk(original))
{
return false;
}
int instanceID = ((Object)component).GetInstanceID();
if (_lastAppliedText.TryGetValue(instanceID, out string value) && string.Equals(value, original, StringComparison.Ordinal))
{
return false;
}
string text = Translate(original);
if (string.Equals(text, original, StringComparison.Ordinal))
{
return false;
}
setText(text);
_lastAppliedText[instanceID] = text;
if (_logChanges.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)(kind + " translated (" + reason + "): " + EscapeForLog(original) + " -> " + EscapeForLog(text)));
}
return true;
}
private string Translate(string input)
{
string key = NormalizeText(input);
if (_exactRules.TryGetValue(key, out string value))
{
return value;
}
string text = input;
foreach (RegexRule regexRule in _regexRules)
{
if (regexRule.Regex.IsMatch(text))
{
text = regexRule.Regex.Replace(text, regexRule.Replacement);
}
}
foreach (KeyValuePair<string, string> item in _postRules.OrderByDescending<KeyValuePair<string, string>, int>((KeyValuePair<string, string> rule) => rule.Key.Length))
{
text = Regex.Replace(text, Regex.Escape(item.Key), EscapeReplacement(item.Value), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
return text;
}
private void ReloadTranslationsIfNeeded(bool force)
{
if (!Directory.Exists(_translationTextDirectory))
{
return;
}
string[] array = new string[2]
{
Path.Combine(_translationTextDirectory, "Complate.txt"),
Path.Combine(_translationTextDirectory, "_Postprocessors.txt")
};
bool flag = force;
string[] array2 = array;
foreach (string text in array2)
{
if (File.Exists(text))
{
DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(text);
if (!_translationFileTimes.TryGetValue(text, out var value) || lastWriteTimeUtc > value)
{
flag = true;
}
}
}
if (!flag)
{
return;
}
_exactRules.Clear();
_regexRules.Clear();
_postRules.Clear();
array2 = array;
foreach (string text2 in array2)
{
if (File.Exists(text2))
{
LoadTranslationFile(text2, Path.GetFileName(text2).Equals("_Postprocessors.txt", StringComparison.OrdinalIgnoreCase));
_translationFileTimes[text2] = File.GetLastWriteTimeUtc(text2);
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded XUnity translations: exact={_exactRules.Count}, regex={_regexRules.Count}, post={_postRules.Count}");
}
private void LoadTranslationFile(string path, bool isPostprocessor)
{
string[] array = File.ReadAllLines(path, Encoding.UTF8);
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (string.IsNullOrWhiteSpace(text) || text.StartsWith("#", StringComparison.Ordinal))
{
continue;
}
int num = text.IndexOf('=');
if (num <= 0)
{
continue;
}
string text2 = StripNoParse(text.Substring(0, num).Trim());
string text3 = StripNoParse(DecodeEscapes(text.Substring(num + 1).Trim()));
if (!string.IsNullOrWhiteSpace(text2) && !string.IsNullOrWhiteSpace(text3))
{
if (text2.StartsWith("r:\"", StringComparison.Ordinal) && text2.EndsWith("\"", StringComparison.Ordinal))
{
string pattern = text2.Substring(3, text2.Length - 4);
_regexRules.Add(new RegexRule(new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant), text3));
}
else if (!isPostprocessor)
{
_exactRules[NormalizeText(text2)] = text3;
}
else if (IsSafePostprocessorSource(text2))
{
_postRules[text2] = text3;
}
}
}
}
private bool TryLoadFontFromBundle(AssetBundle bundle, string source)
{
string text = _assetBundleFontAssetName.Value.Trim();
TMP_FontAsset val = null;
if (!string.IsNullOrWhiteSpace(text))
{
val = bundle.LoadAsset<TMP_FontAsset>(text);
}
if (val == null)
{
val = bundle.LoadAllAssets<TMP_FontAsset>().FirstOrDefault();
}
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("No TMP_FontAsset found in AssetBundle: " + source));
return false;
}
Texture2D val2 = bundle.LoadAllAssets<Texture2D>().FirstOrDefault();
if ((Object)(object)val2 != (Object)null)
{
typeof(TMP_FontAsset).GetField("m_AtlasTexture", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(val, val2);
FieldInfo field = typeof(TMP_FontAsset).GetField("m_AtlasTextures", BindingFlags.Instance | BindingFlags.NonPublic);
if (field?.GetValue(val) is Texture2D[] array && array.Length != 0)
{
array[0] = val2;
}
else
{
field?.SetValue(val, new Texture2D[1] { val2 });
}
if ((Object)(object)((TMP_Asset)val).material != (Object)null && HasMainTextureProperty(((TMP_Asset)val).material))
{
((TMP_Asset)val).material.SetTexture(ShaderUtilities.ID_MainTex, (Texture)(object)val2);
}
if (_logChanges.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Bound atlas texture: {((Object)val2).name} ({((Texture)val2).width}x{((Texture)val2).height})");
}
}
else
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("No Texture2D found in AssetBundle: " + source + "; glyphs may render incorrectly."));
}
_externalFontAsset = val;
((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded TMP font: " + ((Object)_externalFontAsset).name + " from " + source));
return true;
}
private static bool IsSafePostprocessorSource(string source)
{
if (source.Length < 3 || source.Any((char ch) => char.IsDigit(ch) || ch == '$'))
{
return false;
}
return source.Any(char.IsLetter);
}
private static string StripNoParse(string value)
{
return value.Replace("<noparse></noparse>", string.Empty).Replace("<noparse><\\/noparse>", string.Empty).Trim();
}
private static string NormalizeText(string value)
{
return Regex.Replace(StripNoParse(value).Replace('\u00a0', ' ').Replace('\u200b', ' ').Replace('\u200c', ' ')
.Replace('\u200d', ' ')
.Replace("\\n", " ")
.Replace("\r", " ")
.Replace("\n", " "), "\\s+", " ").Trim();
}
private static string DecodeEscapes(string value)
{
return value.Replace("\\n", Environment.NewLine).Replace("\\t", "\t");
}
private static string EscapeReplacement(string value)
{
return value.Replace("$", "$$");
}
private static string EscapeForLog(string value)
{
return value.Replace("\r", "\\r").Replace("\n", "\\n");
}
private static bool IsEditorOrAssetObject(Component component)
{
//IL_0011: 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)
GameObject gameObject = component.gameObject;
if (!((Object)(object)gameObject == (Object)null))
{
Scene scene = gameObject.scene;
return !((Scene)(ref scene)).IsValid();
}
return true;
}
private static bool IsMostlyCjk(string value)
{
int num = 0;
int num2 = 0;
foreach (char c in value)
{
if (IsCjk(c))
{
num++;
}
else if (char.IsLetter(c))
{
num2++;
}
}
if (num > 0)
{
return num >= num2;
}
return false;
}
private static bool IsCjk(char ch)
{
if ((ch < '一' || ch > '\u9fff') && (ch < '㐀' || ch > '䶿'))
{
if (ch >= '豈')
{
return ch <= '\ufaff';
}
return false;
}
return true;
}
}
}