Decompiled source of SteamGlyphs v1.0.0

plugins/DeckGlyphs.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using TMPro;
using UnityEngine;
using UnityEngine.TextCore;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace DeckGlyphs;

[BepInPlugin("com.himiko.deckglyphs", "Deck Glyphs", "1.0.0")]
public class DeckGlyphsPlugin : BaseUnityPlugin
{
	public const string GUID = "com.himiko.deckglyphs";

	public const string NAME = "Deck Glyphs";

	public const string VERSION = "1.0.0";

	private const string TargetSpriteAsset = "tmpsprXboxOneGlyphs";

	internal static ManualLogSource Log;

	private readonly Dictionary<string, Texture2D> _deckByGlyphName = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

	private bool _patched;

	private void Awake()
	{
		Log = ((BaseUnityPlugin)this).Logger;
		LoadDeckTextures();
		if (_deckByGlyphName.Count == 0)
		{
			Log.LogError((object)"No Deck glyphs loaded; check the glyphs/ folder and glyph_map.json.");
		}
		else
		{
			((MonoBehaviour)this).StartCoroutine(PatchWhenReady());
		}
	}

	private void LoadDeckTextures()
	{
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Expected O, but got Unknown
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string text = Path.Combine(directoryName, "glyphs");
		string path = Path.Combine(directoryName, "glyph_map.json");
		if (!Directory.Exists(text) || !File.Exists(path))
		{
			Log.LogError((object)"Missing glyphs/ folder or glyph_map.json next to the DLL.");
			return;
		}
		foreach (KeyValuePair<string, string> item in ReadFlatJson(File.ReadAllText(path)))
		{
			if (!item.Key.StartsWith("_"))
			{
				string text2 = Path.Combine(text, item.Value);
				if (!File.Exists(text2))
				{
					Log.LogWarning((object)("Glyph png not found: " + text2));
					continue;
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				ImageConversion.LoadImage(val, File.ReadAllBytes(text2));
				((Texture)val).wrapMode = (TextureWrapMode)1;
				_deckByGlyphName[item.Key] = val;
			}
		}
		Log.LogInfo((object)("Loaded " + _deckByGlyphName.Count + " Deck glyph textures."));
	}

	private IEnumerator PatchWhenReady()
	{
		float deadline = Time.realtimeSinceStartup + 120f;
		while (!_patched && Time.realtimeSinceStartup < deadline)
		{
			if (TryPatch())
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(0.5f);
		}
		if (!_patched)
		{
			Log.LogWarning((object)"Gave up: 'tmpsprXboxOneGlyphs' sprite asset never appeared.");
		}
	}

	private bool TryPatch()
	{
		TMP_SpriteAsset[] array = Resources.FindObjectsOfTypeAll<TMP_SpriteAsset>();
		bool flag = false;
		TMP_SpriteAsset[] array2 = array;
		foreach (TMP_SpriteAsset val in array2)
		{
			if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "tmpsprXboxOneGlyphs"))
			{
				try
				{
					RepaintAtlas(val);
					flag = true;
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Failed to repaint " + ((Object)val).name + ": " + ex));
				}
			}
		}
		if (flag)
		{
			_patched = true;
			Log.LogInfo((object)"Deck glyphs applied.");
		}
		return flag;
	}

	private void RepaintAtlas(TMP_SpriteAsset sa)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		//IL_00fb: 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_0100: Unknown result type (might be due to invalid IL or missing references)
		Texture spriteSheet = sa.spriteSheet;
		Texture2D val = (Texture2D)(object)((spriteSheet is Texture2D) ? spriteSheet : null);
		int num = ((!((Object)(object)val != (Object)null)) ? 1024 : ((Texture)val).width);
		int num2 = ((!((Object)(object)val != (Object)null)) ? 1024 : ((Texture)val).height);
		Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false);
		((Texture)val2).wrapMode = (TextureWrapMode)1;
		((Texture)val2).filterMode = (FilterMode)1;
		Color32[] pixels = (Color32[])(object)new Color32[num * num2];
		val2.SetPixels32(pixels);
		int num3 = 0;
		List<TMP_SpriteCharacter> spriteCharacterTable = sa.spriteCharacterTable;
		for (int i = 0; i < spriteCharacterTable.Count; i++)
		{
			TMP_SpriteCharacter val3 = spriteCharacterTable[i];
			if (val3 == null || string.IsNullOrEmpty(val3.name) || !_deckByGlyphName.TryGetValue(val3.name, out var value) || (Object)(object)value == (Object)null)
			{
				continue;
			}
			GlyphRect val4 = ((((TMP_TextElement)val3).glyph == null) ? FindRect(sa, ((TMP_TextElement)val3).glyphIndex) : ((TMP_TextElement)val3).glyph.glyphRect);
			if (((GlyphRect)(ref val4)).width > 0 && ((GlyphRect)(ref val4)).height > 0)
			{
				Color32[] array = Resample(value, ((GlyphRect)(ref val4)).width, ((GlyphRect)(ref val4)).height);
				if (((GlyphRect)(ref val4)).x >= 0 && ((GlyphRect)(ref val4)).y >= 0 && ((GlyphRect)(ref val4)).x + ((GlyphRect)(ref val4)).width <= num && ((GlyphRect)(ref val4)).y + ((GlyphRect)(ref val4)).height <= num2)
				{
					val2.SetPixels32(((GlyphRect)(ref val4)).x, ((GlyphRect)(ref val4)).y, ((GlyphRect)(ref val4)).width, ((GlyphRect)(ref val4)).height, array);
					num3++;
				}
			}
		}
		val2.Apply(false, false);
		sa.spriteSheet = (Texture)(object)val2;
		Material material = ((TMP_Asset)sa).material;
		if ((Object)(object)material != (Object)null)
		{
			material.mainTexture = (Texture)(object)val2;
			if (material.HasProperty("_MainTex"))
			{
				material.SetTexture("_MainTex", (Texture)(object)val2);
			}
		}
		Log.LogInfo((object)("Repainted " + num3 + " glyphs on " + ((Object)sa).name + " (" + num + "x" + num2 + ")."));
	}

	private static GlyphRect FindRect(TMP_SpriteAsset sa, uint glyphIndex)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		List<TMP_SpriteGlyph> spriteGlyphTable = sa.spriteGlyphTable;
		for (int i = 0; i < spriteGlyphTable.Count; i++)
		{
			if (spriteGlyphTable[i] != null && ((Glyph)spriteGlyphTable[i]).index == glyphIndex)
			{
				return ((Glyph)spriteGlyphTable[i]).glyphRect;
			}
		}
		return new GlyphRect(0, 0, 0, 0);
	}

	private static Color32[] Resample(Texture2D src, int w, int h)
	{
		//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_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: 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)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: 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_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		Color[] pixels = src.GetPixels();
		int width = ((Texture)src).width;
		int height = ((Texture)src).height;
		Color32[] array = (Color32[])(object)new Color32[w * h];
		for (int i = 0; i < h; i++)
		{
			float num = ((float)i + 0.5f) * (float)height / (float)h - 0.5f;
			int num2 = Mathf.Clamp(Mathf.FloorToInt(num), 0, height - 1);
			int num3 = Mathf.Clamp(num2 + 1, 0, height - 1);
			float num4 = Mathf.Clamp01(num - (float)num2);
			for (int j = 0; j < w; j++)
			{
				float num5 = ((float)j + 0.5f) * (float)width / (float)w - 0.5f;
				int num6 = Mathf.Clamp(Mathf.FloorToInt(num5), 0, width - 1);
				int num7 = Mathf.Clamp(num6 + 1, 0, width - 1);
				float num8 = Mathf.Clamp01(num5 - (float)num6);
				Color val = pixels[num2 * width + num6];
				Color val2 = pixels[num2 * width + num7];
				Color val3 = pixels[num3 * width + num6];
				Color val4 = pixels[num3 * width + num7];
				Color val5 = Color.Lerp(val, val2, num8);
				Color val6 = Color.Lerp(val3, val4, num8);
				ref Color32 reference = ref array[i * w + j];
				reference = Color32.op_Implicit(Color.Lerp(val5, val6, num4));
			}
		}
		return array;
	}

	private static IEnumerable<KeyValuePair<string, string>> ReadFlatJson(string json)
	{
		List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
		int startIndex = 0;
		while (true)
		{
			int num = json.IndexOf('"', startIndex);
			if (num < 0)
			{
				break;
			}
			int num2 = json.IndexOf('"', num + 1);
			if (num2 < 0)
			{
				break;
			}
			string key = json.Substring(num + 1, num2 - num - 1);
			int num3 = json.IndexOf(':', num2);
			if (num3 < 0)
			{
				break;
			}
			int num4 = json.IndexOf('\n', num2);
			int num5 = json.IndexOf('"', num3);
			if (num5 < 0)
			{
				break;
			}
			if (num4 >= 0 && num5 > num4)
			{
				startIndex = num2 + 1;
				continue;
			}
			int num6 = json.IndexOf('"', num5 + 1);
			if (num6 < 0)
			{
				break;
			}
			string value = json.Substring(num5 + 1, num6 - num5 - 1);
			list.Add(new KeyValuePair<string, string>(key, value));
			startIndex = num6 + 1;
		}
		return list;
	}
}