Decompiled source of EvilCompany v1.0.2

EvilCompany.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EvilCompany.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using LC_API.Networking;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EvilCompany")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Mess with your friends")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EvilCompany")]
[assembly: AssemblyTitle("EvilCompany")]
[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 EvilCompany
{
	[BepInPlugin("EvilCompany", "EvilCompany", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		public static Plugin Instance;

		public static readonly InputActionClass inputActionClass = new InputActionClass();

		public const string signature = "EvilCompany";

		public static int evilPoints;

		public static ulong targetID;

		public static bool isSyncedWithHost = false;

		public static int[] clientConfigVals = new int[8];

		public static bool isExecutingSomeone = false;

		public static bool isDamagingSomeone = false;

		public static bool isForcingSomeoneToCrouch = false;

		public static bool isDeletingSomeonesHeldItem = false;

		private static readonly Harmony harmony = new Harmony("EvilCompany");

		public static Config MyConfig { get; internal set; }

		public static bool canJump { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"More than one of the plugin EvilCompany is detected!");
			}
			Instance = this;
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(PlayerControllerBPatch));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(Config));
			Log = ((BaseUnityPlugin)this).Logger;
			canJump = true;
			MyConfig = new Config(((BaseUnityPlugin)this).Config);
			Network.RegisterAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin EvilCompany is loaded!");
		}

		[NetworkMessage("EvilCompany", false)]
		public static void EvilCompanyHandler(ulong sender, string data)
		{
			if (!BroadcastDataSanityCheck(data))
			{
				return;
			}
			string[] array = data.Split();
			if (array.Length < 3)
			{
				targetID = ulong.Parse(array[1]);
			}
			switch (array[0])
			{
			case "Kill":
				Log.LogInfo((object)"Received Kill broadcast!");
				isExecutingSomeone = true;
				break;
			case "Damage":
				Log.LogInfo((object)"Received Damage broadcast!");
				isDamagingSomeone = true;
				break;
			case "Crouch":
				Log.LogInfo((object)"Received Crouch broadcast!");
				isForcingSomeoneToCrouch = true;
				break;
			case "Delete":
				Log.LogInfo((object)"Received Delete broadcast!");
				isDeletingSomeonesHeldItem = true;
				break;
			case "NoJump":
				Log.LogInfo((object)"Received NoJump broadcast!");
				Log.LogInfo((object)("Attempting to prevent jump on target: " + targetID));
				if (PlayerControllerBPatch.actualClientID == targetID)
				{
					Log.LogInfo((object)"Preventing this player from jumping!");
					canJump = false;
				}
				break;
			case "Config":
				if (!PlayerControllerBPatch.isHost && !isSyncedWithHost)
				{
					Config.evilPointsStart.Value = int.Parse(array[1]);
					Config.evilPointsIncrement.Value = int.Parse(array[2]);
					Config.killCost.Value = int.Parse(array[3]);
					Config.damageCost.Value = int.Parse(array[4]);
					Config.damageAmount.Value = int.Parse(array[5]);
					Config.crouchCost.Value = int.Parse(array[6]);
					Config.deleteCost.Value = int.Parse(array[7]);
					Config.jumpCost.Value = int.Parse(array[8]);
					evilPoints = Config.evilPointsStart.Value;
					Log.LogInfo((object)"Synced config with host!");
				}
				break;
			default:
				Log.LogWarning((object)"Received unknown order!");
				break;
			}
		}

		public string PackBroadcastData(string[] dataStrings)
		{
			string text = string.Empty;
			foreach (string text2 in dataStrings)
			{
				text = text + text2 + " ";
			}
			Log.LogInfo((object)("Packed data: " + text.TrimEnd()));
			return text.TrimEnd();
		}

		private static bool BroadcastDataSanityCheck(string data)
		{
			string[] array = data.Split();
			if (array.Length < 2 || (array[0].Equals("Config") && array.Length < 9))
			{
				Log.LogError((object)"Missing data!");
				return false;
			}
			if (array.Length < 3)
			{
				try
				{
					ulong num = ulong.Parse(array[1]);
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
					Log.LogError((object)"Target string could not be parsed as ulong!");
					return false;
				}
			}
			else
			{
				for (int i = 0; i < array.Length; i++)
				{
					if (i != 0)
					{
						try
						{
							ulong num2 = ulong.Parse(array[i]);
						}
						catch (Exception ex2)
						{
							Log.LogError((object)ex2);
							Log.LogError((object)"Value string could not be parsed as ulong!");
							return false;
						}
					}
				}
			}
			return true;
		}

		public void ResetVars()
		{
			canJump = true;
		}

		public void IncrementEvilPoints()
		{
			evilPoints += Config.evilPointsIncrement.Value;
		}

		public static void ResetConfigVars()
		{
			Config.evilPointsStart.Value = clientConfigVals[0];
			Config.evilPointsIncrement.Value = clientConfigVals[1];
			Config.killCost.Value = clientConfigVals[2];
			Config.damageCost.Value = clientConfigVals[3];
			Config.damageAmount.Value = clientConfigVals[4];
			Config.crouchCost.Value = clientConfigVals[5];
			Config.deleteCost.Value = clientConfigVals[6];
			Config.jumpCost.Value = clientConfigVals[7];
		}
	}
	public class InputActionClass : LcInputActions
	{
		[InputAction("<Keyboard>/#(0)", Name = "Kill Key")]
		public InputAction KillKey { get; set; }

		[InputAction("<Keyboard>/#(9)", Name = "Damage Key")]
		public InputAction DamageKey { get; set; }

		[InputAction("<Keyboard>/#(8)", Name = "Force Crouch Key")]
		public InputAction CrouchKey { get; set; }

		[InputAction("<Keyboard>/#(7)", Name = "Delete Held Item Key")]
		public InputAction DeleteKey { get; set; }

		[InputAction("<Keyboard>/#(6)", Name = "No Jump Key")]
		public InputAction NoJumpKey { get; set; }

		[InputAction("<Keyboard>/#(5)", Name = "Debug Key")]
		public InputAction DebugKey { get; set; }
	}
	[Serializable]
	public class Config
	{
		public static ConfigEntry<int> evilPointsStart;

		public static ConfigEntry<int> evilPointsIncrement;

		public static ConfigEntry<int> killCost;

		public static ConfigEntry<int> damageCost;

		public static ConfigEntry<int> damageAmount;

		public static ConfigEntry<int> crouchCost;

		public static ConfigEntry<int> deleteCost;

		public static ConfigEntry<int> jumpCost;

		public Config(ConfigFile cfg)
		{
			evilPointsStart = cfg.Bind<int>("General", "Starting Evil Points", 0, "How much evil points you start the game with");
			evilPointsIncrement = cfg.Bind<int>("General", "Evil Points Increment", 1, "How much evil points you gain at the end of each round");
			killCost = cfg.Bind<int>("General", "Kill Cost", 10, "How much evil points you need to kill someone on command");
			damageCost = cfg.Bind<int>("General", "Damage Cost", 3, "How much evil points you need to damage someone on command");
			damageAmount = cfg.Bind<int>("General", "Damage Amount", 10, "How much damage a person takes from the damage command");
			crouchCost = cfg.Bind<int>("General", "Crouch Cost", 1, "How much evil points you need to force someone to crouch on command");
			deleteCost = cfg.Bind<int>("General", "Crouch Cost", 5, "How much evil points you need to delete someone's held item on command");
			jumpCost = cfg.Bind<int>("General", "No Jump Cost", 5, "How much evil points you need to prevent someone from jumping on command");
			Plugin.clientConfigVals[0] = evilPointsStart.Value;
			Plugin.clientConfigVals[1] = evilPointsIncrement.Value;
			Plugin.clientConfigVals[2] = killCost.Value;
			Plugin.clientConfigVals[3] = damageCost.Value;
			Plugin.clientConfigVals[4] = damageAmount.Value;
			Plugin.clientConfigVals[5] = crouchCost.Value;
			Plugin.clientConfigVals[6] = deleteCost.Value;
			Plugin.clientConfigVals[7] = jumpCost.Value;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "EvilCompany";

		public const string PLUGIN_NAME = "EvilCompany";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace EvilCompany.Patches
{
	internal class PlayerControllerBPatch
	{
		public static ulong actualClientID { get; private set; }

		public static bool isDead { get; private set; }

		public static bool isHost { get; private set; }

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void SetVars(PlayerControllerB __instance)
		{
			actualClientID = __instance.actualClientId;
			isDead = __instance.isPlayerDead;
			isHost = ((NetworkBehaviour)__instance).NetworkManager.IsHost;
			if (isHost)
			{
				Plugin.isSyncedWithHost = true;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		[HarmonyPostfix]
		private static void SetDeathBool(PlayerControllerB __instance)
		{
			isDead = __instance.isPlayerDead;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")]
		[HarmonyPrefix]
		private static bool AffectJump()
		{
			return Plugin.canJump;
		}
	}
	internal class StartOfRoundPatch
	{
		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		[HarmonyPostfix]
		private static void ResetCommands()
		{
			Plugin.Instance.ResetVars();
			Plugin.Instance.IncrementEvilPoints();
		}

		[HarmonyPatch(typeof(StartOfRound), "Update")]
		[HarmonyPostfix]
		private static void Broadcast(StartOfRound __instance)
		{
			if (Plugin.inputActionClass.KillKey.WasPressedThisFrame() && Plugin.evilPoints >= Config.killCost.Value)
			{
				Plugin.Log.LogInfo((object)"Broadcasting Kill message!");
				string targetedPlayer = GetTargetedPlayer(__instance);
				if (targetedPlayer.Equals(string.Empty))
				{
					Plugin.Log.LogInfo((object)"Player is not dead. Ignoring broadcast request...");
					return;
				}
				string[] dataStrings = new string[2] { "Kill", targetedPlayer };
				Network.Broadcast<string>("EvilCompany", Plugin.Instance.PackBroadcastData(dataStrings));
				Plugin.evilPoints -= Config.killCost.Value;
			}
			if (Plugin.inputActionClass.DamageKey.WasPressedThisFrame() && Plugin.evilPoints >= Config.damageCost.Value)
			{
				Plugin.Log.LogInfo((object)"Broadcasting Damage message!");
				string targetedPlayer2 = GetTargetedPlayer(__instance);
				if (targetedPlayer2.Equals(string.Empty))
				{
					Plugin.Log.LogInfo((object)"Player is not dead. Ignoring broadcast request...");
					return;
				}
				string[] dataStrings2 = new string[2] { "Damage", targetedPlayer2 };
				Network.Broadcast<string>("EvilCompany", Plugin.Instance.PackBroadcastData(dataStrings2));
				Plugin.evilPoints -= Config.damageCost.Value;
			}
			if (Plugin.inputActionClass.CrouchKey.WasPressedThisFrame() && Plugin.evilPoints >= Config.crouchCost.Value)
			{
				Plugin.Log.LogInfo((object)"Broadcasting Crouch message!");
				string targetedPlayer3 = GetTargetedPlayer(__instance);
				if (targetedPlayer3.Equals(string.Empty))
				{
					Plugin.Log.LogInfo((object)"Player is not dead. Ignoring broadcast request...");
					return;
				}
				string[] dataStrings3 = new string[2] { "Crouch", targetedPlayer3 };
				Network.Broadcast<string>("EvilCompany", Plugin.Instance.PackBroadcastData(dataStrings3));
				Plugin.evilPoints -= Config.crouchCost.Value;
			}
			if (Plugin.inputActionClass.DeleteKey.WasPressedThisFrame() && Plugin.evilPoints >= Config.deleteCost.Value)
			{
				Plugin.Log.LogInfo((object)"Broadcasting Delete message!");
				string targetedPlayer4 = GetTargetedPlayer(__instance);
				if (targetedPlayer4.Equals(string.Empty))
				{
					Plugin.Log.LogInfo((object)"Player is not dead. Ignoring broadcast request...");
					return;
				}
				string[] dataStrings4 = new string[2] { "Delete", targetedPlayer4 };
				Network.Broadcast<string>("EvilCompany", Plugin.Instance.PackBroadcastData(dataStrings4));
				Plugin.evilPoints -= Config.deleteCost.Value;
			}
			if (Plugin.inputActionClass.NoJumpKey.WasPressedThisFrame() && Plugin.evilPoints >= Config.jumpCost.Value)
			{
				Plugin.Log.LogInfo((object)"Broadcasting NoJump message!");
				string targetedPlayer5 = GetTargetedPlayer(__instance);
				if (targetedPlayer5.Equals(string.Empty))
				{
					Plugin.Log.LogInfo((object)"Player is not dead. Ignoring broadcast request...");
					return;
				}
				string[] dataStrings5 = new string[2] { "NoJump", targetedPlayer5 };
				Network.Broadcast<string>("EvilCompany", Plugin.Instance.PackBroadcastData(dataStrings5));
				Plugin.evilPoints -= Config.jumpCost.Value;
			}
			if (Plugin.inputActionClass.DebugKey.WasPressedThisFrame())
			{
				Plugin.Log.LogInfo((object)("Current Evil Points: " + Plugin.evilPoints));
				Plugin.Log.LogInfo((object)("Points needed to kill: " + Config.killCost.Value));
				Plugin.Log.LogInfo((object)("Points needed to damage: " + Config.damageCost.Value));
				Plugin.Log.LogInfo((object)("Points needed to force crouch/uncrouch: " + Config.crouchCost.Value));
				Plugin.Log.LogInfo((object)("Points needed to delete held item: " + Config.deleteCost.Value));
				Plugin.Log.LogInfo((object)("Points needed to prevent jumping: " + Config.jumpCost.Value));
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Update")]
		[HarmonyPostfix]
		private static void ActOnBroadcastOrder(StartOfRound __instance)
		{
			//IL_0117: 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_0284: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.isExecutingSomeone)
			{
				Plugin.Log.LogInfo((object)("Attempting to execute target: " + Plugin.targetID));
				PlayerControllerB[] allPlayerScripts = __instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if (!val.disconnectedMidGame && !val.isPlayerDead && !val.isPlayerControlled)
					{
						Plugin.Log.LogInfo((object)("Player " + val.actualClientId + " is not controlled by a player. Skipping..."));
					}
					else if (val.disconnectedMidGame || val.isPlayerDead)
					{
						Plugin.Log.LogInfo((object)("Player " + val.actualClientId + " is not in control of a body. Skipping..."));
					}
					else if (!val.isPlayerDead && val.actualClientId != Plugin.targetID)
					{
						Plugin.Log.LogInfo((object)("Player " + val.actualClientId + " is not targetted player. Skipping..."));
					}
					else
					{
						val.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0);
					}
				}
				Plugin.isExecutingSomeone = false;
				Plugin.targetID = 999uL;
			}
			if (Plugin.isDamagingSomeone)
			{
				Plugin.Log.LogInfo((object)("Attempting to damage target: " + Plugin.targetID));
				PlayerControllerB[] allPlayerScripts2 = __instance.allPlayerScripts;
				foreach (PlayerControllerB val2 in allPlayerScripts2)
				{
					if (!val2.disconnectedMidGame && !val2.isPlayerDead && !val2.isPlayerControlled)
					{
						Plugin.Log.LogInfo((object)("Player " + val2.actualClientId + " is not controlled by a player. Skipping..."));
					}
					else if (val2.disconnectedMidGame || val2.isPlayerDead)
					{
						Plugin.Log.LogInfo((object)("Player " + val2.actualClientId + " is not in control of a body. Skipping..."));
					}
					else if (!val2.isPlayerDead && val2.actualClientId != Plugin.targetID)
					{
						Plugin.Log.LogInfo((object)("Player " + val2.actualClientId + " is not targetted player. Skipping..."));
					}
					else
					{
						val2.DamagePlayer(Config.damageAmount.Value, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
					}
				}
				Plugin.isDamagingSomeone = false;
				Plugin.targetID = 999uL;
			}
			if (Plugin.isForcingSomeoneToCrouch)
			{
				Plugin.Log.LogInfo((object)("Attempting to force crouch target: " + Plugin.targetID));
				PlayerControllerB[] allPlayerScripts3 = __instance.allPlayerScripts;
				foreach (PlayerControllerB val3 in allPlayerScripts3)
				{
					if (!val3.disconnectedMidGame && !val3.isPlayerDead && !val3.isPlayerControlled)
					{
						Plugin.Log.LogInfo((object)("Player " + val3.actualClientId + " is not controlled by a player. Skipping..."));
					}
					else if (val3.disconnectedMidGame || val3.isPlayerDead)
					{
						Plugin.Log.LogInfo((object)("Player " + val3.actualClientId + " is not in control of a body. Skipping..."));
					}
					else if (!val3.isPlayerDead && val3.actualClientId != Plugin.targetID)
					{
						Plugin.Log.LogInfo((object)("Player " + val3.actualClientId + " is not targetted player. Skipping..."));
					}
					else
					{
						val3.Crouch(!__instance.localPlayerController.isCrouching);
					}
				}
				Plugin.isForcingSomeoneToCrouch = false;
				Plugin.targetID = 999uL;
			}
			if (!Plugin.isDeletingSomeonesHeldItem)
			{
				return;
			}
			Plugin.Log.LogInfo((object)("Attempting to delete held item of target: " + Plugin.targetID));
			PlayerControllerB[] allPlayerScripts4 = __instance.allPlayerScripts;
			foreach (PlayerControllerB val4 in allPlayerScripts4)
			{
				if (!val4.disconnectedMidGame && !val4.isPlayerDead && !val4.isPlayerControlled)
				{
					Plugin.Log.LogInfo((object)("Player " + val4.actualClientId + " is not controlled by a player. Skipping..."));
				}
				else if (val4.disconnectedMidGame || val4.isPlayerDead)
				{
					Plugin.Log.LogInfo((object)("Player " + val4.actualClientId + " is not in control of a body. Skipping..."));
				}
				else if (!val4.isPlayerDead && val4.actualClientId != Plugin.targetID)
				{
					Plugin.Log.LogInfo((object)("Player " + val4.actualClientId + " is not targetted player. Skipping..."));
				}
				else
				{
					val4.DespawnHeldObject();
				}
			}
			Plugin.isDeletingSomeonesHeldItem = false;
			Plugin.targetID = 999uL;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnEnable")]
		[HarmonyPostfix]
		private static void SetEvilPoints()
		{
			Plugin.evilPoints = Config.evilPointsStart.Value;
		}

		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		[HarmonyPostfix]
		private static void SyncConfig()
		{
			if (PlayerControllerBPatch.isHost)
			{
				string[] dataStrings = new string[9]
				{
					"Config",
					Config.evilPointsStart.Value.ToString(),
					Config.evilPointsIncrement.Value.ToString(),
					Config.killCost.Value.ToString(),
					Config.damageCost.Value.ToString(),
					Config.damageAmount.Value.ToString(),
					Config.crouchCost.Value.ToString(),
					Config.deleteCost.Value.ToString(),
					Config.jumpCost.Value.ToString()
				};
				Plugin.Log.LogInfo((object)"Syncing config with clients!");
				Network.Broadcast<string>("EvilCompany", Plugin.Instance.PackBroadcastData(dataStrings));
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPostfix]
		private static void ResetVars()
		{
			Plugin.isSyncedWithHost = false;
			Plugin.ResetConfigVars();
		}

		private static string GetTargetedPlayer(StartOfRound __instance)
		{
			if (!PlayerControllerBPatch.isDead)
			{
				return string.Empty;
			}
			return __instance.localPlayerController.spectatedPlayerScript.actualClientId.ToString();
		}
	}
}