Decompiled source of Zaprillator v1.0.2

Zaprillator.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using Zaprillator.Behaviors;
using Zaprillator.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sehelitar")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Sehelitar @ https://sehelitar.tv")]
[assembly: AssemblyDescription("Use your zapgun to turn your dead friend into a living one.")]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: AssemblyInformationalVersion("1.0.2+e958c1c767064a91860a7580fd36430376fb9681")]
[assembly: AssemblyProduct("Zaprillator")]
[assembly: AssemblyTitle("Zaprillator")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 Zaprillator
{
	[BepInPlugin("Zaprillator", "Zaprillator", "1.0.2")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		private static Harmony _globalHarmony;

		private static ManualLogSource Log { get; set; }

		internal static PluginConfigStruct GameConfig { get; private set; }

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Zaprillator is loaded! ;)");
			PatchNetwork();
			_globalHarmony = new Harmony("Zaprillator");
			_globalHarmony.PatchAll();
			PluginConfigStruct gameConfig = default(PluginConfigStruct);
			gameConfig.RequiresFullCharge = ((BaseUnityPlugin)this).Config.Bind<bool>("Revive", "RequiresFullCharge", false, "A full charge is required to revive a player.");
			gameConfig.RelativeHealth = ((BaseUnityPlugin)this).Config.Bind<bool>("Revive", "RelativeHealth", true, "Define if restored health is relative to the gun's charge.");
			GameConfig = gameConfig;
		}

		private static void PatchNetwork()
		{
			try
			{
				Type[] types = Assembly.GetExecutingAssembly().GetTypes();
				foreach (Type type in types)
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
						{
							Log.LogInfo((object)("Initialize network patch for " + type.FullName));
							methodInfo.Invoke(null, null);
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}
	}
	internal struct PluginConfigStruct
	{
		public ConfigEntry<bool> RequiresFullCharge;

		public ConfigEntry<bool> RelativeHealth;
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Zaprillator";

		public const string PLUGIN_NAME = "Zaprillator";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace Zaprillator.Patches
{
	[HarmonyPatch(typeof(PatcherTool))]
	internal class PatcherToolPatch
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ScanGunTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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)
			//IL_0067: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.FirstMethod(typeof(GameObject), (Func<MethodInfo, bool>)((MethodInfo m) => m.Name == "TryGetComponent" && m.GetParameters().Length == 1)).MakeGenericMethod(typeof(IShockableWithGun)), (string)null)
			}).ThrowIfInvalid("Call to GameObject.TryGetComponent not found!").Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatcherToolPatch), "TryGetShockableWithGun", (Type[])null, (Type[])null))
				.ThrowIfInvalid("Could not patch PatcherTool.ScanGun!")
				.InstructionEnumeration();
		}

		private static bool TryGetShockableWithGun(GameObject obj, out Component component)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			component = (Component)obj.GetComponentInChildren<IShockableWithGun>();
			return (Object)(object)component != (Object)null;
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start(ref PatcherTool __instance)
		{
			PatcherTool obj = __instance;
			obj.anomalyMask |= 0x100000;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake()
		{
			GameObject val = (from o in Resources.FindObjectsOfTypeAll<GameObject>()
				where ((Object)o).name == "RagdollGrabbableObject"
				select o).FirstOrDefault();
			if (((val != null) ? val.gameObject.GetComponent<RevivablePlayer>() : null) == null && val != null)
			{
				val.gameObject.AddComponent<RevivablePlayer>();
			}
		}
	}
}
namespace Zaprillator.Behaviors
{
	[RequireComponent(typeof(RagdollGrabbableObject))]
	internal class RevivablePlayer : NetworkBehaviour, IShockableWithGun
	{
		private RagdollGrabbableObject _ragdoll;

		private bool _bodyShocked;

		private GrabbableObject _shockedBy;

		private float _batteryLevel;

		private void Start()
		{
			_ragdoll = ((Component)this).gameObject.GetComponent<RagdollGrabbableObject>();
		}

		bool IShockableWithGun.CanBeShocked()
		{
			return (Object)(object)_ragdoll != (Object)null;
		}

		float IShockableWithGun.GetDifficultyMultiplier()
		{
			return 0.1f;
		}

		NetworkObject IShockableWithGun.GetNetworkObject()
		{
			return ((NetworkBehaviour)this).NetworkObject;
		}

		Vector3 IShockableWithGun.GetShockablePosition()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position;
		}

		Transform IShockableWithGun.GetShockableTransform()
		{
			return ((Component)this).transform;
		}

		void IShockableWithGun.ShockWithGun(PlayerControllerB shockedByPlayer)
		{
			_bodyShocked = true;
			RoundManager.Instance.FlickerLights(false, false);
			if (((NetworkBehaviour)shockedByPlayer).IsOwner)
			{
				_shockedBy = shockedByPlayer.currentlyHeldObjectServer;
				if (_shockedBy is PatcherTool)
				{
					_batteryLevel = _shockedBy.insertedBattery.charge;
					((MonoBehaviour)this).StartCoroutine(AutoStopShocking());
				}
			}
		}

		private IEnumerator AutoStopShocking()
		{
			yield return (object)new WaitForSeconds(1f);
			PatcherTool val = (PatcherTool)_shockedBy;
			if ((int)val != 0)
			{
				val.StopShockingAnomalyOnClient(false);
			}
		}

		void IShockableWithGun.StopShockingWithGun()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (_bodyShocked)
			{
				_bodyShocked = false;
				RoundManager.Instance.FlickerLights(false, false);
				if (!((Object)(object)_shockedBy == (Object)null))
				{
					int health = Mathf.RoundToInt(_batteryLevel * 100f);
					_shockedBy.UseUpBatteries();
					_shockedBy.SyncBatteryServerRpc(0);
					_shockedBy = null;
					RevivePlayerAtServerRpc(_ragdoll.ragdoll.playerScript.actualClientId, ((Component)_ragdoll.ragdoll).transform.position, health);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void RevivePlayerAtServerRpc(ulong clientId, Vector3 position, int health)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2354502692u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref position);
				BytePacker.WriteValueBitPacked(val2, health);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2354502692u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && (!Plugin.GameConfig.RequiresFullCharge.Value || health >= 100))
			{
				if (!Plugin.GameConfig.RelativeHealth.Value)
				{
					health = 100;
				}
				RevivePlayerAtClientRpc(clientId, position, health);
			}
		}

		[ClientRpc]
		private void RevivePlayerAtClientRpc(ulong clientId, Vector3 position, int health)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1265580350u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref position);
				BytePacker.WriteValueBitPacked(val2, health);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1265580350u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				ulong clientId2 = clientId;
				PlayerControllerB val3 = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB playerScript) => playerScript.actualClientId == clientId2).FirstOrDefault();
				if ((Object)(object)val3 != (Object)null)
				{
					((MonoBehaviour)StartOfRound.Instance).StartCoroutine(RevivePlayerCoroutine(val3, position + new Vector3(0f, 0.5f, 0f), health));
				}
			}
		}

		private static IEnumerator RevivePlayerCoroutine(PlayerControllerB targetPlayer, Vector3? reviveAt = null, int health = 100)
		{
			if (!targetPlayer.isPlayerDead)
			{
				yield break;
			}
			int num = Array.IndexOf(StartOfRound.Instance.allPlayerScripts, targetPlayer);
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			bool flag = (Object)(object)targetPlayer == (Object)(object)localPlayerController;
			targetPlayer.ResetPlayerBloodObjects(targetPlayer.isPlayerDead);
			targetPlayer.isClimbingLadder = false;
			targetPlayer.ResetZAndXRotation();
			((Collider)targetPlayer.thisController).enabled = true;
			targetPlayer.health = health;
			targetPlayer.disableLookInput = false;
			targetPlayer.isPlayerDead = false;
			targetPlayer.isPlayerControlled = true;
			targetPlayer.isInElevator = true;
			targetPlayer.isInHangarShipRoom = true;
			targetPlayer.isInsideFactory = false;
			if (flag)
			{
				StartOfRound.Instance.SetPlayerObjectExtrapolate(false);
			}
			targetPlayer.TeleportPlayer((Vector3)(((??)reviveAt) ?? StartOfRound.Instance.GetPlayerSpawnPosition(num, false)), false, 0f, false, true);
			targetPlayer.setPositionOfDeadPlayer = false;
			targetPlayer.DisablePlayerModel(StartOfRound.Instance.allPlayerObjects[num], true, true);
			((Behaviour)targetPlayer.helmetLight).enabled = false;
			targetPlayer.Crouch(false);
			targetPlayer.criticallyInjured = false;
			Animator playerBodyAnimator = targetPlayer.playerBodyAnimator;
			if (playerBodyAnimator != null)
			{
				playerBodyAnimator.SetBool("Limp", false);
			}
			targetPlayer.bleedingHeavily = false;
			targetPlayer.activatingItem = false;
			targetPlayer.twoHanded = false;
			targetPlayer.inSpecialInteractAnimation = false;
			targetPlayer.disableSyncInAnimation = false;
			targetPlayer.inAnimationWithEnemy = null;
			targetPlayer.holdingWalkieTalkie = false;
			targetPlayer.speakingToWalkieTalkie = false;
			targetPlayer.isSinking = false;
			targetPlayer.isUnderwater = false;
			targetPlayer.sinkingValue = 0f;
			targetPlayer.statusEffectAudio.Stop();
			targetPlayer.DisableJetpackControlsLocally();
			targetPlayer.health = health;
			targetPlayer.mapRadarDotAnimator.SetBool("dead", false);
			if (((NetworkBehaviour)targetPlayer).IsOwner && flag)
			{
				HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false);
				targetPlayer.hasBegunSpectating = false;
				HUDManager.Instance.RemoveSpectateUI();
				HUDManager.Instance.gameOverAnimator.SetTrigger("revive");
				targetPlayer.hinderedMultiplier = 1f;
				targetPlayer.isMovementHindered = 0;
				targetPlayer.sourcesCausingSinking = 0;
				targetPlayer.reverbPreset = StartOfRound.Instance.shipReverb;
			}
			if (flag)
			{
				SoundManager.Instance.earsRingingTimer = 0f;
			}
			targetPlayer.voiceMuffledByEnemy = false;
			SoundManager.Instance.playerVoicePitchTargets[num] = 1f;
			SoundManager.Instance.SetPlayerPitch(1f, num);
			if ((Object)(object)targetPlayer.currentVoiceChatIngameSettings == (Object)null)
			{
				StartOfRound.Instance.RefreshPlayerVoicePlaybackObjects();
			}
			if ((Object)(object)targetPlayer.currentVoiceChatIngameSettings != (Object)null)
			{
				if ((Object)(object)targetPlayer.currentVoiceChatIngameSettings.voiceAudio == (Object)null)
				{
					targetPlayer.currentVoiceChatIngameSettings.InitializeComponents();
				}
				if ((Object)(object)targetPlayer.currentVoiceChatIngameSettings.voiceAudio == (Object)null)
				{
					yield break;
				}
				((Component)targetPlayer.currentVoiceChatIngameSettings.voiceAudio).GetComponent<OccludeAudio>().overridingLowPass = false;
			}
			if (flag)
			{
				HUDManager.Instance.UpdateHealthUI(100, false);
				localPlayerController.spectatedPlayerScript = null;
				((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false;
				StartOfRound.Instance.SetSpectateCameraToGameOverMode(false, localPlayerController);
			}
			RagdollGrabbableObject[] array = Object.FindObjectsOfType<RagdollGrabbableObject>();
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i].ragdoll.playerScript == (Object)(object)targetPlayer && ((GrabbableObject)array[i]).isHeld && (Object)(object)((GrabbableObject)array[i]).playerHeldBy != (Object)null)
				{
					((GrabbableObject)array[i]).playerHeldBy.DropAllHeldItems(true, false);
				}
			}
			DeadBodyInfo[] array2 = Object.FindObjectsOfType<DeadBodyInfo>();
			foreach (DeadBodyInfo val in array2)
			{
				if ((Object)(object)val.playerScript == (Object)(object)targetPlayer)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			StartOfRound instance = StartOfRound.Instance;
			instance.livingPlayers++;
			StartOfRound.Instance.UpdatePlayerVoiceEffects();
			if (flag)
			{
				yield return (object)new WaitForSeconds(2f);
				HUDManager.Instance.HideHUD(false);
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_RevivablePlayer()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2354502692u, new RpcReceiveHandler(__rpc_handler_2354502692));
			NetworkManager.__rpc_func_table.Add(1265580350u, new RpcReceiveHandler(__rpc_handler_1265580350));
		}

		private static void __rpc_handler_2354502692(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				Vector3 position = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref position);
				int health = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref health);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((RevivablePlayer)(object)target).RevivePlayerAtServerRpc(clientId, position, health);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1265580350(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				Vector3 position = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref position);
				int health = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref health);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RevivablePlayer)(object)target).RevivePlayerAtClientRpc(clientId, position, health);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "RevivablePlayer";
		}
	}
}
namespace Zaprillator.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}