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 ReviveUtils v1.1.1
ReviveUtils.dll
Decompiled 11 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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 ReviveUtils.Components; using ReviveUtils.Patches; using UnityEngine; using UnityEngine.InputSystem; [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("Jay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ab4536b0ebae776412bfdc40aaa16cdf6a612f01")] [assembly: AssemblyProduct("ReviveUtils")] [assembly: AssemblyTitle("ReviveUtils")] [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 ReviveUtils { [BepInPlugin("jaydev.ReviveUtils", "ReviveUtils", "1.1.1")] public class ReviveUtils : BaseUnityPlugin { internal static ReviveUtils Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; ConfigManager.Init(); Patch(); Logger.LogInfo((object)"模組載入完成!"); } internal void Patch() { //IL_0019: 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_0020: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(typeof(PlayerAvatarPatch)); Harmony.PatchAll(typeof(PlayerControllerPatch)); Harmony.PatchAll(typeof(PlayerDeathHeadPatch)); Harmony.PatchAll(typeof(ShopManagerPatch)); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } public static class ConfigManager { private static readonly ConfigFile configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ReviveUtils.cfg"), true); private static ConfigEntry<bool> _enableShopRespawn; private static ConfigEntry<int> _shopRespawnDelay; private static ConfigEntry<bool> _enableExtractionHeal; private static ConfigEntry<int> _extractionHealValue; private static ConfigEntry<bool> _enableExtractionHealPercentage; private static ConfigEntry<int> _extractionHealPercentage; private static ConfigEntry<bool> _enableCustomTruckHeal; private static ConfigEntry<int> _truckHealValue; private static ConfigEntry<bool> _enableTruckHealPercentage; private static ConfigEntry<int> _truckHealPercentage; private static ConfigEntry<bool> _enableSacrificialRevive; private static ConfigEntry<int> _sacrificialReviveHpCost; private static ConfigEntry<string> _sacrificialReviveKeybind; private static ConfigEntry<bool> _enablePointRevive; public static bool EnableShopRespawn => _enableShopRespawn.Value; public static int ShopRespawnDelay => _shopRespawnDelay.Value; public static bool EnableExtractionHeal => _enableExtractionHeal.Value; public static int ExtractionHealValue => _extractionHealValue.Value; public static bool EnableExtractionHealPercentage => _enableExtractionHealPercentage.Value; public static int ExtractionHealPercentage => _extractionHealPercentage.Value; public static bool EnableCustomTruckHeal => _enableCustomTruckHeal.Value; public static int TruckHealValue => _truckHealValue.Value; public static bool EnableTruckHealPercentage => _enableTruckHealPercentage.Value; public static int TruckHealPercentage => _truckHealPercentage.Value; public static bool EnableSacrificialRevive => _enableSacrificialRevive.Value; public static int SacrificialReviveHpCost => _sacrificialReviveHpCost.Value; public static string SacrificialReviveKeybind => _sacrificialReviveKeybind.Value; public static bool EnablePointRevive => _enablePointRevive.Value; public static void Init() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown _enableShopRespawn = configFile.Bind<bool>("Shop Respawn", "Enable", true, "Enable shop respawn"); _shopRespawnDelay = configFile.Bind<int>("Shop Respawn", "Respawn Delay", 5, new ConfigDescription("Respawn delay in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), Array.Empty<object>())); _enableExtractionHeal = configFile.Bind<bool>("Extraction Heal", "Enable", true, "Enable extraction healing"); _extractionHealValue = configFile.Bind<int>("Extraction Heal", "Heal Value", 50, "Extraction healing value"); _enableExtractionHealPercentage = configFile.Bind<bool>("Extraction Heal", "Enable Percentage Healing", false, "Whether to heal player by the percentage of their max hp"); _extractionHealPercentage = configFile.Bind<int>("Extraction Heal", "Heal Percentage", 50, new ConfigDescription("Extraction healing percentage", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); _enableCustomTruckHeal = configFile.Bind<bool>("Truck Heal", "Enable", true, "Enable custom truck healing value"); _truckHealValue = configFile.Bind<int>("Truck Heal", "Heal Value", 50, "Truck healing value"); _enableTruckHealPercentage = configFile.Bind<bool>("Truck Heal", "Enable Percentage Healing", false, "Whether to heal player by the percentage of their max hp"); _truckHealPercentage = configFile.Bind<int>("Truck Heal", "Heal Percentage", 50, new ConfigDescription("Truck healing percentage", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); _enableSacrificialRevive = configFile.Bind<bool>("Sacrificial Revive", "Enable", true, "Enable sacrificial revive"); _sacrificialReviveHpCost = configFile.Bind<int>("Sacrificial Revive", "Health Cost", 10, "Amount of health to spend on reviving"); _sacrificialReviveKeybind = configFile.Bind<string>("Sacrificial Revive", "Keybind", "R", "Keybind for sacrificial revive"); _enablePointRevive = configFile.Bind<bool>("Extraction Point Revive", "Enable", false, "Enable instant revive on extraction point"); } } } namespace ReviveUtils.Patches { [HarmonyPatch(typeof(PlayerAvatar))] public static class PlayerAvatarPatch { [HarmonyPostfix] [HarmonyPatch("ReviveRPC")] public static void ExtractionHealPatch(PlayerAvatar __instance, bool _revivedByTruck) { if (!(!ConfigManager.EnableExtractionHeal || _revivedByTruck)) { int num = ConfigManager.ExtractionHealValue; if (ConfigManager.EnableExtractionHealPercentage) { num = __instance.playerHealth.maxHealth * ConfigManager.ExtractionHealPercentage / 100; } __instance.playerHealth.Heal(num - 1, true); ReviveUtils.Logger.LogInfo((object)$"玩家 {__instance.playerName} 復活,恢復 {num} 血量"); } } [HarmonyPrefix] [HarmonyPatch("FinalHealRPC")] public static bool TruckHealPatch(PlayerAvatar __instance) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (!ConfigManager.EnableCustomTruckHeal || __instance.finalHeal || !__instance.isLocal) { return true; } int num = ConfigManager.TruckHealValue; if (ConfigManager.EnableTruckHealPercentage) { num = __instance.playerHealth.maxHealth * ConfigManager.TruckHealPercentage / 100; } if (SemiFunc.IsMasterClientOrSingleplayer()) { TruckScreenText.instance.MessageSendCustom("", __instance.playerName + " {arrowright}{truck}{check}\n {point}{shades}{pointright}<b><color=#00FF00>+" + num + "</color></b>{heart}", 0); } __instance.playerHealth.EyeMaterialOverride((EyeOverrideState)2, 2f, 1); __instance.playerHealth.Heal(num, true); TruckHealer.instance.Heal(__instance); __instance.truckReturn.Play(__instance.PlayerVisionTarget.VisionTransform.position, 1f, 1f, 1f, 1f); __instance.truckReturnGlobal.Play(__instance.PlayerVisionTarget.VisionTransform.position, 1f, 1f, 1f, 1f); ((Component)__instance.playerAvatarVisuals.effectGetIntoTruck).gameObject.SetActive(true); __instance.finalHeal = true; ReviveUtils.Logger.LogInfo((object)$"玩家 {__instance.playerName} 上車,恢復 {num} 血量"); return false; } [HarmonyPostfix] [HarmonyPatch("PlayerDeathRPC")] public static void ShopRespawnPatch(PlayerAvatar __instance) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if (ConfigManager.EnableShopRespawn && SemiFunc.IsMasterClient() && !((Object)(object)RunManager.instance.levelCurrent != (Object)(object)RunManager.instance.levelShop)) { ReviveUtils.Logger.LogInfo((object)("玩家 " + __instance.playerName + " 死於商店中,準備復活...")); GameObject val = new GameObject("ShopRespawn"); ShopRespawn shopRespawn = val.AddComponent<ShopRespawn>(); shopRespawn.PlayerAvatarInstance = __instance; } } } [HarmonyPatch(typeof(PlayerController))] public static class PlayerControllerPatch { public static PlayerDeathHead? grabbedHead { get; private set; } [HarmonyPostfix] [HarmonyPatch("FixedUpdate")] public static void GrabbedHeadDetectionPatch(PlayerController __instance) { if (!ConfigManager.EnableSacrificialRevive || !SemiFunc.IsMultiplayer() || (Object)(object)__instance == (Object)null) { return; } if ((Object)(object)__instance.physGrabObject != (Object)null && __instance.physGrabActive) { PlayerDeathHead component = __instance.physGrabObject.GetComponent<PlayerDeathHead>(); if ((Object)(object)component != (Object)null && (Object)(object)component.playerAvatar != (Object)null) { grabbedHead = component; } } else if ((Object)(object)grabbedHead != (Object)null) { grabbedHead = null; } } } [HarmonyPatch(typeof(PlayerDeathHead))] public static class PlayerDeathHeadPatch { [HarmonyPostfix] [HarmonyPatch("Update")] public static void InstantRevivePatch(PlayerDeathHead __instance) { if (ConfigManager.EnablePointRevive && SemiFunc.IsMasterClient() && __instance.inExtractionPoint) { __instance.playerAvatar.Revive(false); ReviveUtils.Logger.LogInfo((object)("點上復活 " + __instance.playerAvatar.playerName)); } } } [HarmonyPatch(typeof(ShopManager))] public static class ShopManagerPatch { [HarmonyPostfix] [HarmonyPatch("Awake")] public static void SacrificialReviveListener(ShopManager __instance) { if (ConfigManager.EnableSacrificialRevive && (Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).gameObject.GetComponent<SacrificialRevive>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<SacrificialRevive>(); } } } } namespace ReviveUtils.Components { public class SacrificialRevive : MonoBehaviour { private void Update() { PlayerDeathHead grabbedHead = PlayerControllerPatch.grabbedHead; PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; int sacrificialReviveHpCost = ConfigManager.SacrificialReviveHpCost; if (InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[ConfigManager.SacrificialReviveKeybind], 0f) && !((Object)(object)grabbedHead == (Object)null) && playerAvatarScript.playerHealth.health >= sacrificialReviveHpCost) { grabbedHead.playerAvatar.Revive(false); playerAvatarScript.playerHealth.Hurt(sacrificialReviveHpCost, false, -1); ReviveUtils.Logger.LogInfo((object)("復活 " + grabbedHead.playerAvatar.playerName)); } } } public class ShopRespawn : MonoBehaviour { [CompilerGenerated] private sealed class <RespawnPlayer>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ShopRespawn <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RespawnPlayer>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; ShopRespawn shopRespawn = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds((float)ConfigManager.ShopRespawnDelay); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)LevelGenerator.Instance == (Object)null) { ReviveUtils.Logger.LogWarning((object)"LevelGenerator不存在"); } else if (shopRespawn.PlayerAvatarInstance.deadSet) { Vector3 position = ((Component)Object.FindObjectOfType<SpawnPoint>()).transform.position; Quaternion rotation = ((Component)shopRespawn.PlayerAvatarInstance.playerDeathHead).transform.rotation; shopRespawn.PlayerAvatarInstance.Revive(false); shopRespawn.PlayerAvatarInstance.Spawn(position, rotation); ReviveUtils.Logger.LogInfo((object)("復活玩家 " + shopRespawn.PlayerAvatarInstance.playerName)); } else { ReviveUtils.Logger.LogInfo((object)("取消復活,玩家 " + shopRespawn.PlayerAvatarInstance.playerName + " 已復活或未死亡")); } Object.Destroy((Object)(object)((Component)shopRespawn).gameObject); 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(); } } public PlayerAvatar PlayerAvatarInstance { get; set; } private void Start() { ((MonoBehaviour)this).StartCoroutine(RespawnPlayer()); } [IteratorStateMachine(typeof(<RespawnPlayer>d__5))] private IEnumerator RespawnPlayer() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RespawnPlayer>d__5(0) { <>4__this = this }; } } }