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 ReviveCompany Patched v1.6.0
Erksmit.LethalRevives.dll
Decompiled 3 weeks agousing System; using System.Collections; 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 GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using OPJosMod.ReviveCompany.CustomRpc; using OPJosMod.ReviveCompany.Patches; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Erksmit.LethalRevives")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LethalRevives")] [assembly: AssemblyTitle("Erksmit.LethalRevives")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 LethalRevives { public static class MyPluginInfo { public const string PLUGIN_GUID = "Erksmit.LethalRevives"; public const string PLUGIN_NAME = "LethalRevives"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace OPJosMod.ReviveCompany { public static class ConfigVariables { public static float reviveTime; public static bool reviveTeleportedBodies; public static Key ReviveButton; public static bool CanPickUpBodies; public static float DeadPlayerWeight; public static int ReviveToHealth; public static bool LimitedRevives; public static float RevivesPerLevelMultiplier; public static int HardAmountOfLives; public static int ExtraHealthLostPerRevive; public static bool InfiniteReviveTime; public static int TimeUnitlCantBeRevived; } public static class GeneralUtil { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static Vector3 StringToVector3(string str) { //IL_0046: 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_004f: Unknown result type (might be due to invalid IL or missing references) string[] array = str.Trim('(', ')').Split(new char[1] { ',' }); float num = float.Parse(array[0]); float num2 = float.Parse(array[1]); float num3 = float.Parse(array[2]); return new Vector3(num, num2, num3); } public static RagdollGrabbableObject GetClosestDeadBody(Vector3 position) { //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) RagdollGrabbableObject result = null; float num = float.MaxValue; RagdollGrabbableObject[] array = Object.FindObjectsOfType<RagdollGrabbableObject>(); RagdollGrabbableObject[] array2 = array; RagdollGrabbableObject[] array3 = array2; foreach (RagdollGrabbableObject val in array3) { float num2 = Vector3.Distance(((Component)val).transform.position, position); if (num2 < num) { result = val; num = num2; } } return result; } public static PlayerControllerB GetClosestAlivePlayer(Vector3 position) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB result = null; float num = float.MaxValue; PlayerControllerB[] allPlayerScripts = RoundManager.Instance.playersManager.allPlayerScripts; PlayerControllerB[] array = allPlayerScripts; PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if (!val.isPlayerDead) { float num2 = Vector3.Distance(((Component)val).transform.position, position); if (num2 < num) { result = val; num = num2; } } } return result; } public static string simplifyObjectNames(string ogName) { string text = ogName; int num = text.IndexOf("("); if (num != -1) { text = text.Substring(0, num).Trim(); } return text; } public static void RevivePlayer(int playerId) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Expected O, but got Unknown //IL_062b: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Expected O, but got Unknown //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_0601: Unknown result type (might be due to invalid IL or missing references) //IL_0607: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0615: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) if (playerId >= RoundManager.Instance.playersManager.allPlayerScripts.Length || playerId < 0) { Debug.Log((object)$"ReiveCompanyERROR: error when trying to revive player {playerId} as it is outside the range of the allPlayerScripts array"); return; } PlayerControllerB val = RoundManager.Instance.playersManager.allPlayerScripts[playerId]; if ((Object)val != (Object)null && !val.isPlayerDead) { Debug.Log((object)$"ReiveCompanyERROR: error when trying to revive player {playerId} player is already alive! do nothing more"); return; } Vector3 val2 = val.serverPlayerPosition; if ((Object)val.deadBody != (Object)null && (Object)((Component)val.deadBody).transform != (Object)null) { _ = ((Component)val.deadBody).transform.position; bool flag = true; val2 = ((Component)val.deadBody).transform.position; PlayerControllerB closestAlivePlayer = GetClosestAlivePlayer(((Component)val.deadBody).transform.position); if ((Object)closestAlivePlayer != (Object)null && Vector3.Distance(val2, ((Component)closestAlivePlayer).transform.position) > 7f) { val2 = ((Component)closestAlivePlayer).transform.position; } } bool isInsideFactory = false; PlayerControllerB closestAlivePlayer2 = GetClosestAlivePlayer(((Component)val.deadBody).transform.position); if ((Object)closestAlivePlayer2 != (Object)null) { isInsideFactory = closestAlivePlayer2.isInsideFactory; } StartOfRound instance = StartOfRound.Instance; instance.livingPlayers++; StartOfRound.Instance.allPlayersDead = false; StartOfRound.Instance.UpdatePlayerVoiceEffects(); GlobalVariables.RemainingRevives--; if (GlobalVariables.RemainingRevives < 100) { HUDManager.Instance.DisplayTip(val.playerUsername + " was revived", $"{GlobalVariables.RemainingRevives} revives remain!", false, false, "LC_Tip1"); } int num = (int)val.playerClientId; val.ResetPlayerBloodObjects(val.isPlayerDead); val.isClimbingLadder = false; val.ResetZAndXRotation(); ((Collider)val.thisController).enabled = true; val.health = ConfigVariables.ReviveToHealth; val.disableLookInput = false; if (val.isPlayerDead) { val.isPlayerDead = false; val.isPlayerControlled = true; val.isInElevator = true; val.isInHangarShipRoom = true; val.isInsideFactory = isInsideFactory; val.TeleportPlayer(val2, false, 0f, false, true); val.setPositionOfDeadPlayer = false; val.DisablePlayerModel(StartOfRound.Instance.allPlayerObjects[num], true, true); ((Behaviour)val.helmetLight).enabled = false; val.Crouch(false); val.criticallyInjured = false; if ((Object)(object)val.playerBodyAnimator != (Object)null) { val.playerBodyAnimator.SetBool("Limp", false); } val.bleedingHeavily = false; val.activatingItem = false; val.twoHanded = false; val.inSpecialInteractAnimation = false; val.disableSyncInAnimation = false; val.inAnimationWithEnemy = null; val.holdingWalkieTalkie = false; val.speakingToWalkieTalkie = false; val.isSinking = false; val.isUnderwater = false; val.sinkingValue = 0f; val.statusEffectAudio.Stop(); val.DisableJetpackControlsLocally(); val.health = ConfigVariables.ReviveToHealth; val.mapRadarDotAnimator.SetBool("dead", false); val.hasBegunSpectating = false; val.hinderedMultiplier = 1f; val.isMovementHindered = 0; val.sourcesCausingSinking = 0; val.reverbPreset = StartOfRound.Instance.shipReverb; } SoundManager.Instance.earsRingingTimer = 0f; val.voiceMuffledByEnemy = false; SoundManager.Instance.playerVoicePitchTargets[num] = 1f; SoundManager.Instance.SetPlayerPitch(1f, num); if ((Object)(object)val.currentVoiceChatIngameSettings == (Object)null) { StartOfRound.Instance.RefreshPlayerVoicePlaybackObjects(); } if ((Object)(object)val.currentVoiceChatIngameSettings != (Object)null) { if ((Object)(object)val.currentVoiceChatIngameSettings.voiceAudio == (Object)null) { val.currentVoiceChatIngameSettings.InitializeComponents(); } if ((Object)(object)val.currentVoiceChatIngameSettings.voiceAudio == (Object)null) { return; } ((Component)val.currentVoiceChatIngameSettings.voiceAudio).GetComponent<OccludeAudio>().overridingLowPass = false; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (localPlayerController.playerClientId == val.playerClientId) { GlobalVariables.AmountOfTimesRevived++; int num2 = ConfigVariables.ReviveToHealth - GlobalVariables.AmountOfTimesRevived * ConfigVariables.ExtraHealthLostPerRevive; localPlayerController.bleedingHeavily = false; localPlayerController.criticallyInjured = false; localPlayerController.playerBodyAnimator.SetBool("Limp", false); localPlayerController.health = num2; localPlayerController.spectatedPlayerScript = null; ((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false; StartOfRound.Instance.SetSpectateCameraToGameOverMode(false, localPlayerController); StartOfRound.Instance.SetPlayerObjectExtrapolate(false); HUDManager.Instance.UpdateHealthUI(num2, true); HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false); HUDManager.Instance.RemoveSpectateUI(); HUDManager.Instance.gameOverAnimator.SetTrigger("revive"); } RagdollGrabbableObject closestDeadBody = GetClosestDeadBody(((Component)val).transform.position); if ((Object)closestDeadBody != (Object)null) { if (!((GrabbableObject)closestDeadBody).isHeld) { if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { if (((NetworkBehaviour)closestDeadBody).NetworkObject.IsSpawned) { ((NetworkBehaviour)closestDeadBody).NetworkObject.Despawn(true); } else { Object.Destroy((Object)(object)((Component)closestDeadBody).gameObject); } } } else if (((GrabbableObject)closestDeadBody).isHeld && (Object)(object)((GrabbableObject)closestDeadBody).playerHeldBy != (Object)null) { ((GrabbableObject)closestDeadBody).playerHeldBy.DropAllHeldItems(true, false, false, false, default(Vector3), default(Vector3), default(Vector3), default(Vector3), default(Vector3)); } if ((Object)closestDeadBody.ragdoll != (Object)null) { Object.Destroy((Object)(object)((Component)closestDeadBody.ragdoll).gameObject); } } if (localPlayerController.isPlayerDead) { HUDManager.Instance.UpdateBoxesSpectateUI(); } } public static void ResetAllPlayerInfos() { GlobalVariables.PlayerInfos.Clear(); PlayerControllerB[] allPlayerScripts = RoundManager.Instance.playersManager.allPlayerScripts; PlayerControllerB[] array = allPlayerScripts; foreach (PlayerControllerB val in array) { GlobalVariables.PlayerInfos.Add(new PlayerInfo { PlayerId = (int)val.playerClientId }); } } public static bool HasPlayerTeleported(int playerClientId) { int num = GlobalVariables.PlayerInfos.FindIndex((PlayerInfo p) => p.PlayerId == playerClientId); if (num != -1) { return GlobalVariables.PlayerInfos[num].HasBeenTeleported; } return false; } public static void SetPlayerAsTeleported(int playerClientId) { int num = GlobalVariables.PlayerInfos.FindIndex((PlayerInfo p) => p.PlayerId == playerClientId); if (num != -1) { GlobalVariables.PlayerInfos[num].HasBeenTeleported = true; } } public static void SetPlayerDiedAt(int playerClientId) { int num = GlobalVariables.PlayerInfos.FindIndex((PlayerInfo p) => p.PlayerId == playerClientId); if (num != -1) { GlobalVariables.PlayerInfos[num].TimeDiedAt = Time.time; } } public static float GetPlayersDiedAtTime(int playerClientId) { int num = GlobalVariables.PlayerInfos.FindIndex((PlayerInfo p) => p.PlayerId == playerClientId); if (num != -1) { return GlobalVariables.PlayerInfos[num].TimeDiedAt; } return Time.time; } } public static class GlobalVariables { public static bool ModActivated = false; public static List<PlayerInfo> PlayerInfos = new List<PlayerInfo>(); public static int RemainingRevives = int.MaxValue; public static int AmountOfTimesRevived = 0; } public class PlayerInfo { public int PlayerId { get; set; } public bool HasBeenTeleported { get; set; } public float TimeDiedAt { get; set; } } [BepInPlugin("OpJosMod.ReviveCompany", "ReviveCompany", "1.4.0")] public class OpJosMod : BaseUnityPlugin { private const string modGUID = "OpJosMod.ReviveCompany"; private const string modName = "ReviveCompany"; private const string modVersion = "1.4.0"; private readonly Harmony harmony = new Harmony("OpJosMod.ReviveCompany"); private static OpJosMod Instance; internal ManualLogSource mls; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if ((Object)Instance == (Object)null) { Instance = this; } mls = new ManualLogSource("OpJosMod.ReviveCompany"); Logger.Sources.Add((ILogSource)(object)mls); mls.LogInfo((object)"Test"); setupConfig(); PatchesForRPC.SetLogSource(mls); RpcMessageHandler.SetLogSource(mls); CompleteRecievedTasks.SetLogSource(mls); ResponseHandler.SetLogSource(mls); PlayerControllerBPatch.SetLogSource(mls); ShipTeleporterPatch.SetLogSource(mls); StartOfRoundPatch.SetLogSource(mls); RagdollGrabbableObjectPatch.SetLogSource(mls); GeneralUtil.SetLogSource(mls); harmony.PatchAll(); } private void setupConfig() { //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>("Revive Time", "ReviveTime", 5f, "How long it takes to revive someone"); ConfigEntry<Key> val2 = ((BaseUnityPlugin)this).Config.Bind<Key>("ReviveButton", "ReviveButton", (Key)32, "Button Used to Revive Players"); ConfigEntry<bool> val3 = ((BaseUnityPlugin)this).Config.Bind<bool>("Can Pick Up Bodies", "CanPickUpBodies", true, "Toggle if you can pick up bodies."); ConfigEntry<float> val4 = ((BaseUnityPlugin)this).Config.Bind<float>("Dead Body Weight Multiplier", "DeadBodyWeight", 3.25f, "How heavy are the dead players."); ConfigEntry<bool> val5 = ((BaseUnityPlugin)this).Config.Bind<bool>("Can Revive Teleported Bodies", "CanReviveTeleportedBodies", false, "Toggle for if you are able to revive dead players you teleport back to the ship"); ConfigEntry<int> val6 = ((BaseUnityPlugin)this).Config.Bind<int>("Health you revive with.", "HealthYouReviveWith", 25, "How much health you revive with."); ConfigEntry<int> val7 = ((BaseUnityPlugin)this).Config.Bind<int>("Extra Health Lost Per Revive", "ExtraHealthLostPerRevive", 5, "If player is revived more than once per level, revive with this much less HP each time"); ConfigEntry<bool> val8 = ((BaseUnityPlugin)this).Config.Bind<bool>("Limit amount of revives", "LimitAmountOfRevives", true, "do you want to have limited revives?"); ConfigEntry<float> val9 = ((BaseUnityPlugin)this).Config.Bind<float>("Revives Per Level Multiplier", "RevivesPerLevelMultiplier", 1.25f, "How many revives you get per level, mulitplied by players in game. ex) value set to 2 and have 4 players then you get 8 revives."); ConfigEntry<int> val10 = ((BaseUnityPlugin)this).Config.Bind<int>("Set Amount of Revives", "SetAmountOfRevives", 0, "Set amount of revives per level. If not at 0 This will override the revive amount being set by the (Revives Per Level Multiplier) setting"); ConfigEntry<bool> val11 = ((BaseUnityPlugin)this).Config.Bind<bool>("Infinite Revive Time", "InfiniteReviveTime", false, "Can you alwasy revive someone no longer how long they have been dead?"); ConfigEntry<int> val12 = ((BaseUnityPlugin)this).Config.Bind<int>("Time Until Cant Be Revived", "TimeUntilCantBeRevived", 120, "How long someone can be dead for and still be revived in seconds"); ConfigVariables.reviveTime = val.Value; ConfigVariables.ReviveButton = val2.Value; ConfigVariables.CanPickUpBodies = val3.Value; ConfigVariables.DeadPlayerWeight = val4.Value; ConfigVariables.reviveTeleportedBodies = val5.Value; ConfigVariables.ReviveToHealth = val6.Value; ConfigVariables.LimitedRevives = val8.Value; ConfigVariables.RevivesPerLevelMultiplier = val9.Value; ConfigVariables.HardAmountOfLives = val10.Value; ConfigVariables.ExtraHealthLostPerRevive = val7.Value; ConfigVariables.InfiniteReviveTime = val11.Value; ConfigVariables.TimeUnitlCantBeRevived = val12.Value; } } } namespace OPJosMod.ReviveCompany.CustomRpc { public static class ResponseHandler { private static ManualLogSource mls; private static float LastSendTime; private static RpcMessage ResendMessageMessage; private static bool StartWaitForResend; private static int TotalResponses; private static int TotalSentMessages; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static void RecievedResponse(MessageTasks messageTask) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown if (messageTask == MessageTasks.RevivePlayer && !((Object)StartOfRound.Instance == (Object)null) && StartOfRound.Instance.allPlayerScripts != null) { TotalResponses++; } } public static void SentMessageNeedResponses(RpcMessage message) { LastSendTime = Time.time; ResendMessageMessage = message; StartWaitForResend = true; TotalResponses = 0; TotalSentMessages = 0; } public static void CalculateIfShouldResend() { if (ResendMessageMessage == null || ResendMessageMessage.Task != MessageTasks.RevivePlayer || !StartWaitForResend || !(Time.time - LastSendTime > 2f)) { return; } if (TotalSentMessages > 4) { mls.LogError((object)"No longer retrying message send as it has already sent 5 extra times."); LastSendTime = 0f; StartWaitForResend = false; TotalResponses = 0; TotalSentMessages = 0; return; } int num = RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => !x.playerUsername.Contains("Player")).ToList().Count(); mls.LogMessage((object)$"TotalResponses:{TotalResponses}, playerCount:{num}"); if (TotalResponses > num - 2 || num - 2 < 0) { LastSendTime = 0f; StartWaitForResend = false; TotalResponses = 0; TotalSentMessages = 0; } else { mls.LogMessage((object)"resending revive message as dont have enough responses"); TotalSentMessages++; LastSendTime = Time.time; RpcMessageHandler.SendRpcMessage(ResendMessageMessage); ResendMessageMessage.Task = MessageTasks.TurnOffGhostMode; RpcMessageHandler.SendRpcMessage(ResendMessageMessage); ResendMessageMessage.Task = MessageTasks.RevivePlayer; } } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatchResponseHandler { [HarmonyPatch("Update")] [HarmonyPostfix] private static void patchUpdate(PlayerControllerB __instance) { if (GlobalVariables.ModActivated && ((NetworkBehaviour)__instance).IsOwner) { ResponseHandler.CalculateIfShouldResend(); } } } public static class CompleteRecievedTasks { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static void ModActivated(string modName) { if (mls.SourceName == modName) { mls.LogMessage((object)"Mod Activated"); GlobalVariables.ModActivated = true; } } public static void RevivePlayer(string playerIdString) { if (int.TryParse(playerIdString, out var result)) { GeneralUtil.RevivePlayer(result); } else { mls.LogError((object)("Error: Invalid player ID '" + playerIdString + "' did not revive")); } } } public static class PatchesForRPC { public static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } } [HarmonyPatch(typeof(HUDManager))] internal static class HUDManagerPatchForRPC { private static float lastRecievedAt = Time.time; private static string lastRecievedMessage = null; private static float messageWaitTime = 0.5f; [HarmonyPatch("AddPlayerChatMessageClientRpc")] [HarmonyPrefix] private static void addPlayerChatMessageClientRpcPatch(ref string chatMessage, ref int playerId) { string text = MessageCodeUtil.returnMessageNoSeperators(chatMessage); if (MessageCodeUtil.stringContainsMessageCode(chatMessage) && (Time.time - lastRecievedAt > messageWaitTime || text != lastRecievedMessage) && playerId != (int)GameNetworkManager.Instance.localPlayerController.playerClientId) { lastRecievedAt = Time.time; lastRecievedMessage = text; RpcMessageHandler.ReceiveRpcMessage(chatMessage, playerId); } } [HarmonyPatch("AddChatMessage")] [HarmonyPrefix] private static bool addChatMessagePatch(ref string chatMessage) { if (MessageCodeUtil.stringContainsMessageCode(chatMessage)) { return false; } return true; } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatchForRPC { [CompilerGenerated] private sealed class <activateModForOthers>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public StartOfRound __instance; private RpcMessage <rpcMessage>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <activateModForOthers>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rpcMessage>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; case 1: <>1__state = -1; if (((NetworkBehaviour)__instance).IsHost) { GlobalVariables.ModActivated = true; <rpcMessage>5__1 = new RpcMessage(MessageTasks.ModActivated, PatchesForRPC.mls.SourceName, (int)__instance.localPlayerController.playerClientId, MessageCodes.Request); RpcMessageHandler.SendRpcMessage(<rpcMessage>5__1); <rpcMessage>5__1 = null; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch("OnClientConnect")] [HarmonyPostfix] private static void patchOnClientConnect(StartOfRound __instance) { ((MonoBehaviour)__instance).StartCoroutine(activateModForOthers(__instance)); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void patchStart(StartOfRound __instance) { if (((NetworkBehaviour)__instance).IsHost) { GlobalVariables.ModActivated = true; } } [HarmonyPatch("OnLocalDisconnect")] [HarmonyPostfix] private static void patchOnLocalDisconnect(StartOfRound __instance) { GlobalVariables.ModActivated = false; } [IteratorStateMachine(typeof(<activateModForOthers>d__3))] private static IEnumerator activateModForOthers(StartOfRound __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <activateModForOthers>d__3(0) { __instance = __instance }; } } public enum MessageCodes { Request, Response } public static class MessageCodeUtil { public static string GetCode(MessageCodes code) { if (1 == 0) { } string result = code switch { MessageCodes.Request => ":rpcRequest:", MessageCodes.Response => ":rpcResponse:", _ => ":Error:", }; if (1 == 0) { } return result; } public static bool stringContainsMessageCode(string givenString) { if (string.IsNullOrEmpty(givenString)) { return false; } return givenString.Contains(GetCode(MessageCodes.Request)) || givenString.Contains(GetCode(MessageCodes.Response)); } public static string returnMessageWithoutCode(string message) { if (stringContainsMessageCode(message)) { message = message.Replace(GetCode(MessageCodes.Request), string.Empty); message = message.Replace(GetCode(MessageCodes.Response), string.Empty); } return message; } public static string returnMessageNoSeperators(string message) { if (stringContainsMessageCode(message)) { return new string(message.Where((char c) => c != ':').ToArray()); } return message; } } public enum MessageTasks { ModActivated, RevivePlayer, TurnOffGhostMode, ErrorNoTask } public static class MessageTaskUtil { public static string GetCode(MessageTasks code) { if (1 == 0) { } string result = code switch { MessageTasks.ModActivated => ":ModActivated:", MessageTasks.RevivePlayer => ":RevivePlayer:", MessageTasks.TurnOffGhostMode => ":TurnOffGhostMode:", MessageTasks.ErrorNoTask => ":Error:", _ => ":Error:", }; if (1 == 0) { } return result; } public static string getMessageWithoutTask(string message) { foreach (MessageTasks value in Enum.GetValues(typeof(MessageTasks))) { string code2 = GetCode(value); message = message.Replace(code2, ""); } return message.Trim(); } public static MessageTasks getMessageTask(string givenString) { if (givenString.Contains(GetCode(MessageTasks.ModActivated))) { return MessageTasks.ModActivated; } if (givenString.Contains(GetCode(MessageTasks.RevivePlayer))) { return MessageTasks.RevivePlayer; } if (givenString.Contains(GetCode(MessageTasks.TurnOffGhostMode))) { return MessageTasks.TurnOffGhostMode; } return MessageTasks.ErrorNoTask; } } public class RpcMessage { public MessageTasks Task { get; set; } public string Message { get; set; } public int FromUser { get; set; } public MessageCodes MessageCode { get; set; } public RpcMessage(MessageTasks task, string message, int user, MessageCodes code) { Task = task; Message = message; FromUser = user; MessageCode = code; } public string getMessageWithCode() { return MessageCodeUtil.GetCode(MessageCode) + MessageTaskUtil.GetCode(Task) + Message; } } public static class RpcMessageHandler { private static ManualLogSource mls; private static RpcMessage lastSentMessage = null; private static float lastSentTime = Time.time; private static float messageWaitTime = 0.5f; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static void SendRpcMessage(RpcMessage message) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (Time.time - lastSentTime > messageWaitTime || lastSentMessage != message) { mls.LogMessage((object)$"Sending rpc message: {message.getMessageWithCode()}, user:{message.FromUser}"); lastSentTime = Time.time; lastSentMessage = message; HUDManager instance = HUDManager.Instance; if ((Object)instance != (Object)null) { MethodInfo method = typeof(HUDManager).GetMethod("AddPlayerChatMessageServerRpc", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { object[] parameters = new object[2] { message.getMessageWithCode(), message.FromUser }; method.Invoke(instance, parameters); } else { mls.LogError((object)"AddPlayerChatMessageServerRpc method not found in HUDManager class."); } } else { mls.LogError((object)"HUDManager.Instance is null."); } } else { mls.LogError((object)("didnt' send message as it was too soon and was the same message as last message " + message.getMessageWithCode())); } } public static void ReceiveRpcMessage(string message, int user) { mls.LogMessage((object)$"recieved message: {message}, user:{user}"); if (user != (int)StartOfRound.Instance.localPlayerController.playerClientId) { string text = MessageCodeUtil.returnMessageWithoutCode(message); if (message.Contains(MessageCodeUtil.GetCode(MessageCodes.Request))) { MessageTasks messageTask = MessageTaskUtil.getMessageTask(text); string messageWithoutTask = MessageTaskUtil.getMessageWithoutTask(text); SendRpcResponse(messageTask, messageWithoutTask); handleTask(messageTask, messageWithoutTask); } else if (message.Contains(MessageCodeUtil.GetCode(MessageCodes.Response))) { ResponseHandler.RecievedResponse(MessageTaskUtil.getMessageTask(text)); } } } public static void SendRpcResponse(MessageTasks task, string message) { try { RpcMessage message2 = new RpcMessage(task, message, (int)StartOfRound.Instance.localPlayerController.playerClientId, MessageCodes.Response); SendRpcMessage(message2); } catch (Exception arg) { mls.LogError((object)$"failed to send response message: {arg}"); } } private static void handleTask(MessageTasks task, string message) { try { switch (task) { case MessageTasks.ModActivated: CompleteRecievedTasks.ModActivated(message); break; case MessageTasks.RevivePlayer: CompleteRecievedTasks.RevivePlayer(message); break; case MessageTasks.ErrorNoTask: mls.LogError((object)"got an error task"); break; case MessageTasks.TurnOffGhostMode: break; } } catch (Exception arg) { mls.LogError((object)$"failed handlign rpc task: {arg}, task:{task}, message:{message}"); } } } } namespace OPJosMod.ReviveCompany.Patches { [HarmonyPatch(typeof(RagdollGrabbableObject))] internal class RagdollGrabbableObjectPatch { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("Start")] [HarmonyPrefix] private static void patchStart(RagdollGrabbableObject __instance) { if (GlobalVariables.ModActivated) { ((GrabbableObject)__instance).itemProperties.weight = ConfigVariables.DeadPlayerWeight; } } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatch { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("EndOfGame")] [HarmonyPrefix] private static void patchEndOfGame() { if (GlobalVariables.ModActivated) { mls.LogMessage((object)"reset bodies teleported list"); GeneralUtil.ResetAllPlayerInfos(); } } [HarmonyPatch("openingDoorsSequence")] [HarmonyPrefix] private static void patchOpeningDoorsSequence() { if (GlobalVariables.ModActivated) { mls.LogMessage((object)"round starting, reseting allowed revive count"); GeneralUtil.ResetAllPlayerInfos(); setStartingRevives(); } } private static void setStartingRevives() { int num = RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => x.isPlayerControlled).Count(); GlobalVariables.AmountOfTimesRevived = 0; if (ConfigVariables.LimitedRevives) { if (ConfigVariables.HardAmountOfLives != 0) { GlobalVariables.RemainingRevives = ConfigVariables.HardAmountOfLives; } else { GlobalVariables.RemainingRevives = Mathf.RoundToInt((float)num * ConfigVariables.RevivesPerLevelMultiplier); } } else { GlobalVariables.RemainingRevives = int.MaxValue; } } } [HarmonyPatch(typeof(ShipTeleporter))] internal class ShipTeleporterPatch { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("beamUpPlayer")] [HarmonyPrefix] private static void patchbeamUpPlayer() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (GlobalVariables.ModActivated) { PlayerControllerB targetedPlayer = StartOfRound.Instance.mapScreen.targetedPlayer; if (!((Object)targetedPlayer == (Object)null) && !((Object)targetedPlayer.redirectToEnemy != (Object)null) && !((Object)targetedPlayer.deadBody == (Object)null) && targetedPlayer.isPlayerDead) { GeneralUtil.SetPlayerAsTeleported((int)targetedPlayer.playerClientId); } } } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatch { private static ManualLogSource mls; private static int interactableObjectsMask = 832; private static float StartedReviveAt = Time.time; private static bool StartedRevive = false; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("Interact_performed")] [HarmonyPrefix] private static bool interact_performedPatch(PlayerControllerB __instance) { if (!GlobalVariables.ModActivated) { return true; } if (ConfigVariables.CanPickUpBodies) { return true; } if (((NetworkBehaviour)__instance).IsOwner && !__instance.isPlayerDead && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject) && !canUse(__instance)) { return false; } return true; } [HarmonyPatch("KillPlayerClientRpc")] [HarmonyPrefix] private static void killPlayerClientRpcPatch(PlayerControllerB __instance, ref int playerId) { if (GlobalVariables.ModActivated) { GeneralUtil.SetPlayerDiedAt(playerId); } } [HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")] [HarmonyPostfix] private static void setHoverTipAndCurrentInteractTriggerPatch(PlayerControllerB __instance) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!GlobalVariables.ModActivated) { return; } if (!canUse(__instance) && ((TMP_Text)__instance.cursorTip).text != "") { if (((ButtonControl)Keyboard.current[ConfigVariables.ReviveButton]).isPressed) { if (!StartedRevive) { StartedRevive = true; StartedReviveAt = Time.time; } else if (Time.time - StartedReviveAt > ConfigVariables.reviveTime) { RagdollGrabbableObject closestDeadBody = GeneralUtil.GetClosestDeadBody(((Component)__instance).transform.position); if (!canRevive(closestDeadBody)) { ((TMP_Text)__instance.cursorTip).text = "[Can't Revive Player!]"; return; } StartedRevive = false; RpcMessage message = new RpcMessage(MessageTasks.RevivePlayer, closestDeadBody.ragdoll.playerScript.playerClientId.ToString(), (int)__instance.playerClientId, MessageCodes.Request); RpcMessageHandler.SendRpcMessage(message); ResponseHandler.SentMessageNeedResponses(message); GeneralUtil.RevivePlayer((int)closestDeadBody.ragdoll.playerScript.playerClientId); RpcMessage message2 = new RpcMessage(MessageTasks.TurnOffGhostMode, closestDeadBody.ragdoll.playerScript.playerClientId.ToString(), (int)__instance.playerClientId, MessageCodes.Request); RpcMessageHandler.SendRpcMessage(message2); } ((TMP_Text)__instance.cursorTip).text = $"[Reviving! {(int)Mathf.Round(Time.time - StartedReviveAt)}/{ConfigVariables.reviveTime}s]"; return; } if (ConfigVariables.InfiniteReviveTime) { ((TMP_Text)__instance.cursorTip).text = $"[Hold {ConfigVariables.ReviveButton} to revive!]"; } else { RagdollGrabbableObject closestDeadBody2 = GeneralUtil.GetClosestDeadBody(((Component)__instance).transform.position); double num = Math.Round((float)ConfigVariables.TimeUnitlCantBeRevived - (Time.time - GeneralUtil.GetPlayersDiedAtTime((int)closestDeadBody2.ragdoll.playerScript.playerClientId))); if (num > 0.0) { ((TMP_Text)__instance.cursorTip).text = $"[Hold {ConfigVariables.ReviveButton} to revive!] {num}s Left!"; } else { ((TMP_Text)__instance.cursorTip).text = "0 Time Left!"; } } StartedRevive = false; } else { StartedRevive = false; } } private static bool canUse(PlayerControllerB __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) Ray val = default(Ray); ((Ray)(ref val))..ctor(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, ref val2, __instance.grabDistance, interactableObjectsMask)) { GrabbableObject component = ((Component)((RaycastHit)(ref val2)).collider).GetComponent<GrabbableObject>(); if ((Object)(object)component != (Object)null) { string text = GeneralUtil.simplifyObjectNames(((Object)component).name); if (text == "RagdollGrabbableObject") { return false; } } } return true; } private static bool canRevive(RagdollGrabbableObject revivingBody) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown if (GlobalVariables.RemainingRevives <= 0) { return false; } if ((Object)revivingBody != (Object)null && (Object)revivingBody.ragdoll != (Object)null && (Object)revivingBody.ragdoll.playerScript != (Object)null && GameNetworkManager.Instance.localPlayerController.playerClientId == revivingBody.ragdoll.playerScript.playerClientId) { return false; } int playerClientId = (int)revivingBody.ragdoll.playerScript.playerClientId; if (GeneralUtil.HasPlayerTeleported(playerClientId) && !ConfigVariables.reviveTeleportedBodies) { return false; } mls.LogInfo((object)(Time.time + " | " + GeneralUtil.GetPlayersDiedAtTime(playerClientId))); if (Time.time - GeneralUtil.GetPlayersDiedAtTime(playerClientId) > (float)ConfigVariables.TimeUnitlCantBeRevived && !ConfigVariables.InfiniteReviveTime) { return false; } return true; } } } namespace OPJosMod.ReviveCompany.Utils { public class ReflectionUtils { public static void InvokeMethod(object obj, string methodName, object[] parameters) { Type type = obj.GetType(); MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); method.Invoke(obj, parameters); } public static void InvokeMethod(object obj, Type forceType, string methodName, object[] parameters) { MethodInfo method = forceType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); method.Invoke(obj, parameters); } public static void SetPropertyValue(object obj, string propertyName, object value) { Type type = obj.GetType(); PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); property.SetValue(obj, value); } public static T InvokeMethod<T>(object obj, string methodName, object[] parameters) { Type type = obj.GetType(); MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (T)method.Invoke(obj, parameters); } public static T GetFieldValue<T>(object obj, string fieldName) { Type type = obj.GetType(); FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (T)field.GetValue(obj); } public static void SetFieldValue(object obj, string fieldName, object value) { Type type = obj.GetType(); FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); field.SetValue(obj, value); } } }