Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BunkbedRevive v1.0.1
BunkbedRevive.dll
Decompiled 13 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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 BunkbedRevive.Configuration; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BunkbedRevive")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BunkbedRevive")] [assembly: AssemblyTitle("BunkbedRevive")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.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 BunkbedRevive { public class BunkbedController : MonoBehaviour { private static InteractTrigger interactTrigger; private static Sprite defaultIcon; private static Sprite disabledIcon; public static BunkbedController Instance; public static int GetReviveCost() { return ModConfig.ReviveCost.Value; } public static bool HasDeadPlayers() { if ((Object)(object)StartOfRound.Instance == (Object)null) { return false; } return StartOfRound.Instance.connectedPlayersAmount + 1 - StartOfRound.Instance.livingPlayers > 0; } private static void CreateTrigger() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_006a: 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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown GameObject val = new GameObject("ReviveBed", new Type[2] { typeof(BoxCollider), typeof(InteractTrigger) }); val.transform.SetParent(((Component)Instance).transform); val.transform.localPosition = Vector3.zero; val.layer = LayerMask.NameToLayer("InteractableObject"); val.tag = "InteractTrigger"; BoxCollider component = val.GetComponent<BoxCollider>(); component.center = Vector3.zero; component.size = new Vector3(2.5f, 3f, 1f); ((Collider)component).enabled = true; interactTrigger = val.GetComponent<InteractTrigger>(); interactTrigger.twoHandedItemAllowed = true; interactTrigger.interactable = true; interactTrigger.holdInteraction = false; interactTrigger.timeToHold = 0.4f; interactTrigger.cooldownTime = 0.25f; interactTrigger.timeToHoldSpeedMultiplier = 1f; int reviveCost = GetReviveCost(); interactTrigger.hoverTip = "Revive for " + ((reviveCost <= 0) ? "free" : (reviveCost + " credits")) + " : [E]"; interactTrigger.hoverIcon = defaultIcon; interactTrigger.disabledHoverIcon = disabledIcon; interactTrigger.disabledHoverTip = "No dead players"; interactTrigger.onCancelAnimation = new InteractEvent(); interactTrigger.holdingInteractEvent = new InteractEventFloat(); interactTrigger.onInteractEarly = new InteractEvent(); interactTrigger.onInteract = new InteractEvent(); interactTrigger.onStopInteract = new InteractEvent(); ((UnityEvent<PlayerControllerB>)(object)interactTrigger.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate { OnInteract(); }); ((UnityEvent<PlayerControllerB>)(object)interactTrigger.onStopInteract).AddListener((UnityAction<PlayerControllerB>)delegate { OnStopInteract(); }); } private static void GetIcons() { StartMatchLever val = Object.FindObjectOfType<StartMatchLever>(); if ((Object)(object)val != (Object)null) { defaultIcon = val.triggerScript.hoverIcon; disabledIcon = val.triggerScript.disabledHoverIcon; } } private static RagdollGrabbableObject GetHeldBody() { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (!localPlayerController.isHoldingObject || (Object)(object)localPlayerController.currentlyHeldObjectServer == (Object)null) { return null; } GrabbableObject currentlyHeldObjectServer = localPlayerController.currentlyHeldObjectServer; RagdollGrabbableObject val = (RagdollGrabbableObject)(object)((currentlyHeldObjectServer is RagdollGrabbableObject) ? currentlyHeldObjectServer : null); if (val != null) { return val; } return null; } private void Awake() { Instance = this; GetIcons(); CreateTrigger(); } private void Update() { if (!((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)) { bool flag = HasDeadPlayers(); RagdollGrabbableObject heldBody = GetHeldBody(); interactTrigger.interactable = flag && (Object)(object)heldBody != (Object)null; if ((Object)(object)heldBody != (Object)null) { string text = (((Object)(object)heldBody.ragdoll != (Object)null) ? heldBody.ragdoll.playerScript.playerUsername : "Player"); int reviveCost = GetReviveCost(); interactTrigger.hoverTip = "Revive " + text + " for " + ((reviveCost <= 0) ? "free" : (reviveCost + " credits")) + " : [E]"; } } } public static void OnInteract() { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; RagdollGrabbableObject heldBody = GetHeldBody(); if ((Object)(object)heldBody == (Object)null) { return; } int reviveCost = GetReviveCost(); Terminal val = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val != (Object)null && val.groupCredits < reviveCost) { BunkbedRevivePlugin.Log.LogMessage((object)"Not enough credits for revive"); interactTrigger.StopInteraction(); return; } if ((Object)(object)val != (Object)null) { val.groupCredits -= reviveCost; val.SyncGroupCreditsServerRpc(val.groupCredits, val.numberOfItemsInDropship); } BunkbedNetworking.RevivePlayerServerRpc(heldBody.bodyID); if ((Object)(object)localPlayerController != (Object)null) { localPlayerController.DespawnHeldObject(); } string text = (((Object)(object)heldBody.ragdoll != (Object)null) ? heldBody.ragdoll.playerScript.playerUsername : "Player"); BunkbedRevivePlugin.Log.LogMessage((object)(text + " has been revived")); } private static void OnStopInteract() { int reviveCost = GetReviveCost(); interactTrigger.hoverTip = "Revive for " + ((reviveCost <= 0) ? "free" : (reviveCost + " credits")) + " : [E]"; } public static void RevivePlayer(int playerId) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId]; if ((Object)(object)val == (Object)null) { return; } bool isPlayerDead = val.isPlayerDead; val.ResetPlayerBloodObjects(isPlayerDead); if (isPlayerDead) { val.isPlayerDead = false; val.isPlayerControlled = true; val.isInElevator = true; val.isInHangarShipRoom = true; val.isInsideFactory = false; val.health = 100; val.criticallyInjured = false; val.bleedingHeavily = false; val.setPositionOfDeadPlayer = false; val.deadBody = null; val.isClimbingLadder = false; val.clampLooking = false; val.inVehicleAnimation = false; val.disableMoveInput = false; val.disableLookInput = false; val.disableInteract = false; val.ResetZAndXRotation(); ((Collider)val.thisController).enabled = true; StartOfRound.Instance.SetPlayerObjectExtrapolate(false); Vector3 position = StartOfRound.Instance.playerSpawnPositions[playerId].position; val.TeleportPlayer(position, false, 0f, false, true); if ((Object)(object)val.playerBodyAnimator != (Object)null) { val.playerBodyAnimator.SetBool("Limp", false); } } StartOfRound instance = StartOfRound.Instance; instance.livingPlayers++; StartOfRound.Instance.allPlayersDead = false; ((Renderer)val.thisPlayerModel).enabled = true; ((Renderer)val.thisPlayerModelLOD1).enabled = true; ((Renderer)val.thisPlayerModelLOD2).enabled = true; if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController) { val.health = 100; val.hasBegunSpectating = false; val.hinderedMultiplier = 1f; val.isMovementHindered = 0; val.sourcesCausingSinking = 0; val.criticallyInjured = false; val.bleedingHeavily = false; val.isSinking = false; val.isUnderwater = false; val.sinkingValue = 0f; val.statusEffectAudio.Stop(); val.DisableJetpackControlsLocally(); HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false); HUDManager.Instance.RemoveSpectateUI(); HUDManager.Instance.gameOverAnimator.SetTrigger("revive"); HUDManager.Instance.HideHUD(false); HUDManager.Instance.UpdateHealthUI(100, false); val.spectatedPlayerScript = null; ((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false; StartOfRound.Instance.SetSpectateCameraToGameOverMode(false, val); TimeOfDay.Instance.DisableAllWeather(false); StartOfRound.Instance.UpdatePlayerVoiceEffects(); val.reverbPreset = StartOfRound.Instance.shipReverb; SoundManager.Instance.earsRingingTimer = 0f; SoundManager.Instance.playerVoicePitchTargets[playerId] = 1f; SoundManager.Instance.SetPlayerPitch(1f, playerId); } } } public static class BunkbedNetworking { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__HandleReviveRequest; public static HandleNamedMessageDelegate <1>__HandleReviveBroadcast; } private const string ReviveServerMsg = "BunkbedRevive.ReviveServer"; private const string ReviveClientMsg = "BunkbedRevive.ReviveClient"; public static void Init() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager; object obj = <>O.<0>__HandleReviveRequest; if (obj == null) { HandleNamedMessageDelegate val = HandleReviveRequest; <>O.<0>__HandleReviveRequest = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("BunkbedRevive.ReviveServer", (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager; object obj2 = <>O.<1>__HandleReviveBroadcast; if (obj2 == null) { HandleNamedMessageDelegate val2 = HandleReviveBroadcast; <>O.<1>__HandleReviveBroadcast = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("BunkbedRevive.ReviveClient", (HandleNamedMessageDelegate)obj2); BunkbedRevivePlugin.Log.LogInfo((object)"BunkbedRevive networking initialized"); } public static void Cleanup() { if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.CustomMessagingManager != null) { NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("BunkbedRevive.ReviveServer"); NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("BunkbedRevive.ReviveClient"); } } public static void RevivePlayerServerRpc(int playerId) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { BroadcastRevive(playerId); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1); ((FastBufferWriter)(ref val)).WriteValue<int>(ref playerId, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("BunkbedRevive.ReviveServer", 0uL, val, (NetworkDelivery)2); } private static void HandleReviveRequest(ulong clientId, FastBufferReader reader) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) int playerId = default(int); ((FastBufferReader)(ref reader)).ReadValue<int>(ref playerId, default(ForPrimitives)); BroadcastRevive(playerId); } private static void BroadcastRevive(int playerId) { //IL_0045: 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_0065: Unknown result type (might be due to invalid IL or missing references) BunkbedController.RevivePlayer(playerId); PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController != (Object)null && localPlayerController.isHoldingObject && localPlayerController.currentlyHeldObjectServer is RagdollGrabbableObject) { localPlayerController.DespawnHeldObject(); } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1); ((FastBufferWriter)(ref val)).WriteValue<int>(ref playerId, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("BunkbedRevive.ReviveClient", (IReadOnlyList<ulong>)GetClientIds(), val, (NetworkDelivery)2); } private static List<ulong> GetClientIds() { List<ulong> list = new List<ulong>(); if (NetworkManager.Singleton.ConnectedClientsList != null) { foreach (NetworkClient connectedClients in NetworkManager.Singleton.ConnectedClientsList) { list.Add(connectedClients.ClientId); } } return list; } private static void HandleReviveBroadcast(ulong clientId, FastBufferReader reader) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) int playerId = default(int); ((FastBufferReader)(ref reader)).ReadValue<int>(ref playerId, default(ForPrimitives)); BunkbedController.RevivePlayer(playerId); } } [BepInPlugin("com.user.BunkbedRevive", "BunkbedRevive", "1.0.1")] public sealed class BunkbedRevivePlugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.user.BunkbedRevive"); public static BunkbedRevivePlugin Instance; public static ManualLogSource Log { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModConfig.Init(); harmony.PatchAll(); Log.LogInfo((object)"BunkbedRevive v1.0.1 loaded!"); } } } namespace BunkbedRevive.Patches { [HarmonyPatch(typeof(RagdollGrabbableObject))] public class RagdollGrabbableObjectPatch { [HarmonyPatch("Start")] [HarmonyPrefix] private static void StartPatch(RagdollGrabbableObject __instance) { ((GrabbableObject)__instance).itemProperties.weight = ModConfig.BodyWeight.Value; } } [HarmonyPatch(typeof(StartOfRound))] public class StartOfRoundPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(StartOfRound __instance) { BunkbedNetworking.Init(); int bunkBedId = __instance.unlockablesList.unlockables.FindIndex((UnlockableItem un) => un.unlockableName.IndexOf("bunkbeds", StringComparison.CurrentCultureIgnoreCase) >= 0); if (bunkBedId >= 0) { PlaceableShipObject val = ((IEnumerable<PlaceableShipObject>)Object.FindObjectsOfType<PlaceableShipObject>()).FirstOrDefault((Func<PlaceableShipObject, bool>)((PlaceableShipObject pc) => pc.unlockableID == bunkBedId)); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject.GetComponent<BunkbedController>() == (Object)null) { ((Component)val).gameObject.AddComponent<BunkbedController>(); BunkbedRevivePlugin.Log.LogInfo((object)"BunkbedController added to bunk beds"); } } } [HarmonyPatch("openingDoorsSequence")] [HarmonyPrefix] private static void openingDoorsSequencePatch() { BunkbedController.Instance = null; } [HarmonyPatch("EndOfGame")] [HarmonyPrefix] private static void EndOfGamePatch() { BunkbedNetworking.Cleanup(); BunkbedController.Instance = null; } } } namespace BunkbedRevive.Configuration { public static class ModConfig { public static ConfigEntry<int> ReviveCost; public static ConfigEntry<float> BodyWeight; public static void Init() { ConfigFile config = ((BaseUnityPlugin)BunkbedRevivePlugin.Instance).Config; ReviveCost = config.Bind<int>("Revive", "Cost", 25, "Number of credits to revive a dead player at the bunk beds"); BodyWeight = config.Bind<float>("Revive", "Body Weight", 1.1f, "Weight of dead bodies when carried"); } } }