using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
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: AssemblyCompany("InstantResurrection")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("InstantResurrection")]
[assembly: AssemblyTitle("InstantResurrection")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Hura.InstantResurrection;
internal static class Log
{
private const string PREFIX = "[Hura Instant Resurrection] ";
public static void Message(string text)
{
Mod.ModLogger.LogMessage((object)("[Hura Instant Resurrection] " + text));
}
public static void Warning(string text)
{
Mod.ModLogger.LogWarning((object)("[Hura Instant Resurrection] " + text));
}
public static void Error(string text)
{
Mod.ModLogger.LogError((object)("[Hura Instant Resurrection] " + text));
}
}
[BepInPlugin("HuraInstantRevive", "HuraInstantRevive", "1.0.0")]
public class Mod : BaseUnityPlugin
{
private const string GUID = "HuraInstantRevive";
private const string NAME = "HuraInstantRevive";
private const string VERSION = "1.0.0";
private readonly Harmony _harmony = new Harmony("HuraInstantRevive");
private readonly Type[] _patches = new Type[1] { typeof(PlayerDeathHeadPatches) };
internal static Mod Instance { get; private set; }
internal static ManualLogSource ModLogger => ((BaseUnityPlugin)Instance).Logger;
private void Awake()
{
Instance = this;
try
{
Settings.Bind(this);
RepoReflection.Initialize();
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
Patch();
}
private void Patch()
{
Type[] patches = _patches;
foreach (Type type in patches)
{
_harmony.PatchAll(type);
}
}
}
[HarmonyPatch(typeof(PlayerDeathHead))]
internal class PlayerDeathHeadPatches
{
private const float UPDATE_INTERVAL = 1f;
private static float lastUpdateTime;
[HarmonyPatch("Update")]
[HarmonyPostfix]
internal static void UpdatePatch(PlayerDeathHead __instance)
{
if (Settings.EnableInstantRevive && GameManager.Multiplayer() && PhotonNetwork.IsMasterClient)
{
RoomVolumeCheck playerHeadVolumeCheck = __instance.GetPlayerHeadVolumeCheck();
if ((Object)(object)playerHeadVolumeCheck != (Object)null && playerHeadVolumeCheck.IsInExtractionPoint())
{
__instance.Revive();
}
}
}
}
internal static class RepoReflection
{
private static FieldInfo DeathHeadVolumeCheckField;
private static FieldInfo IsInExtractionPointVolumeCheckField;
internal static void Initialize()
{
DeathHeadVolumeCheckField = GetFieldOrLog(typeof(PlayerDeathHead), "roomVolumeCheck", BindingFlags.Instance | BindingFlags.NonPublic);
IsInExtractionPointVolumeCheckField = GetFieldOrLog(typeof(RoomVolumeCheck), "inExtractionPoint", BindingFlags.Instance | BindingFlags.NonPublic);
}
private static FieldInfo GetFieldOrLog(Type type, string fieldName, BindingFlags bindingFlags)
{
FieldInfo? field = type.GetField(fieldName, bindingFlags);
if (field == null)
{
Log.Error($"Couldn't find field info {fieldName} on type {type}");
}
return field;
}
public static T GetValueFromField<T>(FieldInfo field, object instance)
{
if (field == null || instance == null)
{
return default(T);
}
return (T)field.GetValue(instance);
}
internal static RoomVolumeCheck GetPlayerHeadVolumeCheck(this PlayerDeathHead head)
{
return GetValueFromField<RoomVolumeCheck>(DeathHeadVolumeCheckField, head);
}
internal static bool IsInExtractionPoint(this RoomVolumeCheck volumeCheck)
{
return GetValueFromField<bool>(IsInExtractionPointVolumeCheckField, volumeCheck);
}
}
internal static class Settings
{
private static ConfigEntry<bool> _enableInstantReviveEntry;
internal static bool EnableInstantRevive => _enableInstantReviveEntry.Value;
internal static void Bind(Mod mod)
{
_enableInstantReviveEntry = ((BaseUnityPlugin)mod).Config.Bind<bool>("General", "Enable Instant Revive", true, "When enabled, player will instantly revive when their head is in the extraction point.");
((BaseUnityPlugin)mod).Config.Save();
}
}