using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("HQFixes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HQFixes")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fa30484b-ab56-4d52-8f67-67fdfe4948a4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HQFixes;
[BepInPlugin("chboo1.lethalcompany.hqfixes", "High Quota Fixes", "1.56.5")]
public class HQFixes : BaseUnityPlugin
{
public const string subVersion = "5";
public static float timeSinceGrabbing = -1f;
public static float timeSinceThrowing = -1f;
public const string fact = "If bread is playing, HQFixes.timeSinceThrowing should always = 0, don't know what bug makes it not happen.";
public const string fact2 = "Why are you reading this?";
public const string fact3 = "If you are, DM me on discord and tell me if you like potatoes. I kind of wonder how often I'll get DMs about potatoes. I might not remember I wrote this, so make sure to remind me.";
public const string fact4 = "Boo!";
public const string funfact = "I actually have code that's a couple months old for a fix to bracken camping, which I'm too scared too delete but also elected that it's a little too dramatic to implement, so it's now permanently a comment.";
public static float timeSinceSpiderCheck = -1f;
public static bool inShipByCar = false;
public static ConfigEntry<bool> webFixOn;
public static ConfigEntry<bool> interactFixOn;
public static ConfigEntry<bool> QEFixOn;
public static ConfigEntry<bool> salesWeatherRerollFixOn;
public static ConfigEntry<bool> MechDesyncFixOn;
public static ConfigEntry<bool> CruiserTeleportFixOn;
public static ConfigEntry<bool> CruiserMagnetLagFixOn;
public static ConfigEntry<bool> CruiserMurderAuraFixOn;
public static ManualLogSource logger;
public void Awake()
{
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
logger = Logger.CreateLogSource("chboo1.lethalcompany.hqfixes");
webFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableWebFix", true, "Whether to enable the web bug fix");
interactFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableInteractFix", true, "Whether to enable the interact bug fix");
QEFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableQELockFix", true, "Whether to enable the QE lock bug fix");
salesWeatherRerollFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableSalesAndWeatherRerollPatch", true, "Whether to disallow sales and weather rerolls.");
MechDesyncFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableMechDesyncFix", true, "Whether to enable the Old bird Desync bug fix");
CruiserTeleportFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableCruiserTeleportFix", true, "Whether to enable the fix for inconsistency on teleporting into the ship from a magneted cruiser.");
CruiserMagnetLagFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableCruiserMagnetLagFix", true, "Whether to enable the fix for lagspikes when magneting cruiser.");
CruiserMurderAuraFixOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General.Toggles", "EnableCruiserMurderAuraFix", true, "Whether to enable the fix for cruiser instakilling players upon demagnetizing.");
Harmony harmony = new Harmony("chboo1.lethalcompany.hqfixes");
FixFolder fixFolder = new HQFixesv49();
fixFolder.OnBoot();
fixFolder.PatchFixes(harmony);
FixFolder fixFolder2 = new HQFixesv50();
fixFolder2.OnBoot();
fixFolder2.PatchFixes(harmony);
FixFolder fixFolder3 = new HQFixesv56();
fixFolder3.OnBoot();
fixFolder3.PatchFixes(harmony);
if (Random.Range(0, 100) == 0)
{
switch (Random.Range(0, 100))
{
case 0:
logger.LogInfo((object)"HQFixes: Removing Bog Crawler...");
break;
case 1:
logger.LogInfo((object)"HQFixes: Removing Goopy Goblin...");
break;
case 2:
logger.LogInfo((object)"HQFixes: Adding John back into v62...");
break;
case 3:
logger.LogInfo((object)"HQFixes: Retroactively adding Jeff into every version of Lethal Company...");
break;
case 4:
logger.LogInfo((object)"HQFixes: Leaking Zeekerss' private beta code...");
break;
case 5:
logger.LogInfo((object)("HQFixes: " + Random.Range(1, 256) + "." + Random.Range(0, 256) + "." + Random.Range(0, 256) + "." + Random.Range(0, 256)));
break;
case 6:
((BaseUnityPlugin)this).Logger.LogInfo((object)"HQFixes: Hacking into your computer and removing every occurence of the letter F in your hard drive...");
break;
default:
logger.LogInfo((object)"HQFixes: I shat my pants");
break;
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("HQ Fixes: Web Bug Fix is " + (webFixOn.Value ? "On" : "Off") + "!"));
((BaseUnityPlugin)this).Logger.LogInfo((object)("HQ Fixes: Interact Bug Fix is " + (interactFixOn.Value ? "On" : "Off") + "!"));
((BaseUnityPlugin)this).Logger.LogInfo((object)("HQ Fixes: QE Lock Fix is " + (QEFixOn.Value ? "On" : "Off") + "!"));
((BaseUnityPlugin)this).Logger.LogInfo((object)("HQ Fixes: Old Bird Desync Fix is " + (MechDesyncFixOn.Value ? "On" : "Off") + "!"));
((BaseUnityPlugin)this).Logger.LogInfo((object)("HQ Fixes: Cruiser Teleport Fix is " + (CruiserTeleportFixOn.Value ? "On" : "Off") + "!"));
((BaseUnityPlugin)this).Logger.LogInfo((object)("HQ Fixes: Cruiser Magnet Lag Fix is " + (CruiserMagnetLagFixOn.Value ? "On" : "Off") + "!"));
((BaseUnityPlugin)this).Logger.LogInfo((object)"HQ Fixes is loaded!");
}
}
public class HQFixesPatches
{
}
public class Fix
{
public Type type;
public string func;
public bool enabled;
public MethodInfo specificPrefix = null;
public MethodInfo specificPostfix = null;
public Fix(Type patchType, string funcName, bool config)
{
type = patchType;
func = funcName;
enabled = config;
}
public Fix(Type patchType, string funcName, bool config, FixFolder parent)
{
type = patchType;
func = funcName;
enabled = config;
if (parent.fixes == null)
{
parent.fixes = new List<Fix>();
}
parent.fixes.Add(this);
}
public Fix(Type patchType, string funcName, bool config, MethodInfo pre, MethodInfo post)
{
type = patchType;
func = funcName;
enabled = config;
specificPrefix = pre;
specificPostfix = post;
}
public Fix(Type patchType, string funcName, bool config, FixFolder parent, MethodInfo pre, MethodInfo post)
{
type = patchType;
func = funcName;
enabled = config;
specificPrefix = pre;
specificPostfix = post;
if (parent.fixes == null)
{
parent.fixes = new List<Fix>();
}
parent.fixes.Add(this);
}
}
public class FixFolder
{
internal List<Fix> fixes;
public void PatchFixes(Harmony harmony)
{
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_0289: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
HQFixes.logger.LogInfo((object)("HQFixes: Patching in bundle [" + GetType().Name + "]"));
if (fixes == null)
{
HQFixes.logger.LogInfo((object)"HQFixes: Bundle fixes was null!");
return;
}
foreach (Fix fix in fixes)
{
if (fix == null)
{
HQFixes.logger.LogInfo((object)"Fix is null!");
}
else
{
if (!fix.enabled)
{
continue;
}
HQFixes.logger.LogInfo((object)("HQFixes: Attempting to patch " + fix.type.Name + "." + fix.func));
MethodInfo methodInfo = AccessTools.Method(fix.type, fix.func, (Type[])null, (Type[])null);
if (methodInfo == null)
{
continue;
}
HQFixes.logger.LogInfo((object)"Found original!");
if (fix.specificPostfix != null || fix.specificPrefix != null)
{
if (fix.specificPostfix != null)
{
HQFixes.logger.LogInfo((object)"Using specific postfix!");
if (fix.specificPrefix != null)
{
HQFixes.logger.LogInfo((object)"Using specific prefix!");
}
}
else
{
HQFixes.logger.LogInfo((object)"Using specific prefix!");
}
object obj = harmony;
obj = methodInfo;
obj = (object)((!(fix.specificPrefix != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(fix.specificPrefix));
obj = (object)((!(fix.specificPostfix != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(fix.specificPostfix));
((Harmony)obj).Patch((MethodBase)obj, (HarmonyMethod)obj, (HarmonyMethod)obj, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
continue;
}
MethodInfo methodInfo2 = AccessTools.Method(GetType(), fix.type.Name + "_" + fix.func + "_Prefix", (Type[])null, (Type[])null);
MethodInfo methodInfo3 = AccessTools.Method(GetType(), fix.type.Name + "_" + fix.func + "_Postfix", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
HQFixes.logger.LogInfo((object)"Found a prefix!");
}
if (methodInfo3 != null)
{
HQFixes.logger.LogInfo((object)"Found a postfix!");
}
object obj2 = harmony;
obj2 = methodInfo;
obj2 = (object)((!(methodInfo2 != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(methodInfo2));
obj2 = (object)((!(methodInfo3 != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(methodInfo3));
((Harmony)obj2).Patch((MethodBase)obj2, (HarmonyMethod)obj2, (HarmonyMethod)obj2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
}
public virtual void OnBoot()
{
}
}
public class HQFixesv49 : FixFolder
{
public static int randomSeed;
public override void OnBoot()
{
new Fix(typeof(SandSpiderAI), "RemoveWeb", HQFixes.webFixOn.Value, this);
new Fix(typeof(GrabbableObject), "PocketItem", HQFixes.QEFixOn.Value, this);
new Fix(typeof(EntranceTeleport), "TeleportPlayer", HQFixes.webFixOn.Value, this, null, AccessTools.Method(typeof(HQFixesv49), "ResetHinderedPrefix", (Type[])null, (Type[])null));
new Fix(typeof(PlayerControllerB), "TeleportPlayer", HQFixes.webFixOn.Value, this, null, AccessTools.Method(typeof(HQFixesv49), "ResetHinderedPrefix", (Type[])null, (Type[])null));
new Fix(typeof(PlayerControllerB), "Update", HQFixes.webFixOn.Value || HQFixes.interactFixOn.Value, this);
new Fix(typeof(StartOfRound), "OpenShipDoors", config: true, this);
new Fix(typeof(PlayerControllerB), "DiscardHeldObject", HQFixes.interactFixOn.Value, this);
new Fix(typeof(StartOfRound), "ResetShip", HQFixes.salesWeatherRerollFixOn.Value, this);
new Fix(typeof(StartOfRound), "StartGame", HQFixes.salesWeatherRerollFixOn.Value, this);
}
public static void StartOfRound_ResetShip_Postfix(ref StartOfRound __instance)
{
if (((NetworkBehaviour)__instance).IsServer)
{
__instance.randomMapSeed = 0;
}
}
public static void StartOfRound_StartGame_Prefix(ref StartOfRound __instance)
{
randomSeed = __instance.randomMapSeed;
}
public static void StartOfRound_StartGame_Postfix(ref StartOfRound __instance)
{
if (!__instance.currentLevel.spawnEnemiesAndScrap && ((NetworkBehaviour)__instance).IsServer)
{
__instance.randomMapSeed = randomSeed;
}
}
public static void GrabbableObject_PocketItem_Prefix(ref PlayerControllerB ___playerHeldBy)
{
if (!((Object)(object)___playerHeldBy == (Object)null))
{
___playerHeldBy.equippedUsableItemQE = false;
}
}
public static void StartOfRound_OpenShipDoors_Prefix(StartOfRound __instance)
{
HQFixes.logger.LogInfo((object)("HQFixes: Random Map Seed is " + __instance.randomMapSeed));
}
public static void SandSpiderAI_RemoveWeb_Postfix(int trapID, List<SandSpiderWebTrap> ___webTraps)
{
if (!((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) && (Object)(object)___webTraps[trapID] != (Object)null && (Object)(object)___webTraps[trapID].currentTrappedPlayer == (Object)(object)StartOfRound.Instance.localPlayerController)
{
PlayerControllerB currentTrappedPlayer = ___webTraps[trapID].currentTrappedPlayer;
currentTrappedPlayer.hinderedMultiplier *= 0.8f;
}
}
public static void ResetHinderedPrefix()
{
if (!((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null))
{
StartOfRound.Instance.localPlayerController.hinderedMultiplier = 1f;
StartOfRound.Instance.localPlayerController.isMovementHindered = 0;
}
}
public static bool PlayerControllerB_DiscardHeldItem_Prefix(PlayerControllerB __instance)
{
if (!((NetworkBehaviour)__instance).IsOwner)
{
return true;
}
if ((Object)(object)__instance.currentlyHeldObjectServer == (Object)null)
{
return false;
}
return true;
}
public static void PlayerControllerB_Update_Postfix(ref PlayerControllerB __instance)
{
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.localPlayerController == (Object)null || (Object)(object)__instance != (Object)(object)StartOfRound.Instance.localPlayerController)
{
return;
}
if (HQFixes.webFixOn.Value)
{
__instance.hinderedMultiplier = Mathf.Max(1f, __instance.hinderedMultiplier);
if (HQFixes.timeSinceSpiderCheck < 0f || Time.realtimeSinceStartup - HQFixes.timeSinceSpiderCheck > 1f)
{
HQFixes.timeSinceSpiderCheck = Time.realtimeSinceStartup;
SandSpiderWebTrap[] array = Object.FindObjectsOfType<SandSpiderWebTrap>();
float num = -1f;
SandSpiderWebTrap[] array2 = array;
foreach (SandSpiderWebTrap val in array2)
{
float num2 = Vector3.SqrMagnitude(((Component)val).transform.position - ((Component)__instance).transform.position);
if (num > num2 || num < 0f)
{
num = num2;
if (num2 < 25f)
{
break;
}
}
if (num2 > 25f && (bool)AccessTools.Field(typeof(SandSpiderWebTrap), "hinderingLocalPlayer").GetValue(val))
{
AccessTools.Method(typeof(SandSpiderWebTrap), "PlayerLeaveWeb", (Type[])null, (Type[])null).Invoke(val, new object[1] { __instance });
}
}
if (num > 25f && __instance.isInsideFactory)
{
__instance.isMovementHindered = 0;
__instance.hinderedMultiplier = 1f;
}
}
}
if (!HQFixes.interactFixOn.Value)
{
return;
}
if (__instance.isGrabbingObjectAnimation)
{
if (HQFixes.timeSinceGrabbing < 0f)
{
HQFixes.timeSinceGrabbing = Time.realtimeSinceStartup;
}
else if (Time.realtimeSinceStartup - HQFixes.timeSinceGrabbing > 1f)
{
__instance.isGrabbingObjectAnimation = false;
HQFixes.timeSinceGrabbing = -1f;
}
}
else
{
HQFixes.timeSinceGrabbing = -1f;
}
}
}
public class HQFixesv50 : FixFolder
{
public override void OnBoot()
{
new Fix(typeof(RadMechAI), "LateUpdate", HQFixes.MechDesyncFixOn.Value, this);
}
public static void RadMechAI_LateUpdate_Postfix(ref RadMechAI __instance)
{
if (((EnemyAI)__instance).currentBehaviourStateIndex != 2)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(RadMechAI), "finishingFlight");
if ((bool)fieldInfo.GetValue(__instance))
{
fieldInfo.SetValue(__instance, false);
}
FieldInfo fieldInfo2 = AccessTools.Field(typeof(RadMechAI), "inFlyingMode");
if ((bool)fieldInfo2.GetValue(__instance))
{
fieldInfo2.SetValue(__instance, false);
((EnemyAI)__instance).inSpecialAnimation = false;
}
}
}
}
public class HQFixesv56 : FixFolder
{
public static List<VehicleController> cars;
public static bool carsCleared = false;
public static int currentCarCount = -1;
public static float timeSinceRefreshCruiser = 0f;
public static float timeSinceDemagnet = 0f;
public static VehicleController lastCarMagneted = null;
public override void OnBoot()
{
cars = new List<VehicleController>();
new Fix(typeof(ElevatorAnimationEvents), "ElevatorFullyRunning", HQFixes.CruiserTeleportFixOn.Value, this);
new Fix(typeof(StartOfRound), "Update", HQFixes.CruiserMagnetLagFixOn.Value, this);
new Fix(typeof(VehicleController), "LateUpdate", HQFixes.CruiserMagnetLagFixOn.Value || HQFixes.CruiserMurderAuraFixOn.Value, this);
new Fix(typeof(VehicleController), "CollectItemsInTruck", HQFixes.CruiserMagnetLagFixOn.Value, this);
new Fix(typeof(GrabbableObject), "Update", HQFixes.CruiserMagnetLagFixOn.Value, this);
new Fix(typeof(VehicleController), "OnTriggerEnter", HQFixes.CruiserMurderAuraFixOn.Value, this);
new Fix(typeof(StartOfRound), "SetMagnetOn", HQFixes.CruiserMurderAuraFixOn.Value, this);
}
public static void StartOfRound_Update_Postfix()
{
if (!(Time.realtimeSinceStartup - timeSinceRefreshCruiser < 1f))
{
timeSinceRefreshCruiser = Time.realtimeSinceStartup;
carsCleared = true;
currentCarCount = cars.Count;
cars.Clear();
}
}
public static void VehicleController_LateUpdate_Postfix(VehicleController __instance)
{
if (HQFixes.CruiserMagnetLagFixOn.Value)
{
if (!cars.Contains(__instance))
{
cars.Add(__instance);
}
if (cars.Count >= currentCarCount)
{
carsCleared = false;
}
}
if (HQFixes.CruiserMurderAuraFixOn.Value && __instance.magnetedToShip)
{
lastCarMagneted = __instance;
}
}
public static void StartOfRound_SetMagnetOn_Prefix(bool on)
{
if (!on)
{
timeSinceDemagnet = Time.realtimeSinceStartup;
}
}
public static bool VehicleController_OnTriggerEnter_Prefix(VehicleController __instance)
{
return (Object)(object)__instance != (Object)(object)lastCarMagneted || (double)timeSinceDemagnet > 0.2;
}
public static void GrabbableObject_Update_Postfix(GrabbableObject __instance)
{
if (carsCleared || (Object)(object)__instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || cars == null)
{
return;
}
foreach (VehicleController car in cars)
{
if ((Object)(object)car != (Object)null && (Object)(object)((Component)__instance).transform.parent == (Object)(object)((Component)car).transform)
{
if (car.magnetedToShip != __instance.isInShipRoom && !__instance.isHeld && !__instance.isHeldByEnemy)
{
GameNetworkManager.Instance.localPlayerController.SetItemInElevator(car.magnetedToShip, car.magnetedToShip, __instance);
}
break;
}
}
}
public static bool VehicleController_CollectItemsInTruck_Prefix()
{
return false;
}
public static void ElevatorAnimationEvents_ElevatorFullyRunning_Prefix()
{
if (!HQFixes.CruiserTeleportFixOn.Value || (Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
{
return;
}
VehicleController val = Object.FindObjectOfType<VehicleController>();
if ((Object)(object)val == (Object)null)
{
return;
}
if (((Object)(object)((Component)GameNetworkManager.Instance.localPlayerController).transform.parent != (Object)null && (Object)(object)((Component)GameNetworkManager.Instance.localPlayerController).transform.parent == (Object)(object)((Component)val).transform) || ((Object)(object)val.currentPassenger != (Object)null && (Object)(object)val.currentPassenger == (Object)(object)GameNetworkManager.Instance.localPlayerController) || ((Object)(object)val.currentDriver != (Object)null && (Object)(object)val.currentDriver == (Object)(object)GameNetworkManager.Instance.localPlayerController))
{
HQFixes.logger.LogInfo((object)"Player is in cruiser!");
if (!GameNetworkManager.Instance.localPlayerController.isInElevator && val.magnetedToShip)
{
HQFixes.inShipByCar = true;
GameNetworkManager.Instance.localPlayerController.isInElevator = true;
}
}
HQFixes.logger.LogInfo((object)("Ship is leaving! Is in ship from car? " + (HQFixes.inShipByCar ? "Yes" : "No")));
}
public static void ElevatorAnimationEvents_ElevatorFullyRunning_Postfix()
{
if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
{
if (HQFixes.inShipByCar)
{
GameNetworkManager.Instance.localPlayerController.isInElevator = false;
}
HQFixes.inShipByCar = false;
}
}
}