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 HarmonyLib; using Microsoft.CodeAnalysis; using TruckSafeZone.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] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 TruckSafeZone { [BepInPlugin("benjamin.trucksafezone", "TruckSafeZone", "1.0.0")] [BepInProcess("REPO.exe")] public class Plugin : BaseUnityPlugin { public const string Guid = "benjamin.trucksafezone"; public const string Name = "TruckSafeZone"; public const string Version = "1.0.0"; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry Enabled; internal static ConfigEntry BlindEnemies; internal static ConfigEntry BlockEnemyDamage; internal static ConfigEntry BlockAllDamage; internal static ConfigEntry PreventDeath; internal static ConfigEntry RepelEnemies; internal static ConfigEntry RepelRadius; internal static ConfigEntry RepelInterval; internal static ConfigEntry Verbose; private void Awake() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Master switch. Turn off to disable the safe zone entirely without uninstalling."); BlindEnemies = ((BaseUnityPlugin)this).Config.Bind("Safety", "BlindEnemies", true, "Enemies cannot see or register players standing inside the truck. HOST ONLY - enemy AI runs on the host."); BlockEnemyDamage = ((BaseUnityPlugin)this).Config.Bind("Safety", "BlockEnemyDamage", true, "Players inside the truck take no damage from enemies. Each player needs the mod for their own protection."); BlockAllDamage = ((BaseUnityPlugin)this).Config.Bind("Safety", "BlockAllDamage", false, "Block ALL damage inside the truck, including fall damage and friendly fire. Off by default so you can still hurt yourself being an idiot."); PreventDeath = ((BaseUnityPlugin)this).Config.Bind("Safety", "PreventDeath", true, "Last-resort catch: cancel instant-kill grabs (Robe, Apex Predator, etc.) if the player is inside the truck."); RepelEnemies = ((BaseUnityPlugin)this).Config.Bind("Repel", "RepelEnemies", true, "Force enemies that wander within RepelRadius of the truck to leave. HOST ONLY."); RepelRadius = ((BaseUnityPlugin)this).Config.Bind("Repel", "RepelRadius", 6f, new ConfigDescription("Radius in metres around the truck safety spawn point that enemies get pushed out of.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 30f), Array.Empty())); RepelInterval = ((BaseUnityPlugin)this).Config.Bind("Repel", "RepelInterval", 1f, new ConfigDescription("How often (seconds) to scan for enemies near the truck. Higher = cheaper.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 10f), Array.Empty())); Verbose = ((BaseUnityPlugin)this).Config.Bind("Debug", "Verbose", false, "Log every time the safe zone blocks something. Noisy."); _harmony = new Harmony("benjamin.trucksafezone"); _harmony.PatchAll(typeof(VisionPatch)); _harmony.PatchAll(typeof(DamagePatch)); _harmony.PatchAll(typeof(DeathPatch)); ((Component)this).gameObject.AddComponent(); Log.LogInfo((object)"TruckSafeZone v1.0.0 loaded. Truck is now a safe zone."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static void Trace(string msg) { if (Verbose != null && Verbose.Value) { Log.LogInfo((object)msg); } } } internal static class SafeZone { internal static bool IsPlayerSafe(PlayerAvatar player) { if (!Plugin.Enabled.Value) { return false; } if ((Object)(object)player == (Object)null) { return false; } if (!SemiFunc.RunIsLevel()) { return false; } RoomVolumeCheck roomVolumeCheck = player.RoomVolumeCheck; if ((Object)(object)roomVolumeCheck == (Object)null) { return false; } return roomVolumeCheck.inTruck; } internal static bool IsLocalPlayerSafe() { return IsPlayerSafe(PlayerAvatar.instance); } internal static bool TryGetTruckPosition(out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; TruckSafetySpawnPoint instance = TruckSafetySpawnPoint.instance; if ((Object)(object)instance == (Object)null) { return false; } position = ((Component)instance).transform.position; return true; } } internal class TruckZoneWatcher : MonoBehaviour { private float _timer; private void Update() { if (Plugin.Enabled.Value && Plugin.RepelEnemies.Value && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel()) { _timer -= Time.deltaTime; if (!(_timer > 0f)) { _timer = Plugin.RepelInterval.Value; Sweep(); } } } private void Sweep() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!SafeZone.TryGetTruckPosition(out var position)) { return; } float value = Plugin.RepelRadius.Value; if (value <= 0f) { return; } float num = value * value; Enemy[] array = Object.FindObjectsOfType(); foreach (Enemy val in array) { if ((Object)(object)val == (Object)null) { continue; } EnemyParent enemyParent = val.EnemyParent; if ((Object)(object)enemyParent == (Object)null || !enemyParent.Spawned || enemyParent.forceLeave) { continue; } Vector3 val2 = (((Object)(object)val.CenterTransform != (Object)null) ? val.CenterTransform.position : ((Component)val).transform.position) - position; if (!(((Vector3)(ref val2)).sqrMagnitude > num)) { if (val.HasVision && (Object)(object)val.Vision != (Object)null) { val.Vision.DisableVision(3f); } enemyParent.forceLeave = true; Plugin.Trace("[TruckSafeZone] Repelled '" + enemyParent.enemyName + "' from the truck."); } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "TruckSafeZone"; public const string PLUGIN_NAME = "TruckSafeZone"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace TruckSafeZone.Patches { [HarmonyPatch(typeof(EnemyVision))] internal static class VisionPatch { [HarmonyPrefix] [HarmonyPatch("VisionTrigger")] private static bool BeforeVisionTrigger(int playerID, PlayerAvatar player, bool culled, bool playerNear) { if (!Plugin.Enabled.Value || !Plugin.BlindEnemies.Value) { return true; } if (!SafeZone.IsPlayerSafe(player)) { return true; } Plugin.Trace("[TruckSafeZone] Suppressed vision trigger for " + player.playerName + " (in truck)."); return false; } } [HarmonyPatch(typeof(PlayerHealth))] internal static class DamagePatch { private static bool ShouldBlock(PlayerHealth health, int enemyIndex) { if (!Plugin.Enabled.Value) { return false; } if ((Object)(object)health == (Object)null) { return false; } if (!SafeZone.IsPlayerSafe(health.playerAvatar)) { return false; } bool flag = enemyIndex >= 0; if (Plugin.BlockAllDamage.Value) { return true; } if (flag) { return Plugin.BlockEnemyDamage.Value; } return false; } [HarmonyPrefix] [HarmonyPatch("Hurt")] private static bool BeforeHurt(PlayerHealth __instance, int damage, bool savingGrace, int enemyIndex, bool hurtByHeal) { if (!ShouldBlock(__instance, enemyIndex)) { return true; } Plugin.Trace($"[TruckSafeZone] Blocked {damage} damage (enemyIndex {enemyIndex}) - player in truck."); return false; } [HarmonyPrefix] [HarmonyPatch("HurtOther")] private static bool BeforeHurtOther(PlayerHealth __instance, int damage, Vector3 hurtPosition, bool savingGrace, int enemyIndex, bool hurtByHeal) { if (!ShouldBlock(__instance, enemyIndex)) { return true; } Plugin.Trace($"[TruckSafeZone] Blocked {damage} remote damage (enemyIndex {enemyIndex}) - player in truck."); return false; } } [HarmonyPatch(typeof(PlayerAvatar))] internal static class DeathPatch { [HarmonyPrefix] [HarmonyPatch("PlayerDeath")] private static bool BeforePlayerDeath(PlayerAvatar __instance, int enemyIndex) { if (!Plugin.Enabled.Value || !Plugin.PreventDeath.Value) { return true; } if (enemyIndex < 0) { return true; } if (!SafeZone.IsPlayerSafe(__instance)) { return true; } Plugin.Trace("[TruckSafeZone] Cancelled enemy kill on " + __instance.playerName + " - player in truck."); return false; } } }