using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Mirror;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RespawnMod_M4GMaR")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RespawnMod_M4GMaR")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fc922182-bb62-4b0d-8de5-46794294d7cf")]
[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")]
[BepInPlugin("com.yourname.respawnmod", "Respawn Mod", "1.8.5")]
public class RespawnMod : BaseUnityPlugin
{
public static FeelThePunch UnnarmedCombat;
public static GameObject leftHandWeapon = null;
public static GameObject rightHandWeapon = null;
public static GameObject nullRefDetector;
private static readonly HashSet<PlayerHealth> RespawningPlayers = new HashSet<PlayerHealth>();
public static RespawnMod Instance { get; private set; }
private void Awake()
{
((Object)Chainloader.ManagerObject).hideFlags = (HideFlags)61;
Instance = this;
Harmony.CreateAndPatchAll(typeof(RespawnMod), (string)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE: Hooking into SceneManager.sceneLoaded");
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("SCENE LOADED: " + ((Scene)(ref scene)).name));
RespawningPlayers.Clear();
UnnarmedCombat = Object.FindObjectOfType<FeelThePunch>();
}
private void Start()
{
Instance = this;
}
[HarmonyPatch(typeof(PlayerHealth), "Die")]
[HarmonyPrefix]
private static bool PreventOriginalDeath(PlayerHealth __instance)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
if (!NetworkServer.active)
{
return false;
}
if (RespawningPlayers.Contains(__instance))
{
return false;
}
RespawningPlayers.Add(__instance);
((MonoBehaviour)Instance).StartCoroutine(SimulateDeathAndResurrect(__instance));
if ((Object)(object)nullRefDetector == (Object)null)
{
nullRefDetector = new GameObject("NullRefDetector");
nullRefDetector.AddComponent<NullExceptionCatcher>();
Object.DontDestroyOnLoad((Object)(object)nullRefDetector);
}
return false;
}
private static IEnumerator SimulateDeathAndResurrect(PlayerHealth player)
{
Debug.Log((object)"Simulating Death...");
SetAllJointStrengths(player, 0f);
SetBallHolderJointStrength(player, 0f);
if (player.bleedableOrgans != null)
{
player.bleedableOrgans.ForEach(delegate(WeaponDamageablePart organ)
{
organ.StopDestroyVisuals();
});
}
if ((Object)(object)player.leftHand != (Object)null && player.leftHand.currentlyGrabbedItem != null)
{
Weapon weapon = player.leftHand.currentlyGrabbedItem.GetWeapon();
if ((Object)(object)weapon != (Object)null)
{
leftHandWeapon = ((Component)weapon).gameObject;
}
else
{
Debug.LogWarning((object)"GetWeapon() returned null for leftHand");
}
}
else
{
Debug.LogWarning((object)"player.leftHand or currentlyGrabbedItem is null");
}
if ((Object)(object)player.rightHand != (Object)null && player.rightHand.currentlyGrabbedItem != null)
{
Weapon weapon2 = player.rightHand.currentlyGrabbedItem.GetWeapon();
if ((Object)(object)weapon2 != (Object)null)
{
rightHandWeapon = ((Component)weapon2).gameObject;
}
else
{
Debug.LogWarning((object)"GetWeapon() returned null for rightHand");
}
}
else
{
Debug.LogWarning((object)"player.leftHand or currentlyGrabbedItem is null");
}
((MonoBehaviour)player).Invoke("HandleHandsOnDeath", 0.4f);
Debug.Log((object)"Death Simulated Succesfully, Respawning in 5 seconds...");
yield return (object)new WaitForSecondsRealtime(0.05f);
float transcurrido = 0f;
float objetivo = 5f;
while (transcurrido < objetivo)
{
transcurrido += Time.deltaTime;
SetAllJointStrengths(player, 0f);
yield return null;
}
PlayerMultiplayerInputManager inputManager = FindInputManager(player);
if ((Object)(object)inputManager != (Object)null)
{
Debug.Log((object)"Destroying old character...");
if ((Object)(object)leftHandWeapon != (Object)null)
{
NetworkServer.Destroy(leftHandWeapon);
}
if ((Object)(object)rightHandWeapon != (Object)null)
{
NetworkServer.Destroy(rightHandWeapon);
}
NetworkServer.Destroy(((Component)player).gameObject);
if ((Object)(object)StaminaManager.singleton != (Object)null)
{
StaminaManager.singleton.CleanUp();
}
ResetInputManager(inputManager);
inputManager.multiplayerRoomPlayer.SetMoveSet(inputManager.multiplayerRoomPlayer.selectedMoveSet);
Debug.Log((object)"Respawning Character in 1 sec...");
((MonoBehaviour)Instance).StartCoroutine(Resurrect(inputManager));
}
else
{
Debug.LogError((object)"InputManager not found!, Destroying Character");
NetworkServer.Destroy(((Component)player).gameObject);
}
if (RespawningPlayers.Contains(player))
{
RespawningPlayers.Remove(player);
}
}
private static IEnumerator Resurrect(PlayerMultiplayerInputManager IM)
{
Debug.Log((object)"Respawning Character...");
yield return (object)new WaitForSecondsRealtime(0.2f);
Debug.Log((object)"Respawning Character NOW");
IM.AttemptToCreatePlayerCharacter();
ResetInputManager(IM);
PlayerHealth[] playerHealths = Object.FindObjectsOfType<PlayerHealth>();
StaminaManager staminaManager = Object.FindObjectOfType<StaminaManager>();
if ((Object)(object)staminaManager != (Object)null && playerHealths != null)
{
StaminaManager.singleton.FindPlayers();
}
Debug.Log((object)"Applying Moveset and Equipment...");
yield return (object)new WaitForSecondsRealtime(0.2f);
IM.playerHealth.leftHand.grabbed = false;
IM.playerHealth.rightHand.grabbed = false;
IM.playerHealth.playerAnimator.SetMoveSet(IM.multiplayerRoomPlayer.selectedMoveSet, false, false);
IM.playerHealth.SetEquipment(IM.multiplayerRoomPlayer.selectedEquipment, true);
if ((Object)(object)UnnarmedCombat == (Object)null)
{
UnnarmedCombat = Object.FindObjectOfType<FeelThePunch>();
if ((Object)(object)UnnarmedCombat == (Object)null)
{
Hand[] hands = Object.FindObjectsOfType<Hand>();
if (hands != null)
{
Hand[] array = hands;
foreach (Hand hand in array)
{
if ((Object)(object)((Component)((Component)hand).transform.parent).gameObject.GetComponent<BluntTransmitter>() == (Object)null)
{
((Component)((Component)hand).transform.parent).gameObject.AddComponent<BluntTransmitter>();
((Component)((Component)hand).transform.parent).gameObject.GetComponent<Rigidbody>();
BoxCollider handColl = ((Component)((Component)hand).transform.parent).GetComponentInChildren<BoxCollider>();
if (!((Object)(object)handColl != (Object)null))
{
}
}
}
}
GameObject[] knees = Object.FindObjectsOfType<GameObject>();
GameObject[] array2 = knees;
foreach (GameObject knee in array2)
{
if (((((Object)knee).name.ToLower().Contains("knee_right") && Object.op_Implicit((Object)(object)knee.GetComponent<Rigidbody>())) || (((Object)knee).name.ToLower().Contains("knee_left") && Object.op_Implicit((Object)(object)knee.GetComponent<Rigidbody>()))) && (Object)(object)knee.gameObject.GetComponent<BluntTransmitter>() == (Object)null)
{
knee.gameObject.AddComponent<BluntTransmitter>();
}
}
}
}
if ((Object)(object)UnnarmedCombat != (Object)null)
{
UnnarmedCombat.DelayedSetup();
}
}
private static PlayerMultiplayerInputManager FindInputManager(PlayerHealth player)
{
if ((Object)(object)player == (Object)null)
{
return null;
}
uint playerNetId = ((Component)player).GetComponent<NetworkIdentity>().netId;
return ((IEnumerable<PlayerMultiplayerInputManager>)Resources.FindObjectsOfTypeAll<PlayerMultiplayerInputManager>()).FirstOrDefault((Func<PlayerMultiplayerInputManager, bool>)((PlayerMultiplayerInputManager mgr) => Traverse.Create((object)mgr).Field<uint>("playerHealthIdentity").Value == playerNetId));
}
private static void ResetInputManager(PlayerMultiplayerInputManager mgr)
{
Debug.Log((object)"Reseting Input Manager");
Traverse val = Traverse.Create((object)mgr);
val.Field("playerHealth").SetValue((object)null);
}
private static void SetAllJointStrengths(PlayerHealth player, float strength)
{
JointStrength[] componentsInChildren = ((Component)player).GetComponentsInChildren<JointStrength>();
foreach (JointStrength val in componentsInChildren)
{
val.SetStrengthPercent(strength);
Traverse.Create((object)val).Field("currentPercent").SetValue((object)strength);
}
}
private static void SetBallHolderJointStrength(PlayerHealth player, float strengthPercent)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: 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)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: 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_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: 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_0094: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)player.ballHolderjoint == (Object)null))
{
JointDrive val = default(JointDrive);
JointDrive angularXDrive = player.ballHolderjoint.angularXDrive;
((JointDrive)(ref val)).positionSpring = ((JointDrive)(ref angularXDrive)).positionSpring * (strengthPercent / 100f);
angularXDrive = player.ballHolderjoint.angularXDrive;
((JointDrive)(ref val)).positionDamper = ((JointDrive)(ref angularXDrive)).positionDamper * (strengthPercent / 100f);
angularXDrive = player.ballHolderjoint.angularXDrive;
((JointDrive)(ref val)).maximumForce = ((JointDrive)(ref angularXDrive)).maximumForce;
JointDrive val2 = val;
player.ballHolderjoint.angularXDrive = val2;
player.ballHolderjoint.angularYZDrive = val2;
}
}
[HarmonyPatch(typeof(MultiplayerRoomPlayer), "GetJoinedMidGame")]
[HarmonyPrefix]
private static bool ForceGetJoinedMidGameFalse(ref bool __result)
{
__result = false;
return false;
}
[HarmonyPatch(typeof(PlayerHealth), "HandleDeath")]
[HarmonyPrefix]
private static bool PreventHandleDeath()
{
return false;
}
[HarmonyPatch(typeof(PlayerHealth), "HandleClientDeath")]
[HarmonyPrefix]
private static bool PreventClientDeath()
{
return false;
}
[HarmonyPatch(typeof(PlayerInputManager), "HandlePlayerDeath")]
[HarmonyPrefix]
private static bool PreventInputDisabling()
{
return false;
}
[HarmonyPatch(typeof(PlayerAnimator), "PlayerDied")]
[HarmonyPrefix]
private static bool PreventAnimatorDeathState()
{
return false;
}
}
public class NullExceptionCatcher : MonoBehaviour
{
private void Start()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
Application.logMessageReceived += new LogCallback(HandleLog);
Debug.Log((object)"Null Detector Succesfully Created");
}
private void OnDisable()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
Application.logMessageReceived -= new LogCallback(HandleLog);
}
private void HandleLog(string logString, string stackTrace, LogType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Invalid comparison between Unknown and I4
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
if (((int)type == 4 && logString.Contains("NullReferenceException")) || ((int)type == 0 && logString.Contains("NullReferenceException")))
{
Debug.Log((object)"A NullReferenceException was logged!");
HandleNullException();
if (((int)type == 4 && logString.Contains("StaminaManager")) || ((int)type == 0 && logString.Contains("StaminaManager")))
{
StaminaManager.singleton.CleanUp();
StaminaManager.singleton.FindPlayers();
}
}
}
private void HandleNullException()
{
MultiplayerTransform[] array = Object.FindObjectsOfType<MultiplayerTransform>();
MultiplayerTransform[] array2 = array;
foreach (MultiplayerTransform val in array2)
{
if ((Object)(object)((NetworkTransformBase)val).target == (Object)null)
{
Object.Destroy((Object)(object)val);
}
}
}
}