Decompiled source of Straftat Kill Counter v1.0.0

BepInEx/plugins/WeaponKC.dll

Decompiled a day ago
using 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 System.Text.RegularExpressions;
using BepInEx;
using ComputerysModdingUtilities;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("WeaponKC")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Straftat Kill Counter Mod")]
[assembly: AssemblyFileVersion("3.1.0.0")]
[assembly: AssemblyInformationalVersion("3.1.0")]
[assembly: AssemblyProduct("WeaponKC")]
[assembly: AssemblyTitle("WeaponKC")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.1.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 StraftatKillCounter
{
	[BepInPlugin("com.yourname.straftatkillcounter", "Straftat Kill Counter", "3.8.0")]
	public class KillCounterMod : BaseUnityPlugin
	{
		public static class UniversalGunPatch
		{
			public static void Prefix(object __instance)
			{
				RegisterKill(GetBestWeaponName(__instance));
			}
		}

		public static class MineKillPatch
		{
			public static void Postfix(object __instance)
			{
				RegisterKill(GetBestWeaponName(__instance));
			}
		}

		public static Dictionary<string, int> WeaponKillCounts = new Dictionary<string, int>();

		private static string JsonPath;

		private static float lastKillTime;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			JsonPath = Path.Combine(Paths.ConfigPath, "weapon_kills.json");
			LoadJson();
			Harmony val = new Harmony("com.yourname.straftatkillcounter");
			MethodInfo methodInfo = AccessTools.Method(typeof(UniversalGunPatch), "Prefix", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MineKillPatch), "Postfix", (Type[])null, (Type[])null);
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			List<Type> list = new List<Type>();
			List<Type> list2 = new List<Type>();
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				try
				{
					if (assembly.FullName.StartsWith("System") || assembly.FullName.StartsWith("mscorlib"))
					{
						continue;
					}
					Type[] types = assembly.GetTypes();
					foreach (Type type in types)
					{
						if (type.GetMethod("KillServer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null)
						{
							list.Add(type);
						}
						if (type.GetMethod("SendKillLog", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null)
						{
							list2.Add(type);
						}
					}
				}
				catch
				{
				}
			}
			foreach (Type item in list.Distinct())
			{
				try
				{
					val.Patch((MethodBase)AccessTools.Method(item, "KillServer", (Type[])null, (Type[])null), new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				catch
				{
				}
			}
			foreach (Type item2 in list2.Distinct())
			{
				try
				{
					val.Patch((MethodBase)AccessTools.Method(item2, "SendKillLog", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				catch
				{
				}
			}
		}

		public static void SaveJson()
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("{");
				List<KeyValuePair<string, int>> list = WeaponKillCounts.OrderByDescending((KeyValuePair<string, int> x) => x.Value).ToList();
				for (int i = 0; i < list.Count; i++)
				{
					string arg = ((i < list.Count - 1) ? "," : "");
					stringBuilder.AppendLine($"\t\"{list[i].Key}\": {list[i].Value}{arg}");
				}
				stringBuilder.AppendLine("}");
				File.WriteAllText(JsonPath, stringBuilder.ToString());
			}
			catch
			{
			}
		}

		public static void LoadJson()
		{
			if (!File.Exists(JsonPath))
			{
				return;
			}
			try
			{
				string text = File.ReadAllText(JsonPath).Replace("{", "").Replace("}", "")
					.Trim();
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				string[] array = text.Split(',');
				foreach (string text2 in array)
				{
					string[] array2 = text2.Split(':');
					if (array2.Length == 2)
					{
						string key = array2[0].Trim().Trim('"');
						if (int.TryParse(array2[1].Trim(), out var result))
						{
							WeaponKillCounts[key] = result;
						}
					}
				}
			}
			catch
			{
			}
		}

		public static void RegisterKill(string name)
		{
			if (!string.IsNullOrEmpty(name) && !(name == "PredictedProjectile") && !(name == "PhysicsProp") && !(Time.time - lastKillTime < 0.05f))
			{
				if (!WeaponKillCounts.ContainsKey(name))
				{
					WeaponKillCounts[name] = 0;
				}
				WeaponKillCounts[name]++;
				lastKillTime = Time.time;
				SaveJson();
			}
		}

		public static string GetBestWeaponName(object instance)
		{
			if (instance == null)
			{
				return null;
			}
			Type type = instance.GetType();
			string text = TryGetField(instance, "weaponName");
			if (!string.IsNullOrEmpty(text))
			{
				return text;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, "behaviour");
			if (fieldInfo != null)
			{
				object value = fieldInfo.GetValue(instance);
				string text2 = TryGetField(value, "weaponName");
				if (!string.IsNullOrEmpty(text2))
				{
					return text2;
				}
			}
			Component val = (Component)((instance is Component) ? instance : null);
			if (val != null)
			{
				return Regex.Replace(((Object)val.gameObject).name, "\\(Clone\\)$", "");
			}
			return type.Name;
		}

		private static string TryGetField(object instance, string fieldName)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(instance.GetType(), fieldName);
				if (fieldInfo != null && fieldInfo.FieldType == typeof(string))
				{
					return (string)fieldInfo.GetValue(instance);
				}
				PropertyInfo propertyInfo = AccessTools.Property(instance.GetType(), fieldName);
				if (propertyInfo != null && propertyInfo.PropertyType == typeof(string))
				{
					return (string)propertyInfo.GetValue(instance, null);
				}
			}
			catch
			{
			}
			return null;
		}
	}
}