using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace CjkFontFix;
[BepInPlugin("local.ultrakill.cjkfontfix", "CJK Font Fix", "1.2.0")]
public class CjkFontFixPlugin : BaseUnityPlugin
{
private static readonly char[] Probe = new char[3] { 'あ', '日', '한' };
private readonly List<TMP_FontAsset> donors = new List<TMP_FontAsset>();
private readonly HashSet<int> donorIds = new HashSet<int>();
private readonly HashSet<string> patchedPairs = new HashSet<string>();
private static readonly string[] FontFiles = new string[11]
{
"YuGothR.ttc", "YuGothM.ttc", "meiryo.ttc", "msgothic.ttc", "malgun.ttf", "gulim.ttc", "batang.ttc", "msyh.ttc", "msjh.ttc", "simsun.ttc",
"simhei.ttf"
};
private const int MaxFileFonts = 5;
private readonly List<TMP_FontAsset> fileFonts = new List<TMP_FontAsset>();
private float nextPatch;
private int logged;
private void Awake()
{
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
try
{
LoadFileFonts();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Loading font files failed: " + ex));
}
SceneManager.sceneLoaded += delegate
{
nextPatch = 0f;
};
}
private void LoadFileFonts()
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Expected O, but got Unknown
string text = Environment.GetEnvironmentVariable("WINDIR");
if (string.IsNullOrEmpty(text))
{
text = "C:\\Windows";
}
string text2 = Path.Combine(text, "Fonts");
string[] fontFiles = FontFiles;
foreach (string text3 in fontFiles)
{
if (fileFonts.Count >= 5)
{
break;
}
string text4 = Path.Combine(text2, text3);
if (!File.Exists(text4))
{
continue;
}
try
{
Font val = new Font(text4);
TMP_FontAsset val2 = TMP_FontAsset.CreateFontAsset(val);
if ((Object)(object)val2 == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not make a font from " + text3));
continue;
}
if (!CanDraw(val2))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)(text3 + " loaded but has no CJK glyphs; skipped."));
continue;
}
((Object)val2).name = "CJK " + text3;
fileFonts.Add(val2);
donors.Add(val2);
donorIds.Add(((Object)val2).GetInstanceID());
((BaseUnityPlugin)this).Logger.LogInfo((object)("CJK font loaded from file: " + text3));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Skipping " + text3 + ": " + ex.Message));
}
}
if (fileFonts.Count == 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("No usable CJK font files found in " + text2));
}
}
private static bool CanDraw(TMP_FontAsset fa)
{
try
{
char[] probe = Probe;
foreach (char c in probe)
{
if (fa.HasCharacter(c, true, true))
{
return true;
}
}
}
catch (Exception)
{
}
return false;
}
private void Update()
{
if (Time.unscaledTime < nextPatch)
{
return;
}
nextPatch = Time.unscaledTime + 2f;
try
{
Patch();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Patch failed: " + ex));
nextPatch = Time.unscaledTime + 30f;
}
}
private void Patch()
{
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_026a: Unknown result type (might be due to invalid IL or missing references)
TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
TMP_FontAsset[] array2 = array;
foreach (TMP_FontAsset val in array2)
{
if (!((Object)(object)val == (Object)null) && !donorIds.Contains(((Object)val).GetInstanceID()) && CanDraw(val))
{
donorIds.Add(((Object)val).GetInstanceID());
donors.Add(val);
if (logged++ < 10)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("CJK-capable font found: " + ((Object)val).name));
}
}
}
if (donors.Count == 0)
{
return;
}
List<TMP_FontAsset> fallbackFontAssets = TMP_Settings.fallbackFontAssets;
if (fallbackFontAssets != null)
{
foreach (TMP_FontAsset donor in donors)
{
if ((Object)(object)donor != (Object)null && !fallbackFontAssets.Contains(donor))
{
fallbackFontAssets.Add(donor);
}
}
}
bool flag = false;
TMP_FontAsset[] array3 = array;
foreach (TMP_FontAsset val2 in array3)
{
if ((Object)(object)val2 == (Object)null || donorIds.Contains(((Object)val2).GetInstanceID()))
{
continue;
}
if (val2.fallbackFontAssetTable == null)
{
val2.fallbackFontAssetTable = new List<TMP_FontAsset>();
}
foreach (TMP_FontAsset donor2 in donors)
{
if (!((Object)(object)donor2 == (Object)null))
{
string item = ((Object)val2).GetInstanceID() + ">" + ((Object)donor2).GetInstanceID();
if (patchedPairs.Add(item) && !val2.fallbackFontAssetTable.Contains(donor2))
{
val2.fallbackFontAssetTable.Add(donor2);
flag = true;
}
}
}
}
if (!flag)
{
return;
}
TMP_Text[] array4 = Resources.FindObjectsOfTypeAll<TMP_Text>();
foreach (TMP_Text val3 in array4)
{
if ((Object)(object)val3 != (Object)null)
{
Scene scene = ((Component)val3).gameObject.scene;
if (((Scene)(ref scene)).IsValid() && ((Component)val3).gameObject.activeInHierarchy)
{
((Graphic)val3).SetAllDirty();
}
}
}
}
}