Decompiled source of StaminaLinked v0.2.0

legocool.StaminaLinked.dll

Decompiled 2 months ago
using System;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.legocool.StaminaLinked")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("com.github.legocool.StaminaLinked")]
[assembly: AssemblyTitle("StaminaLinked")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace StaminaLinked
{
	[BepInPlugin("legocool.StaminaLinked", "StaminaLinked", "0.2.0")]
	public class StaminaLinked : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Character), "UseStamina")]
		public static class Patch_UseStamina
		{
			private static bool Prefix(Character __instance, float usage, bool useBonusStamina)
			{
				if (!__instance.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient && staminaUseToggle.Value)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestUseStamina", (RpcTarget)2, new object[2] { usage, useBonusStamina });
				}
				return true;
			}

			private static void Postfix(CharacterAfflictions __instance, float usage, bool useBonusStamina)
			{
				if (PhotonNetwork.IsMasterClient && staminaUseToggle.Value)
				{
					StaminaSync.Instance.BroadcastStamina();
				}
			}
		}

		[HarmonyPatch(typeof(Character), "AddExtraStamina")]
		public static class Patch_AddExtraStamina
		{
			private static bool Prefix(Character __instance, float add)
			{
				if (!__instance.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestAddExtraStamina", (RpcTarget)2, new object[1] { add });
				}
				return true;
			}

			private static void Postfix(CharacterAfflictions __instance, float add)
			{
				if (PhotonNetwork.IsMasterClient)
				{
					StaminaSync.Instance.BroadcastStamina();
				}
			}
		}

		[HarmonyPatch(typeof(Character), "SetExtraStamina")]
		public static class Patch_SetExtraStamina
		{
			private static bool Prefix(Character __instance, float amt)
			{
				if (!__instance.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestSetExtraStamina", (RpcTarget)2, new object[1] { amt });
				}
				return true;
			}

			private static void Postfix(CharacterAfflictions __instance, float amt)
			{
				if (PhotonNetwork.IsMasterClient)
				{
					StaminaSync.Instance.BroadcastStamina();
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "SubtractStatus")]
		public static class Patch_SubtractStatus
		{
			private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC = false)
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected I4, but got Unknown
				if (!__instance.character.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestSubtractStatus", (RpcTarget)2, new object[2]
					{
						(int)statusType,
						amount
					});
				}
				return true;
			}

			private static void Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC = false)
			{
				if (PhotonNetwork.IsMasterClient)
				{
					StaminaSync.Instance.BroadcastStatuses();
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
		public static class Patch_AddStatus
		{
			private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount, bool fromRPC = false)
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Invalid comparison between Unknown and I4
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected I4, but got Unknown
				if (!__instance.character.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					if ((int)statusType == 1)
					{
						return false;
					}
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestAddStatus", (RpcTarget)2, new object[2]
					{
						(int)statusType,
						amount
					});
				}
				if ((int)statusType == 1)
				{
					amount *= PlayerHandler.GetAllPlayers().Count;
				}
				return true;
			}

			private static void Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC = false)
			{
				if (PhotonNetwork.IsMasterClient)
				{
					StaminaSync.Instance.BroadcastStatuses();
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "SetStatus")]
		public static class Patch_SetStatus
		{
			private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount)
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected I4, but got Unknown
				if (!__instance.character.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestSetStatus", (RpcTarget)2, new object[2]
					{
						(int)statusType,
						amount
					});
				}
				return true;
			}

			private static void Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount)
			{
				if (PhotonNetwork.IsMasterClient)
				{
					StaminaSync.Instance.BroadcastStatuses();
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "UpdateWeight")]
		public static class Patch_UpdateWeight
		{
			private static bool Prefix(CharacterAfflictions __instance)
			{
				calcWeight();
				return false;
			}
		}

		[HarmonyPatch(typeof(Action_ApplyInfiniteStamina), "RunAction")]
		public static class Patch_ApplyInfiniteStamina
		{
			private static bool Prefix(Action_ApplyInfiniteStamina __instance)
			{
				if (!((ItemActionBase)__instance).character.view.IsMine)
				{
					return false;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_RequestInfiniteStamina", (RpcTarget)2, new object[1] { __instance.buffTime });
					return false;
				}
				((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_ApplyInfiniteStamina", (RpcTarget)1, new object[1] { __instance.buffTime });
				return false;
			}
		}

		[HarmonyPatch(typeof(Character), "UpdateVariablesFixed")]
		public static class Patch_MoreStaminaRegen
		{
			private static void Postfix(Character __instance)
			{
				if (__instance.CanRegenStamina())
				{
					float num = 0.2f * staminaRegenModifier.Value;
					__instance.AddStamina(Time.fixedDeltaTime * num);
				}
			}
		}

		[HarmonyPatch(typeof(Character), "CanRegenStamina")]
		public static class Patch_CanRegenStamina
		{
			private static bool Prefix(Character __instance, ref bool __result)
			{
				if (staminaUseToggle.Value)
				{
					return true;
				}
				foreach (Character allPlayerCharacter in PlayerHandler.GetAllPlayerCharacters())
				{
					if (!Object.op_Implicit((Object)(object)allPlayerCharacter.data.currentClimbHandle) && !allPlayerCharacter.IsStuck())
					{
						float num = ((allPlayerCharacter.data.currentStamina > 0f) ? 1f : 2f);
						if (!(allPlayerCharacter.data.sinceGrounded <= 0.2f) || !(allPlayerCharacter.data.sinceUseStamina >= num))
						{
							__result = false;
							return false;
						}
					}
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "OnPlayerEnteredRoom")]
		public static class Patch_SyncConfig
		{
			private static void Postfix(Player __instance, Player newPlayer)
			{
				if (PhotonNetwork.IsMasterClient)
				{
					((MonoBehaviourPun)StaminaSync.Instance).photonView.RPC("RPC_SyncConfig", newPlayer, new object[3] { staminaUseToggle.Value, backpackModifier.Value, staminaRegenModifier.Value });
				}
			}
		}

		private Harmony _harmony;

		public static ConfigEntry<bool> staminaUseToggle;

		public static ConfigEntry<float> backpackModifier;

		public static ConfigEntry<float> staminaRegenModifier;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("legocool.StaminaLinked");
			_harmony.PatchAll();
			GameObject val = new GameObject("StaminaSyncManager");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<StaminaSync>();
			PhotonView val2 = val.AddComponent<PhotonView>();
			val2.ViewID = 999999999;
			staminaUseToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Stamina Use Sharing", true, "Whether stamina use should be shared or not.");
			backpackModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifiers", "Backpack weight modifier", 0.5f, "The weight modifier of the items in the backpack. 0.5 = 50% less");
			staminaRegenModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifiers", "Stamina regeneration modifier", 0.5f, "Modifier for how fast stamina willl regen. 0.5 = 50% faster");
			Log.LogInfo((object)"Plugin StaminaLinked is loaded!");
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}

		public static void calcWeight()
		{
			int num = 0;
			int num2 = 0;
			BackpackData val2 = default(BackpackData);
			foreach (Character allPlayerCharacter in PlayerHandler.GetAllPlayerCharacters())
			{
				int num3 = 0;
				int num4 = 0;
				float currentStatus = allPlayerCharacter.refs.afflictions.GetCurrentStatus((STATUSTYPE)9);
				for (int i = 0; i < allPlayerCharacter.player.itemSlots.Length; i++)
				{
					ItemSlot val = allPlayerCharacter.player.itemSlots[i];
					if ((Object)(object)val.prefab != (Object)null)
					{
						num3 += val.prefab.CarryWeight;
					}
				}
				BackpackSlot backpackSlot = allPlayerCharacter.player.backpackSlot;
				if (!((ItemSlot)backpackSlot).IsEmpty() && ((ItemSlot)backpackSlot).data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val2))
				{
					for (int j = 0; j < val2.itemSlots.Length; j++)
					{
						ItemSlot val3 = val2.itemSlots[j];
						if (!val3.IsEmpty())
						{
							num3 += (int)((float)val3.prefab.CarryWeight * backpackModifier.Value);
						}
					}
				}
				ItemSlot itemSlot = allPlayerCharacter.player.GetItemSlot((byte)250);
				if (!itemSlot.IsEmpty())
				{
					num3 += itemSlot.prefab.CarryWeight;
				}
				if ((Object)(object)allPlayerCharacter.data.carriedPlayer != (Object)null)
				{
					num3 += 8;
				}
				foreach (StickyItemComponent aLL_STUCK_ITEM in StickyItemComponent.ALL_STUCK_ITEMS)
				{
					if ((Object)(object)aLL_STUCK_ITEM.stuckToCharacter == (Object)(object)allPlayerCharacter)
					{
						num3 += aLL_STUCK_ITEM.addWeightToStuckPlayer;
						num4 += aLL_STUCK_ITEM.addThornsToStuckPlayer;
					}
				}
				if (Object.op_Implicit((Object)(object)allPlayerCharacter.data.currentStickyItem))
				{
					num4 += allPlayerCharacter.data.currentStickyItem.addThornsToStuckPlayer;
				}
				num4 += allPlayerCharacter.refs.afflictions.GetTotalThornStatusIncrements();
				float num5 = 0.025f * (float)num4;
				if (num5 > currentStatus)
				{
					allPlayerCharacter.refs.afflictions.StatusSFX((STATUSTYPE)9, num5 - currentStatus);
					if (allPlayerCharacter.IsLocal && (Object)(object)allPlayerCharacter == (Object)(object)Character.observedCharacter)
					{
						GUIManager.instance.AddStatusFX((STATUSTYPE)9, num5 - currentStatus);
					}
					allPlayerCharacter.refs.afflictions.PlayParticle((STATUSTYPE)9);
				}
				num += num3;
				num2 += num4;
			}
			Character.localCharacter.refs.afflictions.SetStatus((STATUSTYPE)7, 0.025f * (float)num);
			Character.localCharacter.refs.afflictions.SetStatus((STATUSTYPE)9, 0.025f * (float)num2);
		}
	}
	public class StaminaSync : MonoBehaviourPun
	{
		public static StaminaSync Instance;

		private void Awake()
		{
			Instance = this;
		}

		[PunRPC]
		public void RPC_RequestUseStamina(float usage, bool useBonus)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.UseStamina(usage, useBonus);
				BroadcastStamina();
			}
		}

		[PunRPC]
		public void RPC_RequestAddExtraStamina(float add)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.AddExtraStamina(add);
				BroadcastStamina();
			}
		}

		[PunRPC]
		public void RPC_RequestSetExtraStamina(float amt)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.SetExtraStamina(amt);
				BroadcastStamina();
			}
		}

		[PunRPC]
		public void RPC_RequestAddStatus(int statusType, float amt)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.refs.afflictions.AddStatus((STATUSTYPE)statusType, amt, false);
				BroadcastStatuses();
			}
		}

		[PunRPC]
		public void RPC_RequestSubtractStatus(int statusType, float amt)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.refs.afflictions.SubtractStatus((STATUSTYPE)statusType, amt, false);
				BroadcastStatuses();
			}
		}

		[PunRPC]
		public void RPC_RequestSetStatus(int statusType, float amt)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.refs.afflictions.SetStatus((STATUSTYPE)statusType, amt);
				BroadcastStatuses();
			}
		}

		[PunRPC]
		public void RPC_RequestInfiniteStamina(float buffTime)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient)
			{
				Character.localCharacter.refs.afflictions.AddAffliction((Affliction)new Affliction_InfiniteStamina(buffTime), false);
				((MonoBehaviourPun)this).photonView.RPC("RPC_ApplyInfiniteStamina", (RpcTarget)1, new object[1] { buffTime });
			}
		}

		[PunRPC]
		public void RPC_ApplyInfiniteStamina(float buffTime)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Character.localCharacter.refs.afflictions.AddAffliction((Affliction)new Affliction_InfiniteStamina(buffTime), false);
		}

		public void BroadcastStamina()
		{
			Character localCharacter = Character.localCharacter;
			((MonoBehaviourPun)this).photonView.RPC("RPC_SyncStamina", (RpcTarget)1, new object[4]
			{
				localCharacter.data.currentStamina,
				localCharacter.data.extraStamina,
				localCharacter.data.sinceUseStamina,
				localCharacter.infiniteStam
			});
		}

		public void BroadcastStatuses()
		{
			CharacterAfflictions afflictions = Character.localCharacter.refs.afflictions;
			((MonoBehaviourPun)this).photonView.RPC("RPC_SyncStatus", (RpcTarget)1, new object[5] { afflictions.currentStatuses, afflictions.currentIncrementalStatuses, afflictions.currentDecrementalStatuses, afflictions.lastAddedStatus, afflictions.lastAddedIncrementalStatus });
		}

		[PunRPC]
		public void RPC_SyncStamina(float current, float extra, float sinceUse, bool infinite)
		{
			if ((Object)(object)Character.localCharacter != (Object)null)
			{
				Character.localCharacter.data.currentStamina = current;
				Character.localCharacter.data.extraStamina = extra;
				Character.localCharacter.data.sinceUseStamina = sinceUse;
				Character.localCharacter.ClampStamina();
				GUIManager.instance.bar.ChangeBar();
			}
		}

		[PunRPC]
		public void RPC_SyncStatus(float[] current, float[] inc, float[] dec, float[] last, float[] lastInc)
		{
			if ((Object)(object)Character.localCharacter != (Object)null)
			{
				CharacterAfflictions afflictions = Character.localCharacter.refs.afflictions;
				Array.Copy(current, afflictions.currentStatuses, current.Length);
				Array.Copy(inc, afflictions.currentIncrementalStatuses, inc.Length);
				Array.Copy(dec, afflictions.currentDecrementalStatuses, dec.Length);
				Array.Copy(last, afflictions.lastAddedStatus, last.Length);
				Array.Copy(lastInc, afflictions.lastAddedIncrementalStatus, lastInc.Length);
				GUIManager.instance.bar.ChangeBar();
			}
		}

		[PunRPC]
		public void RPC_SyncConfig(bool StamTogg, float bpMod, float StamRegenMod)
		{
			StaminaLinked.staminaUseToggle.Value = StamTogg;
			StaminaLinked.backpackModifier.Value = bpMod;
			StaminaLinked.staminaRegenModifier.Value = StamRegenMod;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}