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();
}
}
}