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 UltimateReviveNew v1.1.0
UltimateReviveMod.dll
Decompiled 6 days agousing 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 Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [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("UltimateReviveMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("UltimateReviveMod")] [assembly: AssemblyTitle("UltimateReviveMod")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace RevivePlayer { [BepInPlugin("com.yuniverse.reviveplayer", "Revive Player", "1.1.0")] public class Plugin : BaseUnityPlugin { public static Plugin Instance; public static ManualLogSource Log; private Harmony harmony; private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ConfigManager.Init(((BaseUnityPlugin)this).Config); harmony = new Harmony("com.yuniverse.reviveplayer"); harmony.PatchAll(); Log.LogInfo((object)"RevivePlayer 模組已成功載入!(修正多人連線血量同步問題)"); } } public static class ConfigManager { public static ConfigEntry<float> HpPercentCost; public static ConfigEntry<int> TargetReviveHp; public static ConfigEntry<string> ReviveKey; public static void Init(ConfigFile config) { HpPercentCost = config.Bind<float>("General", "HP Percent Cost", 0.1f, "施救者需要消耗自己當前血量的百分比 (0.10 = 10%)"); TargetReviveHp = config.Bind<int>("General", "Target Revive HP", 100, "隊友復活後的血量 (預設 100 為滿血)"); ReviveKey = config.Bind<string>("Controls", "Revive Key", "H", "執行復活的按鍵"); } } [HarmonyPatch(typeof(PlayerController), "FixedUpdate")] public static class PlayerControllerPatch { public static PlayerDeathHead GrabbedHead; public static PlayerAvatar GrabbedAvatar; public static bool IsGrabbing; private static void Postfix(PlayerController __instance) { IsGrabbing = false; GrabbedHead = null; GrabbedAvatar = null; if ((Object)(object)__instance != (Object)null && __instance.physGrabActive && (Object)(object)__instance.physGrabObject != (Object)null) { PlayerDeathHead component = __instance.physGrabObject.GetComponent<PlayerDeathHead>(); if ((Object)(object)component != (Object)null && (Object)(object)component.playerAvatar != (Object)null) { GrabbedHead = component; GrabbedAvatar = component.playerAvatar; IsGrabbing = true; } } } } [HarmonyPatch(typeof(PhysGrabCart), "Update")] public static class PhysGrabCartPatch { private static void Postfix() { //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.RunIsShop() || !PlayerControllerPatch.IsGrabbing) { return; } PlayerAvatar grabbedAvatar = PlayerControllerPatch.GrabbedAvatar; if ((Object)(object)grabbedAvatar == (Object)null) { return; } PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerAvatarScript == (Object)null) { return; } PlayerHealth playerHealth = instance.playerAvatarScript.playerHealth; if ((Object)(object)playerHealth != (Object)null) { int healthInternal = Helpers.GetHealthInternal(playerHealth); float num = Mathf.Clamp01(ConfigManager.HpPercentCost.Value); int num2 = Mathf.Max(1, Mathf.CeilToInt((float)healthInternal * num)); string value = ConfigManager.ReviveKey.Value; if (healthInternal <= num2) { ItemInfoExtraUI.instance.ItemInfoText($"血量不足以施展復活 (需要 {num2} HP)", new Color(1f, 0.2f, 0.2f)); return; } string name = ((Object)grabbedAvatar).name; ItemInfoExtraUI.instance.ItemInfoText($"按下 [{value}] 復活 {name} (-{num2} HP / {Mathf.RoundToInt(num * 100f)}%)", new Color(0.2f, 1f, 0.2f)); } } } [HarmonyPatch(typeof(PlayerController), "Awake")] public static class InjectPatch { private static void Postfix(PlayerController __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<ReviveManager>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<ReviveManager>(); } } } public class ReviveManager : MonoBehaviourPun { private void Update() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown if (!Input.GetKeyDown(Helpers.ParseKey(ConfigManager.ReviveKey.Value)) || !PlayerControllerPatch.IsGrabbing) { return; } PlayerAvatar grabbedAvatar = PlayerControllerPatch.GrabbedAvatar; if ((Object)(object)grabbedAvatar == (Object)null || (Object)(object)grabbedAvatar.photonView == (Object)null) { return; } PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerAvatarScript == (Object)null) { return; } PlayerHealth playerHealth = instance.playerAvatarScript.playerHealth; if ((Object)(object)playerHealth == (Object)null) { return; } int healthInternal = Helpers.GetHealthInternal(playerHealth); float num = Mathf.Clamp01(ConfigManager.HpPercentCost.Value); int num2 = Mathf.Max(1, Mathf.CeilToInt((float)healthInternal * num)); if (healthInternal > num2) { PhotonView val = PhotonView.Get((Component)this); if ((Object)(object)val != (Object)null) { int viewID = grabbedAvatar.photonView.ViewID; Plugin.Log.LogInfo((object)$"[連線要求] 正在向伺服器申請復活 {((Object)grabbedAvatar).name} (ID: {viewID}),扣除自身 {num2} HP"); val.RPC("HostRevive", (RpcTarget)2, new object[1] { viewID }); playerHealth.Hurt(num2, true, -1, false); } } } [PunRPC] private void HostRevive(int viewID) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if (!PhotonNetwork.IsMasterClient) { return; } Plugin.Log.LogInfo((object)$"[伺服器端] 房主收到復活請求,正在處理 ViewID: {viewID}"); PhotonView val = PhotonView.Find(viewID); if (!((Object)(object)val != (Object)null)) { return; } PlayerAvatar component = ((Component)val).GetComponent<PlayerAvatar>(); if ((Object)(object)component != (Object)null) { component.Revive(false); int value = ConfigManager.TargetReviveHp.Value; PhotonView val2 = PhotonView.Get((Component)this); if ((Object)(object)val2 != (Object)null) { val2.RPC("SyncHealth", (RpcTarget)0, new object[2] { viewID, value }); } } } [PunRPC] private void SyncHealth(int viewID, int targetHp) { PhotonView val = PhotonView.Find(viewID); if (!((Object)(object)val != (Object)null)) { return; } PlayerHealth component = ((Component)val).GetComponent<PlayerHealth>(); if ((Object)(object)component != (Object)null) { Traverse.Create((object)component).Field("health").SetValue((object)targetHp); if (val.IsMine) { Traverse.Create((object)component).Method("UpdateHealthUI", Array.Empty<object>()).GetValue(); } Plugin.Log.LogInfo((object)$"[連線同步] 玩家 (ViewID: {viewID}) 的血量已強制同步為: {targetHp}"); } } } public static class Helpers { public static KeyCode ParseKey(string key) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(key)) { return (KeyCode)104; } try { return (KeyCode)Enum.Parse(typeof(KeyCode), key.ToUpperInvariant(), ignoreCase: true); } catch { return (KeyCode)104; } } public static int GetHealthInternal(PlayerHealth health) { return Traverse.Create((object)health).Field("health").GetValue<int>(); } } }