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 Team Upgrades v0.2.1
BepInEx/plugins/team-upgrades/dev.lordfirespeed.team_upgrades.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using REPOLib.Modules; using TeamUpgrades.Extensions; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("REPOLib")] [assembly: AssemblyCompany("Lordfirespeed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Team upgrades, done right. Vanilla upgrades only. Everyone should have this installed.")] [assembly: AssemblyFileVersion("0.2.1.0")] [assembly: AssemblyInformationalVersion("0.2.1+117ccaa58d35948ae343b438e8b0e3a488587a7f")] [assembly: AssemblyProduct("Lordfirespeed's Team Upgrades")] [assembly: AssemblyTitle("dev.lordfirespeed.team_upgrades")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Lordfirespeed/repo-team-upgrades")] [assembly: NeutralResourcesLanguage("en-GB")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.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 TeamUpgrades { [BepInDependency("REPOLib", "2.1.0")] [BepInPlugin("dev.lordfirespeed.team_upgrades", "Lordfirespeed's Team Upgrades", "0.2.1")] public class Plugin : BaseUnityPlugin { private class Patches { [HarmonyPatch(typeof(StatsManager))] private static class StatsManagerPatches { [HarmonyPatch("PlayerAdd")] [HarmonyPostfix] private static void OnPlayerAdd_Postfix(StatsManager __instance, object[] __args) { if (!DoTeamUpgrades || !(__args[0] is string key)) { return; } foreach (Dictionary<string, int> item in __instance.AllDictionariesWithPrefix("playerUpgrade")) { item[key] = item.Values.Max(); } } } [HarmonyPatch(typeof(ItemUpgradePlayerHealth))] private static class ItemUpgradePlayerHealthPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerHealth __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeHealth"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerEnergy))] private static class ItemUpgradePlayerEnergyPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerEnergy __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeStamina"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerSprintSpeed))] private static class ItemUpgradePlayerSprintSpeedPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerSprintSpeed __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeSpeed"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerGrabStrength))] private static class ItemUpgradePlayerGrabStrengthPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerGrabStrength __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeStrength"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerGrabRange))] private static class ItemUpgradePlayerGrabRangePatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerGrabRange __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeRange"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerGrabThrow))] private static class ItemUpgradePlayerGrabThrowPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerGrabThrow __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeThrow"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerTumbleLaunch))] private static class ItemUpgradePlayerTumbleLaunchPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerTumbleLaunch __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeLaunch"); return false; } } [HarmonyPatch(typeof(ItemUpgradePlayerExtraJump))] private static class ItemUpgradePlayerExtraJumpPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradePlayerExtraJump __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeExtraJump"); return false; } } [HarmonyPatch(typeof(ItemUpgradeMapPlayerCount))] private static class ItemUpgradeMapPlayerCountPatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref ItemUpgradeMapPlayerCount __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance.itemToggle.GetTogglingPlayerSteamId(), "playerUpgradeMapPlayerCount"); return false; } } [HarmonyPatch(typeof(REPOLibItemUpgrade))] private static class REPOLibItemUpgradePatches { [HarmonyPatch("Upgrade")] [HarmonyPrefix] private static bool Upgrade_Prefix(ref REPOLibItemUpgrade __instance) { TeamUpgradesManager.Instance?.ApplyUpgrade(__instance._itemToggle.GetTogglingPlayerSteamId(), "playerUpgrade" + __instance.UpgradeId); return false; } } [HarmonyPatch(typeof(PhysGrabber))] private static class PhysGrabberPatches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> LateStart_MoveNext_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[6] { new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)typeof(StatsManager).GetField("instance"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)typeof(StatsManager).GetField("playerUpgradeStrength"), (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instr) => instr.opcode == OpCodes.Ldfld), (string)null), new CodeMatch((OpCode?)OpCodes.Callvirt, (object)typeof(Dictionary<string, int>).GetMethod("ContainsKey"), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instr) => instr.opcode == OpCodes.Brfalse), (string)null) }); if (val.IsInvalid) { throw new InvalidOperationException(); } if (!(val.InstructionAt(3).operand is FieldInfo fieldInfo)) { throw new InvalidOperationException(); } if (!(val.InstructionAt(5).operand is Label label)) { throw new InvalidOperationException(); } val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[8] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)typeof(PhysGrabber).GetField("playerAvatar")), new CodeInstruction(OpCodes.Call, (object)typeof(SemiFunc).GetMethod("PlayerGetSteamID")), new CodeInstruction(OpCodes.Stfld, (object)fieldInfo), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo), new CodeInstruction(OpCodes.Brfalse, (object)label) }); CodeInstructionExtensions.MoveLabelsTo(val.Instruction, val.InstructionAt(-8)); Logger.LogDebugInstructionsFrom(val); return val.InstructionEnumeration(); } } } internal static readonly bool DoTeamUpgrades = true; internal const string MainScenePath = "Assets/Scenes/Main/Main.unity"; internal static Plugin Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; public Plugin() { if (Instance != null) { throw new InvalidOperationException(typeof(Plugin).AssemblyQualifiedName + " was instantiated twice"); } Instance = this; } private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; GameObject val = new GameObject("TeamUpgradesPrefabContainer") { hideFlags = (HideFlags)61 }; val.SetActive(false); GameObject val2 = new GameObject("TeamUpgradesManagerPrefab") { hideFlags = (HideFlags)61 }; val2.transform.parent = val.transform; val2.AddComponent<PhotonView>(); val2.AddComponent<TeamUpgradesManager>(); string myPrefabId = "dev.lordfirespeed.team_upgrades/team-upgrades-manager"; NetworkPrefabs.RegisterNetworkPrefab(myPrefabId, val2); SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode loadSceneMode) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!(((Scene)(ref scene)).path != "Assets/Scenes/Main/Main.unity") && SemiFunc.IsMultiplayer() && SemiFunc.IsMasterClient() && !((Object)(object)TeamUpgradesManager.Instance != (Object)null)) { PhotonNetwork.InstantiateRoomObject(myPrefabId, Vector3.zero, Quaternion.identity, (byte)0, (object[])null); } }; HarmonyExtensions.PatchAllNestedTypes(new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID), typeof(Patches)); } } public class TeamUpgradesManager : MonoBehaviour { private PhotonView _photonView; internal static TeamUpgradesManager? Instance { get; private set; } private static IEnumerable<string> AllPlayerSteamIds => StatsManager.instance.dictionaryOfDictionaries["playerColor"].Keys; public event EventHandler<UpgradeQuantityChangedEventArgs>? UpgradeQuantityChanged; private void Start() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Instance = this; ((Component)this).transform.parent = ((Component)PunManager.instance).transform; ((Object)((Component)this).gameObject).name = "TeamUpgradesManager"; GameObject gameObject = ((Component)this).gameObject; ((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags & -62); _photonView = ((Component)this).GetComponent<PhotonView>(); RegisterVanillaUpgradeQuantityChangedCallbacks(); RegisterREPOLibUpgradeQuantityChangedCallbacks(); } private void RegisterVanillaUpgradeQuantityChangedCallbacks() { UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeHealth") && args.IsLocalPlayer && args.NewQuantity != args.OldQuantity && Object.op_Implicit((Object)(object)args.PlayerAvatar)) { int num5 = args.NewQuantity - args.OldQuantity; PlayerHealth playerHealth = args.PlayerAvatar.playerHealth; playerHealth.maxHealth += num5 * 20; if (num5 > 0) { args.PlayerAvatar.playerHealth.Heal(num5 * 20, false); } } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeStamina") && args.IsLocalPlayer && args.NewQuantity != args.OldQuantity && Object.op_Implicit((Object)(object)PlayerController.instance)) { int num4 = args.NewQuantity - args.OldQuantity; PlayerController instance4 = PlayerController.instance; instance4.EnergyStart += (float)num4 * 10f; PlayerController.instance.EnergyCurrent = PlayerController.instance.EnergyStart; } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeSpeed") && args.IsLocalPlayer && args.NewQuantity != args.OldQuantity && Object.op_Implicit((Object)(object)PlayerController.instance)) { int num3 = args.NewQuantity - args.OldQuantity; PlayerController instance2 = PlayerController.instance; instance2.SprintSpeed += (float)num3; PlayerController instance3 = PlayerController.instance; instance3.SprintSpeedUpgrades += (float)num3; } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeStrength") && Object.op_Implicit((Object)(object)args.PlayerAvatar) && args.NewQuantity != args.OldQuantity) { int num2 = args.NewQuantity - args.OldQuantity; PhysGrabber physGrabber3 = args.PlayerAvatar.physGrabber; physGrabber3.grabStrength += (float)num2 * 0.2f; } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeRange") && Object.op_Implicit((Object)(object)args.PlayerAvatar) && args.NewQuantity != args.OldQuantity) { PhysGrabber physGrabber2 = args.PlayerAvatar.physGrabber; physGrabber2.grabRange += (float)(args.NewQuantity - args.OldQuantity); } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeThrow") && Object.op_Implicit((Object)(object)args.PlayerAvatar) && args.NewQuantity != args.OldQuantity) { int num = args.NewQuantity - args.OldQuantity; PhysGrabber physGrabber = args.PlayerAvatar.physGrabber; physGrabber.throwStrength += (float)num * 0.3f; } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeLaunch") && args.NewQuantity != args.OldQuantity && Object.op_Implicit((Object)(object)args.PlayerAvatar)) { PlayerTumble tumble = args.PlayerAvatar.tumble; tumble.tumbleLaunch += args.NewQuantity - args.OldQuantity; } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeExtraJump") && args.IsLocalPlayer && args.NewQuantity != args.OldQuantity && Object.op_Implicit((Object)(object)PlayerController.instance)) { PlayerController instance = PlayerController.instance; instance.JumpExtra += args.NewQuantity - args.OldQuantity; } }; UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (!(args.StatsKey != "playerUpgradeMapPlayerCount") && args.IsLocalPlayer && args.NewQuantity != args.OldQuantity && Object.op_Implicit((Object)(object)args.PlayerAvatar)) { PlayerAvatar playerAvatar = args.PlayerAvatar; playerAvatar.upgradeMapPlayerCount += args.NewQuantity - args.OldQuantity; } }; } private void RegisterREPOLibUpgradeQuantityChangedCallbacks() { UpgradeQuantityChanged += delegate(object sender, UpgradeQuantityChangedEventArgs args) { if (args.StatsKey.StartsWith("playerUpgrade")) { string statsKey = args.StatsKey; int length = "playerUpgrade".Length; PlayerUpgrade val = default(PlayerUpgrade); if (Upgrades.TryGetUpgrade(statsKey.Substring(length, statsKey.Length - length), ref val) && val._upgradeAction != null && Object.op_Implicit((Object)(object)args.PlayerAvatar)) { val._upgradeAction(args.PlayerAvatar, args.NewQuantity); } } }; } public void ApplyUpgrade(string playerSteamId, string playerUpgradeStatsKey) { if (!SemiFunc.IsMasterClient()) { return; } Dictionary<string, int> valueOrDefault = StatsManager.instance.dictionaryOfDictionaries.GetValueOrDefault(playerUpgradeStatsKey, null); if (valueOrDefault != null) { if (Plugin.DoTeamUpgrades) { int num = valueOrDefault.Values.Max(); AssignUpgradeQuantityToAllPlayers(playerUpgradeStatsKey, num + 1); } else { int num2 = valueOrDefault[playerSteamId]; AssignUpgradeQuantity(playerSteamId, playerUpgradeStatsKey, num2 + 1); } } } public void AssignUpgradeQuantityImmediately(string playerSteamId, string playerUpgradeStatsKey, int quantity) { Dictionary<string, int> valueOrDefault = StatsManager.instance.dictionaryOfDictionaries.GetValueOrDefault(playerUpgradeStatsKey, null); if (valueOrDefault != null) { int oldQuantity = valueOrDefault[playerSteamId]; valueOrDefault[playerSteamId] = quantity; UpgradeQuantityChangedEventArgs e = new UpgradeQuantityChangedEventArgs { PlayerSteamId = playerSteamId, StatsKey = playerUpgradeStatsKey, OldQuantity = oldQuantity, NewQuantity = quantity }; this.UpgradeQuantityChanged?.Invoke(null, e); } } public void AssignUpgradeQuantity(string playerSteamId, string playerUpgradeStatsKey, int quantity) { if (SemiFunc.IsMasterClientOrSingleplayer()) { AssignUpgradeQuantityImmediately(playerSteamId, playerUpgradeStatsKey, quantity); } if (SemiFunc.IsMasterClient()) { _photonView.RPC("AssignUpgradeQuantityRPC", (RpcTarget)1, new object[3] { playerSteamId, playerUpgradeStatsKey, quantity }); } } [PunRPC] public void AssignUpgradeQuantityRPC(string playerSteamId, string playerUpgradeStatsKey, int quantity, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (info.Sender.IsMasterClient) { AssignUpgradeQuantityImmediately(playerSteamId, playerUpgradeStatsKey, quantity); } } public void AssignUpgradeQuantityToAllPlayersImmediately(string playerUpgradeStatsKey, int quantity) { Dictionary<string, int> valueOrDefault = StatsManager.instance.dictionaryOfDictionaries.GetValueOrDefault(playerUpgradeStatsKey, null); if (valueOrDefault == null) { return; } foreach (string allPlayerSteamId in AllPlayerSteamIds) { int oldQuantity = valueOrDefault[allPlayerSteamId]; valueOrDefault[allPlayerSteamId] = quantity; UpgradeQuantityChangedEventArgs e = new UpgradeQuantityChangedEventArgs { PlayerSteamId = allPlayerSteamId, StatsKey = playerUpgradeStatsKey, OldQuantity = oldQuantity, NewQuantity = quantity }; this.UpgradeQuantityChanged?.Invoke(null, e); } } public void AssignUpgradeQuantityToAllPlayers(string playerUpgradeStatsKey, int quantity) { if (SemiFunc.IsMasterClientOrSingleplayer()) { AssignUpgradeQuantityToAllPlayersImmediately(playerUpgradeStatsKey, quantity); } if (SemiFunc.IsMasterClient()) { _photonView.RPC("AssignUpgradeQuantityToAllPlayersRPC", (RpcTarget)1, new object[2] { playerUpgradeStatsKey, quantity }); } } [PunRPC] public void AssignUpgradeQuantityToAllPlayersRPC(string playerUpgradeStatsKey, int quantity, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (info.Sender.IsMasterClient) { AssignUpgradeQuantityToAllPlayersImmediately(playerUpgradeStatsKey, quantity); } } } public class UpgradeQuantityChangedEventArgs : EventArgs { public required string PlayerSteamId { get; init; } public required string StatsKey { get; init; } public required int OldQuantity { get; init; } public required int NewQuantity { get; init; } public PlayerAvatar PlayerAvatar => SemiFunc.PlayerAvatarGetFromSteamID(PlayerSteamId); public bool IsLocalPlayer => (Object)(object)PlayerAvatar == (Object)(object)SemiFunc.PlayerAvatarLocal(); } internal static class MyPluginInfo { public const string PLUGIN_GUID = "dev.lordfirespeed.team_upgrades"; public const string PLUGIN_NAME = "Lordfirespeed's Team Upgrades"; public const string PLUGIN_VERSION = "0.2.1"; } } namespace TeamUpgrades.Extensions { public static class HarmonyExtensions { public class SimpleEnumerator<T> : IEnumerable<T>, IEnumerable { public required IEnumerator<T> Enumerator { get; init; } public Action PrefixAction { get; init; } = delegate { }; public Action PostfixAction { get; init; } = delegate { }; public Action<T> PreItemAction { get; init; } = delegate { }; public Action<T> PostItemAction { get; init; } = delegate { }; public Func<T, T> ItemAction { get; init; } = (T item) => item; IEnumerator<T> IEnumerable<T>.GetEnumerator() { return _GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _GetEnumerator(); } private IEnumerator<T> _GetEnumerator() { PrefixAction(); while (Enumerator.MoveNext()) { T item = Enumerator.Current; PreItemAction(item); yield return ItemAction(item); PostItemAction(item); } PostfixAction(); } } private const BindingFlags SearchNestedTypeBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static Type[] AllNestedTypesOf(Type type) { return type.GetNestedTypes(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static void PatchAllNestedTypes(this Harmony harmony, Type type) { Type[] array = AllNestedTypesOf(type); foreach (Type type2 in array) { harmony.PatchAll(type2); } } public static void PatchAllNestedTypesRecursively(this Harmony harmony, Type type) { Type[] array = AllNestedTypesOf(type); foreach (Type type2 in array) { harmony.PatchAll(type2); harmony.PatchAllNestedTypesRecursively(type2); } } } public static class ItemToggleExtensions { public static PlayerAvatar GetTogglingPlayerAvatar(this ItemToggle toggle) { return SemiFunc.PlayerAvatarGetFromPhotonID(toggle.playerTogglePhotonID); } public static string GetTogglingPlayerSteamId(this ItemToggle toggle) { return SemiFunc.PlayerGetSteamID(toggle.GetTogglingPlayerAvatar()); } } public static class ManualLogSourceExtensions { private class CodeInstructionFormatter { private int _instructionIndexPadLength = instructionCount.ToString().Length; public CodeInstructionFormatter(int instructionCount) { } public string Format(CodeInstruction instruction, int index) { return $" IL_{index.ToString().PadLeft(_instructionIndexPadLength, '0')}: {instruction}"; } } public static void LogDebugInstructionsFrom(this ManualLogSource source, CodeMatcher matcher) { string name = new StackTrace().GetFrame(1).GetMethod().Name; CodeInstructionFormatter @object = new CodeInstructionFormatter(matcher.Length); StringBuilder stringBuilder = new StringBuilder("'" + name + "' Matcher Instructions:\n").AppendLine(string.Join("\n", matcher.InstructionEnumeration().Select(@object.Format))).AppendLine("End of matcher instructions."); source.LogDebug((object)stringBuilder.ToString()); } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class OverloadResolutionPriorityAttribute : Attribute { public int Priority { get; } public OverloadResolutionPriorityAttribute(int priority) { Priority = priority; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class ParamCollectionAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } }