using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TradeForReviveMod { [BepInPlugin("REPOJP.TradeForRevive", "TradeForRevive", "1.1.0")] public sealed class TradeForRevivePlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.TradeForRevive"; public const string PluginName = "TradeForRevive"; public const string PluginVersion = "1.1.0"; internal static TradeForRevivePlugin Instance; internal static ManualLogSource Log; private void Awake() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown try { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); GameObject val = new GameObject("TradeForReviveManager"); val.transform.parent = null; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"TradeForRevive 1.1.0 loaded"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Awake failed\n" + ex)); } } } internal sealed class TradeForReviveManager : MonoBehaviour { private sealed class HoldState { public int ItemKey; public float StartTime; } private sealed class TradeCandidate { public PlayerDeathHead DeathHead; public PlayerAvatar PlayerAvatar; public PhysGrabObject PhysGrabObject; public ItemAttributes ItemAttributes; public string SourceLabel; public int TargetHp; public bool IsUsedHealthPack; public float DistanceSqr; } private struct ReviveValueResult { public bool Valid; public int TargetHp; public string SourceLabel; public bool IsUsedHealthPack; } [CompilerGenerated] private sealed class d__36 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TradeCandidate candidate; public int headViewId; public int itemKey; public TradeForReviveManager <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__36(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!<>4__this.CanExecuteTrade(candidate)) { <>4__this.ReleaseTradeLocks(headViewId, itemKey, consumed: false); return false; } <>4__this.ForceReleaseAllGrabbers(candidate.PhysGrabObject); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if (!<>4__this.CanExecuteTrade(candidate)) { <>4__this.ReleaseTradeLocks(headViewId, itemKey, consumed: false); return false; } <>4__this.ExecuteTradeCore(candidate); <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = null; <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = null; <>1__state = 4; return true; case 4: <>1__state = -1; <>4__this.FinalizeReviveHealth(candidate, headViewId); <>4__this.ReleaseTradeLocks(headViewId, itemKey, consumed: true); 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(); } } private static ConfigEntry configEnableMod; private static ConfigEntry configDetectRadius; private static ConfigEntry configTouchHoldSeconds; private static ConfigEntry configScanInterval; private static ConfigEntry configHeadCooldown; private static ConfigEntry configRequirePurchasedItem; private static ConfigEntry configAllowBatteryItems; private static ConfigEntry configAllowHealthPacks; private static ConfigEntry configAllowUsedHealthPacks; private static ConfigEntry configAllowZeroBatteryRevive; private static ConfigEntry configConsumeItem; private static ConfigEntry configDestroyWithEffects; private static ConfigEntry configDebugLog; private static readonly FieldInfo FieldPlayerDeathHeadTriggered = typeof(PlayerDeathHead).GetField("triggered", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerDeathHeadInExtractionPoint = typeof(PlayerDeathHead).GetField("inExtractionPoint", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerAvatarIsDisabled = typeof(PlayerAvatar).GetField("isDisabled", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerHealthHealth = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerHealthMaxHealth = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldItemAttributesInstanceName = typeof(ItemAttributes).GetField("instanceName", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldItemHealthPackUsed = typeof(ItemHealthPack).GetField("used", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPhysGrabObjectImpactDetector = typeof(PhysGrabObject).GetField("impactDetector", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo FieldPlayerDeathHeadPhysGrabObject = typeof(PlayerDeathHead).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.NonPublic); private readonly Dictionary headCooldownUntil = new Dictionary(); private readonly HashSet runningHeadIds = new HashSet(); private readonly HashSet runningItemIds = new HashSet(); private readonly HashSet consumedItemIds = new HashSet(); private readonly Dictionary holdStates = new Dictionary(); private float scanTimer; private void Awake() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown try { if (configEnableMod == null) { ConfigFile config = ((BaseUnityPlugin)TradeForRevivePlugin.Instance).Config; configEnableMod = config.Bind("General", "EnableMod", true, "Enable revive trading system.蘇生トレード機能の有効化"); configDetectRadius = config.Bind("General", "DetectRadius", 0.55f, new ConfigDescription("Detection radius around a death head for trade items.デスヘッド周囲で引き換えアイテムを検知する半径", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 2f), Array.Empty())); configTouchHoldSeconds = config.Bind("General", "TouchHoldSeconds", 2f, new ConfigDescription("Required continuous contact time before revive trade activates.蘇生トレードが発動するまでに必要な連続接触時間 秒", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 10f), Array.Empty())); configScanInterval = config.Bind("General", "ScanInterval", 0.05f, new ConfigDescription("Scan interval in seconds.検知処理の実行間隔 秒", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 1f), Array.Empty())); configHeadCooldown = config.Bind("General", "HeadCooldown", 0.75f, new ConfigDescription("Cooldown per death head after a successful trade.蘇生成功後の同一デスヘッド再判定クールダウン 秒", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); configRequirePurchasedItem = config.Bind("General", "RequirePurchasedItem", true, "Only allow purchased items to be traded.購入済みアイテムのみ引き換え対象にする"); configAllowBatteryItems = config.Bind("General", "AllowBatteryItems", true, "Allow battery powered items as revive payment.バッテリー付きアイテムを蘇生素材として許可する"); configAllowHealthPacks = config.Bind("General", "AllowHealthPacks", true, "Allow health packs as revive payment.ヘルスパックを蘇生素材として許可する"); configAllowUsedHealthPacks = config.Bind("General", "AllowUsedHealthPacks", true, "Allow used health packs to revive with 1 HP.使用済みヘルスパックによるHP1蘇生を許可する"); configAllowZeroBatteryRevive = config.Bind("General", "AllowZeroBatteryRevive", true, "Allow battery items with zero charge to revive with 1 HP.残量0のバッテリーでもHP1で蘇生を許可する"); configConsumeItem = config.Bind("General", "ConsumeItem", true, "Consume the traded item on success.蘇生成功時にアイテムを消費する"); configDestroyWithEffects = config.Bind("General", "DestroyWithEffects", true, "Destroy normal consumed items with break effects. 空のヘルスパック以外の消費アイテムを破壊演出ありで消す"); configDebugLog = config.Bind("Debug", "DebugLog", false, "Enable verbose debug logging.詳細デバッグログの有効化"); } ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("Manager Awake failed\n" + ex)); } } private void Update() { try { if (configEnableMod == null || !configEnableMod.Value || !SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel()) { return; } scanTimer -= Time.deltaTime; if (scanTimer > 0f) { return; } scanTimer = configScanInterval.Value; if (!((Object)(object)GameDirector.instance == (Object)null) && GameDirector.instance.PlayerList != null) { for (int i = 0; i < GameDirector.instance.PlayerList.Count; i++) { PlayerAvatar player = GameDirector.instance.PlayerList[i]; TryProcessPlayerDeathHead(player); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("Update failed\n" + ex)); } } private void TryProcessPlayerDeathHead(PlayerAvatar player) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.playerDeathHead == (Object)null || (Object)(object)player.playerHealth == (Object)null || !GetPlayerIsDisabled(player)) { return; } PlayerDeathHead playerDeathHead = player.playerDeathHead; PhysGrabObject deathHeadPhysGrabObject = GetDeathHeadPhysGrabObject(playerDeathHead); if (!IsDeathHeadTriggered(playerDeathHead) || (Object)(object)deathHeadPhysGrabObject == (Object)null) { return; } PhotonView component = ((Component)playerDeathHead).GetComponent(); int num = (((Object)(object)component != (Object)null) ? component.ViewID : ((Object)playerDeathHead).GetInstanceID()); if (runningHeadIds.Contains(num) || (headCooldownUntil.TryGetValue(num, out var value) && Time.time < value)) { return; } Collider[] array = Physics.OverlapSphere(deathHeadPhysGrabObject.centerPoint, configDetectRadius.Value, -1, (QueryTriggerInteraction)2); if (array == null || array.Length == 0) { return; } TradeCandidate tradeCandidate = null; for (int i = 0; i < array.Length; i++) { TradeCandidate tradeCandidate2 = BuildCandidateFromCollider(array[i], playerDeathHead); if (tradeCandidate2 != null && (tradeCandidate == null || tradeCandidate2.DistanceSqr < tradeCandidate.DistanceSqr)) { tradeCandidate = tradeCandidate2; } } if (tradeCandidate == null) { ClearHoldState(num); } else if (UpdateHoldStateAndCheckReady(num, tradeCandidate)) { int tradeItemKey = GetTradeItemKey(tradeCandidate.PhysGrabObject, tradeCandidate.ItemAttributes); if (!TryLockTradeItem(tradeItemKey)) { ClearHoldState(num); return; } runningHeadIds.Add(num); ClearHoldState(num); ClearHoldStatesByItem(tradeItemKey); ((MonoBehaviour)this).StartCoroutine(ExecuteTradeReviveRoutine(tradeCandidate, num, tradeItemKey)); } } private TradeCandidate BuildCandidateFromCollider(Collider hitCollider, PlayerDeathHead deathHead) { //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hitCollider == (Object)null) { return null; } PlayerDeathHead componentInParent = ((Component)hitCollider).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { return null; } PhysGrabObject componentInParent2 = ((Component)hitCollider).GetComponentInParent(); if ((Object)(object)componentInParent2 == (Object)null) { return null; } PhysGrabObject deathHeadPhysGrabObject = GetDeathHeadPhysGrabObject(deathHead); if ((Object)(object)componentInParent2 == (Object)(object)deathHeadPhysGrabObject) { return null; } ItemAttributes val = ((Component)componentInParent2).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)componentInParent2).GetComponentInParent(); } if ((Object)(object)val == (Object)null || (Object)(object)val.item == (Object)null) { return null; } if (!IsTradeItemCurrentlyHeld(componentInParent2)) { return null; } int tradeItemKey = GetTradeItemKey(componentInParent2, val); if (IsTradeItemLocked(tradeItemKey)) { return null; } int playerMaxHealth = GetPlayerMaxHealth(deathHead.playerAvatar); ReviveValueResult reviveValue = GetReviveValue(val, componentInParent2, playerMaxHealth); if (!reviveValue.Valid) { return null; } if (configRequirePurchasedItem.Value && !IsPurchasedTradeItem(val) && (!reviveValue.IsUsedHealthPack || !configAllowUsedHealthPacks.Value)) { return null; } if ((Object)(object)deathHeadPhysGrabObject == (Object)null) { return null; } TradeCandidate tradeCandidate = new TradeCandidate(); tradeCandidate.DeathHead = deathHead; tradeCandidate.PlayerAvatar = deathHead.playerAvatar; tradeCandidate.PhysGrabObject = componentInParent2; tradeCandidate.ItemAttributes = val; tradeCandidate.SourceLabel = reviveValue.SourceLabel; tradeCandidate.TargetHp = Mathf.Clamp(reviveValue.TargetHp, 1, playerMaxHealth); tradeCandidate.IsUsedHealthPack = reviveValue.IsUsedHealthPack; Vector3 val2 = componentInParent2.centerPoint - deathHeadPhysGrabObject.centerPoint; tradeCandidate.DistanceSqr = ((Vector3)(ref val2)).sqrMagnitude; return tradeCandidate; } private bool UpdateHoldStateAndCheckReady(int headViewId, TradeCandidate candidate) { if (candidate == null || (Object)(object)candidate.PhysGrabObject == (Object)null) { ClearHoldState(headViewId); return false; } int tradeItemKey = GetTradeItemKey(candidate.PhysGrabObject, candidate.ItemAttributes); float time = Time.time; if (!holdStates.TryGetValue(headViewId, out var value)) { value = new HoldState(); value.ItemKey = tradeItemKey; value.StartTime = time; holdStates[headViewId] = value; return false; } if (value.ItemKey != tradeItemKey) { value.ItemKey = tradeItemKey; value.StartTime = time; holdStates[headViewId] = value; return false; } if (time - value.StartTime < configTouchHoldSeconds.Value) { return false; } return true; } private void ClearHoldState(int headViewId) { if (holdStates.ContainsKey(headViewId)) { holdStates.Remove(headViewId); } } private int GetTradeItemKey(PhysGrabObject physGrabObject, ItemAttributes itemAttributes) { if ((Object)(object)physGrabObject != (Object)null) { PhotonView component = ((Component)physGrabObject).GetComponent(); if ((Object)(object)component != (Object)null) { return component.ViewID; } } if ((Object)(object)itemAttributes != (Object)null) { string instanceName = GetInstanceName(itemAttributes); if (!string.IsNullOrEmpty(instanceName)) { return instanceName.GetHashCode(); } } if ((Object)(object)physGrabObject != (Object)null) { return ((Object)physGrabObject).GetInstanceID(); } return 0; } private ReviveValueResult GetReviveValue(ItemAttributes itemAttributes, PhysGrabObject physGrabObject, int playerMaxHealth) { ReviveValueResult result = default(ReviveValueResult); result.Valid = false; result.TargetHp = 0; result.SourceLabel = string.Empty; result.IsUsedHealthPack = false; if (configAllowHealthPacks.Value) { ItemHealthPack val = ((Component)physGrabObject).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)physGrabObject).GetComponentInParent(); } if ((Object)(object)val != (Object)null) { bool flag = IsHealthPackUsed(val); if (flag && !configAllowUsedHealthPacks.Value) { return result; } result.Valid = true; result.TargetHp = (flag ? 1 : Mathf.Clamp(val.healAmount, 1, playerMaxHealth)); result.SourceLabel = (flag ? (GetDisplayItemName(itemAttributes) + " Used") : GetDisplayItemName(itemAttributes)); result.IsUsedHealthPack = flag; return result; } } if (configAllowBatteryItems.Value) { ItemBattery val2 = ((Component)physGrabObject).GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)physGrabObject).GetComponentInParent(); } if ((Object)(object)val2 != (Object)null) { string instanceName = GetInstanceName(itemAttributes); float batteryPercent = GetBatteryPercent(val2, instanceName); int targetHp; if (batteryPercent <= 0f) { if (!configAllowZeroBatteryRevive.Value) { return result; } targetHp = 1; } else { targetHp = Mathf.Max(1, Mathf.FloorToInt((float)playerMaxHealth * batteryPercent)); } result.Valid = true; result.TargetHp = targetHp; result.SourceLabel = GetDisplayItemName(itemAttributes); return result; } } return result; } [IteratorStateMachine(typeof(d__36))] private IEnumerator ExecuteTradeReviveRoutine(TradeCandidate candidate, int headViewId, int itemKey) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__36(0) { <>4__this = this, candidate = candidate, headViewId = headViewId, itemKey = itemKey }; } private bool CanExecuteTrade(TradeCandidate candidate) { try { if (candidate == null) { return false; } if ((Object)(object)candidate.DeathHead == (Object)null || (Object)(object)candidate.PlayerAvatar == (Object)null || (Object)(object)candidate.PlayerAvatar.playerHealth == (Object)null) { return false; } if ((Object)(object)candidate.PhysGrabObject == (Object)null || (Object)(object)candidate.ItemAttributes == (Object)null || (Object)(object)candidate.ItemAttributes.item == (Object)null) { return false; } if (!GetPlayerIsDisabled(candidate.PlayerAvatar)) { return false; } if (!IsDeathHeadTriggered(candidate.DeathHead)) { return false; } return true; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("CanExecuteTrade failed\n" + ex)); return false; } } private void ExecuteTradeCore(TradeCandidate candidate) { try { if (configConsumeItem.Value) { ConsumePurchasedItem(candidate.ItemAttributes); RemoveFromShoppingList(candidate.ItemAttributes); DestroyTradeItem(candidate); } SetDeathHeadInExtractionPoint(candidate.DeathHead, value: true); candidate.DeathHead.Revive(); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("ExecuteTradeCore failed\n" + ex)); } } private void FinalizeReviveHealth(TradeCandidate candidate, int headViewId) { try { if (candidate != null && !((Object)(object)candidate.PlayerAvatar == (Object)null) && !((Object)(object)candidate.PlayerAvatar.playerHealth == (Object)null) && !GetPlayerIsDisabled(candidate.PlayerAvatar)) { int playerCurrentHealth = GetPlayerCurrentHealth(candidate.PlayerAvatar); int playerMaxHealth = GetPlayerMaxHealth(candidate.PlayerAvatar); int num = Mathf.Clamp(candidate.TargetHp, 1, playerMaxHealth); int num2 = num - playerCurrentHealth; if (num2 > 0) { candidate.PlayerAvatar.playerHealth.HealOther(num2, true); } headCooldownUntil[headViewId] = Time.time + configHeadCooldown.Value; if (configDebugLog.Value) { TradeForRevivePlugin.Log.LogInfo((object)("Revived " + GetPlayerName(candidate.PlayerAvatar) + " with " + num + " HP by " + candidate.SourceLabel)); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("FinalizeReviveHealth failed\n" + ex)); } } private bool IsTradeItemLocked(int itemKey) { if (itemKey == 0) { return true; } return runningItemIds.Contains(itemKey) || consumedItemIds.Contains(itemKey); } private bool TryLockTradeItem(int itemKey) { if (IsTradeItemLocked(itemKey)) { return false; } runningItemIds.Add(itemKey); return true; } private void ReleaseTradeLocks(int headViewId, int itemKey, bool consumed) { runningHeadIds.Remove(headViewId); runningItemIds.Remove(itemKey); if (consumed && itemKey != 0) { consumedItemIds.Add(itemKey); } } private void ClearHoldStatesByItem(int itemKey) { List list = new List(); foreach (KeyValuePair holdState in holdStates) { if (holdState.Value != null && holdState.Value.ItemKey == itemKey) { list.Add(holdState.Key); } } for (int i = 0; i < list.Count; i++) { holdStates.Remove(list[i]); } } private bool IsTradeItemCurrentlyHeld(PhysGrabObject physGrabObject) { try { if ((Object)(object)physGrabObject == (Object)null) { return false; } if (physGrabObject.playerGrabbing != null && physGrabObject.playerGrabbing.Count > 0) { return true; } if (physGrabObject.grabbed || physGrabObject.grabbedLocal) { return true; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsTradeItemCurrentlyHeld failed\n" + ex)); } return false; } private void ForceReleaseAllGrabbers(PhysGrabObject physGrabObject) { try { if ((Object)(object)physGrabObject == (Object)null) { return; } List list = new List(physGrabObject.playerGrabbing); PhotonView component = ((Component)physGrabObject).GetComponent(); if ((Object)(object)component == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { PhysGrabber val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.photonView == (Object)null)) { val.photonView.RPC("ReleaseObjectRPC", (RpcTarget)0, new object[3] { false, 0.1f, component.ViewID }); } } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("ForceReleaseAllGrabbers failed\n" + ex)); } } private void ConsumePurchasedItem(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null || (Object)(object)StatsManager.instance == (Object)null) { return; } string instanceName = GetInstanceName(itemAttributes); if (!string.IsNullOrEmpty(instanceName) && StatsManager.instance.item.ContainsKey(instanceName)) { StatsManager.instance.ItemRemove(instanceName); } else { int num = 0; if (StatsManager.instance.itemsPurchased.ContainsKey(((Object)itemAttributes.item).name)) { num = StatsManager.instance.itemsPurchased[((Object)itemAttributes.item).name]; } StatsManager.instance.SetItemPurchase(itemAttributes.item, Mathf.Max(0, num - 1)); } if ((Object)(object)ItemManager.instance != (Object)null) { ItemManager.instance.purchasedItems.Remove(itemAttributes.item); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("ConsumePurchasedItem failed\n" + ex)); } } private void RemoveFromShoppingList(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes != (Object)null && (Object)(object)ShopManager.instance != (Object)null) { ShopManager.instance.ShoppingListItemRemove(itemAttributes); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("RemoveFromShoppingList failed\n" + ex)); } } private void DestroyTradeItem(TradeCandidate candidate) { try { if (candidate == null || (Object)(object)candidate.PhysGrabObject == (Object)null) { return; } PhysGrabObject physGrabObject = candidate.PhysGrabObject; ForceReleaseAllGrabbers(physGrabObject); if (candidate.IsUsedHealthPack) { physGrabObject.dead = true; physGrabObject.DestroyPhysGrabObject(); return; } PhysGrabObjectImpactDetector val = GetImpactDetector(physGrabObject); if ((Object)(object)val == (Object)null) { val = ((Component)physGrabObject).GetComponent(); } if ((Object)(object)val == (Object)null) { physGrabObject.dead = true; physGrabObject.DestroyPhysGrabObject(); } else { val.DestroyObject(configDestroyWithEffects.Value); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("DestroyTradeItem failed\n" + ex)); } } private bool IsHealthPackUsed(ItemHealthPack itemHealthPack) { try { if ((Object)(object)itemHealthPack == (Object)null || FieldItemHealthPackUsed == null) { return false; } object value = FieldItemHealthPackUsed.GetValue(itemHealthPack); return value is bool && (bool)value; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsHealthPackUsed failed\n" + ex)); return false; } } private float GetBatteryPercent(ItemBattery itemBattery, string instanceName) { try { if ((Object)(object)StatsManager.instance != (Object)null && !string.IsNullOrEmpty(instanceName) && StatsManager.instance.itemStatBattery.ContainsKey(instanceName)) { int batteryLevel = StatsManager.instance.GetBatteryLevel(instanceName); return Mathf.Clamp01((float)batteryLevel / 100f); } if ((Object)(object)itemBattery != (Object)null) { return Mathf.Clamp01(itemBattery.batteryLife / 100f); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetBatteryPercent failed\n" + ex)); } return 0f; } private bool IsPurchasedTradeItem(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null || (Object)(object)StatsManager.instance == (Object)null) { return false; } string instanceName = GetInstanceName(itemAttributes); if (!string.IsNullOrEmpty(instanceName) && StatsManager.instance.item.ContainsKey(instanceName)) { return true; } if (StatsManager.instance.itemsPurchased.ContainsKey(((Object)itemAttributes.item).name)) { return StatsManager.instance.itemsPurchased[((Object)itemAttributes.item).name] > 0; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsPurchasedTradeItem failed\n" + ex)); } return false; } private bool IsDeathHeadTriggered(PlayerDeathHead deathHead) { try { if ((Object)(object)deathHead == (Object)null || FieldPlayerDeathHeadTriggered == null) { return false; } object value = FieldPlayerDeathHeadTriggered.GetValue(deathHead); return value is bool && (bool)value; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("IsDeathHeadTriggered failed\n" + ex)); return false; } } private void SetDeathHeadInExtractionPoint(PlayerDeathHead deathHead, bool value) { try { if ((Object)(object)deathHead != (Object)null && FieldPlayerDeathHeadInExtractionPoint != null) { FieldPlayerDeathHeadInExtractionPoint.SetValue(deathHead, value); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("SetDeathHeadInExtractionPoint failed\n" + ex)); } } private bool GetPlayerIsDisabled(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null || FieldPlayerAvatarIsDisabled == null) { return false; } object value = FieldPlayerAvatarIsDisabled.GetValue(playerAvatar); return value is bool && (bool)value; } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetPlayerIsDisabled failed\n" + ex)); return false; } } private int GetPlayerCurrentHealth(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null || (Object)(object)playerAvatar.playerHealth == (Object)null || FieldPlayerHealthHealth == null) { return 1; } object value = FieldPlayerHealthHealth.GetValue(playerAvatar.playerHealth); if (value is int) { return (int)value; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetPlayerCurrentHealth failed\n" + ex)); } return 1; } private int GetPlayerMaxHealth(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null || (Object)(object)playerAvatar.playerHealth == (Object)null || FieldPlayerHealthMaxHealth == null) { return 100; } object value = FieldPlayerHealthMaxHealth.GetValue(playerAvatar.playerHealth); if (value is int) { return Mathf.Max(1, (int)value); } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetPlayerMaxHealth failed\n" + ex)); } return 100; } private string GetPlayerName(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar == (Object)null) { return "Unknown"; } return ((Object)playerAvatar).name; } catch { return "Unknown"; } } private string GetDisplayItemName(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null) { return "Unknown Item"; } return itemAttributes.item.itemName; } catch { return "Unknown Item"; } } private string GetInstanceName(ItemAttributes itemAttributes) { try { if ((Object)(object)itemAttributes == (Object)null || FieldItemAttributesInstanceName == null) { return string.Empty; } object value = FieldItemAttributesInstanceName.GetValue(itemAttributes); if (value is string) { return (string)value; } } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetInstanceName failed\n" + ex)); } return string.Empty; } private PhysGrabObject GetDeathHeadPhysGrabObject(PlayerDeathHead deathHead) { try { if ((Object)(object)deathHead == (Object)null || FieldPlayerDeathHeadPhysGrabObject == null) { return null; } object? value = FieldPlayerDeathHeadPhysGrabObject.GetValue(deathHead); return (PhysGrabObject)((value is PhysGrabObject) ? value : null); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetDeathHeadPhysGrabObject failed\n" + ex)); return null; } } private PhysGrabObjectImpactDetector GetImpactDetector(PhysGrabObject physGrabObject) { try { if ((Object)(object)physGrabObject == (Object)null || FieldPhysGrabObjectImpactDetector == null) { return null; } object? value = FieldPhysGrabObjectImpactDetector.GetValue(physGrabObject); return (PhysGrabObjectImpactDetector)((value is PhysGrabObjectImpactDetector) ? value : null); } catch (Exception ex) { TradeForRevivePlugin.Log.LogError((object)("GetImpactDetector failed\n" + ex)); return null; } } } }