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 Pinger v3.2.0
plugins/Pinger.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using GameNetcodeStuff; using HarmonyLib; using LC_API.ServerAPI; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Pinger.Overrider; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Pinger")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Pings Player")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Pinger")] [assembly: AssemblyTitle("Pinger")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Pinger { internal struct CustomScanNode { public long created { get; set; } public ScanNodeProperties scanNode { get; set; } public string owner { get; set; } } [JsonObject(/*Could not decode attribute arguments.*/)] internal class PingData { [JsonProperty] public float x { get; set; } [JsonProperty] public float y { get; set; } [JsonProperty] public float z { get; set; } [JsonProperty] public long created { get; set; } [JsonProperty] public string owner { get; set; } [JsonProperty] public bool isDanger { get; set; } } [BepInPlugin("Pinger", "Pinger", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string SIGNATURE = "player_ping"; private const int LIFESPAN = 10000; private Harmony _harmony; private ScanNodeProperties _scanNodeMaster; private LinkedList<CustomScanNode> _scanNodes = new LinkedList<CustomScanNode>(); private static bool _isPatched; private static bool _isPatching; private static PlayerControllerB _mainPlayer; private static HUDManager _hudManager; public static Plugin Instance { get; private set; } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Instance = this; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Pinger is loaded!"); _harmony = new Harmony("Pinger"); _harmony.PatchAll(typeof(StartOfRound_Awake)); _harmony.PatchAll(typeof(KeyboardPing)); StartLogicLoop(); } private async void StartLogicLoop() { while ((Object)(object)StartOfRound.Instance == (Object)null) { await Task.Delay(1000); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"StartOfRound.Instance found..."); _mainPlayer = StartOfRound.Instance.localPlayerController; while ((Object)(object)_mainPlayer == (Object)null) { await Task.Delay(250); _mainPlayer = StartOfRound.Instance.localPlayerController; } while ((Object)(object)_hudManager == (Object)null) { await Task.Delay(250); _hudManager = HUDManager.Instance; } _isPatched = true; handleIncomingPings(); } private void handleIncomingPings() { Networking.GetString = (Action<string, string>)Delegate.Combine(Networking.GetString, (Action<string, string>)delegate(string message, string signature) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (signature.Equals("player_ping")) { PingData pingData = JsonConvert.DeserializeObject<PingData>(message); if (pingData == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Failed to parse ping data"); } else { ((BaseUnityPlugin)this).Logger.LogMessage((object)$"Received ping from {pingData.owner} at {pingData.x} {pingData.y} {pingData.z}"); float x = pingData.x; float y = pingData.y; float z = pingData.z; RaycastHit hit = default(RaycastHit); createPing(x, y, z, in hit, pingData.isDanger, pingData.owner); } } }); } private void DeletePings(string owner) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) ScanNodeProperties[] array = Object.FindObjectsByType<ScanNodeProperties>((FindObjectsSortMode)0); for (LinkedListNode<CustomScanNode> linkedListNode = _scanNodes.First; linkedListNode != null; linkedListNode = linkedListNode.Next) { if (!((Object)(object)linkedListNode.Value.scanNode == (Object)null)) { if (linkedListNode.Value.owner != owner) { Debug.Log((object)$"Skipping ping at {((Component)linkedListNode.Value.scanNode).transform.position} (Predicate failed: {linkedListNode.Value.owner} != {owner})"); } else { Debug.Log((object)$"Deleting ping at {((Component)linkedListNode.Value.scanNode).transform.position}"); Object.Destroy((Object)(object)linkedListNode.Value.scanNode); for (int i = 0; i < array.Length; i++) { if (((Component)array[i]).transform.position == ((Component)linkedListNode.Value.scanNode).transform.position) { Object.Destroy((Object)(object)array[i]); break; } } } } } } private async void checkAndDeleteOldPings() { int lifespan = 10000; while (true) { await Task.Delay(1000); long now = DateTimeOffset.Now.ToUnixTimeMilliseconds(); for (LinkedListNode<CustomScanNode> node = _scanNodes.First; node != null; node = node.Next) { if (!((Object)(object)node.Value.scanNode == (Object)null) && now - node.Value.created > lifespan) { ((BaseUnityPlugin)this).Logger.LogMessage((object)$"Deleting ping at {((Component)node.Value.scanNode).transform.position}"); Object.Destroy((Object)(object)node.Value.scanNode); _scanNodes.Remove(node); } } } } private void OnDestroy() { //IL_0038: 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) ScanNodeProperties[] array = Object.FindObjectsByType<ScanNodeProperties>((FindObjectsSortMode)0); for (LinkedListNode<CustomScanNode> linkedListNode = _scanNodes.First; linkedListNode != null; linkedListNode = linkedListNode.Next) { Object.Destroy((Object)(object)linkedListNode.Value.scanNode); for (int i = 0; i < array.Length; i++) { if (((Component)array[i]).transform.position == ((Component)linkedListNode.Value.scanNode).transform.position) { Object.Destroy((Object)(object)array[i]); break; } } } } public bool createPingWherePlayerIsLooking(bool is_danger = false) { //IL_005b: 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_008f: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mainPlayer == (Object)null || (Object)(object)_hudManager == (Object)null) { if (_isPatching) { return false; } StartLogicLoop(); _isPatching = true; return false; } float x = ((Component)_mainPlayer.gameplayCamera).transform.position.x; float y = ((Component)_mainPlayer.gameplayCamera).transform.position.y; float z = ((Component)_mainPlayer.gameplayCamera).transform.position.z; RaycastHit hit = shootRay(x, y, z); float x2 = ((RaycastHit)(ref hit)).point.x; float y2 = ((RaycastHit)(ref hit)).point.y; float z2 = ((RaycastHit)(ref hit)).point.z; ((BaseUnityPlugin)this).Logger.LogMessage((object)("Creating Ping on the surface of " + ((Object)((RaycastHit)(ref hit)).transform).name)); CustomScanNode customScanNode = createPing(x2, y2, z2, in hit, is_danger); if ((Object)(object)customScanNode.scanNode == (Object)null) { return false; } string text = JsonConvert.SerializeObject((object)new PingData { x = x2, y = y2, z = z2, created = customScanNode.created, owner = _mainPlayer.playerUsername, isDanger = is_danger }); Networking.Broadcast(text, "player_ping"); return true; } private CustomScanNode createPing(float x, float y, float z, in RaycastHit hit) { return createPing(x, y, z, in hit, isDanger: false, _mainPlayer.playerUsername); } private CustomScanNode createPing(float x, float y, float z, in RaycastHit hit, bool isDanger) { return createPing(x, y, z, in hit, isDanger, _mainPlayer.playerUsername); } private CustomScanNode createPing(float x, float y, float z, in RaycastHit hit, string playerName) { return createPing(x, y, z, in hit, isDanger: false, playerName); } private CustomScanNode createPing(float x, float y, float z, in RaycastHit hit, bool isDanger, string playerName) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (hasPlayerPinged(playerName)) { DeletePings(playerName); } string headerText = playerName + "'s ping"; string subText = "Player Ping <!>"; ((BaseUnityPlugin)this).Logger.LogMessage((object)$"Creating Ping at : {x} {y} {z}"); ScanNodeProperties[] array = Object.FindObjectsByType<ScanNodeProperties>((FindObjectsSortMode)0); if ((Object)(object)_scanNodeMaster == (Object)null) { if (array.Length == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"No scan node master found"); return default(CustomScanNode); } _scanNodeMaster = array[0]; checkAndDeleteOldPings(); } ScanNodeProperties val = Object.Instantiate<ScanNodeProperties>(_scanNodeMaster); ((Object)val).name = "PlayerPing"; val.headerText = headerText; val.subText = subText; ((Component)val).transform.position = new Vector3(x, y, z); val.maxRange = 200; val.minRange = 0; val.requiresLineOfSight = true; if (isDanger) { val.nodeType = 1; val.subText = "DANGER <!>"; } else { val.nodeType = 2; } CustomScanNode customScanNode = default(CustomScanNode); long created = DateTimeOffset.Now.ToUnixTimeMilliseconds(); customScanNode.created = created; customScanNode.scanNode = val; customScanNode.owner = playerName; _scanNodes.AddLast(customScanNode); if ((Object)(object)_hudManager == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"HUDManager is null"); } else if (customScanNode.owner == _mainPlayer.playerUsername) { _hudManager.UIAudio.PlayOneShot(_hudManager.scanSFX); } return customScanNode; } private bool hasPlayerPinged(string name) { for (LinkedListNode<CustomScanNode> linkedListNode = _scanNodes.First; linkedListNode != null; linkedListNode = linkedListNode.Next) { if (linkedListNode.Value.owner == name) { return true; } } return false; } private RaycastHit shootRay(float x, float y, float z) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) float num = 2.5f; Transform transform = ((Component)_mainPlayer.gameplayCamera).transform; Vector3 val = transform.position + transform.forward * num; RaycastHit result = default(RaycastHit); Physics.Raycast(val, transform.forward, ref result, 1000f); return result; } } public static class PluginInfo { public const string PLUGIN_GUID = "Pinger"; public const string PLUGIN_NAME = "Pinger"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace Pinger.Overrider { [HarmonyPatch(typeof(StartOfRound), "Awake")] internal class StartOfRound_Awake { [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPrefix] private static bool Prefix() { Debug.Log((object)"StartOfRound.Awake() is called"); return true; } } [HarmonyPatch] internal class KeyboardPing { private static float lastQPress; private const float PING_RESET = 0.3f; private static bool isWaiting; private static bool pingPressed; private static IEnumerator WaitForNextQ() { if (!isWaiting) { isWaiting = true; yield return (object)new WaitForSeconds(0.3f); if (!pingPressed) { Plugin.Instance.createPingWherePlayerIsLooking(); } isWaiting = false; } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void PingCommand(PlayerControllerB __instance) { long num = DateTimeOffset.Now.ToUnixTimeMilliseconds(); bool flag = false; if (!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || __instance.inTerminalMenu || __instance.isTypingChat || __instance.isPlayerDead) { flag = true; } if (flag) { return; } if (((ButtonControl)Keyboard.current.qKey).wasPressedThisFrame) { if (!pingPressed) { pingPressed = true; ((MonoBehaviour)__instance).StartCoroutine(WaitForNextQ()); } else { bool flag2 = Plugin.Instance.createPingWherePlayerIsLooking(is_danger: true); } } else if (pingPressed) { lastQPress += Time.deltaTime; if (lastQPress >= 0.3f) { pingPressed = false; isWaiting = false; lastQPress = 0f; } } } } } namespace Pinger.CircleHelper { public static class Helper { private const string TAG = "[Pinger::CircleHelper]"; public static void debug_DisplayEntireComponentTree(Transform obj) { if ((Object)(object)obj == (Object)null) { return; } int childCount = obj.childCount; if (childCount > 0) { for (int i = 0; i < childCount; i++) { Transform child = obj.GetChild(i); Debug.Log((object)("[Pinger::CircleHelper]: " + ((Object)obj).name + "/" + ((Object)child).name)); debug_DisplayComponent(obj); debug_DisplayEntireComponentTree(child); } Debug.Log((object)("EOF - " + ((Object)obj).name)); } } private static void debug_DisplayComponent(Transform obj) { Debug.Log((object)string.Format("{0}: {1} :: typeof {2}", "[Pinger::CircleHelper]", ((Object)obj).name, ((object)obj).GetType())); } public static Transform debug_GrabInnerCircle(Transform obj) { if ((Object)(object)obj == (Object)null) { return null; } int childCount = obj.childCount; if (childCount <= 0) { return null; } Transform result = null; for (int i = 0; i < childCount; i++) { Transform child = obj.GetChild(i); if (((Object)child).name == "Inner") { result = child; break; } } return result; } } } namespace Pinger.Adder { internal static class Adder { public static void AddToClass<T>(this T obj, Action action) { obj.GetType().GetMethod("AddToClass").Invoke(obj, new object[1] { action }); } } }