Decompiled source of JetpackFixes v1.5.4

JetpackFixes.dll

Decompiled a week ago
using System;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("JetpackFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Fixes some (lethal) bugs with the jetpack")]
[assembly: AssemblyFileVersion("1.5.4.0")]
[assembly: AssemblyInformationalVersion("1.5.4+2a0fcf0d260bf270e3e3679ed1ecb7b7bf9a3859")]
[assembly: AssemblyProduct("JetpackFixes")]
[assembly: AssemblyTitle("JetpackFixes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.4.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 JetpackFixes
{
	internal static class LobbyCompatibility
	{
		internal static void Init()
		{
			PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.jetpackfixes", Version.Parse("1.5.4"), (CompatibilityLevel)0, (VersionStrictness)0);
		}
	}
	internal enum MidAirExplosions
	{
		Off = -1,
		OnlyTooHigh,
		Always
	}
	[BepInPlugin("butterystancakes.lethalcompany.jetpackfixes", "Jetpack Fixes", "1.5.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.jetpackfixes";

		internal const string PLUGIN_NAME = "Jetpack Fixes";

		internal const string PLUGIN_VERSION = "1.5.4";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<MidAirExplosions> configMidAirExplosions;

		internal static ConfigEntry<bool> configTransferMomentum;

		private const string GUID_JETPACK_WARNING = "JetpackWarning";

		private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility";

		internal static bool DISABLE_BEEP_PATCH;

		private void Awake()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected");
				LobbyCompatibility.Init();
			}
			if (Chainloader.PluginInfos.ContainsKey("JetpackWarning"))
			{
				DISABLE_BEEP_PATCH = true;
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - Jetpack Warning detected");
			}
			configMidAirExplosions = ((BaseUnityPlugin)this).Config.Bind<MidAirExplosions>("Misc", "MidAirExplosions", MidAirExplosions.OnlyTooHigh, "When should high speeds (exceeding 50u/s, vanilla's \"speed limit\") explode the jetpack?\n\"Off\" will only explode when you crash into something solid.\n\"OnlyTooHigh\" will explode if you are flying too fast, while you are also *extremely* high above the terrain.\n\"Always\" will explode any time you are flying too fast. (Most similar to vanilla's behavior)");
			configTransferMomentum = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "TransferMomentum", false, "When dropping the jetpack, instead of immediately coming to a stop, you will maintain the same direction and speed.");
			if (configMidAirExplosions.Value == MidAirExplosions.OnlyTooHigh)
			{
				if (!((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "BecomeFirework", true, "Legacy setting, use \"MidAirExplosions\" instead").Value)
				{
					configMidAirExplosions.Value = MidAirExplosions.Off;
				}
				((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Misc", "BecomeFirework"].Definition);
				((BaseUnityPlugin)this).Config.Save();
			}
			new Harmony("butterystancakes.lethalcompany.jetpackfixes").PatchAll();
			Logger.LogInfo((object)"Jetpack Fixes v1.5.4 loaded");
		}
	}
	[HarmonyPatch]
	internal class JetpackFixesPatches
	{
		private const float SAFE_HEIGHT = 110.55537f;

		private const float MIN_DEATH_SPEED = 50f;

		private const float MAX_DEATH_SPEED = 54f;

		private static EnemyType flowerSnakeEnemy;

		[HarmonyPatch(typeof(JetpackItem), "Update")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> JetpackItem_Trans_Update(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			List<CodeInstruction> list = instructions.ToList();
			LayerMask val = LayerMask.op_Implicit(-1111789641);
			val = LayerMask.op_Implicit(LayerMask.op_Implicit(val) & ~(1 << LayerMask.NameToLayer("PlaceableShipObjects")));
			val = LayerMask.op_Implicit(LayerMask.op_Implicit(val) | (1 << LayerMask.NameToLayer("Terrain")));
			val = LayerMask.op_Implicit(LayerMask.op_Implicit(val) & ~(1 << LayerMask.NameToLayer("InteractableObject")));
			FieldInfo fieldInfo = AccessTools.Field(typeof(JetpackItem), "jetpackPower");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(JetpackItem), "rayHit");
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(StartOfRound), "allPlayersCollideWithMask");
			for (int i = 1; i < list.Count - 3; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 10f && list[i - 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 1].operand == fieldInfo)
				{
					list[i + 1].opcode = OpCodes.Bgt_Un;
					Plugin.Logger.LogDebug((object)"Transpiler: Reverse jetpackPower comparison on isGrounded check (allows for sliding)");
				}
				else if (list[i].opcode == OpCodes.Ldflda && (FieldInfo)list[i].operand == fieldInfo2)
				{
					if (list[i + 1].opcode == OpCodes.Ldc_R4 && (float)list[i + 1].operand == 25f)
					{
						list[i + 1].operand = 4f;
						Plugin.Logger.LogDebug((object)"Transpiler: Reduce raycast range from 25 to 4");
					}
					else if (list[i + 2].opcode == OpCodes.Ldc_R4 && (float)list[i + 2].operand == 4f)
					{
						for (int num = i + 3; num >= i - 1; num--)
						{
							list.RemoveAt(num);
						}
						Plugin.Logger.LogDebug((object)"Transpiler: Remove 4 unit distance check (redundant)");
					}
				}
				else if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == fieldInfo3)
				{
					list[i].opcode = OpCodes.Ldc_I4;
					list[i].operand = LayerMask.op_Implicit(val);
					list.RemoveAt(i - 1);
					Plugin.Logger.LogDebug((object)"Transpiler: Replace layer mask with custom");
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(JetpackItem), "Update")]
		[HarmonyPostfix]
		private static void JetpackItem_Post_Update(JetpackItem __instance)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
			{
				return;
			}
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController && !((GrabbableObject)__instance).playerHeldBy.isPlayerDead && __instance.jetpackActivated && ((GrabbableObject)__instance).playerHeldBy.jetpackControls)
			{
				if (__instance.jetpackPower > 10f)
				{
					float magnitude = ((Vector3)(ref __instance.forces)).magnitude;
					if (magnitude > 50f)
					{
						if (magnitude > 54f && (Plugin.configMidAirExplosions.Value == MidAirExplosions.Always || (Plugin.configMidAirExplosions.Value == MidAirExplosions.OnlyTooHigh && ((Component)__instance).transform.position.y > 110.55537f)))
						{
							((GrabbableObject)__instance).playerHeldBy.KillPlayer(__instance.forces, true, (CauseOfDeath)2, 0, default(Vector3));
							if (Plugin.configMidAirExplosions.Value == MidAirExplosions.Always)
							{
								Plugin.Logger.LogDebug((object)"Player killed from flying too fast");
							}
							else
							{
								Plugin.Logger.LogDebug((object)$"Player killed from flying too fast while too high (Altitude: {((Component)__instance).transform.position.y} > {110.55537f})");
							}
						}
						else if (((GrabbableObject)__instance).playerHeldBy.thisController.isGrounded)
						{
							((GrabbableObject)__instance).playerHeldBy.KillPlayer(__instance.forces, true, (CauseOfDeath)2, 0, default(Vector3));
							Plugin.Logger.LogDebug((object)"Player killed from touching ground while flying too fast");
						}
					}
				}
				if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null)
				{
					if (((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle >= 0f && ((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle < 360f)
					{
						((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle = float.MaxValue;
						((GrabbableObject)__instance).playerHeldBy.jetpackRandomIntensity = 60f;
						Plugin.Logger.LogDebug((object)"Uncap player rotation (using jetpack while tulip snakes riding)");
					}
					if (((GrabbableObject)__instance).playerHeldBy.isInElevator && (Object)(object)((Component)((GrabbableObject)__instance).playerHeldBy).transform.parent == (Object)(object)StartOfRound.Instance.elevatorTransform && StartOfRound.Instance.shipDoorsEnabled && ((GrabbableObject)__instance).playerHeldBy.parentedToElevatorLastFrame)
					{
						Bounds bounds = StartOfRound.Instance.shipBounds.bounds;
						if (!((Bounds)(ref bounds)).Contains(((Component)__instance).transform.position))
						{
							((GrabbableObject)__instance).playerHeldBy.parentedToElevatorLastFrame = false;
							((GrabbableObject)__instance).playerHeldBy.isInElevator = false;
							((GrabbableObject)__instance).playerHeldBy.isInHangarShipRoom = false;
							((Component)((GrabbableObject)__instance).playerHeldBy).transform.SetParent(StartOfRound.Instance.playersContainer);
							Plugin.Logger.LogDebug((object)"Player flew off of ship, change parent off the ship");
						}
					}
				}
			}
			((GrabbableObject)__instance).isBeingUsed = __instance.jetpackActivated;
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null))
			{
				return;
			}
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController || (GameNetworkManager.Instance.localPlayerController.isPlayerDead && (Object)(object)GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript != (Object)null && (Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript))
			{
				if (__instance.jetpackAudio.dopplerLevel != 0f || __instance.jetpackBeepsAudio.dopplerLevel != 0f)
				{
					__instance.jetpackAudio.dopplerLevel = 0f;
					__instance.jetpackBeepsAudio.dopplerLevel = 0f;
					Plugin.Logger.LogDebug((object)("Jetpack held by " + (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController) ? "you" : "spectate target") + ", disable doppler effect"));
				}
			}
			else if (__instance.jetpackAudio.dopplerLevel != 1f || __instance.jetpackBeepsAudio.dopplerLevel != 1f)
			{
				__instance.jetpackAudio.dopplerLevel = 1f;
				__instance.jetpackBeepsAudio.dopplerLevel = 1f;
				Plugin.Logger.LogDebug((object)"Jetpack held by other player, enable doppler effect");
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		[HarmonyPrefix]
		private static void PlayerControllerB_Pre_DamagePlayer(PlayerControllerB __instance, ref int damageNumber, CauseOfDeath causeOfDeath)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)causeOfDeath == 2 && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController && __instance.jetpackControls && __instance.averageVelocity >= 50f)
			{
				Plugin.Logger.LogInfo((object)$"Player took {damageNumber} \"Gravity\" damage while flying too fast; should be instant death");
				damageNumber = Mathf.Max(100, __instance.health);
			}
		}

		[HarmonyPatch(typeof(JetpackItem), "EquipItem")]
		[HarmonyPostfix]
		private static void JetpackItem_Post_EquipItem(JetpackItem __instance)
		{
			((GrabbableObject)__instance).useCooldown = 0f;
		}

		[HarmonyPatch(typeof(JetpackItem), "DeactivateJetpack")]
		[HarmonyPostfix]
		private static void JetpackItem_Post_DeactivateJetpack(JetpackItem __instance)
		{
			if ((Object)(object)__instance.previousPlayerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController || !__instance.previousPlayerHeldBy.disablingJetpackControls || !((Object)(object)flowerSnakeEnemy != (Object)null) || flowerSnakeEnemy.numberSpawned <= 0)
			{
				return;
			}
			int num = flowerSnakeEnemy.numberSpawned;
			foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
			{
				FlowerSnakeEnemy val = (FlowerSnakeEnemy)(object)((spawnedEnemy is FlowerSnakeEnemy) ? spawnedEnemy : null);
				if ((Object)(object)val != (Object)null)
				{
					num--;
					if (!((EnemyAI)val).isEnemyDead && (Object)(object)val.clingingToPlayer == (Object)(object)__instance.previousPlayerHeldBy && val.flightPower > 0f)
					{
						val.clingingToPlayer.disablingJetpackControls = false;
						val.clingingToPlayer.maxJetpackAngle = float.MaxValue;
						val.clingingToPlayer.jetpackRandomIntensity = 60f;
						Plugin.Logger.LogDebug((object)"Jetpack disabled, but tulip snake is still carrying");
						break;
					}
					if (num <= 0)
					{
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(FlowerSnakeEnemy), "SetFlappingLocalClient")]
		[HarmonyPostfix]
		private static void FlowerSnakeEnemy_Post_SetFlappingLocalClient(FlowerSnakeEnemy __instance, bool isMainSnake)
		{
			if (!isMainSnake || (Object)(object)__instance.clingingToPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController || !__instance.clingingToPlayer.disablingJetpackControls)
			{
				return;
			}
			for (int i = 0; i < __instance.clingingToPlayer.ItemSlots.Length; i++)
			{
				if (!((Object)(object)__instance.clingingToPlayer.ItemSlots[i] == (Object)null) && !__instance.clingingToPlayer.ItemSlots[i].isPocketed)
				{
					GrabbableObject obj = __instance.clingingToPlayer.ItemSlots[i];
					JetpackItem val = (JetpackItem)(object)((obj is JetpackItem) ? obj : null);
					if ((Object)(object)val != (Object)null && val.jetpackActivated)
					{
						__instance.clingingToPlayer.disablingJetpackControls = false;
						__instance.clingingToPlayer.maxJetpackAngle = -1f;
						__instance.clingingToPlayer.jetpackRandomIntensity = 0f;
						Plugin.Logger.LogInfo((object)"Player still using jetpack when tulip snake dropped; re-enable flight controls");
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(FlowerSnakeEnemy), "Start")]
		[HarmonyPostfix]
		private static void FlowerSnakeEnemy_Post_Start(FlowerSnakeEnemy __instance)
		{
			if ((Object)(object)flowerSnakeEnemy == (Object)null)
			{
				flowerSnakeEnemy = ((EnemyAI)__instance).enemyType;
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPostfix]
		private static void GameNetworkManager_Post_Disconnect()
		{
			flowerSnakeEnemy = null;
		}

		[HarmonyPatch(typeof(JetpackItem), "DiscardItem")]
		[HarmonyPostfix]
		private static void JetpackItem_Post_DiscardItem(JetpackItem __instance)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.configTransferMomentum.Value && !__instance.previousPlayerHeldBy.isPlayerDead && __instance.previousPlayerHeldBy.jetpackControls && ((Vector3)(ref __instance.forces)).magnitude > 0f)
			{
				PlayerControllerB previousPlayerHeldBy = __instance.previousPlayerHeldBy;
				previousPlayerHeldBy.externalForceAutoFade += new Vector3(__instance.forces.x, __instance.forces.y * __instance.verticalMultiplier, __instance.forces.z);
				Plugin.Logger.LogDebug((object)"Player dropped jetpack while flying, fling them!");
			}
			__instance.forces = Vector3.zero;
		}

		[HarmonyPatch(typeof(JetpackItem), "SetJetpackAudios")]
		[HarmonyPrefix]
		private static bool JetpackItem_SetJetpackAudios(JetpackItem __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.DISABLE_BEEP_PATCH)
			{
				return true;
			}
			if (__instance.jetpackActivated)
			{
				if (__instance.noiseInterval >= 0.5f)
				{
					__instance.noiseInterval = 0f;
					RoundManager.Instance.PlayAudibleNoise(((Component)__instance).transform.position, 25f, 0.85f, 0, ((GrabbableObject)__instance).playerHeldBy.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed, 41);
				}
				else
				{
					__instance.noiseInterval += Time.deltaTime;
				}
				if (((GrabbableObject)__instance).insertedBattery.charge < 0.15f)
				{
					if ((Object)(object)__instance.jetpackBeepsAudio.clip != (Object)(object)__instance.jetpackLowBatteriesSFX)
					{
						__instance.jetpackBeepsAudio.Stop();
						__instance.jetpackBeepsAudio.clip = __instance.jetpackLowBatteriesSFX;
					}
					if (!__instance.jetpackBeepsAudio.isPlaying)
					{
						__instance.jetpackBeepsAudio.Play();
					}
				}
				else
				{
					if ((Object)(object)__instance.jetpackBeepsAudio.clip != (Object)(object)__instance.jetpackWarningBeepSFX)
					{
						__instance.jetpackBeepsAudio.Stop();
						__instance.jetpackBeepsAudio.clip = __instance.jetpackWarningBeepSFX;
					}
					if (Physics.CheckSphere(((Component)__instance).transform.position, 6f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
					{
						if (!__instance.jetpackBeepsAudio.isPlaying)
						{
							__instance.jetpackBeepsAudio.Play();
						}
					}
					else
					{
						__instance.jetpackBeepsAudio.Stop();
					}
				}
			}
			else
			{
				__instance.jetpackBeepsAudio.Stop();
			}
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "JetpackFixes";

		public const string PLUGIN_NAME = "JetpackFixes";

		public const string PLUGIN_VERSION = "1.5.4";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}