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 VBMapPingSmooth v0.0.1
VBMapPingSmooth.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Guid("d9c87954-ce20-459d-81ec-96599caed427")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyProduct("VBMapPingSmooth")] [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("VBMapPingSmooth")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [Embedded] [CompilerGenerated] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [Embedded] [CompilerGenerated] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VBMapPingSmooth { [HarmonyPatch(typeof(Minimap), "UpdatePlayerPins")] public static class Minimap_UpdatePlayerPins_Patch { private class PlayerTrackData { public Vector3 lastRealPosition; public Vector3 lastRealVelocity; public Vector3 smoothPosition; public Vector3 smoothVelocity; public float lastUpdateTime; public float predictedTimeout; public bool wasTeleporting; public float teleportEndTime; } public static float InterpolationSpeed; public static float SmoothTime; public static float TeleportThreshold; public static float MaxPredictionTime; private static bool? serverModDetected; private static float serverLastUpdateTime; private static Dictionary<long, PlayerTrackData> playerData; private static FieldInfo m_characterIDField; private static FieldInfo m_userIDField; static Minimap_UpdatePlayerPins_Patch() { InterpolationSpeed = 2000f; SmoothTime = 0.033f; TeleportThreshold = 50f; MaxPredictionTime = 0.3f; serverModDetected = null; serverLastUpdateTime = 0f; playerData = new Dictionary<long, PlayerTrackData>(); Type typeFromHandle = typeof(PlayerInfo); m_characterIDField = typeFromHandle.GetField("m_characterID"); if (m_characterIDField != null) { Type fieldType = m_characterIDField.FieldType; m_userIDField = fieldType.GetField("m_userID"); } } [HarmonyPrefix] private static void Prefix() { if (Time.frameCount % 600 == 0) { CleanupOldData(); } } [HarmonyPostfix] private static void Postfix(Minimap __instance, float dt) { //IL_002a: 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_0030: 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_004a: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008c: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0187: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022a: 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) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; DetectServerMod(time); for (int i = 0; i < __instance.m_playerPins.Count && i < __instance.m_tempPlayerInfo.Count; i++) { PinData val = __instance.m_playerPins[i]; PlayerInfo val2 = __instance.m_tempPlayerInfo[i]; long playerId = GetPlayerId(val2); if (playerId == 0) { continue; } Vector3 position = val2.m_position; if (!playerData.TryGetValue(playerId, out var value)) { value = new PlayerTrackData(); playerData[playerId] = value; value.smoothPosition = position; value.lastRealPosition = position; value.lastUpdateTime = time; } float num = time - value.lastUpdateTime; if (num > 0.001f && num < 1f) { Vector3 val3 = position - value.lastRealPosition; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude > TeleportThreshold) { value.wasTeleporting = true; value.teleportEndTime = time + 0.2f; value.lastRealVelocity = Vector3.zero; } else { value.lastRealVelocity = val3 / num; if (((Vector3)(ref value.lastRealVelocity)).magnitude > 100f) { value.lastRealVelocity = ((Vector3)(ref value.lastRealVelocity)).normalized * 100f; } } } value.lastRealPosition = position; value.lastUpdateTime = time; if (value.teleportEndTime > time) { val.m_pos = position; value.smoothPosition = position; value.smoothVelocity = Vector3.zero; continue; } if (value.wasTeleporting) { value.wasTeleporting = false; } Vector3 val4 = position; float num2 = time - value.lastUpdateTime; bool flag = serverModDetected == true; if (num2 > 0.033f && ((Vector3)(ref value.lastRealVelocity)).magnitude > 0.1f && !flag) { float num3 = Mathf.Min(num2, MaxPredictionTime); val4 = position + value.lastRealVelocity * num3; } float num4 = SmoothTime; float num5 = InterpolationSpeed; float num6 = Vector3.Distance(value.smoothPosition, val4); if (num6 > 30f) { num4 = 0.01f; } else if (num6 > 10f) { num4 = 0.02f; } if (flag) { num5 = InterpolationSpeed * 1.5f; } value.smoothPosition = Vector3.SmoothDamp(value.smoothPosition, val4, ref value.smoothVelocity, num4, num5, dt); val.m_pos = value.smoothPosition; } } private static void DetectServerMod(float now) { if (!serverModDetected.HasValue && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && now - serverLastUpdateTime > 0.5f) { serverLastUpdateTime = now; List<ZNetPeer> peers = ZNet.instance.GetPeers(); if (peers.Count > 0 && peers[0].m_rpc != null) { serverModDetected = false; } } } private static long GetPlayerId(PlayerInfo info) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) try { if (m_characterIDField != null) { object value = m_characterIDField.GetValue(info); if (value != null && m_userIDField != null) { return (long)m_userIDField.GetValue(value); } } } catch { } try { FieldInfo field = typeof(PlayerInfo).GetField("m_name"); if (field != null) { string text = field.GetValue(info) as string; if (!string.IsNullOrEmpty(text)) { return text.GetHashCode(); } } } catch { } return 0L; } private static void CleanupOldData() { float time = Time.time; List<long> list = new List<long>(); foreach (KeyValuePair<long, PlayerTrackData> playerDatum in playerData) { if (time - playerDatum.Value.lastUpdateTime > 10f) { list.Add(playerDatum.Key); } } foreach (long item in list) { playerData.Remove(item); } } } [BepInPlugin("VitByr.VBMapPingSmooth", "VBMapPingSmooth", "0.0.1")] public class VBMapPingSmooth : BaseUnityPlugin { private const string ModName = "VBMapPingSmooth"; private const string ModVersion = "0.0.1"; private const string ModGUID = "VitByr.VBMapPingSmooth"; public static ConfigEntry<Language> ConfigLanguage; public static ConfigEntry<float> ConfigInterpolationSpeed; public static ConfigEntry<float> ConfigSmoothTime; public static ConfigEntry<float> ConfigTeleportThreshold; public static ConfigEntry<float> ConfigMaxPredictionTime; public static ConfigEntry<float> ConfigUpdateInterval; public static VBMapPingSmooth Instance { get; private set; } public void Awake() { Instance = this; InitConfig(); Minimap_UpdatePlayerPins_Patch.InterpolationSpeed = ConfigInterpolationSpeed.Value; Minimap_UpdatePlayerPins_Patch.SmoothTime = ConfigSmoothTime.Value; Minimap_UpdatePlayerPins_Patch.TeleportThreshold = ConfigTeleportThreshold.Value; Minimap_UpdatePlayerPins_Patch.MaxPredictionTime = ConfigMaxPredictionTime.Value; ZNet_SendPeriodicData_Patch.UpdateInterval = ConfigUpdateInterval.Value; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "VitByr.VBMapPingSmooth"); } private void InitConfig() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown ConfigLanguage = ((BaseUnityPlugin)this).Config.Bind<Language>("0 - General", "Language", Language.Russian, new ConfigDescription("Select interface language / Выберите язык интерфейса \nRequired Restart / Требуется рестарт", (AcceptableValueBase)null, Array.Empty<object>())); ConfigInterpolationSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Client", "InterpolationSpeed", 1000f, GetConfigDescription("Скорость интерполяции маркера (единиц/сек)\nЧем выше, тем быстрее маркер догоняет реальную позицию", "Marker interpolation speed (units/sec)\nHigher = faster marker catches up to real position", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 10000f))); ConfigSmoothTime = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Client", "SmoothTime", 0.033f, GetConfigDescription("Время сглаживания движения (сек)\nМеньше значение = быстрее реакция, но может быть дёргано\nРекомендуется: 0.016-0.066", "Smooth time (sec)\nLower = faster response, but may be jittery\nRecommended: 0.016-0.066", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.005f, 0.2f))); ConfigTeleportThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Client", "TeleportThreshold", 50f, GetConfigDescription("Дистанция для определения телепорта (метров)\nЕсли игрок переместился дальше этого значения за один кадр — считаем телепортом", "Distance for teleport detection (meters)\nIf player moves beyond this value in one frame - consider it a teleport", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f))); ConfigMaxPredictionTime = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Client", "MaxPredictionTime", 0.3f, GetConfigDescription("Максимальное время предсказания движения (сек)\nПри задержках маркер будет двигаться по инерции", "Maximum movement prediction time (sec)\nDuring lag, marker will move by inertia", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f))); ConfigUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Server", "UpdateInterval", 0.5f, GetConfigDescription("Интервал отправки позиций игроков (сек)\nМеньше = плавнее, но больше нагрузка на сеть\nВаниль: 2.0, Рекомендуется: 0.1-0.5", "Player position update interval (sec)\nLower = smoother, but more network load\nVanilla: 2.0, Recommended: 0.1-0.5", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f))); } private ConfigDescription GetConfigDescription(string russianDesc, string englishDesc, AcceptableValueBase acceptableValues = null) { //IL_0034: 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_003a: Expected O, but got Unknown ConfigEntry<Language> configLanguage = ConfigLanguage; string text = ((configLanguage != null && configLanguage.Value == Language.English) ? englishDesc : russianDesc); return (acceptableValues != null) ? new ConfigDescription(text, acceptableValues, Array.Empty<object>()) : new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>()); } } public enum Language { Russian, English } [HarmonyPatch(typeof(ZNet), "SendPeriodicData")] public static class ZNet_SendPeriodicData_Patch { private const float ORIGINAL_INTERVAL = 2f; public static float UpdateInterval = 0.1f; [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)2f, (string)null) }); if (val.IsValid) { val.SetInstruction(new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(ZNet_SendPeriodicData_Patch), "UpdateInterval"))); } return val.InstructionEnumeration(); } } }