Decompiled source of BetterFont v1.0.1

plugins/BetterFont/BetterFont.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("BetterFont")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Troca a fonte do jogo por uma serifada (Times New Roman ou similar) preservando a estilizacao (cor, contorno, sombra) dos textos.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("BetterFont")]
[assembly: AssemblyTitle("BetterFont")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace BetterFont;

[BepInPlugin("com.gumatos.betterfont", "Better Font", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log { get; private set; }

	internal static ConfigEntry<bool> PreservarEstilo { get; private set; }

	internal static ConfigEntry<bool> PularTextosEstilizados { get; private set; }

	internal static ConfigEntry<bool> LogDiagnosticoEstilo { get; private set; }

	internal static bool PreservarEstiloLigado
	{
		get
		{
			if (PreservarEstilo != null)
			{
				return PreservarEstilo.Value;
			}
			return true;
		}
	}

	internal static bool PularEstilizadosLigado
	{
		get
		{
			if (PularTextosEstilizados != null)
			{
				return PularTextosEstilizados.Value;
			}
			return true;
		}
	}

	internal static bool LogDiagnosticoLigado
	{
		get
		{
			if (LogDiagnosticoEstilo != null)
			{
				return LogDiagnosticoEstilo.Value;
			}
			return false;
		}
	}

	private void Awake()
	{
		Log = ((BaseUnityPlugin)this).Logger;
		PreservarEstilo = BindSeguro("Estilo", "PreservarEstilo", padrao: true, "true = antes de trocar a fonte, copia as propriedades de ESTILO do material que o texto ja usava (cor de face _FaceColor, contorno _OutlineWidth/_OutlineSoftness/_OutlineColor, sombra _UnderlayColor/_UnderlayOffsetX/_UnderlayOffsetY/_UnderlayDilate/_UnderlaySoftness, _FaceDilate) para o material POR COMPONENTE da fonte nova (t.fontMaterial -- nunca o material compartilhado), e liga as keywords OUTLINE_ON/UNDERLAY_ON que estavam ativas. Em TextMeshPro trocar 'font' troca o MATERIAL junto, e o estilo do jogo vive no material. false = troca a fonte deixando o material novo como veio (comportamento da 1.0.0, que apagava cor/contorno/sombra).");
		PularTextosEstilizados = BindSeguro("Estilo", "PularTextosEstilizados", padrao: false, "false (padrao) = troca a fonte TAMBEM dos textos cujo material e estilizado (material proprio, diferente do material padrao da fonte daquele componente, ou com shader diferente do material da fonte serifada) e REAPLICA neles os efeitos de material que ja estavam ali (cor de face, contorno _OutlineWidth/_OutlineSoftness/_OutlineColor, sombra _UnderlayColor/_UnderlayOffsetX/Y/_UnderlayDilate/_UnderlaySoftness e as keywords OUTLINE_ON/UNDERLAY_ON), copiando para o material POR COMPONENTE da fonte nova. E o que faz QUALQUER mod que tenha aplicado efeito antes continuar funcionando. Se o efeito em uso NAO puder ser reproduzido com fidelidade (textura de face _FaceTex, bevel _BumpMap, GLOW_ON/BEVEL_ON ou shader incompativel), o texto NAO e tocado — falha-segura. true = ESCAPE, comportamento antigo da 1.0.1: NAO troca a fonte de quem tem material estilizado (o visual original fica 100% intacto, so nao ganha a serifa). Para ver o que foi pulado, ligue LogDiagnosticoEstilo.");
		LogDiagnosticoEstilo = BindSeguro("Diagnostico", "LogDiagnosticoEstilo", padrao: false, "true = loga um bloco por texto tratado: objeto, fonte, material compartilhado, shader, quais propriedades de estilo foram copiadas e quais existiam na origem mas NAO podem ser transportadas (ex.: _FaceTex, GLOW_ON, _GradientScale do atlas). Serve para conferir um texto especifico e para saber se algo ainda ficou diferente do original. Padrao: false (sem spam no log).");
		((BaseUnityPlugin)this).Logger.LogInfo((object)($"Better Font carregado (v{((BaseUnityPlugin)this).Info.Metadata.Version}): preservar estilo={PreservarEstiloLigado}, " + $"pular textos estilizados={PularEstilizadosLigado}, diagnostico={LogDiagnosticoLigado}."));
		AplicarPatches();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Better Font: o updater sera criado de forma PREGUICOSA no primeiro OptionsManager.Localize da UI (nunca no Awake: a Unity destroi GameObject criado durante o chainloader do BepInEx).");
	}

	private ConfigEntry<T> BindSeguro<T>(string secao, string chave, T padrao, string descricao)
	{
		try
		{
			return ((BaseUnityPlugin)this).Config.Bind<T>(secao, chave, padrao, descricao);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			string[] obj = new string[6] { "Better Font: falha ao ler/criar a chave '", chave, "' do config — usando o padrao (", null, null, null };
			T val = padrao;
			obj[3] = val?.ToString();
			obj[4] = "): ";
			obj[5] = ex.Message;
			log.LogError((object)string.Concat(obj));
			return null;
		}
	}

	private static void AplicarPatches()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		Harmony val = new Harmony("com.gumatos.betterfont");
		List<string> list = new List<string>();
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		Type[] types;
		try
		{
			types = typeof(Plugin).Assembly.GetTypes();
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Better Font: nao deu para listar os tipos do mod — nenhum gancho aplicado: " + ex));
			return;
		}
		foreach (Type type in types)
		{
			if (EhClasseDeGancho(type))
			{
				num++;
				try
				{
					int num4 = val.CreateClassProcessor(type).Patch()?.Count ?? 0;
					num3 += num4;
					num2++;
					Log.LogInfo((object)("Better Font: gancho aplicado — " + type.Name + " (" + num4 + " metodo(s) do jogo)."));
				}
				catch (Exception ex2)
				{
					list.Add(type.Name);
					Log.LogError((object)("Better Font: FALHA ao aplicar o gancho " + type.Name + " — " + ex2.Message));
				}
			}
		}
		string text = "Better Font: patches Harmony aplicados (" + num2 + "/" + num + " ganchos, " + num3 + " metodos do jogo).";
		if (list.Count == 0)
		{
			Log.LogInfo((object)text);
		}
		else
		{
			Log.LogError((object)(text + " GANCHOS QUE FALHARAM: " + string.Join(", ", list.ToArray()) + ". O mod continua de pe, mas o recurso que dependia deles nao existe nesta sessao."));
		}
	}

	private static bool EhClasseDeGancho(Type tipo)
	{
		try
		{
			if (tipo == null || !tipo.IsClass)
			{
				return false;
			}
			return tipo.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0;
		}
		catch (Exception)
		{
			return false;
		}
	}
}
[HarmonyPatch(typeof(OptionsManager), "Localize")]
public static class LocalizeFontTrigger
{
	private static void Postfix()
	{
		try
		{
			FontUpdater.Ensure();
		}
		catch
		{
		}
	}
}
public class FontUpdater : MonoBehaviour
{
	private static bool _everDestroyed;

	private static readonly string[] PropsCor = new string[3] { "_FaceColor", "_OutlineColor", "_UnderlayColor" };

	private static readonly string[] PropsFloat = new string[7] { "_FaceDilate", "_OutlineWidth", "_OutlineSoftness", "_UnderlayOffsetX", "_UnderlayOffsetY", "_UnderlayDilate", "_UnderlaySoftness" };

	private float _lastSweep = -99f;

	private TMP_FontAsset _serifFont;

	private readonly HashSet<TMP_Text> _seenTexts = new HashSet<TMP_Text>();

	private readonly HashSet<string> _diagVistos = new HashSet<string>();

	private readonly HashSet<int> _puladosContados = new HashSet<int>();

	private bool _loggedFirstSweep;

	private int _diagLinhas;

	private bool _diagCortado;

	public static FontUpdater Instance { get; private set; }

	public static void Create()
	{
		//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_001e: Expected O, but got Unknown
		if (!((Object)(object)Instance != (Object)null))
		{
			GameObject val = new GameObject("BetterFont_Updater");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<FontUpdater>();
		}
	}

	public static void Ensure()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			if (_everDestroyed)
			{
				Plugin.Log.LogWarning((object)"Better Font: updater ausente — recriando (a Unity destruiu o anterior).");
			}
			Create();
		}
		Instance?.MaybeSweep();
	}

	private void Awake()
	{
		Instance = this;
		Plugin.Log.LogInfo((object)"Better Font: updater criado.");
		FontSweep();
	}

	private void Start()
	{
		Plugin.Log.LogInfo((object)"Better Font: Start() do updater chamado (objeto vivo na cena).");
	}

	private void OnDestroy()
	{
		Plugin.Log.LogWarning((object)"Better Font: updater DESTRUÍDO pela Unity.");
		_everDestroyed = true;
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	public void MaybeSweep()
	{
		try
		{
			if (Time.realtimeSinceStartup - _lastSweep >= 2f)
			{
				_lastSweep = Time.realtimeSinceStartup;
				FontSweep();
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Better Font erro: " + ex.Message + "\n" + ex.StackTrace));
		}
	}

	private void Update()
	{
		try
		{
			if (Time.realtimeSinceStartup - _lastSweep >= 2f)
			{
				_lastSweep = Time.realtimeSinceStartup;
				FontSweep();
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Better Font erro no Update: " + ex.Message + "\n" + ex.StackTrace));
		}
	}

	private void FontSweep()
	{
		try
		{
			if ((Object)(object)_serifFont == (Object)null)
			{
				_serifFont = CreateSerifFont();
				if ((Object)(object)_serifFont == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Better Font: nenhuma fonte serifada disponível no SO.");
					return;
				}
				if (_serifFont.fallbackFontAssetTable == null)
				{
					_serifFont.fallbackFontAssetTable = new List<TMP_FontAsset>();
				}
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			foreach (TMP_Text val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				RegistrarFallback(val);
				if ((Object)(object)val.font == (Object)(object)_serifFont)
				{
					num4++;
					continue;
				}
				try
				{
					Material fontSharedMaterial = val.fontSharedMaterial;
					TMP_FontAsset font = val.font;
					string motivo;
					bool flag = EhEstilizado(fontSharedMaterial, font, out motivo);
					if (flag && Plugin.PularEstilizadosLigado)
					{
						if (ContarPuloUmaVez(val))
						{
							num2++;
							Diagnostico("PULADO (escape: material estilizado: " + motivo + ")", val, font, fontSharedMaterial, "n/a (texto pulado: fonte e material nao foram tocados)", "n/a (texto pulado: nada foi transportado)");
						}
						continue;
					}
					string motivo2 = null;
					if (flag && Plugin.PreservarEstiloLigado && !EstiloTransportavel(fontSharedMaterial, out motivo2))
					{
						if (ContarPuloUmaVez(val))
						{
							num3++;
							Diagnostico("PULADO (efeito nao transportavel: " + motivo2 + ")", val, font, fontSharedMaterial, "n/a (texto pulado: fonte e material nao foram tocados)", "n/a (texto pulado: nada foi transportado)");
						}
						continue;
					}
					val.font = _serifFont;
					string copiados = null;
					string naoTransportados = null;
					if (Plugin.PreservarEstiloLigado && (Object)(object)fontSharedMaterial != (Object)null && UsaMaterialDaFonteNova(val))
					{
						Material fontMaterial = val.fontMaterial;
						if ((Object)(object)fontMaterial != (Object)null)
						{
							copiados = CopiarEstilo(fontSharedMaterial, fontMaterial, out naoTransportados);
							val.UpdateMeshPadding();
							((Graphic)val).SetVerticesDirty();
						}
					}
					num++;
					Diagnostico(flag ? "CONVERTIDO (efeito do material anterior transportado)" : "CONVERTIDO", val, font, fontSharedMaterial, copiados, naoTransportados);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Better Font: falha ao tratar um texto: " + ex.GetType().Name + ": " + ex.Message));
				}
			}
			if (!_loggedFirstSweep)
			{
				_loggedFirstSweep = true;
				Plugin.Log.LogInfo((object)$"Better Font: varredura aplicada ({_seenTexts.Count} textos vistos).");
			}
			if (num > 0 || num2 > 0 || num3 > 0)
			{
				Plugin.Log.LogInfo((object)($"Better Font: varredura — {num} texto(s) convertidos para a serifa" + (Plugin.PreservarEstiloLigado ? " (efeitos do material anterior transportados)" : string.Empty) + $", {num2} pulado(s) pelo escape (PularTextosEstilizados ligado), " + $"{num3} intocado(s) por efeito nao transportavel, {num4} ja na serifa."));
			}
		}
		catch (Exception ex2)
		{
			Plugin.Log.LogWarning((object)("Better Font erro: " + ex2.Message + "\n" + ex2.StackTrace));
		}
	}

	private void RegistrarFallback(TMP_Text t)
	{
		if (_seenTexts.Contains(t))
		{
			return;
		}
		_seenTexts.Add(t);
		try
		{
			if (_serifFont.fallbackFontAssetTable == null)
			{
				_serifFont.fallbackFontAssetTable = new List<TMP_FontAsset>();
			}
			if ((Object)(object)t.font != (Object)null && (Object)(object)t.font != (Object)(object)_serifFont && !_serifFont.fallbackFontAssetTable.Contains(t.font))
			{
				_serifFont.fallbackFontAssetTable.Add(t.font);
			}
		}
		catch
		{
		}
	}

	private bool EhEstilizado(Material antigo, TMP_FontAsset fonteAntiga, out string motivo)
	{
		motivo = null;
		if ((Object)(object)antigo == (Object)null)
		{
			return false;
		}
		if ((Object)(object)fonteAntiga != (Object)null && (Object)(object)((TMP_Asset)fonteAntiga).material != (Object)null && (Object)(object)antigo != (Object)(object)((TMP_Asset)fonteAntiga).material)
		{
			motivo = "material proprio '" + ((Object)antigo).name + "' (padrao da fonte '" + ((Object)fonteAntiga).name + "' = '" + ((Object)((TMP_Asset)fonteAntiga).material).name + "')";
			return true;
		}
		Material val = (((Object)(object)_serifFont != (Object)null) ? ((TMP_Asset)_serifFont).material : null);
		if ((Object)(object)val != (Object)null && (Object)(object)antigo.shader != (Object)(object)val.shader)
		{
			motivo = "shader '" + Nome(antigo.shader) + "' != '" + Nome(val.shader) + "' da fonte serifada";
			return true;
		}
		return false;
	}

	private bool EstiloTransportavel(Material antigo, out string motivo)
	{
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		motivo = null;
		try
		{
			if ((Object)(object)antigo == (Object)null)
			{
				return true;
			}
			if (antigo.HasProperty("_FaceTex") && (Object)(object)antigo.GetTexture("_FaceTex") != (Object)null)
			{
				motivo = "_FaceTex (textura de face) em uso — a copia nao transporta textura";
				return false;
			}
			if (antigo.HasProperty("_BumpMap") && (Object)(object)antigo.GetTexture("_BumpMap") != (Object)null)
			{
				motivo = "_BumpMap (bevel) em uso — a copia nao transporta bevel";
				return false;
			}
			if (antigo.IsKeywordEnabled("GLOW_ON"))
			{
				motivo = "GLOW_ON ligado — glow nao e transportado";
				return false;
			}
			if (antigo.IsKeywordEnabled("BEVEL_ON"))
			{
				motivo = "BEVEL_ON ligado — bevel nao e transportado";
				return false;
			}
			Material val = (((Object)(object)_serifFont != (Object)null) ? ((TMP_Asset)_serifFont).material : null);
			if ((Object)(object)val == (Object)null)
			{
				motivo = "a fonte serifada ainda nao tem material";
				return false;
			}
			if ((Object)(object)antigo.shader != (Object)(object)val.shader)
			{
				motivo = "shader '" + Nome(antigo.shader) + "' != '" + Nome(val.shader) + "' do material da fonte serifada";
				return false;
			}
			if ((antigo.IsKeywordEnabled("OUTLINE_ON") || ValorAtivo(antigo, "_OutlineWidth")) && !val.HasProperty("_OutlineWidth"))
			{
				motivo = "contorno em uso e o material novo nao expoe _OutlineWidth (fonte bitmap)";
				return false;
			}
			if ((antigo.IsKeywordEnabled("UNDERLAY_ON") || (antigo.HasProperty("_UnderlayColor") && antigo.GetColor("_UnderlayColor").a > 0.001f)) && !val.HasProperty("_UnderlaySoftness"))
			{
				motivo = "sombra em uso e o material novo nao expoe underlay";
				return false;
			}
			return true;
		}
		catch (Exception ex)
		{
			motivo = "nao deu para conferir o efeito (" + ex.GetType().Name + ")";
			return false;
		}
	}

	private static string CopiarEstilo(Material antigo, Material novo, out string naoTransportados)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		List<string> list = new List<string>();
		List<string> list2 = new List<string>();
		for (int i = 0; i < PropsCor.Length; i++)
		{
			string text = PropsCor[i];
			if (antigo.HasProperty(text) && novo.HasProperty(text))
			{
				novo.SetColor(text, antigo.GetColor(text));
				list.Add(text);
			}
			else if (antigo.HasProperty(text))
			{
				list2.Add(text + " (shader novo nao expoe)");
			}
		}
		for (int j = 0; j < PropsFloat.Length; j++)
		{
			string text2 = PropsFloat[j];
			if (antigo.HasProperty(text2) && novo.HasProperty(text2))
			{
				novo.SetFloat(text2, antigo.GetFloat(text2));
				list.Add(text2);
			}
			else if (antigo.HasProperty(text2))
			{
				list2.Add(text2 + " (shader novo nao expoe)");
			}
		}
		bool flag = antigo.IsKeywordEnabled("OUTLINE_ON") || ValorAtivo(antigo, "_OutlineWidth");
		bool flag2 = antigo.IsKeywordEnabled("UNDERLAY_ON") || (antigo.HasProperty("_UnderlayColor") && antigo.GetColor("_UnderlayColor").a > 0.001f);
		if (flag && novo.HasProperty("_OutlineWidth"))
		{
			novo.EnableKeyword("OUTLINE_ON");
			list.Add("OUTLINE_ON");
		}
		else if (flag)
		{
			list2.Add("OUTLINE_ON (shader novo sem _OutlineWidth: fonte bitmap)");
		}
		if (flag2 && novo.HasProperty("_UnderlaySoftness"))
		{
			novo.EnableKeyword("UNDERLAY_ON");
			list.Add("UNDERLAY_ON");
		}
		else if (flag2)
		{
			list2.Add("UNDERLAY_ON (shader novo sem underlay)");
		}
		if (antigo.HasProperty("_FaceTex") && (Object)(object)antigo.GetTexture("_FaceTex") != (Object)null)
		{
			list2.Add("_FaceTex (textura de face)");
		}
		if (antigo.HasProperty("_BumpMap") && (Object)(object)antigo.GetTexture("_BumpMap") != (Object)null)
		{
			list2.Add("_BumpMap (bevel)");
		}
		if (antigo.IsKeywordEnabled("GLOW_ON"))
		{
			list2.Add("GLOW_ON");
		}
		if (antigo.IsKeywordEnabled("BEVEL_ON"))
		{
			list2.Add("BEVEL_ON");
		}
		if (antigo.HasProperty("_GradientScale") && novo.HasProperty("_GradientScale") && !Mathf.Approximately(antigo.GetFloat("_GradientScale"), novo.GetFloat("_GradientScale")))
		{
			list2.Add("_GradientScale origem=" + antigo.GetFloat("_GradientScale").ToString("0.##") + " novo=" + novo.GetFloat("_GradientScale").ToString("0.##") + " (fica o do atlas novo)");
		}
		naoTransportados = ((list2.Count > 0) ? string.Join("; ", list2.ToArray()) : null);
		if (list.Count <= 0)
		{
			return null;
		}
		return string.Join(", ", list.ToArray());
	}

	private static bool ValorAtivo(Material m, string prop)
	{
		if (m.HasProperty(prop))
		{
			return m.GetFloat(prop) > 0.0001f;
		}
		return false;
	}

	private bool ContarPuloUmaVez(TMP_Text t)
	{
		try
		{
			return _puladosContados.Add(((Object)t).GetInstanceID());
		}
		catch
		{
			return true;
		}
	}

	private bool UsaMaterialDaFonteNova(TMP_Text t)
	{
		try
		{
			Material fontSharedMaterial = t.fontSharedMaterial;
			Texture val = (Texture)(object)(((Object)(object)_serifFont != (Object)null) ? _serifFont.atlasTexture : null);
			if ((Object)(object)fontSharedMaterial == (Object)null || (Object)(object)val == (Object)null || !fontSharedMaterial.HasProperty("_MainTex"))
			{
				return false;
			}
			Texture texture = fontSharedMaterial.GetTexture("_MainTex");
			return (Object)(object)texture != (Object)null && ((Object)texture).GetInstanceID() == ((Object)val).GetInstanceID();
		}
		catch
		{
			return false;
		}
	}

	private static string Nome(Shader s)
	{
		if (!((Object)(object)s != (Object)null))
		{
			return "(sem shader)";
		}
		return ((Object)s).name;
	}

	private static string NomeObjeto(TMP_Text t)
	{
		try
		{
			return ((Object)(object)t != (Object)null && (Object)(object)((Component)t).gameObject != (Object)null) ? ((Object)((Component)t).gameObject).name : "(?)";
		}
		catch
		{
			return "(?)";
		}
	}

	private void Diagnostico(string situacao, TMP_Text t, TMP_FontAsset fonteAntiga, Material antigo, string copiados, string naoTransportados)
	{
		if (!Plugin.LogDiagnosticoLigado)
		{
			return;
		}
		if (_diagLinhas >= 120)
		{
			if (!_diagCortado)
			{
				_diagCortado = true;
				Plugin.Log.LogInfo((object)"Better Font [diag]: limite de 120 linhas atingido — restante omitido.");
			}
			return;
		}
		string item;
		try
		{
			item = situacao + "#" + ((Object)t).GetInstanceID();
		}
		catch
		{
			item = situacao + "#" + NomeObjeto(t);
		}
		if (_diagVistos.Add(item))
		{
			_diagLinhas++;
			string text;
			try
			{
				text = (((Object)(object)antigo != (Object)null) ? Nome(antigo.shader) : "(sem material)");
			}
			catch
			{
				text = "(shader indisponivel)";
			}
			bool flag = false;
			try
			{
				flag = t.enableVertexGradient;
			}
			catch
			{
			}
			Plugin.Log.LogInfo((object)("[diag] " + situacao + " | objeto='" + NomeObjeto(t) + "' (" + ((object)t).GetType().Name + ") | fonte='" + (((Object)(object)fonteAntiga != (Object)null) ? ((Object)fonteAntiga).name : "(nula)") + "' -> '" + (((Object)(object)_serifFont != (Object)null) ? ((Object)_serifFont).name : "(nula)") + "' | material compartilhado='" + (((Object)(object)antigo != (Object)null) ? ((Object)antigo).name : "(nulo)") + "' | shader='" + text + "' | " + $"gradiente de vertice={flag} | " + "copiados: " + (string.IsNullOrEmpty(copiados) ? "nenhum" : copiados) + " | nao transportados: " + (string.IsNullOrEmpty(naoTransportados) ? "nenhum" : naoTransportados)));
		}
	}

	private static TMP_FontAsset CreateSerifFont()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		string[] array = new string[3] { "C:/Windows/Fonts/times.ttf", "C:/Windows/Fonts/georgia.ttf", "C:/Windows/Fonts/LiberationSerif-Regular.ttf" };
		foreach (string text in array)
		{
			try
			{
				if (!File.Exists(text))
				{
					continue;
				}
				Font val = new Font(text);
				if (!((Object)(object)val == (Object)null))
				{
					TMP_FontAsset val2 = TMP_FontAsset.CreateFontAsset(val);
					if ((Object)(object)val2 != (Object)null)
					{
						Plugin.Log.LogInfo((object)("Better Font: usando '" + text + "' como fonte serifada."));
						return val2;
					}
					Plugin.Log.LogWarning((object)("Better Font: '" + text + "' carregou mas CreateFontAsset retornou null."));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Better Font: '" + text + "' falhou: " + ex.GetType().Name + ": " + ex.Message));
			}
		}
		array = new string[4] { "Times New Roman", "Georgia", "Liberation Serif", "Cambria" };
		foreach (string text2 in array)
		{
			try
			{
				Font val3 = Font.CreateDynamicFontFromOSFont(text2, 36);
				if (!((Object)(object)val3 == (Object)null))
				{
					TMP_FontAsset val4 = TMP_FontAsset.CreateFontAsset(val3);
					if ((Object)(object)val4 != (Object)null)
					{
						Plugin.Log.LogInfo((object)("Better Font: usando '" + text2 + "' (OS) como fonte serifada."));
						return val4;
					}
				}
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("Better Font: '" + text2 + "' falhou: " + ex2.GetType().Name + ": " + ex2.Message));
			}
		}
		return null;
	}
}