Decompiled source of MoreCriminal Ping v1.0.1

BepInEx\plugins\MoreCriminal_Ping\MoreCriminal.Ping.dll

Decompiled 3 days ago
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Fusion;
using HarmonyLib;
using I2.Loc;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[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("MoreCriminal.Ping")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("3D Object Ping feature for Crime Simulator.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreCriminal.Ping")]
[assembly: AssemblyTitle("MoreCriminal.Ping")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MoreCriminal.Ping;

[BepInPlugin("morecriminal.ping", "MoreCriminal Ping", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
	public static class Localizer
	{
		public static string Get(string key)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			bool flag = LocalizationManager.CurrentLanguage == "Chinese (Simplified)" || LocalizationManager.CurrentLanguage == "Chinese" || (int)Application.systemLanguage == 6 || (int)Application.systemLanguage == 40;
			switch (key)
			{
			case "ping_placed":
				if (!flag)
				{
					return "Ping Placed";
				}
				return "标点已放置";
			case "enemy":
				if (!flag)
				{
					return "Enemy";
				}
				return "敌人";
			case "target":
				if (!flag)
				{
					return "Target";
				}
				return "目标";
			case "vehicle":
				if (!flag)
				{
					return "Vehicle";
				}
				return "载具";
			case "location":
				if (!flag)
				{
					return "Location";
				}
				return "位置";
			case "indicator":
				if (!flag)
				{
					return "Indicator";
				}
				return "指示";
			case "item":
				if (!flag)
				{
					return "Item";
				}
				return "物品";
			default:
				return key;
			}
		}
	}

	[HarmonyPatch(typeof(FPP_Player), "Update")]
	public static class PlayerUpdatePatch
	{
		private const string PING_PREFIX = "[PING_OBJ]";

		private static float pressTimer;

		private static bool highPriorityTriggered;

		private static GameObject uiHolder;

		private static Image progressFill;

		private static Sprite ringSprite;

		private static void Postfix(FPP_Player __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).HasStateAuthority)
			{
				return;
			}
			if (Input.GetKeyDown(PingKey.Value))
			{
				pressTimer = 0f;
				highPriorityTriggered = false;
			}
			if (Input.GetKey(PingKey.Value))
			{
				pressTimer += Time.deltaTime;
				if (pressTimer > 0.05f && !highPriorityTriggered)
				{
					UpdateProgressUI(__instance, pressTimer / LongPressTime.Value);
				}
				if (pressTimer >= LongPressTime.Value && !highPriorityTriggered)
				{
					highPriorityTriggered = true;
					HideUI();
					PerformRaycastAndSend(__instance, isHighPriority: true);
				}
			}
			if (Input.GetKeyUp(PingKey.Value))
			{
				if (!highPriorityTriggered && pressTimer > 0.01f)
				{
					PerformRaycastAndSend(__instance, isHighPriority: false);
				}
				HideUI();
				pressTimer = 0f;
				highPriorityTriggered = false;
			}
		}

		private static void UpdateProgressUI(FPP_Player player, float progress)
		{
			if ((Object)(object)uiHolder == (Object)null)
			{
				CreateUI(player);
			}
			uiHolder.SetActive(true);
			progressFill.fillAmount = progress;
		}

		private static void HideUI()
		{
			if ((Object)(object)uiHolder != (Object)null)
			{
				uiHolder.SetActive(false);
			}
		}

		private static void CreateUI(FPP_Player player)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ringSprite == (Object)null)
			{
				ringSprite = GenerateRingSprite();
			}
			uiHolder = new GameObject("Ping_Progress_UI");
			Canvas obj = uiHolder.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 999;
			uiHolder.AddComponent<CanvasScaler>().uiScaleMode = (ScaleMode)1;
			GameObject val = new GameObject("RingBG");
			val.transform.SetParent(uiHolder.transform);
			RectTransform obj2 = val.AddComponent<RectTransform>();
			obj2.anchoredPosition = Vector2.zero;
			obj2.sizeDelta = new Vector2(28f, 28f);
			Image obj3 = val.AddComponent<Image>();
			obj3.sprite = ringSprite;
			((Graphic)obj3).color = new Color(1f, 1f, 1f, 0.15f);
			GameObject val2 = new GameObject("RingFill");
			val2.transform.SetParent(uiHolder.transform);
			RectTransform obj4 = val2.AddComponent<RectTransform>();
			obj4.anchoredPosition = Vector2.zero;
			obj4.sizeDelta = new Vector2(28f, 28f);
			progressFill = val2.AddComponent<Image>();
			progressFill.sprite = ringSprite;
			progressFill.type = (Type)3;
			progressFill.fillMethod = (FillMethod)4;
			progressFill.fillOrigin = 2;
			((Graphic)progressFill).color = new Color(1f, 1f, 1f, 0.6f);
		}

		private static Sprite GenerateRingSprite()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			int num = 128;
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, false);
			float num2 = (float)num / 2f;
			float num3 = (float)num / 2f - 2f;
			float num4 = num3 - 14f;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num5 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, num2));
					if (num5 <= num3 && num5 >= num4)
					{
						float num6 = 1f;
						if (num5 > num3 - 1f)
						{
							num6 = num3 - num5;
						}
						else if (num5 < num4 + 1f)
						{
							num6 = num5 - num4;
						}
						val.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.Clamp01(num6)));
					}
					else
					{
						val.SetPixel(j, i, Color.clear);
					}
				}
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f));
		}

		private static void PerformRaycastAndSend(FPP_Player player, bool isHighPriority)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Camera val = null;
				if ((Object)(object)player.cameraObject != (Object)null && player.cameraObject.activeInHierarchy)
				{
					val = player.cameraObject.GetComponentInChildren<Camera>();
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Camera.main;
				}
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				string text = Localizer.Get("location");
				string text2 = "";
				RaycastHit val2 = default(RaycastHit);
				Vector3 val3;
				if (Physics.Raycast(new Ray(((Component)val).transform.position, ((Component)val).transform.forward), ref val2, PingDistance.Value))
				{
					val3 = ((RaycastHit)(ref val2)).point;
					GameObject gameObject = ((Component)((RaycastHit)(ref val2)).collider).gameObject;
					Pickupable componentInParent = gameObject.GetComponentInParent<Pickupable>();
					if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.assignedItem != (Object)null)
					{
						text = Localizer.Get("item");
						text2 = componentInParent.assignedItem.GetItemName();
					}
					else if (gameObject.CompareTag("NPC") || ((Object)gameObject).name.ToLower().Contains("police"))
					{
						text = Localizer.Get("enemy");
						text2 = Localizer.Get("target");
					}
					else if ((Object)(object)gameObject.GetComponentInParent<CarController>() != (Object)null)
					{
						text = Localizer.Get("vehicle");
						text2 = Localizer.Get("vehicle");
					}
				}
				else
				{
					val3 = ((Component)val).transform.position + ((Component)val).transform.forward * 30f;
					text = Localizer.Get("indicator");
				}
				string text3 = string.Format(CultureInfo.InvariantCulture, "{0:F2}|{1:F2}|{2:F2}", val3.x, val3.y, val3.z);
				string text4 = "[PING_OBJ]|" + text + "|" + text2 + "|" + text3 + "|" + (isHighPriority ? "1" : "0");
				WorldManager.Instance.RPC_SpawnChatMessage(player.nickname, text4, "");
				player.ShowMessage("<color=#00FF00>" + Localizer.Get("ping_placed") + "</color>", 1f, "good", false);
				if ((Object)(object)player.sfxSource != (Object)null)
				{
					if (isHighPriority && (Object)(object)player.crouchDownClip != (Object)null)
					{
						player.sfxSource.PlayOneShot(player.crouchDownClip, 1f);
					}
					else if ((Object)(object)player.crouchUpClip != (Object)null)
					{
						player.sfxSource.PlayOneShot(player.crouchUpClip, 0.4f);
					}
				}
			}
			catch
			{
			}
		}
	}

	[HarmonyPatch(typeof(FPP_Player), "SpawnChatMessage")]
	public static class ChatPatch
	{
		private const string PING_PREFIX = "[PING_OBJ]";

		private static bool Prefix(string _nickname, string content)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(content) && content.StartsWith("[PING_OBJ]"))
			{
				try
				{
					string[] array = content.Split('|');
					if (array.Length >= 6)
					{
						bool isHighPriority = array.Length >= 7 && array[6] == "1";
						SpawnPingVisual(new Vector3(float.Parse(array[3], CultureInfo.InvariantCulture), float.Parse(array[4], CultureInfo.InvariantCulture), float.Parse(array[5], CultureInfo.InvariantCulture)), array[1], array[2], _nickname, isHighPriority);
					}
				}
				catch
				{
				}
				return false;
			}
			return true;
		}
	}

	internal static ManualLogSource Log;

	internal static ConfigEntry<KeyCode> PingKey;

	internal static ConfigEntry<float> PingDistance;

	internal static ConfigEntry<float> PingDuration;

	internal static ConfigEntry<float> LongPressTime;

	private void Awake()
	{
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		PingKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "PingKey", (KeyCode)325, "Key to perform a ping.");
		PingDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PingDistance", 500f, "Max range for the ping.");
		PingDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PingDuration", 10f, "How long the 3D marker stays visible.");
		LongPressTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LongPressTime", 0.5f, "Seconds to hold for a Priority Ping.");
		new Harmony("morecriminal.ping").PatchAll();
		Log.LogInfo((object)"MoreCriminal Ping System Loaded.");
	}

	public static void SpawnPingVisual(Vector3 pos, string type, string details, string owner, bool isHighPriority)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("PingMarker_Instance");
		val.transform.position = pos;
		val.AddComponent<PingMarker>().Setup(type, details, owner, PingDuration.Value, isHighPriority);
	}
}
public class PingMarker : MonoBehaviour
{
	private float timer;

	private float lifeTime = 10f;

	private Transform visualHolder;

	private LineRenderer snapline;

	private bool isPriority;

	public void Setup(string type, string details, string owner, float duration, bool highPriority)
	{
		//IL_0010: 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_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: 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)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Expected O, but got Unknown
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Expected O, but got Unknown
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e6: Expected O, but got Unknown
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		lifeTime = duration;
		isPriority = highPriority;
		Color val = Color.yellow;
		if (type == Plugin.Localizer.Get("enemy"))
		{
			val = Color.red;
		}
		else if (type == Plugin.Localizer.Get("item"))
		{
			val = Color.green;
		}
		else if (type == Plugin.Localizer.Get("indicator"))
		{
			((Color)(ref val))..ctor(1f, 0.5f, 0f);
		}
		else if (type == Plugin.Localizer.Get("vehicle"))
		{
			val = Color.cyan;
		}
		visualHolder = new GameObject("VisualHolder").transform;
		visualHolder.SetParent(((Component)this).transform);
		visualHolder.localPosition = Vector3.zero;
		Shader val2 = Shader.Find("TextMeshPro/Mobile/Distance Field Overlay") ?? Shader.Find("TextMeshPro/Distance Field Overlay");
		GameObject val3 = new GameObject("Dot");
		val3.transform.SetParent(visualHolder);
		val3.transform.localPosition = Vector3.zero;
		val3.transform.localScale = Vector3.one * 0.2f;
		TextMeshPro val4 = val3.AddComponent<TextMeshPro>();
		((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val4).fontSize = 25f;
		((Graphic)val4).color = val;
		((TMP_Text)val4).text = "●";
		if ((Object)(object)val2 != (Object)null)
		{
			((TMP_Text)val4).fontMaterial = new Material(((TMP_Text)val4).fontMaterial);
			((TMP_Text)val4).fontMaterial.shader = val2;
			((TMP_Text)val4).fontMaterial.renderQueue = 4500;
		}
		GameObject val5 = new GameObject("Text");
		val5.transform.SetParent(visualHolder);
		val5.transform.localPosition = Vector3.up * 0.45f;
		val5.transform.localScale = Vector3.one * 0.15f;
		TextMeshPro val6 = val5.AddComponent<TextMeshPro>();
		((TMP_Text)val6).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val6).fontSize = 12f;
		((Graphic)val6).color = Color.white;
		((TMP_Text)val6).fontStyle = (FontStyles)1;
		if ((Object)(object)val2 != (Object)null)
		{
			((TMP_Text)val6).fontMaterial = new Material(((TMP_Text)val6).fontMaterial);
			((TMP_Text)val6).fontMaterial.shader = val2;
			((TMP_Text)val6).fontMaterial.renderQueue = 4501;
		}
		string text = (string.IsNullOrEmpty(details) ? type : details);
		((TMP_Text)val6).text = "<color=#" + ColorUtility.ToHtmlStringRGB(val) + ">" + text + "</color>\n<size=75%>" + owner + "</size>";
		if (highPriority)
		{
			snapline = ((Component)this).gameObject.AddComponent<LineRenderer>();
			snapline.startWidth = 0.012f;
			snapline.endWidth = 0.004f;
			snapline.positionCount = 2;
			((Renderer)snapline).material = new Material(Shader.Find("Sprites/Default"));
			((Renderer)snapline).material.color = new Color(val.r, val.g, val.b, 0.4f);
			snapline.useWorldSpace = true;
		}
	}

	private void Update()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		timer += Time.deltaTime;
		if (timer >= lifeTime)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Camera main = Camera.main;
		if ((Object)(object)main != (Object)null)
		{
			float num = Vector3.Distance(((Component)this).transform.position, ((Component)main).transform.position);
			((Component)this).transform.rotation = Quaternion.LookRotation(((Component)this).transform.position - ((Component)main).transform.position);
			float num2 = 0.8f + num * 0.012f;
			num2 = Mathf.Clamp(num2, 0.7f, 3.5f);
			visualHolder.localScale = Vector3.one * num2;
			float num3 = 1f + Mathf.Sin(Time.time * (isPriority ? 8f : 4f)) * 0.1f;
			Transform obj = visualHolder;
			obj.localScale *= num3;
			if ((Object)(object)snapline != (Object)null)
			{
				Vector3 val = ((Component)main).transform.position + Vector3.down * 0.5f;
				snapline.SetPosition(0, val);
				snapline.SetPosition(1, ((Component)this).transform.position);
			}
		}
	}
}