Decompiled source of PingPlus v1.0.1

BepInEx/plugins/PingPlus/PingPlus.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PingPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+67487d568e67cfe10e13cf19c326d37dacf00a96")]
[assembly: AssemblyProduct("PingPlus")]
[assembly: AssemblyTitle("PingPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[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 PingPlus
{
	public sealed class PinnedPingMessage : INetMessage, ISerializableObject
	{
		public NetworkInstanceId OwnerId { get; private set; }

		public NetworkInstanceId TargetId { get; private set; }

		public Vector3 Origin { get; private set; }

		public Vector3 Normal { get; private set; }

		public float Duration { get; private set; }

		public int Maximum { get; private set; }

		public bool IsBroadcast { get; private set; }

		public PinnedPingMessage()
		{
		}

		public PinnedPingMessage(NetworkInstanceId ownerId, NetworkInstanceId targetId, Vector3 origin, Vector3 normal, float duration, int maximum, bool isBroadcast)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			OwnerId = ownerId;
			TargetId = targetId;
			Origin = origin;
			Normal = normal;
			Duration = duration;
			Maximum = maximum;
			IsBroadcast = isBroadcast;
		}

		public void Serialize(NetworkWriter writer)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(OwnerId);
			writer.Write(TargetId);
			writer.Write(Origin);
			writer.Write(Normal);
			writer.Write(Duration);
			writer.Write(Maximum);
			writer.Write(IsBroadcast);
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			OwnerId = reader.ReadNetworkId();
			TargetId = reader.ReadNetworkId();
			Origin = reader.ReadVector3();
			Normal = reader.ReadVector3();
			Duration = reader.ReadSingle();
			Maximum = reader.ReadInt32();
			IsBroadcast = reader.ReadBoolean();
		}

		public void OnReceived()
		{
			Plugin.Instance.ReceivePinnedPing(this);
		}
	}
	public sealed class ItemPingRequestMessage : INetMessage, ISerializableObject
	{
		private int _pickupValue;

		public ItemPingRequestMessage()
		{
		}

		public ItemPingRequestMessage(PickupIndex pickupIndex)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_pickupValue = pickupIndex.value;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_pickupValue);
		}

		public void Deserialize(NetworkReader reader)
		{
			_pickupValue = reader.ReadInt32();
		}

		public void OnReceived()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				Plugin.Instance.BroadcastItemOwnership(new PickupIndex(_pickupValue));
			}
		}
	}
	[BepInPlugin("com.cirillom.pingplus", "Ping Plus", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class ItemPingReported : MonoBehaviour
		{
		}

		private sealed class PinnedPing
		{
			public GameObject Owner { get; }

			public GameObject? Target { get; }

			public PingIndicator Indicator { get; }

			public PinnedPing(GameObject owner, GameObject? target, PingIndicator indicator)
			{
				Owner = owner;
				Target = target;
				Indicator = indicator;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_RebuildPing <0>__PingIndicatorRebuildPing;
		}

		public const string PluginGuid = "com.cirillom.pingplus";

		public const string PluginName = "Ping Plus";

		public const string PluginVersion = "1.0.1";

		private readonly List<PinnedPing> _pinnedPings = new List<PinnedPing>();

		private ConfigEntry<float> _duration;

		private ConfigEntry<int> _maximum;

		private ConfigEntry<KeyboardShortcut> _pinKey;

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			Instance = this;
			_duration = ((BaseUnityPlugin)this).Config.Bind<float>("Pinned Pings", "PinnedPingDuration", 0f, new ConfigDescription("Pinned ping lifetime in seconds. Use 0 to keep pings until removed or the stage ends.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), Array.Empty<object>()));
			_maximum = ((BaseUnityPlugin)this).Config.Bind<int>("Pinned Pings", "MaxPinnedPings", 5, new ConfigDescription("Maximum number of pinned pings per player. Creating another removes their oldest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			_pinKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Pinned Pings", "PinKey", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), "Key used to create or remove a pinned ping at the crosshair.");
			NetworkingAPI.RegisterMessageType<PinnedPingMessage>();
			NetworkingAPI.RegisterMessageType<ItemPingRequestMessage>();
			PlayerCharacterMasterController.Update += new hook_Update(PlayerCharacterMasterControllerUpdate);
			object obj = <>O.<0>__PingIndicatorRebuildPing;
			if (obj == null)
			{
				hook_RebuildPing val = PingIndicatorRebuildPing;
				<>O.<0>__PingIndicatorRebuildPing = val;
				obj = (object)val;
			}
			PingIndicator.RebuildPing += (hook_RebuildPing)obj;
			Stage.onStageStartGlobal += delegate
			{
				ClearPinnedPings();
			};
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Ping Plus loaded! Press {_pinKey.Value} while aiming to toggle a shared pinned ping.");
		}

		private void Update()
		{
			_pinnedPings.RemoveAll((PinnedPing ping) => !Object.op_Implicit((Object)(object)ping.Indicator));
		}

		private void PlayerCharacterMasterControllerUpdate(orig_Update orig, PlayerCharacterMasterController self)
		{
			//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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			if (!self.hasEffectiveAuthority || !Object.op_Implicit((Object)(object)self.bodyInputs) || !Object.op_Implicit((Object)(object)self.body))
			{
				return;
			}
			KeyboardShortcut value = _pinKey.Value;
			PingInfo val = default(PingInfo);
			if (!((KeyboardShortcut)(ref value)).IsDown() || !PingerController.GeneratePingInfo(new Ray(self.bodyInputs.aimOrigin, self.bodyInputs.aimDirection), ((Component)self.body).gameObject, ref val))
			{
				return;
			}
			NetworkInstanceId networkId = GetNetworkId(((Component)self).gameObject);
			if (networkId == default(NetworkInstanceId))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not pin ping because the local player has no network identity.");
				return;
			}
			PinnedPingMessage pinnedPingMessage = new PinnedPingMessage(networkId, GetNetworkId(((PingInfo)(ref val)).targetGameObject), val.origin, val.normal, _duration.Value, _maximum.Value, isBroadcast: false);
			if (NetworkServer.active)
			{
				ReceivePinnedPing(pinnedPingMessage);
			}
			else
			{
				NetMessageExtensions.Send((INetMessage)(object)pinnedPingMessage, (NetworkDestination)2);
			}
		}

		private static void PingIndicatorRebuildPing(orig_RebuildPing orig, PingIndicator self)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			if (!Object.op_Implicit((Object)(object)self.pingOwner) || !Object.op_Implicit((Object)(object)self.pingTarget) || Object.op_Implicit((Object)(object)((Component)self).GetComponent<ItemPingReported>()) || !HasAuthority(self.pingOwner) || !TryGetPickupIndex(self.pingTarget, out var pickupIndex))
			{
				return;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (pickupDef != null && ((int)pickupDef.itemIndex != -1 || (int)pickupDef.equipmentIndex != -1))
			{
				((Component)self).gameObject.AddComponent<ItemPingReported>();
				if (NetworkServer.active)
				{
					Instance.BroadcastItemOwnership(pickupIndex);
				}
				else
				{
					NetMessageExtensions.Send((INetMessage)(object)new ItemPingRequestMessage(pickupIndex), (NetworkDestination)2);
				}
			}
		}

		internal void BroadcastItemOwnership(PickupIndex pickupIndex)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			if (!NetworkServer.active || !((PickupIndex)(ref pickupIndex)).isValid)
			{
				return;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (pickupDef != null && ((int)pickupDef.itemIndex != -1 || (int)pickupDef.equipmentIndex != -1))
			{
				string[] array = (from entry in NetworkUser.readOnlyInstancesList.Select(delegate(NetworkUser user)
					{
						CharacterMaster master = user.master;
						return new
						{
							User = user,
							Count = GetCount((master != null) ? master.inventory : null, pickupDef)
						};
					})
					where entry.Count > 0
					select $"{Util.EscapeRichTextForTextMeshPro(entry.User.userName)} ×{entry.Count}").ToArray();
				if (array.Length != 0)
				{
					Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
					{
						baseToken = "<style=cSub>Owned by: " + string.Join(", ", array) + "</style>"
					});
				}
			}
		}

		internal void ReceivePinnedPing(PinnedPingMessage message)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (message.IsBroadcast)
			{
				if (!NetworkServer.active)
				{
					ApplyPinnedPing(message);
				}
			}
			else if (NetworkServer.active)
			{
				PinnedPingMessage pinnedPingMessage = new PinnedPingMessage(message.OwnerId, message.TargetId, message.Origin, message.Normal, Mathf.Clamp(message.Duration, 0f, 3600f), Mathf.Clamp(message.Maximum, 1, 20), isBroadcast: true);
				if (NetworkClient.active)
				{
					ApplyPinnedPing(pinnedPingMessage);
				}
				NetMessageExtensions.Send((INetMessage)(object)pinnedPingMessage, (NetworkDestination)1);
			}
		}

		private void ApplyPinnedPing(PinnedPingMessage message)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			GameObject owner = Util.FindNetworkObject(message.OwnerId);
			if (!Object.op_Implicit((Object)(object)owner))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Could not resolve pinned ping owner {message.OwnerId}.");
				return;
			}
			GameObject target = ((message.TargetId == default(NetworkInstanceId)) ? null : Util.FindNetworkObject(message.TargetId));
			int num = (Object.op_Implicit((Object)(object)target) ? _pinnedPings.FindIndex((PinnedPing ping) => (Object)(object)ping.Owner == (Object)(object)owner && (Object)(object)ping.Target == (Object)(object)target) : (-1));
			if (num >= 0)
			{
				Object.Destroy((Object)(object)((Component)_pinnedPings[num].Indicator).gameObject);
				_pinnedPings.RemoveAt(num);
				return;
			}
			while (_pinnedPings.Count((PinnedPing ping) => (Object)(object)ping.Owner == (Object)(object)owner) >= message.Maximum)
			{
				int index = _pinnedPings.FindIndex((PinnedPing ping) => (Object)(object)ping.Owner == (Object)(object)owner);
				Object.Destroy((Object)(object)((Component)_pinnedPings[index].Indicator).gameObject);
				_pinnedPings.RemoveAt(index);
			}
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/PingIndicator");
			if (!Object.op_Implicit((Object)(object)val))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not load the vanilla ping indicator prefab.");
				return;
			}
			PingIndicator component = Object.Instantiate<GameObject>(val).GetComponent<PingIndicator>();
			component.pingOwner = owner;
			component.pingOrigin = message.Origin;
			component.pingNormal = message.Normal;
			component.pingTarget = target;
			component.RebuildPing();
			component.fixedTimer = (component.pingDuration = ((message.Duration == 0f) ? float.PositiveInfinity : message.Duration));
			((TMP_Text)component.pingText).text = "<color=#80E9FF><b>PINNED</b></color>\n" + ((TMP_Text)component.pingText).text;
			SpriteRenderer[] componentsInChildren = ((Component)component).GetComponentsInChildren<SpriteRenderer>(true);
			foreach (SpriteRenderer val2 in componentsInChildren)
			{
				val2.color = Color.Lerp(val2.color, new Color(0.35f, 0.9f, 1f, val2.color.a), 0.55f);
			}
			_pinnedPings.Add(new PinnedPing(owner, target, component));
		}

		private static bool HasAuthority(GameObject owner)
		{
			NetworkIdentity componentInParent = owner.GetComponentInParent<NetworkIdentity>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				return componentInParent.hasAuthority;
			}
			return false;
		}

		private static NetworkInstanceId GetNetworkId(GameObject? value)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)value == (Object)null)
			{
				return default(NetworkInstanceId);
			}
			NetworkIdentity componentInParent = value.GetComponentInParent<NetworkIdentity>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return default(NetworkInstanceId);
			}
			return componentInParent.netId;
		}

		private static bool TryGetPickupIndex(GameObject target, out PickupIndex pickupIndex)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			GenericPickupController val = target.GetComponentInParent<GenericPickupController>() ?? target.GetComponentInChildren<GenericPickupController>();
			if (Object.op_Implicit((Object)(object)val))
			{
				pickupIndex = val.pickup.pickupIndex;
				return ((PickupIndex)(ref pickupIndex)).isValid;
			}
			PickupDisplay componentInChildren = target.GetComponentInChildren<PickupDisplay>();
			pickupIndex = (Object.op_Implicit((Object)(object)componentInChildren) ? componentInChildren.GetPickupIndex() : PickupIndex.none);
			return ((PickupIndex)(ref pickupIndex)).isValid;
		}

		private static int GetCount(Inventory? inventory, PickupDef pickupDef)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)inventory == (Object)null)
			{
				return 0;
			}
			if ((int)pickupDef.itemIndex != -1)
			{
				return inventory.GetItemCountEffective(pickupDef.itemIndex);
			}
			if ((int)pickupDef.equipmentIndex == -1 || !inventory.HasEquipment(pickupDef.equipmentIndex))
			{
				return 0;
			}
			return 1;
		}

		private void ClearPinnedPings()
		{
			foreach (PinnedPing pinnedPing in _pinnedPings)
			{
				if (Object.op_Implicit((Object)(object)pinnedPing.Indicator))
				{
					Object.Destroy((Object)(object)((Component)pinnedPing.Indicator).gameObject);
				}
			}
			_pinnedPings.Clear();
		}
	}
}