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";
}
}