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 GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using RenderCaves.Patches; 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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.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 RenderCaves { [BepInPlugin("com.sygent.rendercaves.lethalcompany", "RenderCaves", "1.0.0")] public class RenderCavesPlugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry EnableCaveRendering; internal static ConfigEntry HideLostSignalUI; internal static ConfigEntry FixOcclusionCulling; internal static ConfigEntry VerboseLogging; private Harmony _harmony; private void Awake() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; EnableCaveRendering = ((BaseUnityPlugin)this).Config.Bind("General", "EnableCaveRendering", true, "When true, prevents the game from disabling the bodycam (headMountedCam) when the targeted player is in the Mineshaft caves. This is the core fix."); HideLostSignalUI = ((BaseUnityPlugin)this).Config.Bind("General", "HideLostSignalUI", true, "When true, prevents the 'Lost Signal' / 'No Signal' UI overlay from appearing when the targeted player is in caves."); FixOcclusionCulling = ((BaseUnityPlugin)this).Config.Bind("General", "FixOcclusionCulling", true, "When true, forces the occlusion culler to update to the spectated player's position when they are inside the factory. This ensures cave geometry is loaded and rendered for the spectator."); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "VerboseLogging", false, "Enable detailed logging of patch activity. Useful for debugging."); _harmony = new Harmony("com.sygent.rendercaves.lethalcompany"); _harmony.PatchAll(typeof(BodycamCavePatch)); _harmony.PatchAll(typeof(OcclusionCullerPatch)); Log.LogInfo((object)"RenderCaves v1.0.0 loaded! Cave bodycam rendering enabled."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class PluginInfo { public const string PLUGIN_GUID = "com.sygent.rendercaves.lethalcompany"; public const string PLUGIN_NAME = "RenderCaves"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace RenderCaves.Patches { [HarmonyPatch(typeof(ManualCameraRenderer))] internal class BodycamCavePatch { [HarmonyPatch("LateUpdate")] [HarmonyPostfix] private static void LateUpdate_Postfix(ManualCameraRenderer __instance) { if (!RenderCavesPlugin.EnableCaveRendering.Value) { return; } try { if ((Object)(object)__instance.headMountedCam == (Object)null || !AccessTools.FieldRefAccess(__instance, "playerIsInCaves")) { return; } bool flag = AccessTools.FieldRefAccess(__instance, "enableHeadMountedCam"); if (!((Object)(object)__instance.targetedPlayer == (Object)null) || flag) { ((Behaviour)__instance.headMountedCam).enabled = true; ((Behaviour)__instance.headMountedCamUI).enabled = true; if (RenderCavesPlugin.VerboseLogging.Value) { string text = (((Object)(object)__instance.targetedPlayer != (Object)null) ? __instance.targetedPlayer.playerUsername : "unknown"); RenderCavesPlugin.Log.LogDebug((object)("[RenderCaves] Re-enabled bodycam for cave player: " + text)); } } } catch (Exception arg) { RenderCavesPlugin.Log.LogError((object)$"[RenderCaves] LateUpdate_Postfix error: {arg}"); } } [HarmonyPatch("MeetsCameraEnabledConditions")] [HarmonyPostfix] private static void MeetsCameraEnabledConditions_Postfix(ManualCameraRenderer __instance, bool __result) { if (!RenderCavesPlugin.HideLostSignalUI.Value) { return; } try { if (!((Object)(object)__instance.LostSignalUI == (Object)null) && AccessTools.FieldRefAccess(__instance, "playerIsInCaves") && __instance.LostSignalUI.activeSelf) { __instance.LostSignalUI.SetActive(false); if (RenderCavesPlugin.VerboseLogging.Value) { RenderCavesPlugin.Log.LogDebug((object)"[RenderCaves] Suppressed LostSignalUI for cave player"); } } } catch (Exception arg) { RenderCavesPlugin.Log.LogError((object)$"[RenderCaves] MeetsCameraEnabledConditions_Postfix error: {arg}"); } } } [HarmonyPatch(typeof(StartOfRound))] internal class OcclusionCullerPatch { [HarmonyPatch("UpdateOcclusionCuller")] [HarmonyPostfix] private static void UpdateOcclusionCuller_Postfix(StartOfRound __instance) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!RenderCavesPlugin.FixOcclusionCulling.Value) { return; } try { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null || !val.isPlayerDead) { return; } PlayerControllerB spectatedPlayerScript = val.spectatedPlayerScript; if (!((Object)(object)spectatedPlayerScript == (Object)null) && spectatedPlayerScript.isInsideFactory && (Object)(object)__instance.audioListener != (Object)null && ((Component)__instance.audioListener).transform.position.y >= -80f) { __instance.SetOcclusionCullerToPosition(((Component)__instance.audioListener).transform.position); if (RenderCavesPlugin.VerboseLogging.Value) { RenderCavesPlugin.Log.LogDebug((object)("[RenderCaves] Updated occlusion culler for spectated player '" + spectatedPlayerScript.playerUsername + "' at " + $"{((Component)__instance.audioListener).transform.position}")); } } } catch (Exception arg) { RenderCavesPlugin.Log.LogError((object)$"[RenderCaves] UpdateOcclusionCuller_Postfix error: {arg}"); } } } }