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);
}
}
}
}