The current BepInExPack is broken due to the Oakveil update, and mods installed through a mod manager may not work. Join the modding Discord for more information.
Decompiled source of Killfeed v0.3.1
Killfeed.dll
Decompiled 11 months agousing System; 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 System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Bloodstone.API; using Cpp2IL.Core.Extensions; using HarmonyLib; using Il2CppInterop.Runtime; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.Network; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; using VampireCommandFramework; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Killfeed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("PvP Leaderboard and Killfeed Announcements.")] [assembly: AssemblyFileVersion("0.3.1.0")] [assembly: AssemblyInformationalVersion("0.3.1+1.Branch.main.Sha.08dd5b38f4f81d1d82d25dd0b313b55a2ad849db")] [assembly: AssemblyProduct("Killfeed")] [assembly: AssemblyTitle("Killfeed")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.1.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; } } } internal static class ECSExtensions { internal static void With<T>(this Entity entity, ActionRef<T> action) where T : struct { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) T val = entity.RW<T>(); action.Invoke(ref val); EntityManager entityManager = VWorld.Game.EntityManager; ((EntityManager)(ref entityManager)).SetComponentData<T>(entity, val); } internal static bool Has<T>(this Entity entity) where T : struct { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) int num = TypeIndex.op_Implicit(TypeManager.GetTypeIndex(Il2CppType.Of<T>())); EntityManager entityManager = VWorld.Game.EntityManager; return ((EntityManager)(ref entityManager)).HasComponentRaw(entity, TypeIndex.op_Implicit(num)); } internal static bool Has<T>(this Entity entity, out T value) where T : struct { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (entity.Has<T>()) { value = entity.Read<T>(); return true; } value = default(T); return false; } internal unsafe static T RW<T>(this Entity entity) where T : struct { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) int num = TypeIndex.op_Implicit(TypeManager.GetTypeIndex(Il2CppType.Of<T>())); EntityManager entityManager = VWorld.Game.EntityManager; T* componentDataRawRW = (T*)((EntityManager)(ref entityManager)).GetComponentDataRawRW(entity, TypeIndex.op_Implicit(num)); if (componentDataRawRW == null) { throw new InvalidOperationException($"Failure to access ReadWrite <{typeof(T).Name}> typeIndex({num}) on entity({entity})."); } return *componentDataRawRW; } internal unsafe static T Read<T>(this Entity entity) where T : struct { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) int num = TypeIndex.op_Implicit(TypeManager.GetTypeIndex(Il2CppType.Of<T>())); EntityManager entityManager = VWorld.Game.EntityManager; T* componentDataRawRO = (T*)((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, TypeIndex.op_Implicit(num)); if (componentDataRawRO == null) { throw new InvalidOperationException($"Failure to access ReadOnly <{typeof(T).Name}> typeIndex({num}) on entity({entity})."); } return *componentDataRawRO; } } namespace Killfeed { public class Commands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<DataStore.PlayerStatistics, int> <>9__0_0; public static Func<string, string> <>9__0_1; public static Func<DataStore.PlayerStatistics, string> <>9__0_2; public static Func<DataStore.PlayerStatistics, int> <>9__1_0; public static Func<DataStore.PlayerStatistics, int, (DataStore.PlayerStatistics stats, int rank)> <>9__1_1; internal int <TopCommand>b__0_0(DataStore.PlayerStatistics k) { return k.Kills; } internal string <TopCommand>b__0_1(string name) { return new string(MiscExtensions.Repeat<char>('\t', 6 - name.Length / 5).ToArray()); } internal string <TopCommand>b__0_2(DataStore.PlayerStatistics k) { return $"\t<color={"#dda"}><b>{k.Kills,-3}</b> / {k.Deaths,3}</color>\t{Markup.Highlight(k.LastName)}"; } internal int <KillfeedCommand>b__1_0(DataStore.PlayerStatistics k) { return k.Kills; } internal (DataStore.PlayerStatistics stats, int rank) <KillfeedCommand>b__1_1(DataStore.PlayerStatistics stats, int rank) { return (stats, rank); } } [Command("killfeed leaderboard", "kf top", null, null, null, false)] public void TopCommand(ChatCommandContext ctx) { int num = 10; int num2 = 5; DataStore.PlayerStatistics[] array = DataStore.PlayerDatas.Values.OrderByDescending((DataStore.PlayerStatistics k) => k.Kills).Take(num).ToArray(); num2 = ((num2 > array.Length) ? array.Length : num2); num = ((num > array.Length) ? array.Length : num); if (<>c.<>9__0_1 == null) { <>c.<>9__0_1 = (string name) => new string(MiscExtensions.Repeat<char>('\t', 6 - name.Length / 5).ToArray()); } StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.AppendLine(""); StringBuilder stringBuilder3 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder3; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(33, 1, stringBuilder3); handler.AppendFormatted(Markup.Prefix); handler.AppendLiteral(" <size=18><u>Top Kills</u></size>"); stringBuilder4.AppendLine(ref handler); Func<DataStore.PlayerStatistics, string> func = (DataStore.PlayerStatistics k) => $"\t<color={"#dda"}><b>{k.Kills,-3}</b> / {k.Deaths,3}</color>\t{Markup.Highlight(k.LastName)}"; for (int i = 0; i < num2; i++) { DataStore.PlayerStatistics arg = array[i]; stringBuilder3 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder3; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder3); handler.AppendFormatted(i + 1); handler.AppendLiteral(". "); handler.AppendFormatted(func(arg)); stringBuilder5.AppendLine(ref handler); } for (int j = num2; j < num; j++) { DataStore.PlayerStatistics arg2 = array[j]; stringBuilder3 = stringBuilder2; StringBuilder stringBuilder6 = stringBuilder3; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder3); handler.AppendFormatted(j + 1); handler.AppendLiteral(". "); handler.AppendFormatted(func(arg2)); stringBuilder6.AppendLine(ref handler); } ctx.Reply(stringBuilder.ToString()); ctx.Reply(stringBuilder2.ToString()); } [Command("killfeed", "kf", null, "Shows Killfeed info", null, false)] public void KillfeedCommand(ChatCommandContext ctx) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) ulong platformId = ctx.User.PlatformId; if (!DataStore.PlayerDatas.TryGetValue(platformId, out var _)) { throw ctx.Error("You have no stats yet!"); } (DataStore.PlayerStatistics, int) tuple = DataStore.PlayerDatas.Values.OrderByDescending((DataStore.PlayerStatistics k) => k.Kills).Select((DataStore.PlayerStatistics stats, int rank) => (stats, rank)).First<(DataStore.PlayerStatistics, int)>(((DataStore.PlayerStatistics stats, int rank) u) => u.stats.SteamId == ctx.User.PlatformId); DataStore.PlayerStatistics item = tuple.Item1; int item2 = tuple.Item2; StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(36, 2, stringBuilder2); handler.AppendFormatted(Markup.Prefix); handler.AppendLiteral(" <size=21><u>Killfeed Stats for "); handler.AppendFormatted(Markup.Highlight(item.LastName)); handler.AppendLiteral("</u>"); stringBuilder3.AppendLine(ref handler); string value2 = Markup.Highlight($"{item2 + 1}") + " / " + Markup.Secondary(DataStore.PlayerDatas.Count); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(13, 1, stringBuilder2); handler.AppendLiteral("Rank: "); handler.AppendFormatted(value2); handler.AppendLiteral("</size>"); stringBuilder4.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder2); handler.AppendLiteral("Kills: "); handler.AppendFormatted(Markup.Highlight(item.Kills)); stringBuilder5.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(8, 1, stringBuilder2); handler.AppendLiteral("Deaths: "); handler.AppendFormatted(Markup.Highlight(item.Deaths)); stringBuilder6.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder7 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2); handler.AppendLiteral("Current Streak: "); handler.AppendFormatted(Markup.Highlight(item.CurrentStreak)); stringBuilder7.AppendLine(ref handler); stringBuilder2 = stringBuilder; StringBuilder stringBuilder8 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2); handler.AppendLiteral("Highest Streak: "); handler.AppendFormatted(Markup.Highlight(item.HighestStreak)); stringBuilder8.AppendLine(ref handler); ctx.Reply(stringBuilder.ToString()); } } public class DataStore { public record struct PlayerStatistics(ulong SteamId, string LastName, int Kills, int Deaths, int CurrentStreak, int HighestStreak, string LastClanName, int CurrentLevel, int MaxLevel) { public string FormattedName { get { string text = Markup.Highlight(LastName); if (Settings.IncludeLevel) { if (!Settings.UseMaxLevel) { return text + " (" + Markup.Secondary(CurrentLevel) + ")"; } return text + " (" + Markup.Secondary(MaxLevel) + "*)"; } return text ?? ""; } } private static string SafeCSVName(string s) { return s.Replace(",", ""); } public string ToCsv() { return $"{SteamId},{SafeCSVName(LastName)},{Kills},{Deaths},{CurrentStreak},{HighestStreak},{SafeCSVName(LastClanName)},{CurrentLevel},{MaxLevel}"; } public static PlayerStatistics Parse(string csv) { string[] array = csv.Split(','); PlayerStatistics result = default(PlayerStatistics); result.SteamId = ulong.Parse(array[0]); result.LastName = array[1]; result.Kills = int.Parse(array[2]); result.Deaths = int.Parse(array[3]); result.CurrentStreak = int.Parse(array[4]); result.HighestStreak = int.Parse(array[5]); result.LastClanName = ((array.Length > 6) ? array[6] : ""); result.CurrentLevel = ((array.Length > 7) ? int.Parse(array[7]) : (-1)); result.MaxLevel = ((array.Length > 8) ? int.Parse(array[8]) : (-1)); return result; } } public record struct EventData(ulong VictimId, ulong KillerId, float3 Location, long Timestamp, int VictimLevel, int KillerLevel) { public string ToCsv() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) return $"{VictimId},{KillerId},{Location.x},{Location.y},{Location.z},{Timestamp},{VictimLevel},{KillerLevel}"; } public static EventData Parse(string csv) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) string[] array = csv.Split(','); EventData result = default(EventData); result.VictimId = ulong.Parse(array[0]); result.KillerId = ulong.Parse(array[1]); result.Location = new float3(float.Parse(array[2]), float.Parse(array[3]), float.Parse(array[4])); result.Timestamp = long.Parse(array[5]); result.VictimLevel = ((array.Length > 6) ? int.Parse(array[6]) : 0); result.KillerLevel = ((array.Length > 7) ? int.Parse(array[7]) : 0); return result; } [CompilerGenerated] private readonly bool PrintMembers(StringBuilder builder) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) builder.Append("VictimId = "); builder.Append(VictimId.ToString()); builder.Append(", KillerId = "); builder.Append(KillerId.ToString()); builder.Append(", Location = "); float3 location = Location; builder.Append(((object)(float3)(ref location)).ToString()); builder.Append(", Timestamp = "); builder.Append(Timestamp.ToString()); builder.Append(", VictimLevel = "); builder.Append(VictimLevel.ToString()); builder.Append(", KillerLevel = "); builder.Append(KillerLevel.ToString()); return true; } } public static List<EventData> Events = new List<EventData>(); public static Dictionary<ulong, PlayerStatistics> PlayerDatas = new Dictionary<ulong, PlayerStatistics>(); private static readonly Random _rand = new Random(); private const string EVENTS_FILE_NAME = "events.v1.csv"; private const string EVENTS_FILE_PATH = "BepInEx/config/Killfeed/events.v1.csv"; private const string STATS_FILE_NAME = "stats.v1.csv"; private const string STATS_FILE_PATH = "BepInEx/config/Killfeed/stats.v1.csv"; private static EventData GenerateTestEvent() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) EventData result = default(EventData); result.VictimId = (ulong)_rand.NextInt64(); result.KillerId = (ulong)_rand.NextInt64(); result.Location = new float3((float)_rand.NextDouble(), (float)_rand.NextDouble(), (float)_rand.NextDouble()); result.Timestamp = DateTime.UtcNow.AddMinutes(_rand.Next(-10000, 10000)).Ticks; return result; } public static void GenerateNTestData(int count) { for (int i = 0; i < count; i++) { Events.Add(GenerateTestEvent()); } } public static void WriteToDisk() { string directoryName = Path.GetDirectoryName("BepInEx/config/Killfeed/events.v1.csv"); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } using StreamWriter streamWriter = new StreamWriter("BepInEx/config/Killfeed/events.v1.csv", append: false); foreach (EventData @event in Events) { streamWriter.WriteLine(@event.ToCsv()); } using StreamWriter streamWriter2 = new StreamWriter("BepInEx/config/Killfeed/stats.v1.csv", append: false); foreach (PlayerStatistics value in PlayerDatas.Values) { streamWriter2.WriteLine(value.ToCsv()); } } public static void LoadFromDisk() { Events.Clear(); PlayerDatas.Clear(); LoadEventData(); LoadPlayerData(); } private static void LoadEventData() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (!File.Exists("BepInEx/config/Killfeed/events.v1.csv")) { return; } using StreamReader streamReader = new StreamReader("BepInEx/config/Killfeed/events.v1.csv"); bool flag = default(bool); while (!streamReader.EndOfStream) { string text = streamReader.ReadLine(); if (string.IsNullOrWhiteSpace(text)) { continue; } try { Events.Add(EventData.Parse(text)); } catch (Exception) { ManualLogSource logger = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to parse event line: \""); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\""); } logger.LogError(val); } } } private static void LoadPlayerData() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if (!File.Exists("BepInEx/config/Killfeed/stats.v1.csv")) { return; } using StreamReader streamReader = new StreamReader("BepInEx/config/Killfeed/stats.v1.csv"); bool flag = default(bool); while (!streamReader.EndOfStream) { string text = streamReader.ReadLine(); if (string.IsNullOrWhiteSpace(text)) { continue; } try { PlayerStatistics playerStatistics = PlayerStatistics.Parse(text); if (PlayerDatas.TryGetValue(playerStatistics.SteamId, out var value)) { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Duplicate player data found, overwriting "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<PlayerStatistics>(value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" with "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<PlayerStatistics>(playerStatistics); } logger.LogWarning(val); } PlayerDatas[playerStatistics.SteamId] = playerStatistics; } catch (Exception) { ManualLogSource logger2 = Plugin.Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to parse player line: \""); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\""); } logger2.LogError(val2); } } } public static void RegisterKillEvent(PlayerCharacter victim, PlayerCharacter killer, float3 location, int victimLevel, int killerLevel) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) User val = victim.UserEntity.Read<User>(); User val2 = killer.UserEntity.Read<User>(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(1, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(victimLevel); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(killerLevel); } logger.LogWarning(val3); EventData item = new EventData(val.PlatformId, val2.PlatformId, location, DateTime.UtcNow.Ticks, victimLevel, killerLevel); Events.Add(item); PlayerStatistics victimUser = UpsertName(val.PlatformId, ((object)(FixedString64Bytes)(ref val.CharacterName)).ToString(), ((object)(FixedString32Bytes)(ref victim.SmartClanName)).ToString(), victimLevel); PlayerStatistics killerUser = UpsertName(val2.PlatformId, ((object)(FixedString64Bytes)(ref val2.CharacterName)).ToString(), ((object)(FixedString32Bytes)(ref killer.SmartClanName)).ToString(), killerLevel); RecordKill(val2.PlatformId); int lostStreakAmount = RecordDeath(val.PlatformId); AnnounceKill(victimUser, killerUser, lostStreakAmount); WriteToDisk(); static PlayerStatistics UpsertName(ulong steamId, string name, string clanName, int level) { if (PlayerDatas.TryGetValue(steamId, out var value)) { value.LastName = name; value.LastClanName = clanName; value.CurrentLevel = level; value.MaxLevel = Math.Max(value.MaxLevel, level); PlayerDatas[steamId] = value; } else { PlayerDatas[steamId] = new PlayerStatistics { LastName = name, SteamId = steamId, LastClanName = clanName, CurrentLevel = level, MaxLevel = level }; } return PlayerDatas[steamId]; } } private static void AnnounceKill(PlayerStatistics victimUser, PlayerStatistics killerUser, int lostStreakAmount) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) if (Settings.AnnounceKills) { string formattedName = victimUser.FormattedName; string formattedName2 = killerUser.FormattedName; string text = ((lostStreakAmount > Settings.AnnounceKillstreakLostMinimum) ? $"{formattedName2} ended {formattedName}'s {Markup.Secondary(lostStreakAmount)} kill streak!" : (formattedName2 + " killed " + formattedName + "!")); string text2 = killerUser.CurrentStreak switch { 5 => "<size=18>" + formattedName2 + " is on a killing spree!", 10 => "<size=19>" + formattedName2 + " is on a rampage!", 15 => "<size=20>" + formattedName2 + " is dominating!", 20 => "<size=21>" + formattedName2 + " is unstoppable!", 25 => "<size=22>" + formattedName2 + " is godlike!", 30 => "<size=24>" + formattedName2 + " is WICKED SICK!", _ => null, }; ServerChatUtils.SendSystemMessageToAllClients(VWorld.Server.EntityManager, Markup.Prefix + text); if (!string.IsNullOrEmpty(text2) && Settings.AnnounceKillstreak) { ServerChatUtils.SendSystemMessageToAllClients(VWorld.Server.EntityManager, Markup.Prefix + text2); } } } private static int RecordDeath(ulong platformId) { int result = 0; if (PlayerDatas.TryGetValue(platformId, out var value)) { value.Deaths++; result = value.CurrentStreak; value.CurrentStreak = 0; PlayerDatas[platformId] = value; } else { PlayerDatas[platformId] = new PlayerStatistics { Deaths = 1, SteamId = platformId }; } return result; } private static void RecordKill(ulong steamId) { if (PlayerDatas.TryGetValue(steamId, out var value)) { value.Kills++; value.CurrentStreak++; value.HighestStreak = math.max(value.HighestStreak, value.CurrentStreak); PlayerDatas[steamId] = value; } else { PlayerDatas[steamId] = new PlayerStatistics { Kills = 1, CurrentStreak = 1, HighestStreak = 1, SteamId = steamId }; } } } internal static class Markup { public const string HighlightColor = "#def"; public const string SecondaryColor = "#dda"; public static string Prefix = Format.Bold(Format.Color("[kf] ", "#ed1")); public static string Highlight(int i) { return Highlight(i.ToString()); } public static string Highlight(string s) { return Format.Color(Format.Bold(s), "#def"); } public static string Secondary(int i) { return Secondary(i.ToString()); } public static string Secondary(string s) { return Format.Color(Format.Bold(s), "#dda"); } } [BepInPlugin("gg.deca.Killfeed", "Killfeed", "0.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [Reloadable] public class Plugin : BasePlugin { private Harmony _harmony; public static ManualLogSource Logger; public override void Load() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown Logger = ((BasePlugin)this).Log; ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("gg.deca.Killfeed"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.3.1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!"); } log.LogInfo(val); _harmony = new Harmony("gg.deca.Killfeed"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); CommandRegistry.RegisterAll(); Settings.Initialize(((BasePlugin)this).Config); DataStore.LoadFromDisk(); } public override bool Unload() { CommandRegistry.UnregisterAssembly(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } return true; } } internal class Settings { internal static bool AnnounceKills { get; private set; } internal static int AnnounceKillstreakLostMinimum { get; private set; } internal static bool AnnounceKillstreak { get; private set; } internal static bool IncludeLevel { get; private set; } internal static bool UseMaxLevel { get; private set; } internal static void Initialize(ConfigFile config) { AnnounceKills = config.Bind<bool>("General", "AnnounceKills", true, "Announce kills in chat").Value; AnnounceKillstreakLostMinimum = config.Bind<int>("General", "AnnounceKillstreakLostMinimum", 3, "Minimum killstreak count that must be lost to be announced.").Value; AnnounceKillstreak = config.Bind<bool>("General", "AnnounceKillstreak", true, "Announce killstreaks in chat").Value; IncludeLevel = config.Bind<bool>("General", "IncludeLevel", true, "Include player gear levels in announcements.").Value; UseMaxLevel = config.Bind<bool>("General", "UseMaxLevel", false, "Use max gear level instead of current gear level.").Value; } } [HarmonyPatch(typeof(VampireDownedServerEventSystem), "OnUpdate")] public static class VampireDownedHook { public static void Prefix(VampireDownedServerEventSystem __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //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_0021: Unknown result type (might be due to invalid IL or missing references) EntityQuery _query_1174204813_ = __instance.__query_1174204813_0; Enumerator<Entity> enumerator = ((EntityQuery)(ref _query_1174204813_)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)).GetEnumerator(); while (enumerator.MoveNext()) { ProcessVampireDowned(enumerator.Current); } } private static void ProcessVampireDowned(Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) Entity entity2 = default(Entity); if (!VampireDownedServerEventSystem.TryFindRootOwner(entity, 1, VWorld.Server.EntityManager, ref entity2)) { Plugin.Logger.LogMessage((object)"Couldn't get victim entity"); return; } Entity entity3 = default(Entity); if (!VampireDownedServerEventSystem.TryFindRootOwner(entity.Read<VampireDownedBuff>().Source, 1, VWorld.Server.EntityManager, ref entity3)) { Plugin.Logger.LogMessage((object)"Couldn't get victim entity"); return; } PlayerCharacter val = entity2.Read<PlayerCharacter>(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(10, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<FixedString64Bytes>(val.Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is victim"); } logger.LogMessage(val2); if (entity3.Has<UnitLevel>()) { ManualLogSource logger2 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<FixedString64Bytes>(val.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" was killed by a unit. [Not currently tracked]"); } logger2.LogInfo(val3); return; } if (!entity3.Has<PlayerCharacter>()) { ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(121, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Killer could not be identified for "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<FixedString64Bytes>(val.Name); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", if you know how to reproduce this please contact deca on discord or report on github"); } logger3.LogWarning(val4); return; } PlayerCharacter val5 = entity3.Read<PlayerCharacter>(); if (val5.UserEntity == val.UserEntity) { ManualLogSource logger4 = Plugin.Logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<FixedString64Bytes>(val.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" killed themselves. [Not currently tracked]"); } logger4.LogInfo(val3); } else { LocalToWorld val6 = entity2.Read<LocalToWorld>(); Equipment value; int victimLevel = (entity2.Has<Equipment>(out value) ? ((int)Math.Round(((Equipment)(ref value)).GetFullLevel())) : (-1)); Equipment value2; int killerLevel = (entity3.Has<Equipment>(out value2) ? ((int)Math.Round(((Equipment)(ref value2)).GetFullLevel())) : (-1)); DataStore.RegisterKillEvent(val, val5, ((LocalToWorld)(ref val6)).Position, victimLevel, killerLevel); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "gg.deca.Killfeed"; public const string PLUGIN_NAME = "Killfeed"; public const string PLUGIN_VERSION = "0.3.1"; } }