Decompiled source of KillfeedIcons v1.0.0

BepInEx/plugins/KillfeedIcons/KillfeedIcons.dll

Decompiled 4 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 System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.TextCore;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: StraftatMod(true)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("KillfeedIcons")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Replaces text in the killfeed with icons")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Killfeed Icons")]
[assembly: AssemblyTitle("KillfeedIcons")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace KillfeedIcons
{
	public static class IconLoader
	{
		private static bool _attempted;

		public static TMP_SpriteAsset SpriteAsset { get; private set; }

		public static void EnsureLoaded()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: 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_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Expected O, but got Unknown
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			if (_attempted)
			{
				return;
			}
			_attempted = true;
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "icons");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
				Plugin.Logger.LogWarning((object)("[KillfeedIcons] Created icons folder at " + text));
				return;
			}
			string[] files = Directory.GetFiles(text, "*.png");
			if (files.Length == 0)
			{
				Plugin.Logger.LogWarning((object)"[KillfeedIcons] No icons found in icons folder");
				return;
			}
			List<Texture2D> list = new List<Texture2D>();
			List<string> list2 = new List<string>();
			string[] array = files;
			foreach (string text2 in array)
			{
				byte[] array2 = File.ReadAllBytes(text2);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Texture)val).filterMode = (FilterMode)1;
				if (!ImageConversion.LoadImage(val, array2))
				{
					Plugin.Logger.LogWarning((object)("[KillfeedIcons] Failed to load " + text2));
					continue;
				}
				list.Add(val);
				list2.Add(Path.GetFileNameWithoutExtension(text2));
			}
			if (list.Count == 0)
			{
				return;
			}
			Texture2D val2 = new Texture2D(512, 512, (TextureFormat)4, false);
			((Texture)val2).filterMode = (FilterMode)1;
			Rect[] array3 = val2.PackTextures(list.ToArray(), 2, 4096);
			val2.Apply();
			Shader val3 = Shader.Find("TextMeshPro/Sprite");
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.Logger.LogError((object)"[KillfeedIcons] TextMeshPro/Sprite shader not found.");
				return;
			}
			Material val4 = new Material(val3);
			val4.mainTexture = (Texture)(object)val2;
			TMP_SpriteAsset val5 = ScriptableObject.CreateInstance<TMP_SpriteAsset>();
			((Object)val5).name = "KillfeedIconsAsset";
			typeof(TMP_SpriteAsset).GetField("m_Version", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(val5, "1.1.0");
			((TMP_Asset)val5).material = val4;
			val5.spriteSheet = (Texture)(object)val2;
			for (int j = 0; j < list.Count; j++)
			{
				TMP_SpriteGlyph val6 = new TMP_SpriteGlyph
				{
					index = (uint)j,
					glyphRect = new GlyphRect((int)(((Rect)(ref array3[j])).x * (float)((Texture)val2).width), (int)(((Rect)(ref array3[j])).y * (float)((Texture)val2).height), (int)(((Rect)(ref array3[j])).width * (float)((Texture)val2).width), (int)(((Rect)(ref array3[j])).height * (float)((Texture)val2).height)),
					scale = 1f,
					atlasIndex = 0
				};
				GlyphRect glyphRect = ((Glyph)val6).glyphRect;
				float num = ((GlyphRect)(ref glyphRect)).width;
				glyphRect = ((Glyph)val6).glyphRect;
				float num2 = ((GlyphRect)(ref glyphRect)).height;
				glyphRect = ((Glyph)val6).glyphRect;
				float num3 = (float)((GlyphRect)(ref glyphRect)).height * 0.75f;
				glyphRect = ((Glyph)val6).glyphRect;
				((Glyph)val6).metrics = new GlyphMetrics(num, num2, 0f, num3, (float)((GlyphRect)(ref glyphRect)).width);
				val5.spriteGlyphTable.Add(val6);
				val5.spriteCharacterTable.Add(new TMP_SpriteCharacter
				{
					name = list2[j],
					glyphIndex = (uint)j,
					unicode = (uint)(57344 + j),
					scale = 1f,
					glyph = (Glyph)(object)val6
				});
			}
			val5.UpdateLookupTables();
			SpriteAsset = val5;
			Plugin.Logger.LogInfo((object)$"[KillfeedIcons] Loaded {list.Count} icons.");
		}
	}
	[HarmonyPatch(typeof(MatchLogsOffline), "WriteLog")]
	public class KillfeedOfflinePatch
	{
		private static void Prefix(ref string line)
		{
			IconLoader.EnsureLoaded();
			line = KillfeedHelper.ModifyKillfeedText(line);
		}

		private static void Postfix(MatchLogsOffline __instance)
		{
			KillfeedHelper.InjectSpriteAsset(__instance.parentForChatLines);
		}
	}
	[HarmonyPatch(typeof(MatchLogs), "RpcLogic___RpcSendChatLineToAllObservers_3615296227")]
	public class KillfeedOnlineRpcPatch
	{
		private static void Prefix(ref string line)
		{
			IconLoader.EnsureLoaded();
			line = KillfeedHelper.ModifyKillfeedText(line);
		}

		private static void Postfix(MatchLogs __instance)
		{
			KillfeedHelper.InjectSpriteAsset(__instance.parentForChatLines);
		}
	}
	[HarmonyPatch(typeof(MatchLogs), "WriteLocalLog")]
	public class KillfeedOnlineLocalPatch
	{
		private static void Prefix(ref string line)
		{
			IconLoader.EnsureLoaded();
			line = KillfeedHelper.ModifyKillfeedText(line);
		}

		private static void Postfix(MatchLogs __instance)
		{
			KillfeedHelper.InjectSpriteAsset(__instance.parentForChatLines);
		}
	}
	public static class KillfeedHelper
	{
		public static bool needsSpriteInjection;

		private const string KillerColor = "A8BAFF";

		private const string VictimColor = "FF9376";

		private static readonly Regex KillPattern = new Regex("(<b><color=#\\w+>(?:\\{PLAYER_NAME\\}:\\{\\d+\\}|.+?)</color></b>) was (killed|headshot|slain|beheaded) with an?\\s+(?:<b>)?<color=white>(.+?)</color>(?:</b>)? by (<b><color=#\\w+>(?:\\{PLAYER_NAME\\}:\\{\\d+\\}|.+?)</color></b>)");

		private static readonly Regex BubleePattern = new Regex("(<b><color=#\\w+>(?:\\{PLAYER_NAME\\}:\\{\\d+\\}|.+?)</color></b>) was killed with the Bublee by (<b><color=#\\w+>(?:\\{PLAYER_NAME\\}:\\{\\d+\\}|.+?)</color></b>)");

		private static readonly Regex ColorTagPattern = new Regex("<color=#\\w+>");

		private static string FormatName(string nameTag, string hexColor)
		{
			return ColorTagPattern.Replace(nameTag.Replace("<b>", "").Replace("</b>", ""), "<color=#" + hexColor + ">");
		}

		private static string BuildResult(string killer, string victim, string spriteName, bool headshot = false)
		{
			string text = (headshot ? " <sprite name=\"headshot\">" : "");
			return FormatName(killer, "A8BAFF") + " <sprite name=\"" + spriteName + "\">" + text + " " + FormatName(victim, "FF9376");
		}

		public static void InjectSpriteAsset(Transform parent)
		{
			if (!((Object)(object)IconLoader.SpriteAsset == (Object)null) && needsSpriteInjection && !((Object)(object)parent == (Object)null) && parent.childCount != 0)
			{
				Transform child = parent.GetChild(parent.childCount - 1);
				TMP_Text val = ((child != null) ? ((Component)child).GetComponentInChildren<TMP_Text>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					val.spriteAsset = IconLoader.SpriteAsset;
					val.text = val.text.Replace("</sprite>", "");
					val.ForceMeshUpdate(false, false);
					needsSpriteInjection = false;
				}
			}
		}

		public static string ModifyKillfeedText(string text)
		{
			Match match = KillPattern.Match(text);
			if (match.Success)
			{
				string value = match.Groups[2].Value;
				bool flag = ((value == "headshot" || value == "beheaded") ? true : false);
				bool headshot = flag;
				string result = BuildResult(match.Groups[4].Value, match.Groups[1].Value, match.Groups[3].Value, headshot);
				needsSpriteInjection = true;
				return result;
			}
			Match match2 = BubleePattern.Match(text);
			if (match2.Success)
			{
				needsSpriteInjection = true;
				return BuildResult(match2.Groups[2].Value, match2.Groups[1].Value, "bubblee");
			}
			if (text.Contains("commited suicide"))
			{
				string nameTag = text.Substring(0, text.IndexOf(" commited suicide"));
				needsSpriteInjection = true;
				return FormatName(nameTag, "FF9376") + " <sprite name=\"skull\">";
			}
			needsSpriteInjection = false;
			return text;
		}
	}
	[BepInPlugin("KillfeedIcons", "Killfeed Icons", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			new Harmony("KillfeedIcons").PatchAll();
			Logger.LogInfo((object)"Killfeed Icons Loaded :D");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "KillfeedIcons";

		public const string PLUGIN_NAME = "Killfeed Icons";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}