mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-09 02:13:09 +00:00
feat(server): kernel TCP RTT for Player.getPing()
This commit is contained in:
parent
0708120ae8
commit
70a610fd2c
|
|
@ -109,10 +109,12 @@ public class Player : HumanEntity, OfflinePlayer, CommandSender
|
|||
public ulong getRawOfflineXUID() => _playerRawOfflineXUID;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player's estimated ping in milliseconds.
|
||||
/// This value represents a weighted average of the response time to application layer ping packets sent. This value does not represent the network round trip time and as such may have less granularity and be impacted by other sources. For these reasons it should not be used for anti-cheat purposes. Its recommended use is only as a qualitative indicator of connection quality.
|
||||
/// Gets the player's network round trip time in milliseconds.
|
||||
/// On the dedicated Windows server this reads the kernel TCP RTT directly
|
||||
/// (microsecond precision, untouched by tick scheduler delay). If the OS
|
||||
/// query fails it falls back to a smoothed application keepalive value.
|
||||
/// </summary>
|
||||
/// <returns>The player's estimated ping in milliseconds.</returns>
|
||||
/// <returns>The player's RTT in milliseconds, or -1 if unavailable.</returns>
|
||||
public int getPing()
|
||||
{
|
||||
if (NativeBridge.GetPlayerLatency == null)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "../Minecraft.World/Biome.h"
|
||||
#include "../Minecraft.World/LightLayer.h"
|
||||
#include "../Minecraft.Client/Windows64/Network/WinsockNetLayer.h"
|
||||
#include <mstcpip.h>
|
||||
#include "../Minecraft.World/AbstractContainerMenu.h"
|
||||
#include "../Minecraft.World/AddGlobalEntityPacket.h"
|
||||
#include "../Minecraft.World/ArrayWithLength.h"
|
||||
|
|
@ -643,6 +644,33 @@ int __cdecl NativeGetPlayerLatency(int entityId)
|
|||
auto player = FindPlayer(entityId);
|
||||
if (!player) return -1;
|
||||
|
||||
// Prefer the kernel's TCP round trip when available. Microsecond precision
|
||||
// and free of the application-layer tick scheduler delay that smooths
|
||||
// player->latency upward by ~one tick interval per direction.
|
||||
if (player->connection && player->connection->connection &&
|
||||
player->connection->connection->getSocket())
|
||||
{
|
||||
unsigned char smallId = player->connection->connection->getSocket()->getSmallId();
|
||||
if (smallId != 0)
|
||||
{
|
||||
SOCKET sock = WinsockNetLayer::GetSocketForSmallId(smallId);
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
TCP_INFO_v0 info = {};
|
||||
DWORD infoVersion = 0;
|
||||
DWORD bytesReturned = 0;
|
||||
int rc = WSAIoctl(sock, SIO_TCP_INFO,
|
||||
&infoVersion, sizeof(infoVersion),
|
||||
&info, sizeof(info),
|
||||
&bytesReturned, NULL, NULL);
|
||||
if (rc == 0 && bytesReturned == sizeof(info))
|
||||
{
|
||||
return (int)(info.RttUs / 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return player->latency;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue