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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using I2.Loc;
using Microsoft.CodeAnalysis;
using PeglinFonts.Core;
using PeglinUI.SettingsMenu;
using Rewired;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
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("PeglinFonts")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3bdecd4c84d8f20722edfac1f645b11ef0f2a823")]
[assembly: AssemblyProduct("PeglinFonts")]
[assembly: AssemblyTitle("PeglinFonts")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 PeglinFonts
{
internal class FontDropdown : MonoBehaviour
{
private const string ListName = "PeglinFonts_Dropdown";
private static int _blockUntilFrame = -1;
private readonly List<Button> _items = new List<Button>();
private OptionsMenu _menu;
private Transform _row;
private Button _rowButton;
private RectTransform _panel;
private float _openedAt;
private bool _selectedFirst;
private GameObject _highlighted;
private static OptionsMenu _suspendedMenu;
private static OverrideButtonMapWhenSelected _suspendedOverride;
private static Action<OptionsMenu, bool> _setButtonsActive;
private static bool _lookedUpSetButtonsActive;
public static FontDropdown Current { get; private set; }
public static bool BlocksGameMenus
{
get
{
if (!((Object)(object)Current != (Object)null))
{
return Time.frameCount <= _blockUntilFrame;
}
return true;
}
}
public static void Open(OptionsMenu menu, Transform row, Button rowButton)
{
if ((Object)(object)menu == (Object)null || (Object)(object)row == (Object)null || (Object)(object)rowButton == (Object)null || (Object)(object)Current != (Object)null)
{
Plugin.Log.LogDebug((object)$"Font list not opened: menu={(Object)(object)menu != (Object)null} row={(Object)(object)row != (Object)null} button={(Object)(object)rowButton != (Object)null} alreadyOpen={(Object)(object)Current != (Object)null}");
return;
}
try
{
Transform val = ((Component)menu).transform.Find("PeglinFonts_Dropdown");
if ((Object)(object)val != (Object)null)
{
Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
}
FontDropdown fontDropdown = Build(menu, rowButton);
fontDropdown._menu = menu;
fontDropdown._row = row;
fontDropdown._rowButton = rowButton;
fontDropdown.Show();
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Couldn't open the font list: {arg}");
}
}
private static FontDropdown Build(OptionsMenu menu, Button rowButton)
{
//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_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0044: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: 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_00ad: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Expected O, but got Unknown
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Expected O, but got Unknown
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Expected O, but got Unknown
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Expected O, but got Unknown
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_0268: Unknown result type (might be due to invalid IL or missing references)
//IL_031d: Unknown result type (might be due to invalid IL or missing references)
//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("PeglinFonts_Dropdown", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
RectTransform val2 = (RectTransform)val.transform;
((Transform)val2).SetParent(((Component)menu).transform, false);
val2.anchorMin = Vector2.zero;
val2.anchorMax = Vector2.one;
val2.offsetMin = new Vector2(-4000f, -4000f);
val2.offsetMax = new Vector2(4000f, 4000f);
((Transform)val2).SetAsLastSibling();
((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.25f);
val.AddComponent<KeepFont>();
FontDropdown fontDropdown = val.AddComponent<FontDropdown>();
Button obj = val.AddComponent<Button>();
((Selectable)obj).transition = (Transition)0;
Navigation navigation = default(Navigation);
((Navigation)(ref navigation)).mode = (Mode)0;
((Selectable)obj).navigation = navigation;
((UnityEvent)obj.onClick).AddListener(new UnityAction(fontDropdown.Close));
RectTransform val3 = (RectTransform)((Component)rowButton).transform;
GameObject val4 = new GameObject("List", new Type[4]
{
typeof(RectTransform),
typeof(Image),
typeof(GridLayoutGroup),
typeof(ContentSizeFitter)
});
fontDropdown._panel = (RectTransform)val4.transform;
((Transform)fontDropdown._panel).SetParent((Transform)(object)val2, false);
fontDropdown._panel.pivot = new Vector2(1f, 1f);
RectTransform panel = fontDropdown._panel;
RectTransform panel2 = fontDropdown._panel;
Vector2 val5 = default(Vector2);
((Vector2)(ref val5))..ctor(0.5f, 0.5f);
panel2.anchorMax = val5;
panel.anchorMin = val5;
((Graphic)val4.GetComponent<Image>()).color = UiCopy.Frame;
val4.AddComponent<SwallowClicks>();
float num = ((Transform)val3).lossyScale.x / Mathf.Max(0.0001f, ((Transform)fontDropdown._panel).lossyScale.x);
Rect rect = val3.rect;
float num2 = Mathf.Max(((Rect)(ref rect)).width * num, 330f);
rect = val3.rect;
float num3 = Mathf.Max(((Rect)(ref rect)).height * num, 34f);
int count = FontCatalog.All.Count;
int num4 = MenuLayout.Columns(count);
GridLayoutGroup component = val4.GetComponent<GridLayoutGroup>();
((LayoutGroup)component).padding = new RectOffset(6, 6, 6, 6);
component.spacing = new Vector2(6f, 4f);
component.cellSize = new Vector2(num2, num3);
component.startCorner = (Corner)0;
component.startAxis = (Axis)1;
component.constraint = (Constraint)1;
component.constraintCount = num4;
ContentSizeFitter component2 = val4.GetComponent<ContentSizeFitter>();
component2.horizontalFit = (FitMode)2;
component2.verticalFit = (FitMode)2;
TMP_FontAsset gameFont = FontSwapper.GameFontOf(((Component)rowButton).GetComponentInChildren<TMP_Text>(true));
FontChoice current = Plugin.Current;
foreach (FontChoice item2 in FontCatalog.All)
{
Button item = fontDropdown.MakeItem(rowButton, item2, item2 == current, gameFont, num3);
fontDropdown._items.Add(item);
}
for (int i = 0; i < fontDropdown._items.Count; i++)
{
Button obj2 = fontDropdown._items[i];
navigation = default(Navigation);
((Navigation)(ref navigation)).mode = (Mode)4;
((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)fontDropdown._items[MenuLayout.Move(i, 0, -1, count, num4)];
((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)fontDropdown._items[MenuLayout.Move(i, 0, 1, count, num4)];
((Navigation)(ref navigation)).selectOnLeft = (Selectable)(object)fontDropdown._items[MenuLayout.Move(i, -1, 0, count, num4)];
((Navigation)(ref navigation)).selectOnRight = (Selectable)(object)fontDropdown._items[MenuLayout.Move(i, 1, 0, count, num4)];
((Selectable)obj2).navigation = navigation;
}
return fontDropdown;
}
private Button MakeItem(Button template, FontChoice choice, bool selected, TMP_FontAsset gameFont, float height)
{
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Expected O, but got Unknown
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Expected O, but got Unknown
//IL_00ee: 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)
GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, (Transform)(object)_panel, false);
((Object)val).name = "Font_" + choice.Id;
Transform val2 = val.transform.Find("PeglinFonts_Arrow");
if ((Object)(object)val2 != (Object)null)
{
Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
}
MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val3 in componentsInChildren)
{
if (!(val3 is Graphic) && !(val3 is Button) && !(val3 is LayoutElement))
{
Object.DestroyImmediate((Object)(object)val3);
}
}
LayoutElement obj = val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>();
float minHeight = (obj.preferredHeight = height);
obj.minHeight = minHeight;
obj.flexibleWidth = 1f;
Image val4 = default(Image);
if (val.TryGetComponent<Image>(ref val4))
{
((Graphic)val4).color = (selected ? UiCopy.Green : UiCopy.Tan);
}
Outline obj2 = val.AddComponent<Outline>();
((Shadow)obj2).effectColor = UiCopy.Highlight;
((Shadow)obj2).effectDistance = new Vector2(5f, -5f);
((Shadow)obj2).useGraphicAlpha = false;
((Behaviour)obj2).enabled = false;
val.AddComponent<SelectOnHover>();
Button component = val.GetComponent<Button>();
((Selectable)component).transition = (Transition)0;
component.onClick = new ButtonClickedEvent();
((UnityEvent)component.onClick).AddListener((UnityAction)delegate
{
Choose(choice);
});
TMP_FontAsset val5 = (choice.IsDefault ? gameFont : FontLibrary.Tmp(choice));
TMP_Text[] componentsInChildren2 = val.GetComponentsInChildren<TMP_Text>(true);
foreach (TMP_Text val6 in componentsInChildren2)
{
val6.text = choice.DisplayName;
if ((Object)(object)val5 != (Object)null)
{
val6.font = val5;
val6.fontSharedMaterial = ((TMP_Asset)val5).material;
}
}
return component;
}
private void Show()
{
Current = this;
_openedAt = Time.unscaledTime;
Suspend(_menu, _row);
Reposition();
EventSystem current = EventSystem.current;
if (current != null)
{
current.SetSelectedGameObject((GameObject)null);
}
}
private void Reposition()
{
//IL_0031: 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_0071: 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_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_rowButton == (Object)null))
{
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(_panel);
Vector3[] array = (Vector3[])(object)new Vector3[4];
((RectTransform)((Component)_rowButton).transform).GetWorldCorners(array);
((Transform)_panel).position = array[3];
Canvas componentInParent = ((Component)_panel).GetComponentInParent<Canvas>();
RectTransform val = ((!((Object)(object)componentInParent != (Object)null)) ? ((RectTransform)null) : ((RectTransform)((Component)componentInParent.rootCanvas).transform));
if (!((Object)(object)val == (Object)null))
{
Vector3[] array2 = (Vector3[])(object)new Vector3[4];
Vector3[] array3 = (Vector3[])(object)new Vector3[4];
_panel.GetWorldCorners(array2);
val.GetWorldCorners(array3);
float num = (array3[1].y - array3[0].y) * 0.02f;
RectTransform panel = _panel;
((Transform)panel).position = ((Transform)panel).position + new Vector3(MenuLayout.ShiftInto(array2[0].x, array2[2].x, array3[0].x + num, array3[2].x - num, keepEnd: false), MenuLayout.ShiftInto(array2[0].y, array2[1].y, array3[0].y + num, array3[1].y - num, keepEnd: true), 0f);
}
}
}
private void Update()
{
Player val = (ReInput.isReady ? ReInput.players.GetPlayer(0) : null);
if (val != null && (val.GetButtonDown("UICancel") || val.GetButtonDown("Pause")))
{
Close();
return;
}
EventSystem current = EventSystem.current;
if ((Object)(object)current == (Object)null)
{
return;
}
GameObject currentSelectedGameObject = current.currentSelectedGameObject;
bool flag = (Object)(object)currentSelectedGameObject != (Object)null && currentSelectedGameObject.transform.IsChildOf(((Component)this).transform);
ShowHighlight(flag ? currentSelectedGameObject : null);
if (!_selectedFirst)
{
if (val == null || !val.GetButton("UISubmit"))
{
_selectedFirst = true;
current.SetSelectedGameObject(((Component)_items[FontCatalog.IndexOf(Plugin.Current)]).gameObject);
}
}
else if (!flag && val != null && (Mathf.Abs(val.GetAxis("UIVertical")) > 0.5f || Mathf.Abs(val.GetAxis("UIHorizontal")) > 0.5f))
{
current.SetSelectedGameObject(((Component)_items[FontCatalog.IndexOf(Plugin.Current)]).gameObject);
}
}
private void ShowHighlight(GameObject selected)
{
if (!((Object)(object)selected == (Object)(object)_highlighted))
{
SetHighlight(_highlighted, on: false);
SetHighlight(selected, on: true);
_highlighted = selected;
}
}
private static void SetHighlight(GameObject item, bool on)
{
//IL_004d: 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_0052: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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)
if (!((Object)(object)item == (Object)null))
{
Outline val = default(Outline);
if (item.TryGetComponent<Outline>(ref val))
{
((Behaviour)val).enabled = on;
}
Image val2 = default(Image);
if (item.TryGetComponent<Image>(ref val2))
{
Color val3 = ((((Object)item).name == "Font_" + Plugin.Current.Id) ? UiCopy.Green : UiCopy.Tan);
((Graphic)val2).color = (on ? Color.Lerp(val3, Color.white, 0.35f) : val3);
}
}
}
private void LateUpdate()
{
KeepOptionsShortcutsOff(_menu);
if (Time.unscaledTime - _openedAt < 0.5f)
{
Reposition();
}
}
private void Choose(FontChoice choice)
{
Plugin.Choose(choice);
OptionsMenuPatch.UpdateLabel(_row);
Close();
}
private void Close()
{
if (!((Object)(object)Current != (Object)(object)this))
{
Current = null;
_blockUntilFrame = Time.frameCount + 2;
if ((Object)(object)_row != (Object)null && (Object)(object)EventSystem.current != (Object)null)
{
EventSystem.current.SetSelectedGameObject(((Component)_row).gameObject);
}
if ((Object)(object)FontHost.Instance != (Object)null)
{
((MonoBehaviour)FontHost.Instance).StartCoroutine(ResumeSoon());
}
else
{
Resume();
}
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
private void OnDisable()
{
if ((Object)(object)Current == (Object)(object)this)
{
Current = null;
Resume();
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
private static void Suspend(OptionsMenu menu, Transform row)
{
_suspendedMenu = menu;
SetOptionsButtonsActive(menu, active: false);
_suspendedOverride = (((Object)(object)row != (Object)null) ? ((Component)row).GetComponent<OverrideButtonMapWhenSelected>() : null);
if ((Object)(object)_suspendedOverride != (Object)null)
{
((Behaviour)_suspendedOverride).enabled = false;
if ((Object)(object)_suspendedOverride.mapperToEnable != (Object)null)
{
((Behaviour)_suspendedOverride.mapperToEnable).enabled = false;
}
}
}
private static IEnumerator ResumeSoon()
{
yield return (object)new WaitForSecondsRealtime(0.1f);
if ((Object)(object)Current == (Object)null)
{
Resume();
}
}
internal static void Resume()
{
if ((Object)(object)_suspendedMenu != (Object)null)
{
SetOptionsButtonsActive(_suspendedMenu, active: true);
}
if ((Object)(object)_suspendedOverride != (Object)null)
{
if ((Object)(object)_suspendedOverride.mapperToEnable != (Object)null)
{
((Behaviour)_suspendedOverride.mapperToEnable).enabled = false;
}
((Behaviour)_suspendedOverride).enabled = true;
}
_suspendedMenu = null;
_suspendedOverride = null;
}
private static void KeepOptionsShortcutsOff(OptionsMenu menu)
{
if ((Object)(object)menu == (Object)null)
{
return;
}
Behaviour[] array = (Behaviour[])(object)new Behaviour[4]
{
(Behaviour)menu.acceptButton,
(Behaviour)menu.applyButton,
(Behaviour)menu.cancelButton,
(Behaviour)menu.deleteButton
};
foreach (Behaviour val in array)
{
if ((Object)(object)val != (Object)null && val.enabled)
{
val.enabled = false;
}
}
}
private static void SetOptionsButtonsActive(OptionsMenu menu, bool active)
{
if (!_lookedUpSetButtonsActive)
{
_lookedUpSetButtonsActive = true;
MethodInfo methodInfo = AccessTools.Method(typeof(OptionsMenu), "SetButtonsActive", new Type[1] { typeof(bool) }, (Type[])null);
if (methodInfo != null)
{
_setButtonsActive = AccessTools.MethodDelegate<Action<OptionsMenu, bool>>(methodInfo, (object)null, true);
}
else
{
Plugin.Log.LogWarning((object)"OptionsMenu.SetButtonsActive not found; the font list switches the Options shortcuts off directly.");
}
}
if ((Object)(object)menu == (Object)null)
{
return;
}
if (_setButtonsActive != null)
{
_setButtonsActive(menu, active);
return;
}
if (!active)
{
KeepOptionsShortcutsOff(menu);
return;
}
Behaviour[] array = (Behaviour[])(object)new Behaviour[5]
{
(Behaviour)menu.acceptButton,
(Behaviour)menu.applyButton,
(Behaviour)menu.cancelButton,
(Behaviour)menu.deleteButton,
(Behaviour)menu.mappedButtonOverride
};
foreach (Behaviour val in array)
{
if ((Object)(object)val != (Object)null)
{
val.enabled = true;
}
}
}
}
internal class SelectOnHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
EventSystem current = EventSystem.current;
if (current != null)
{
current.SetSelectedGameObject(((Component)this).gameObject);
}
}
}
internal class SwallowClicks : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
{
public void OnPointerClick(PointerEventData eventData)
{
}
}
internal class FontHost : MonoBehaviour
{
private bool _capturedSkinFont;
private Font _skinFont;
public static FontHost Instance { get; private set; }
private void Awake()
{
Instance = this;
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void Start()
{
FontSwapper.ApplyAll();
}
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
FontSwapper.ApplyAll();
}
private void OnGUI()
{
GUISkin skin = GUI.skin;
if (!((Object)(object)skin == (Object)null))
{
if (!_capturedSkinFont)
{
_capturedSkinFont = true;
_skinFont = skin.font;
}
Font val = FontLibrary.Legacy(Plugin.Current);
Font val2 = (((Object)(object)val != (Object)null) ? val : _skinFont);
if ((Object)(object)skin.font != (Object)(object)val2)
{
skin.font = val2;
}
}
}
}
internal static class FontLibrary
{
private sealed class Loaded
{
public TMP_FontAsset Tmp;
public Font Legacy;
}
private static string[] _installed;
private static readonly Dictionary<string, Loaded> Cache = new Dictionary<string, Loaded>();
private static readonly HashSet<string> Failed = new HashSet<string>();
private static readonly HashSet<TMP_FontAsset> Ours = new HashSet<TMP_FontAsset>();
private static readonly List<TMP_FontAsset> GameFonts = new List<TMP_FontAsset>();
private static float _referenceCapRatio = -1f;
private static TMP_FontAsset _reference;
private static bool _findingReference;
public static bool IsOurs(TMP_FontAsset font)
{
if ((Object)(object)font != (Object)null)
{
return Ours.Contains(font);
}
return false;
}
public static TMP_FontAsset Tmp(FontChoice choice)
{
return Load(choice)?.Tmp;
}
public static Font Legacy(FontChoice choice)
{
return Load(choice)?.Legacy;
}
public static void AddGameFont(TMP_FontAsset font)
{
if ((Object)(object)font == (Object)null || IsOurs(font) || GameFonts.Contains(font))
{
return;
}
GameFonts.Add(font);
foreach (Loaded value in Cache.Values)
{
AddFallback(value.Tmp, font);
}
}
private static void AddFallback(TMP_FontAsset ours, TMP_FontAsset game)
{
if ((Object)(object)ours == (Object)null)
{
return;
}
if (ours.fallbackFontAssetTable == null)
{
ours.fallbackFontAssetTable = new List<TMP_FontAsset>();
}
if (!ours.fallbackFontAssetTable.Contains(game))
{
if ((Object)(object)game == (Object)(object)ReferenceGameFont())
{
ours.fallbackFontAssetTable.Insert(0, game);
}
else
{
ours.fallbackFontAssetTable.Add(game);
}
}
}
private static Loaded Load(FontChoice choice)
{
if (choice == null || choice.IsDefault || Failed.Contains(choice.Id))
{
return null;
}
if (Cache.TryGetValue(choice.Id, out var value))
{
return value;
}
try
{
value = Build(choice);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Couldn't load the {choice.DisplayName} font: {arg}");
value = null;
}
if (value == null)
{
Failed.Add(choice.Id);
return null;
}
Cache[choice.Id] = value;
return value;
}
private static Loaded Build(FontChoice choice)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: 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_0108: Unknown result type (might be due to invalid IL or missing references)
string text = Extract(choice.FileName);
Font val = new Font(text)
{
name = "PeglinFonts " + choice.DisplayName,
hideFlags = (HideFlags)32
};
TMP_FontAsset val2 = TMP_FontAsset.CreateFontAsset(val, 64, 6, (GlyphRenderMode)4165, 1024, 1024, (AtlasPopulationMode)1, true);
if ((Object)(object)val2 == (Object)null)
{
Plugin.Log.LogError((object)("Couldn't read the " + choice.DisplayName + " font file (" + text + ")."));
return null;
}
((Object)val2).name = ((Object)val).name;
((Object)val2).hideFlags = (HideFlags)32;
if ((Object)(object)((TMP_Asset)val2).material != (Object)null)
{
((Object)((TMP_Asset)val2).material).name = ((Object)val).name + " Material";
((Object)((TMP_Asset)val2).material).hideFlags = (HideFlags)32;
}
FaceInfo faceInfo = val2.faceInfo;
float num = ReferenceCapRatio();
float num2 = CapRatio(faceInfo);
((FaceInfo)(ref faceInfo)).scale = FontCatalog.MatchScale(num, num2, choice.Scale);
val2.faceInfo = faceInfo;
foreach (TMP_FontAsset gameFont in GameFonts)
{
AddFallback(val2, gameFont);
}
Ours.Add(val2);
Font val3 = LegacyFont(choice);
Plugin.Log.LogInfo((object)($"Loaded {choice.DisplayName}: cap ratio {num2:0.000} vs game {num:0.000}, scale {((FaceInfo)(ref faceInfo)).scale:0.00}; " + "UI Text/IMGUI use " + (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "their own font (no look-alike installed)") + "."));
return new Loaded
{
Tmp = val2,
Legacy = val3
};
}
private static Font LegacyFont(FontChoice choice)
{
if (_installed == null)
{
_installed = Font.GetOSInstalledFontNames() ?? new string[0];
}
string text = FontCatalog.PickSystemFont(choice, _installed);
if (text == null)
{
return null;
}
Font val = Font.CreateDynamicFontFromOSFont(text, 16);
if ((Object)(object)val != (Object)null)
{
((Object)val).name = text;
((Object)val).hideFlags = (HideFlags)32;
}
return val;
}
private static float CapRatio(FaceInfo face)
{
if (((FaceInfo)(ref face)).pointSize <= 0)
{
return 0f;
}
return ((((FaceInfo)(ref face)).capLine > 0f) ? ((FaceInfo)(ref face)).capLine : (((FaceInfo)(ref face)).ascentLine * 0.72f)) / (float)((FaceInfo)(ref face)).pointSize * ((((FaceInfo)(ref face)).scale > 0f) ? ((FaceInfo)(ref face)).scale : 1f);
}
private static float ReferenceCapRatio()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (_referenceCapRatio > 0f)
{
return _referenceCapRatio;
}
TMP_FontAsset val = ReferenceGameFont();
float num = (((Object)(object)val != (Object)null) ? CapRatio(val.faceInfo) : 0f);
if (num > 0f)
{
_referenceCapRatio = num;
Plugin.Log.LogInfo((object)("Sizing fonts to match the game's " + ((Object)val).name + "."));
}
return num;
}
public static TMP_FontAsset ReferenceGameFont()
{
if ((Object)(object)_reference != (Object)null || _findingReference)
{
return _reference;
}
_findingReference = true;
try
{
TMP_FontAsset val = (((Object)(object)TMP_Settings.instance != (Object)null) ? TMP_Settings.defaultFontAsset : null);
_reference = (((Object)(object)val != (Object)null && !IsOurs(val)) ? val : FontSwapper.MostUsedGameFont());
return _reference;
}
finally
{
_findingReference = false;
}
}
public static TMP_FontAsset GameFontWithAtlas(Texture atlas)
{
if ((Object)(object)atlas == (Object)null)
{
return null;
}
foreach (TMP_FontAsset gameFont in GameFonts)
{
if ((Object)(object)gameFont != (Object)null && gameFont.atlasTextures != null && ((IEnumerable<Texture>)(object)gameFont.atlasTextures).Contains(atlas))
{
return gameFont;
}
}
return null;
}
private static string Extract(string fileName)
{
string text = "PeglinFonts." + fileName;
byte[] array;
using (Stream stream = typeof(FontLibrary).Assembly.GetManifestResourceStream(text))
{
if (stream == null)
{
throw new FileNotFoundException("Font missing from the mod DLL", text);
}
array = new byte[stream.Length];
int num;
for (int i = 0; i < array.Length; i += num)
{
num = stream.Read(array, i, array.Length - i);
if (num <= 0)
{
throw new EndOfStreamException(text);
}
}
}
string text2 = Path.Combine(Paths.CachePath, "PeglinFonts");
Directory.CreateDirectory(text2);
string text3 = Path.Combine(text2, fileName);
if (File.Exists(text3) && File.ReadAllBytes(text3).SequenceEqual(array))
{
return text3;
}
string text4 = text3 + "." + Process.GetCurrentProcess().Id + ".tmp";
File.WriteAllBytes(text4, array);
try
{
if (File.Exists(text3))
{
File.Delete(text3);
}
File.Move(text4, text3);
}
catch (IOException) when (File.Exists(text3))
{
File.Delete(text4);
text3 = Path.Combine(text2, Path.GetFileNameWithoutExtension(fileName) + "." + Process.GetCurrentProcess().Id + Path.GetExtension(fileName));
File.WriteAllBytes(text3, array);
}
return text3;
}
}
internal class KeepFont : MonoBehaviour
{
}
internal static class FontSwapper
{
private struct Original
{
public TMP_FontAsset Font;
public Material Material;
}
private static readonly Dictionary<TMP_Text, Original> Originals = new Dictionary<TMP_Text, Original>();
private static readonly Dictionary<Text, Font> LegacyOriginals = new Dictionary<Text, Font>();
private static readonly Dictionary<Material, Original> MaterialOrigins = new Dictionary<Material, Original>();
private static readonly HashSet<Font> OurLegacyFonts = new HashSet<Font>();
private static bool _applying;
private static int _errorsLogged;
public static void Apply(TMP_Text text)
{
if (_applying || (Object)(object)text == (Object)null || (Object)(object)((Component)text).GetComponentInParent<KeepFont>(true) != (Object)null || !TryGetOriginal(text, out var original))
{
return;
}
TMP_FontAsset val = FontLibrary.Tmp(Plugin.Current);
_applying = true;
try
{
if ((Object)(object)val == (Object)null)
{
if (FontLibrary.IsOurs(text.font))
{
text.font = original.Font;
text.fontSharedMaterial = (((Object)(object)original.Material != (Object)null) ? original.Material : ((TMP_Asset)original.Font).material);
}
return;
}
if ((Object)(object)text.font != (Object)(object)val)
{
text.font = val;
}
Material val2 = MaterialFor(original, val);
if ((Object)(object)val2 != (Object)null && (Object)(object)text.fontSharedMaterial != (Object)(object)val2)
{
text.fontSharedMaterial = val2;
}
}
finally
{
_applying = false;
}
}
public static void Apply(Text text)
{
if (_applying || (Object)(object)text == (Object)null || (Object)(object)((Component)text).GetComponentInParent<KeepFont>(true) != (Object)null)
{
return;
}
if (!LegacyOriginals.TryGetValue(text, out var value))
{
if ((Object)(object)text.font == (Object)null || OurLegacyFonts.Contains(text.font))
{
return;
}
value = text.font;
LegacyOriginals[text] = value;
}
Font val = FontLibrary.Legacy(Plugin.Current);
if ((Object)(object)val != (Object)null)
{
OurLegacyFonts.Add(val);
}
Font val2 = (((Object)(object)val != (Object)null) ? val : value);
if (!((Object)(object)text.font != (Object)(object)val2))
{
return;
}
_applying = true;
try
{
text.font = val2;
}
finally
{
_applying = false;
}
}
public static void ApplyAll()
{
Prune();
foreach (TMP_Text item in InScenes<TMP_Text>((IEnumerable<TMP_Text>)Resources.FindObjectsOfTypeAll<TMP_Text>()))
{
Apply(item);
}
foreach (Text item2 in InScenes<Text>((IEnumerable<Text>)Resources.FindObjectsOfTypeAll<Text>()))
{
Apply(item2);
}
}
public static TMP_FontAsset GameFontOf(TMP_Text text)
{
if (!((Object)(object)text != (Object)null) || !TryGetOriginal(text, out var original))
{
return null;
}
return original.Font;
}
public static TMP_FontAsset MostUsedGameFont()
{
return (from f in InScenes<TMP_Text>((IEnumerable<TMP_Text>)Resources.FindObjectsOfTypeAll<TMP_Text>()).Select(GameFontOf)
where (Object)(object)f != (Object)null
group f by f into g
orderby g.Count() descending
select g.Key).FirstOrDefault();
}
public static void Prune()
{
foreach (TMP_Text item in Originals.Keys.Where((TMP_Text t) => (Object)(object)t == (Object)null).ToList())
{
Originals.Remove(item);
}
foreach (Text item2 in LegacyOriginals.Keys.Where((Text t) => (Object)(object)t == (Object)null).ToList())
{
LegacyOriginals.Remove(item2);
}
}
private static IEnumerable<T> InScenes<T>(IEnumerable<T> objects) where T : Component
{
return objects.Where(delegate(T o)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)o != (Object)null)
{
Scene scene = ((Component)o).gameObject.scene;
return ((Scene)(ref scene)).IsValid();
}
return false;
});
}
private static bool TryGetOriginal(TMP_Text text, out Original original)
{
if (Originals.TryGetValue(text, out original) && (Object)(object)original.Font != (Object)null)
{
return true;
}
TMP_FontAsset font = text.font;
if ((Object)(object)font == (Object)null)
{
return false;
}
if (FontLibrary.IsOurs(font))
{
original = GuessOriginal(text.fontSharedMaterial);
if ((Object)(object)original.Font == (Object)null)
{
return false;
}
}
else
{
original = new Original
{
Font = font,
Material = MatchingMaterial(font, text.fontSharedMaterial)
};
FontLibrary.AddGameFont(font);
}
Originals[text] = original;
return true;
}
private static Original GuessOriginal(Material material)
{
if ((Object)(object)material != (Object)null)
{
if (MaterialOrigins.TryGetValue(material, out var value))
{
return value;
}
string text = ((Object)material).name.Replace(" (Instance)", "");
foreach (KeyValuePair<Material, Original> materialOrigin in MaterialOrigins)
{
if ((Object)(object)materialOrigin.Key != (Object)null && ((Object)materialOrigin.Key).name == text)
{
return materialOrigin.Value;
}
}
TMP_FontAsset val = FontLibrary.GameFontWithAtlas(material.HasProperty(ShaderUtilities.ID_MainTex) ? material.GetTexture(ShaderUtilities.ID_MainTex) : null);
if ((Object)(object)val != (Object)null)
{
return new Original
{
Font = val,
Material = material
};
}
}
TMP_FontAsset val2 = FontLibrary.ReferenceGameFont();
return new Original
{
Font = val2,
Material = (((Object)(object)val2 != (Object)null) ? ((TMP_Asset)val2).material : null)
};
}
private static Material MatchingMaterial(TMP_FontAsset font, Material material)
{
if ((Object)(object)material != (Object)null && (Object)(object)((TMP_Asset)font).material != (Object)null && material.HasProperty(ShaderUtilities.ID_MainTex) && (Object)(object)material.GetTexture(ShaderUtilities.ID_MainTex) == (Object)(object)((TMP_Asset)font).material.GetTexture(ShaderUtilities.ID_MainTex))
{
return material;
}
return ((TMP_Asset)font).material;
}
private static Material MaterialFor(Original original, TMP_FontAsset target)
{
Material val = (((Object)(object)original.Material != (Object)null) ? original.Material : ((TMP_Asset)original.Font).material);
if ((Object)(object)((TMP_Asset)target).material == (Object)null)
{
return null;
}
Material val2 = (((Object)(object)val != (Object)null) ? TMP_MaterialManager.GetFallbackMaterial(val, ((TMP_Asset)target).material) : ((TMP_Asset)target).material);
if ((Object)(object)val2 != (Object)null && !MaterialOrigins.ContainsKey(val2))
{
MaterialOrigins[val2] = original;
}
return val2;
}
internal static void FontChangedByGame(TMP_Text text)
{
if (_applying || (Object)(object)text == (Object)null)
{
return;
}
TMP_FontAsset font = text.font;
if ((Object)(object)font != (Object)null && !FontLibrary.IsOurs(font))
{
Original value;
bool flag = Originals.TryGetValue(text, out value) && (Object)(object)value.Font != (Object)null;
if (!flag || (Object)(object)value.Font != (Object)(object)font)
{
Material material = ((flag && (Object)(object)value.Material != (Object)null) ? value.Material : text.fontSharedMaterial);
Originals[text] = new Original
{
Font = font,
Material = MatchingMaterial(font, material)
};
}
FontLibrary.AddGameFont(font);
}
Apply(text);
}
internal static void FontChangedByGame(Text text)
{
if (!_applying && !((Object)(object)text == (Object)null))
{
if ((Object)(object)text.font != (Object)null && !OurLegacyFonts.Contains(text.font))
{
LegacyOriginals[text] = text.font;
}
Apply(text);
}
}
internal static void MaterialChangedByGame(TMP_Text text)
{
if (_applying || (Object)(object)text == (Object)null)
{
return;
}
Material fontSharedMaterial = text.fontSharedMaterial;
if ((Object)(object)fontSharedMaterial == (Object)null)
{
return;
}
if (!Originals.TryGetValue(text, out var value) || (Object)(object)value.Font == (Object)null)
{
Apply(text);
return;
}
if (MaterialOrigins.TryGetValue(fontSharedMaterial, out var value2))
{
value.Material = (((Object)(object)value2.Font == (Object)(object)value.Font) ? value2.Material : MatchingMaterial(value.Font, value2.Material));
}
else
{
value.Material = MatchingMaterial(value.Font, fontSharedMaterial);
}
Originals[text] = value;
Apply(text);
}
internal static void Guard(Action action)
{
try
{
action();
}
catch (Exception arg)
{
if (_errorsLogged++ < 5)
{
Plugin.Log.LogError((object)$"Font swap failed (the text keeps its current font): {arg}");
}
}
}
}
[HarmonyPatch]
internal static class TmpPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(TextMeshProUGUI), "OnEnable")]
private static void UguiEnabled(TMP_Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.Apply(__instance);
});
}
[HarmonyPostfix]
[HarmonyPatch(typeof(TextMeshPro), "OnEnable")]
private static void WorldEnabled(TMP_Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.Apply(__instance);
});
}
[HarmonyPostfix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static void FontSet(TMP_Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.FontChangedByGame(__instance);
});
}
[HarmonyPostfix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static void SharedMaterialSet(TMP_Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.MaterialChangedByGame(__instance);
});
}
[HarmonyPostfix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static void MaterialSet(TMP_Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.MaterialChangedByGame(__instance);
});
}
}
[HarmonyPatch]
internal static class LegacyTextPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Text), "OnEnable")]
private static void Enabled(Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.Apply(__instance);
});
}
[HarmonyPostfix]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static void FontSet(Text __instance)
{
FontSwapper.Guard(delegate
{
FontSwapper.FontChangedByGame(__instance);
});
}
}
[HarmonyPatch]
internal static class LocalizationPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(LocalizeTarget_TextMeshPro_UGUI), "GetFinalTerms")]
private static void Ugui(LocalizeTarget_TextMeshPro_UGUI __instance, ref string secondaryTerm)
{
GameFontTerm((TMP_Text)(object)((LocalizeTarget<TextMeshProUGUI>)(object)__instance).mTarget, ref secondaryTerm);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(LocalizeTarget_TextMeshPro_Label), "GetFinalTerms")]
private static void World(LocalizeTarget_TextMeshPro_Label __instance, ref string secondaryTerm)
{
GameFontTerm((TMP_Text)(object)((LocalizeTarget<TextMeshPro>)(object)__instance).mTarget, ref secondaryTerm);
}
private static void GameFontTerm(TMP_Text target, ref string secondaryTerm)
{
try
{
if ((Object)(object)target != (Object)null && FontLibrary.IsOurs(target.font))
{
TMP_FontAsset val = FontSwapper.GameFontOf(target);
secondaryTerm = (((Object)(object)val != (Object)null) ? ((Object)val).name : string.Empty);
}
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Couldn't give the translation system the game's font name: {arg}");
}
}
}
[HarmonyPatch(typeof(OptionsMenu), "OnEnable")]
internal static class OptionsMenuPatch
{
public const string RowName = "PeglinFonts_FontRow";
public const string ControlsRowName = "PeglinKeybinds_ControlsRow";
[HarmonyAfter(new string[] { "PeglinKeybinds" })]
private static void Prefix(OptionsMenu __instance)
{
try
{
if ((Object)(object)FontDropdown.Current == (Object)null)
{
FontDropdown.Resume();
}
Transform val = FindOrAddRow(__instance);
if (!((Object)(object)val == (Object)null))
{
Place(val);
UpdateLabel(val);
if ((Object)(object)val.parent.Find("PeglinKeybinds_ControlsRow") == (Object)null)
{
__instance.firstSelectable = ((Component)val).gameObject;
}
}
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Couldn't add the Font row to the Options menu: {arg}");
}
}
public static void UpdateAllLabels()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
OptionsMenu[] array = Resources.FindObjectsOfTypeAll<OptionsMenu>();
foreach (OptionsMenu val in array)
{
object obj;
if ((Object)(object)val != (Object)null)
{
Scene scene = ((Component)val).gameObject.scene;
if (((Scene)(ref scene)).IsValid() && (Object)(object)val.deleteButtonSelectable != (Object)null)
{
obj = ((Component)val.deleteButtonSelectable).transform.parent;
goto IL_004e;
}
}
obj = null;
goto IL_004e;
IL_004e:
Transform val2 = (Transform)obj;
Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.Find("PeglinFonts_FontRow") : null);
if ((Object)(object)val3 != (Object)null)
{
UpdateLabel(val3);
}
}
}
public static void UpdateLabel(Transform row)
{
Button val = (((Object)(object)row != (Object)null) ? ((Component)row).GetComponentInChildren<Button>(true) : null);
TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<TMP_Text>(true) : null);
if ((Object)(object)val2 != (Object)null)
{
val2.text = Plugin.Current.DisplayName;
}
}
private static Transform FindOrAddRow(OptionsMenu menu)
{
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected O, but got Unknown
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
Selectable deleteButtonSelectable = menu.deleteButtonSelectable;
if ((Object)(object)deleteButtonSelectable == (Object)null || (Object)(object)((Component)deleteButtonSelectable).transform.parent == (Object)null)
{
Plugin.Log.LogWarning((object)"Options menu layout not recognised (no Delete Save Data row); the Font row wasn't added.");
return null;
}
Transform parent = ((Component)deleteButtonSelectable).transform.parent;
Transform val = parent.Find("PeglinFonts_FontRow");
if ((Object)(object)val != (Object)null)
{
return val;
}
GameObject val2 = new GameObject("PeglinFonts_Holder");
val2.SetActive(false);
GameObject row = Object.Instantiate<GameObject>(((Component)deleteButtonSelectable).gameObject, val2.transform, false);
((Object)row).name = "PeglinFonts_FontRow";
UiCopy.RemoveScripts(row, "Localize", "EventTrigger");
row.SetActive(true);
Button button = row.GetComponentInChildren<Button>(true);
if ((Object)(object)button == (Object)null)
{
Object.Destroy((Object)(object)val2);
Plugin.Log.LogWarning((object)"Options menu's Delete Save Data row has no button; the Font row wasn't added.");
return null;
}
button.onClick = new ButtonClickedEvent();
((UnityEvent)button.onClick).AddListener((UnityAction)delegate
{
FontDropdown.Open(menu, row.transform, button);
});
Image val3 = default(Image);
if (((Component)button).TryGetComponent<Image>(ref val3))
{
((Graphic)val3).color = UiCopy.Tan;
}
TMP_Text[] componentsInChildren = row.GetComponentsInChildren<TMP_Text>(true);
foreach (TMP_Text val4 in componentsInChildren)
{
if (!val4.transform.IsChildOf(((Component)button).transform))
{
val4.text = "Font";
}
}
UiCopy.AddDropdownArrow(button);
row.transform.SetParent(parent, false);
Object.Destroy((Object)(object)val2);
return row.transform;
}
private static void Place(Transform row)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
Transform parent = row.parent;
List<(string, bool)> list = new List<(string, bool)>();
foreach (Transform item in parent)
{
Transform val = item;
if ((Object)(object)val != (Object)(object)row)
{
list.Add((((Object)val).name, (Object)(object)((Component)val).GetComponent<Selectable>() != (Object)null));
}
}
int num = MenuLayout.FontRowIndex(list, "PeglinKeybinds_ControlsRow");
if (row.GetSiblingIndex() != num)
{
row.SetSiblingIndex(num);
}
LinkNavigation(((Component)row).GetComponent<Selectable>(), parent);
}
private static void LinkNavigation(Selectable row, Transform contents)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Invalid comparison between Unknown and I4
//IL_0055: 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_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Invalid comparison between Unknown and I4
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: 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)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: 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_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Invalid comparison between Unknown and I4
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Invalid comparison between Unknown and I4
//IL_00c5: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_020d: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Unknown result type (might be due to invalid IL or missing references)
//IL_0216: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Invalid comparison between Unknown and I4
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_022f: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Invalid comparison between Unknown and I4
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)row == (Object)null)
{
return;
}
Selectable val = Neighbour(contents, ((Component)row).transform.GetSiblingIndex(), -1);
Selectable val2 = Neighbour(contents, ((Component)row).transform.GetSiblingIndex(), 1);
Navigation navigation;
if ((Object)(object)val2 != (Object)null)
{
navigation = val2.navigation;
if ((int)((Navigation)(ref navigation)).mode == 4)
{
goto IL_0087;
}
}
if ((Object)(object)val != (Object)null)
{
navigation = val.navigation;
if ((int)((Navigation)(ref navigation)).mode == 4)
{
goto IL_0087;
}
}
navigation = default(Navigation);
((Navigation)(ref navigation)).mode = (Mode)3;
row.navigation = navigation;
return;
IL_00fe:
object obj;
Selectable val3 = (Selectable)obj;
goto IL_00ff;
IL_00ff:
navigation = default(Navigation);
((Navigation)(ref navigation)).mode = (Mode)4;
((Navigation)(ref navigation)).selectOnUp = val3;
((Navigation)(ref navigation)).selectOnDown = val2;
row.navigation = navigation;
Selectable val4 = Neighbour(contents, -1, 1);
if ((Object)(object)val2 != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)val4 != (Object)(object)val2)
{
for (int i = ((Component)val2).transform.GetSiblingIndex() + 1; i < contents.childCount; i++)
{
Selectable component = ((Component)contents.GetChild(i)).GetComponent<Selectable>();
if (!((Object)(object)component != (Object)null))
{
continue;
}
navigation = component.navigation;
if ((int)((Navigation)(ref navigation)).mode == 4)
{
navigation = component.navigation;
if ((Object)(object)((Navigation)(ref navigation)).selectOnDown == (Object)(object)val2)
{
Navigation navigation2 = component.navigation;
((Navigation)(ref navigation2)).selectOnDown = val4;
component.navigation = navigation2;
}
}
}
}
if ((Object)(object)val != (Object)null)
{
navigation = val.navigation;
if ((int)((Navigation)(ref navigation)).mode == 4)
{
Navigation navigation3 = val.navigation;
((Navigation)(ref navigation3)).selectOnDown = row;
val.navigation = navigation3;
}
}
if ((Object)(object)val2 != (Object)null)
{
navigation = val2.navigation;
if ((int)((Navigation)(ref navigation)).mode == 4)
{
Navigation navigation4 = val2.navigation;
((Navigation)(ref navigation4)).selectOnUp = row;
val2.navigation = navigation4;
}
}
return;
IL_0087:
val3 = val;
if ((Object)(object)val3 == (Object)null)
{
navigation = row.navigation;
if ((int)((Navigation)(ref navigation)).mode == 4)
{
navigation = row.navigation;
if ((Object)(object)((Navigation)(ref navigation)).selectOnUp != (Object)null)
{
navigation = row.navigation;
obj = ((Navigation)(ref navigation)).selectOnUp;
goto IL_00fe;
}
}
if ((Object)(object)val2 != (Object)null)
{
navigation = val2.navigation;
if ((Object)(object)((Navigation)(ref navigation)).selectOnUp != (Object)(object)row)
{
navigation = val2.navigation;
obj = ((Navigation)(ref navigation)).selectOnUp;
goto IL_00fe;
}
}
obj = null;
goto IL_00fe;
}
goto IL_00ff;
}
private static Selectable Neighbour(Transform contents, int index, int direction)
{
for (int i = index + direction; i >= 0 && i < contents.childCount; i += direction)
{
Selectable component = ((Component)contents.GetChild(i)).GetComponent<Selectable>();
if ((Object)(object)component != (Object)null && ((Component)component).gameObject.activeSelf)
{
return component;
}
}
return null;
}
}
[HarmonyPatch(typeof(OptionsMenu), "Update")]
internal static class OptionsMenuUpdatePatch
{
private static bool Prefix()
{
return !FontDropdown.BlocksGameMenus;
}
}
[HarmonyPatch(typeof(PauseMenu), "Update")]
internal static class PauseMenuUpdatePatch
{
private static bool Prefix()
{
return !FontDropdown.BlocksGameMenus;
}
}
[BepInPlugin("PeglinFonts", "PeglinFonts", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private sealed class FontIds : AcceptableValueBase
{
public FontIds()
: base(typeof(string))
{
}
public override object Clamp(object value)
{
return FontCatalog.Find(value as string).Id;
}
public override bool IsValid(object value)
{
string id = value as string;
if (id != null)
{
return FontCatalog.All.Any((FontChoice c) => c.Id == id);
}
return false;
}
public override string ToDescriptionString()
{
return "# Acceptable values: " + string.Join(", ", FontCatalog.All.Select((FontChoice c) => c.Id).ToArray());
}
}
public const string Guid = "PeglinFonts";
public const string Name = "PeglinFonts";
public const string Version = "1.0.0";
internal const string KeybindsGuid = "PeglinKeybinds";
internal static ManualLogSource Log;
internal static ConfigEntry<string> FontSetting;
internal static FontChoice Current => FontCatalog.Find(FontSetting?.Value);
private void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_006c: 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_008f: 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: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
FontSetting = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Font", "default", new ConfigDescription("The font used for all text in the game, including other mods' text. Easiest to change from Options > Font (edits to this file only take effect when the game is closed).", (AcceptableValueBase)(object)new FontIds(), Array.Empty<object>()));
FontSetting.SettingChanged += delegate
{
FontSwapper.ApplyAll();
OptionsMenuPatch.UpdateAllLabels();
};
new Harmony("PeglinFonts").PatchAll(typeof(Plugin).Assembly);
GameObject val = new GameObject("PeglinFonts")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<FontHost>();
Log.LogInfo((object)("PeglinFonts 1.0.0 loaded. Font: " + Current.DisplayName + ". Change it from Options > Font."));
}
internal static void Choose(FontChoice choice)
{
if (choice != null && FontSetting.Value != choice.Id)
{
FontSetting.Value = choice.Id;
}
}
}
internal static class UiCopy
{
public static readonly Color Green = new Color(0.435f, 0.612f, 0.275f, 1f);
public static readonly Color Tan = new Color(0.72f, 0.66f, 0.55f, 1f);
public static readonly Color Frame = new Color(0.27f, 0.18f, 0.13f, 0.97f);
public static readonly Color Highlight = new Color(1f, 0.93f, 0.55f, 1f);
public const string ArrowName = "PeglinFonts_Arrow";
private static Sprite _arrow;
public static void RemoveScripts(GameObject root, params string[] typeNames)
{
MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && typeNames.Contains(((object)val).GetType().Name))
{
Object.DestroyImmediate((Object)(object)val);
}
}
}
public static void AddDropdownArrow(Button button)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: 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_007b: 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_0090: 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_00a5: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)((Component)button).transform.Find("PeglinFonts_Arrow") != (Object)null))
{
GameObject val = new GameObject("PeglinFonts_Arrow", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
RectTransform val2 = (RectTransform)val.transform;
((Transform)val2).SetParent(((Component)button).transform, false);
val2.anchorMin = new Vector2(1f, 0.5f);
val2.anchorMax = new Vector2(1f, 0.5f);
val2.pivot = new Vector2(1f, 0.5f);
val2.sizeDelta = new Vector2(14f, 8f);
val2.anchoredPosition = new Vector2(-8f, 0f);
Image component = val.GetComponent<Image>();
component.sprite = ArrowSprite();
((Graphic)component).color = new Color(0.2f, 0.13f, 0.1f, 1f);
((Graphic)component).raycastTarget = false;
}
}
private static Sprite ArrowSprite()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_0033: Expected O, but got Unknown
//IL_008c: 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_0057: 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)_arrow != (Object)null)
{
return _arrow;
}
Texture2D val = new Texture2D(7, 4, (TextureFormat)4, false)
{
filterMode = (FilterMode)0,
wrapMode = (TextureWrapMode)1,
hideFlags = (HideFlags)61
};
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 7; j++)
{
bool flag = Mathf.Abs(j - 3) <= i;
val.SetPixel(j, i, flag ? Color.white : Color.clear);
}
}
val.Apply();
_arrow = Sprite.Create(val, new Rect(0f, 0f, 7f, 4f), new Vector2(0.5f, 0.5f), 100f);
((Object)_arrow).hideFlags = (HideFlags)61;
return _arrow;
}
}
}
namespace PeglinFonts.Core
{
public enum FontCategory
{
Default,
Accessible,
Serious,
Fun
}
public sealed class FontChoice
{
public string Id { get; }
public string DisplayName { get; }
public FontCategory Category { get; }
public string FileName { get; }
public float Scale { get; }
public string[] SystemFonts { get; }
public bool IsDefault => FileName == null;
public FontChoice(string id, string displayName, FontCategory category, string fileName, string[] systemFonts, float scale = 1f)
{
SystemFonts = systemFonts ?? new string[0];
Id = id;
DisplayName = displayName;
Category = category;
FileName = fileName;
Scale = scale;
}
}
public static class FontCatalog
{
public const string DefaultId = "default";
public static readonly IReadOnlyList<FontChoice> All = new FontChoice[14]
{
new FontChoice("default", "Peglin (default)", FontCategory.Default, null, null),
new FontChoice("opendyslexic", "OpenDyslexic", FontCategory.Accessible, "OpenDyslexic-Regular.otf", new string[3] { "OpenDyslexic", "Comic Sans MS", "Verdana" }),
new FontChoice("atkinson", "Atkinson Hyperlegible", FontCategory.Accessible, "AtkinsonHyperlegible-Regular.ttf", new string[3] { "Atkinson Hyperlegible", "Verdana", "Arial" }),
new FontChoice("lato", "Lato", FontCategory.Serious, "Lato-Regular.ttf", new string[3] { "Lato", "Segoe UI", "Arial" }),
new FontChoice("ptserif", "PT Serif", FontCategory.Serious, "PT_Serif-Web-Regular.ttf", new string[3] { "PT Serif", "Georgia", "Times New Roman" }),
new FontChoice("comicneue", "Comic Neue", FontCategory.Fun, "ComicNeue-Regular.ttf", new string[2] { "Comic Neue", "Comic Sans MS" }),
new FontChoice("patrickhand", "Patrick Hand", FontCategory.Fun, "PatrickHand-Regular.ttf", new string[3] { "Patrick Hand", "Segoe Print", "Comic Sans MS" }),
new FontChoice("permanentmarker", "Permanent Marker", FontCategory.Fun, "PermanentMarker-Regular.ttf", new string[3] { "Permanent Marker", "Ink Free", "Segoe Print" }, 0.95f),
new FontChoice("bangers", "Bangers", FontCategory.Fun, "Bangers-Regular.ttf", new string[2] { "Bangers", "Impact" }),
new FontChoice("vt323", "VT323 Terminal", FontCategory.Fun, "VT323-Regular.ttf", new string[3] { "VT323", "Consolas", "Courier New" }),
new FontChoice("creepster", "Creepster", FontCategory.Fun, "Creepster-Regular.ttf", new string[3] { "Creepster", "Chiller", "Impact" }),
new FontChoice("specialelite", "Special Elite", FontCategory.Fun, "SpecialElite-Regular.ttf", new string[2] { "Special Elite", "Courier New" }),
new FontChoice("luckiestguy", "Luckiest Guy", FontCategory.Fun, "LuckiestGuy-Regular.ttf", new string[3] { "Luckiest Guy", "Impact", "Comic Sans MS" }),
new FontChoice("bungee", "Bungee", FontCategory.Fun, "Bungee-Regular.ttf", new string[3] { "Bungee", "Arial Black", "Impact" })
};
public static FontChoice Default => All[0];
public static FontChoice Find(string id)
{
if (!string.IsNullOrWhiteSpace(id))
{
string b = id.Trim();
foreach (FontChoice item in All)
{
if (string.Equals(item.Id, b, StringComparison.OrdinalIgnoreCase))
{
return item;
}
}
}
return Default;
}
public static int IndexOf(FontChoice choice)
{
for (int i = 0; i < All.Count; i++)
{
if (All[i] == choice)
{
return i;
}
}
return 0;
}
public static string PickSystemFont(FontChoice choice, IEnumerable<string> installed)
{
HashSet<string> hashSet = new HashSet<string>(installed ?? new string[0], StringComparer.OrdinalIgnoreCase);
string[] systemFonts = choice.SystemFonts;
foreach (string text in systemFonts)
{
if (hashSet.Contains(text))
{
return text;
}
}
return null;
}
public static float MatchScale(float referenceCapRatio, float fontCapRatio, float extra = 1f)
{
float num = 1f;
if (referenceCapRatio > 0f && fontCapRatio > 0f && !float.IsNaN(referenceCapRatio) && !float.IsNaN(fontCapRatio))
{
num = referenceCapRatio / fontCapRatio;
}
num *= ((extra > 0f) ? extra : 1f);
return Math.Max(0.5f, Math.Min(1.6f, num));
}
}
public static class MenuLayout
{
public static int FontRowIndex(IReadOnlyList<(string Name, bool Selectable)> rows, string controlsRowName)
{
for (int i = 0; i < rows.Count; i++)
{
if (rows[i].Name == controlsRowName)
{
return i + 1;
}
}
if (rows.Count <= 0 || rows[0].Selectable)
{
return 0;
}
return 1;
}
public static int Columns(int count)
{
if (count <= 10)
{
return 1;
}
return 2;
}
public static int Rows(int count, int columns)
{
if (columns > 0)
{
return (count + columns - 1) / columns;
}
return count;
}
public static int Move(int index, int dx, int dy, int count, int columns)
{
if (count <= 0)
{
return 0;
}
int num = Rows(count, columns);
int num2 = Clamp(index / num + dx, 0, columns - 1);
int num3 = Clamp(index % num + dy, 0, num - 1);
return Clamp(num2 * num + num3, 0, count - 1);
}
public static float ShiftInto(float start, float end, float min, float max, bool keepEnd)
{
if (end - start > max - min)
{
if (!keepEnd)
{
return min - start;
}
return max - end;
}
if (start < min)
{
return min - start;
}
if (!(end > max))
{
return 0f;
}
return max - end;
}
private static int Clamp(int value, int min, int max)
{
if (value >= min)
{
if (value <= max)
{
return value;
}
return max;
}
return min;
}
}
}