Please disclose if your mod was created primarily 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 PingTweaks v1.0.6
PingTweaks.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PingTweaks")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Riintouge")] [assembly: AssemblyProduct("PingTweaks")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7af575dc-7a28-4905-ac30-ac848b9d9aa2")] [assembly: AssemblyFileVersion("1.0.6.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.6.0")] namespace PingTweaks; [BepInPlugin("com.riintouge.pingtweaks", "Ping Tweaks", "1.0.6")] [BepInProcess("valheim.exe")] public class PingTweaks : BaseUnityPlugin { [HarmonyPatch(typeof(Chat))] private class ChatPatch { public static bool BroadcastPing; public static bool CreatePersistentPing; public static Vector3? PersistentPingLocation; public static WorldTextInstance FindExistingWorldText(Chat instance, long senderID) { return Traverse.Create((object)instance).Method("FindExistingWorldText", new Type[1] { typeof(long) }, (object[])null).GetValue<WorldTextInstance>(new object[1] { senderID }); } [HarmonyPatch("AddInworldText")] [HarmonyPrefix] private static void AddInworldTextPrefix(ref Chat __instance, ref long senderID, ref Vector3 position, ref string text, ref Type type, out string __state) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) __state = (Utility.IsNullOrWhiteSpace(text) ? "PING" : text); if (!IsEnabled.Value || (int)type != 3) { return; } float y = ((Component)Player.m_localPlayer).transform.position.y; if (position.y == 0f) { position.y = y; } else if (position.y >= 4500f) { if (!Common.IsLocalPlayerInDungeon()) { position.y = y - 30f; } } else if (Common.IsLocalPlayerInDungeon()) { position.y = y + 30f; } else if (position.y < 30f) { position.y = 30f; } if (CreatePersistentPing && senderID == ZNet.GetUID()) { PersistentPingLocation = position + Vector3.zero; } } [HarmonyPatch("AddInworldText")] [HarmonyPostfix] private static void AddInworldTextPostfix(ref Chat __instance, ref long senderID, ref Type type, ref string __state) { if (IsEnabled.Value && (int)type == 3) { WorldTextInstance val = FindExistingWorldText(__instance, senderID); if (val != null) { val.m_text = Localization.instance.Localize(__state).ToUpperInvariant(); MinimapPatch.RegeneratePingPins = true; } } } [HarmonyPatch("SendPing")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SendPingTranspiler(IEnumerable<CodeInstruction> instructionsIn) { List<CodeInstruction> list = new List<CodeInstruction>(instructionsIn); for (int i = 0; i + 2 < list.Count; i++) { if (list[i].opcode == OpCodes.Ldarg_1 && list[i + 1].opcode == OpCodes.Stloc_1 && list[i + 2].opcode == OpCodes.Ldloca_S) { for (int j = i + 2; j <= i + 7; j++) { list[j].opcode = OpCodes.Nop; } } } return list; } [HarmonyPatch("UpdateWorldTextField")] [HarmonyPrefix] private static void UpdateWorldTextFieldPrefix(ref Chat __instance, ref WorldTextInstance wt) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_002f: 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_005a: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled.Value && (int)wt.m_type == 3) { if (PersistentPingLocation.HasValue && wt.m_position == PersistentPingLocation.GetValueOrDefault() && wt.m_talkerID == ZNet.GetUID()) { ((Graphic)wt.m_textMeshField).color = Common.CopyColor(PersistentPingColor.Value); wt.m_timer = float.NegativeInfinity; } else { ((Graphic)wt.m_textMeshField).color = Common.CopyColor(PingColor.Value); wt.m_timer = __instance.m_worldTextTTL - (float)PingDuration.Value; } } } [HarmonyPatch("UpdateWorldTexts")] [HarmonyPostfix] private static void UpdateWorldTextsPostfix(ref float dt, ref List<WorldTextInstance> ___m_worldTexts) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 if (!IsEnabled.Value) { return; } foreach (WorldTextInstance ___m_worldText in ___m_worldTexts) { if ((int)___m_worldText.m_type == 3) { ___m_worldText.m_position.y -= dt * 0.15f; ((TMP_Text)___m_worldText.m_textMeshField).SetText(Common.PrettyPrintPingText(___m_worldText)); } } } } internal class Common { public const float DungeonFakeDepth = 30f; public const float DungeonMinHeight = 4500f; public const float EstimatedSeaLevel = 30f; public static bool CheckBroadcastKeybind() { //IL_0005: 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) if ((int)PingBroadcastModifier.Value != 0) { return Input.GetKey(PingBroadcastModifier.Value); } return true; } public static bool CheckPersistentKeybind() { //IL_0005: 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) if ((int)PersistentPingBroadcastModifier.Value != 0) { return Input.GetKey(PersistentPingBroadcastModifier.Value); } return false; } public static Color CopyColor(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(color.r, color.g, color.b, color.a); } public static bool IsLocalPlayerInDungeon() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return ((Component)Player.m_localPlayer).transform.position.y >= 4500f; } public static string PrettyPrintDistance(Vector3 from, Vector3 to) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) CultureInfo currentCulture = CultureInfo.CurrentCulture; Vector3 val = to - from; return string.Format(currentCulture, "({0}m)", Math.Round(((Vector3)(ref val)).magnitude, 1)); } public static string PrettyPrintPingText(WorldTextInstance worldText) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) return string.Format("{0}\n{1}\n{2}", worldText.m_name, worldText.m_text, ((Object)(object)Player.m_localPlayer != (Object)null) ? PrettyPrintDistance(((Component)Player.m_localPlayer).transform.position, worldText.m_position) : ""); } } [HarmonyPatch(typeof(Game))] private class GamePatch { [HarmonyPatch("Logout")] [HarmonyPrefix] private static void LogoutPostfix(ref bool ___m_firstSpawn) { ChatPatch.PersistentPingLocation = null; } } [HarmonyPatch(typeof(Minimap))] private class MinimapPatch { internal static bool RegeneratePingPins; private static Vector3 ScreenToWorldPoint(Minimap instance) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) return Traverse.Create((object)instance).Method("ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (object[])null).GetValue<Vector3>(new object[1] { ZInput.mousePosition }); } internal static PinData GetClosestPin(Minimap instance, Vector3 pos, float radius, bool mustBeVisible = true) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) return Traverse.Create((object)instance).Method("GetClosestPin", new Type[3] { typeof(Vector3), typeof(float), typeof(bool) }, (object[])null).GetValue<PinData>(new object[3] { pos, radius, mustBeVisible }); } private static WorldTextInstance GetClosestPing(Vector3 pos, float radius, long uid = -1L) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0044: 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) List<WorldTextInstance> list = new List<WorldTextInstance>(); Chat.instance.GetPingWorldTexts(list); WorldTextInstance result = null; float num = float.PositiveInfinity; foreach (WorldTextInstance item in list) { if ((int)item.m_type == 3 && (uid == -1 || uid == item.m_talkerID)) { float num2 = Utils.DistanceXZ(pos, item.m_position); if (num2 < radius && num2 < num) { result = item; num = num2; } } } return result; } [HarmonyPatch("MapPointToWorld")] [HarmonyPostfix] private static void MapPointToWorldPostfix(ref Vector3 __result) { //IL_002f: 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) if (IsEnabled.Value) { if (Common.IsLocalPlayerInDungeon()) { __result.y = ((Component)Player.m_localPlayer).transform.position.y; return; } Heightmap.GetHeight(__result, ref __result.y); __result.y = Mathf.Max(30f, __result.y); } } [HarmonyPatch("OnMapDblClick")] [HarmonyPrefix] private static bool OnMapDblClickPrefix(ref Minimap __instance, ref float ___m_largeZoom, ref List<PinData> ___m_pins, ref PinType ___m_selectedType) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0090: Unknown result type (might be due to invalid IL or missing references) if (!IsEnabled.Value) { return true; } Vector3 pos = ScreenToWorldPoint(__instance); float radius = __instance.m_removeRadius * ___m_largeZoom * 2f; if (GetClosestPin(__instance, pos, radius) != null) { return false; } WorldTextInstance closestPing = GetClosestPing(pos, radius, -1L); if (closestPing == null || closestPing.m_talkerID == ZNet.GetUID()) { return true; } Vector3 __result = closestPing.m_position; if (__result.y == 0f) { MapPointToWorldPostfix(ref __result); } __instance.AddPin(__result, ___m_selectedType, closestPing.m_text, SavePinnedPings.Value, false, closestPing.m_talkerID, default(PlatformUserID)); return false; } [HarmonyPatch("OnMapMiddleClick")] [HarmonyPrefix] private static bool OnMapMiddleClickPrefix(ref Minimap __instance, ref UIInputHandler handler, ref float ___m_largeZoom) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = ScreenToWorldPoint(__instance); float radius = __instance.m_removeRadius * ___m_largeZoom * 2f; WorldTextInstance closestPing = GetClosestPing(pos, radius, ZNet.GetUID()); if (closestPing != null) { ChatPatch.BroadcastPing = false; ChatPatch.CreatePersistentPing = false; ChatPatch.PersistentPingLocation = null; closestPing.m_timer = float.PositiveInfinity; return false; } ChatPatch.BroadcastPing = Common.CheckBroadcastKeybind(); ChatPatch.CreatePersistentPing = Common.CheckPersistentKeybind(); ChatPatch.PersistentPingLocation = null; return true; } [HarmonyPatch("UpdatePingPins")] [HarmonyPrefix] private static void UpdatePingPinsPrefix(ref Minimap __instance, ref List<PinData> ___m_pingPins) { if (!RegeneratePingPins) { return; } foreach (PinData ___m_pingPin in ___m_pingPins) { __instance.RemovePin(___m_pingPin); } ___m_pingPins.Clear(); RegeneratePingPins = false; } [HarmonyPatch("UpdatePingPins")] [HarmonyPostfix] private static void UpdatePingPinsPostfix(ref List<PinData> ___m_pingPins, ref bool ___m_pinUpdateRequired) { if (!IsEnabled.Value) { return; } List<WorldTextInstance> list = new List<WorldTextInstance>(); Chat.instance.GetPingWorldTexts(list); for (int i = 0; i < list.Count; i++) { PinNameData namePinData = ___m_pingPins[i].m_NamePinData; TMP_Text val = ((namePinData != null) ? namePinData.PinNameText : null); if ((Object)(object)val != (Object)null) { WorldTextInstance worldText = list[i]; val.SetText(Common.PrettyPrintPingText(worldText)); } } } } [HarmonyPatch(typeof(PinNameData))] private class MinimapPinNameDataPatch { [HarmonyPatch("SetTextAndGameObject")] [HarmonyPostfix] private static void SetTextAndGameObjectPostfix(ref PinNameData __instance, ref GameObject text) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled.Value && __instance != null && __instance.ParentPin != null && !((Object)(object)__instance.PinNameText == (Object)null) && (int)__instance.ParentPin.m_type == 12) { int num = __instance.PinNameText.text.IndexOf(": "); __instance.PinNameText.text = $"{__instance.PinNameText.text.Substring(0, num)}\n{__instance.PinNameText.text.Substring(num + 2)}\n{Common.PrettyPrintDistance(((Component)Player.m_localPlayer).transform.position, __instance.ParentPin.m_pos)}"; } } } [HarmonyPatch(typeof(Player))] private class PlayerPatch { [HarmonyPatch("OnDestroy")] [HarmonyPrefix] private static void OnDestroyPostfix(ref Player ___m_localPlayer) { if ((Object)(object)___m_localPlayer == (Object)null) { ChatPatch.PersistentPingLocation = null; } } } [HarmonyPatch(typeof(ZRoutedRpc))] private class ZRoutedRpcPatch { [HarmonyPatch("InvokeRoutedRPC", new Type[] { typeof(long), typeof(string), typeof(object[]) })] [HarmonyPrefix] private static bool InvokeRoutedRPCPrefix(ref string methodName, ref object[] parameters) { //IL_0065: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!IsEnabled.Value || methodName.CompareTo("ChatMessage") != 0) { return true; } int? num = parameters[1] as int?; if (!num.HasValue || num.Value != 3) { return true; } Vector3? val = parameters[0] as Vector3?; if (!val.HasValue || !val.HasValue) { return true; } Vector3 val2 = val.Value; float y = val2.y; object obj = parameters[2]; UserInfo val3 = (UserInfo)((obj is UserInfo) ? obj : null); string text = parameters[3] as string; Minimap instance = Minimap.instance; float value = Traverse.Create((object)instance).Field("m_largeZoom").GetValue<float>(); PinData val4 = MinimapPatch.GetClosestPin(radius: instance.m_removeRadius * value * 2f, instance: instance, pos: val2, mustBeVisible: false); if (val4 != null) { val2 = val4.m_pos; if (val2.y == 0f) { val2.y = y; } if (!Utility.IsNullOrWhiteSpace(val4.m_name)) { parameters[3] = val4.m_name; text = val4.m_NamePinData.PinNameText.text; } } if (!ChatPatch.BroadcastPing && val3 != null) { Chat.instance.OnNewChatMessage((GameObject)null, ZNet.GetUID(), val2, (Type)3, val3, text ?? "PING"); return false; } parameters[0] = val2; return true; } } [CompilerGenerated] private sealed class <CoRefreshPersistentPing>d__17 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CoRefreshPersistentPing>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if (ChatPatch.PersistentPingLocation.HasValue) { Chat.instance.SendPing(ChatPatch.PersistentPingLocation.GetValueOrDefault()); } } else { <>1__state = -1; } <>2__current = (object)new WaitForSecondsRealtime(3f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static PingTweaks Instance; public static ConfigEntry<bool> IsEnabled; public static ConfigEntry<bool> LoadOnStart; public static ConfigEntry<bool> SavePinnedPings; public static ConfigEntry<KeyCode> PingBroadcastModifier; public static ConfigEntry<Color> PingColor; public static ConfigEntry<int> PingDuration; public static ConfigEntry<KeyCode> PersistentPingBroadcastModifier; public static ConfigEntry<Color> PersistentPingColor; private static Coroutine RefreshPersistentPingCoRoutine; private readonly Harmony Harmony = new Harmony("com.riintouge.pingtweaks"); private void Awake() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "Enable", true, "Whether this plugin has any effect when loaded."); LoadOnStart = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "LoadOnStart", true, "Whether this plugin loads on game start."); SavePinnedPings = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "SavePinnedPings", false, "Whether double-clicking on a ping from another player creates a persistent pin. Off by default to not conflict with the cartography table."); PingBroadcastModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2 - Standard Pings", "PingBroadcastModifier", (KeyCode)304, "If set and not \"None\", pings will only be sent to other players when the specified key is pressed. If \"None\", pings will always be broadcast."); PingColor = ((BaseUnityPlugin)this).Config.Bind<Color>("2 - Standard Pings", "PingColor", new Color(0.6f, 0.7f, 1f, 1f), "In-world ping text color."); PingDuration = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Standard Pings", "PingDuration", 5, new ConfigDescription("How long to show pings, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 60), Array.Empty<object>())); PersistentPingBroadcastModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("3 - Persistent Pings", "PersistentPingBroadcastModifier", (KeyCode)308, "If set and not \"None\", pings will be created as persistent when the specified key is pressed. If \"None\", pings will never be persistent."); PersistentPingColor = ((BaseUnityPlugin)this).Config.Bind<Color>("3 - Persistent Pings", "PersistentPingColor", new Color(1f, 0.7f, 0.6f, 1f), "In-world persistent ping text color."); if (LoadOnStart.Value) { Instance = this; Harmony.PatchAll(); RefreshPersistentPingCoRoutine = ((MonoBehaviour)Instance).StartCoroutine(CoRefreshPersistentPing()); } } [IteratorStateMachine(typeof(<CoRefreshPersistentPing>d__17))] private IEnumerator CoRefreshPersistentPing() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CoRefreshPersistentPing>d__17(0); } }