Skip to content

Commit 3ff82a2

Browse files
committed
Merge Add GET_PLAYER_PEER_STATISTICS to get useful peer stats (pr-3162)
a7d4410 - feat(server): add `GET_PLAYER_PEER_STATISTICS` to get useful peer stats
2 parents dfbc1a6 + a7d4410 commit 3ff82a2

File tree

5 files changed

+155
-3
lines changed

5 files changed

+155
-3
lines changed

code/components/citizen-server-impl/include/GameServerNet.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,41 @@ enum NetPacketType
1717
namespace fx
1818
{
1919
class GameServer;
20+
21+
enum ENetPeerStatistics : uint8_t
22+
{
23+
// PacketLoss will only update once every 10 seconds, use PacketLossEpoch if you want the time
24+
// since the last time the packet loss was updated.
25+
26+
// the amount of packet loss the player has, needs to be scaled with PACKET_LOSS_SCALE
27+
PacketLoss = 0,
28+
// The variance in the packet loss
29+
PacketLossVariance = 1,
30+
// The time since the last packet update in ms, relative to the peers connection time
31+
PacketLossEpoch = 2,
32+
// The mean amount of time it takes for a packet to get to the client (ping)
33+
RoundTripTime = 3,
34+
// The variance in the round trip time
35+
RoundTripTimeVariance = 4,
36+
// Despite their name, these are only updated once every 5 seconds, you can get the last time this was updated with PacketThrottleEpoch
37+
// The last recorded round trip time of a packet
38+
LastRoundTripTime = 5,
39+
// The last round trip time variance
40+
LastRoundTripTimeVariance = 6,
41+
// The time since the last packet throttle update, relative to the peers connection time
42+
PacketThrottleEpoch = 7,
43+
44+
MAX
45+
};
46+
2047
class NetPeerBase : public fwRefCountable
2148
{
2249
public:
2350
virtual int GetId() = 0;
2451

2552
virtual int GetPing() = 0;
2653

27-
virtual int GetPingVariance() = 0;
54+
virtual uint32_t GetENetStatistics(ENetPeerStatistics statisticType) = 0;
2855

2956
virtual net::PeerAddress GetAddress() = 0;
3057

code/components/citizen-server-impl/src/GameServerNet.ENet.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ namespace fx
105105
return peer->roundTripTime;
106106
}
107107

108-
virtual int GetPingVariance() override
108+
// Used by the scripting API to get useful statistics
109+
virtual uint32_t GetENetStatistics(ENetPeerStatistics statisticType)
109110
{
110111
auto peer = GetPeer();
111112

@@ -114,7 +115,29 @@ namespace fx
114115
return 0;
115116
}
116117

117-
return peer->roundTripTimeVariance;
118+
switch (statisticType)
119+
{
120+
case PacketLoss:
121+
return peer->packetLoss;
122+
case PacketLossVariance:
123+
return peer->packetLossVariance;
124+
case PacketLossEpoch:
125+
return peer->packetLossEpoch;
126+
case RoundTripTime:
127+
return peer->roundTripTime;
128+
case RoundTripTimeVariance:
129+
return peer->roundTripTimeVariance;
130+
case LastRoundTripTime:
131+
return peer->lastRoundTripTime;
132+
case LastRoundTripTimeVariance:
133+
return peer->lastRoundTripTimeVariance;
134+
case PacketThrottleEpoch:
135+
return peer->packetThrottleEpoch;
136+
case PacketsSent:
137+
return peer->packetsSent;
138+
default:
139+
return 0;
140+
}
118141
}
119142

120143
virtual net::PeerAddress GetAddress() override

code/components/citizen-server-impl/src/PlayerScriptFunctions.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,27 @@ static void CreatePlayerCommands()
116116
return int(peer->GetPing());
117117
}));
118118

119+
fx::ScriptEngine::RegisterNativeHandler("GET_PLAYER_PEER_STATISTICS", MakeClientFunction([](fx::ScriptContext& context, const fx::ClientSharedPtr& client)
120+
{
121+
const int peerStatistic = context.GetArgument<uint8_t>(1);
122+
123+
if (peerStatistic >= fx::ENetPeerStatistics::MAX)
124+
{
125+
throw std::runtime_error(va("Argument 1 is out of range, max peer statistics is %d, got %d", fx::ENetPeerStatistics::MAX - 1, peerStatistic));
126+
}
127+
128+
fx::NetPeerStackBuffer stackBuffer;
129+
gscomms_get_peer(client->GetPeer(), stackBuffer);
130+
auto peer = stackBuffer.GetBase();
131+
132+
if (!peer)
133+
{
134+
return 0;
135+
}
136+
137+
return static_cast<int>(peer->GetENetStatistics(static_cast<fx::ENetPeerStatistics>(peerStatistic)));
138+
}));
139+
119140
fx::ScriptEngine::RegisterNativeHandler("GET_PLAYER_LAST_MSG", MakeClientFunction([](fx::ScriptContext& context, const fx::ClientSharedPtr& client)
120141
{
121142
return (msec() - client->GetLastSeen()).count();
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
ns: CFX
3+
apiset: server
4+
---
5+
## GET_PLAYER_PEER_STATISTICS
6+
7+
```c
8+
int GET_PLAYER_PEER_STATISTICS(char* playerSrc, int peerStatistic);
9+
```
10+
11+
```cpp
12+
const int ENET_PACKET_LOSS_SCALE = 65536;
13+
14+
enum PeerStatistics
15+
{
16+
// PacketLoss will only update once every 10 seconds, use PacketLossEpoch if you want the time
17+
// since the last time the packet loss was updated.
18+
19+
// the amount of packet loss the player has, needs to be scaled with PACKET_LOSS_SCALE
20+
PacketLoss = 0,
21+
// The variance in the packet loss
22+
PacketLossVariance = 1,
23+
// The time since the last packet update in ms, relative to the peers connection time
24+
PacketLossEpoch = 2,
25+
// The mean amount of time it takes for a packet to get to the client (ping)
26+
RoundTripTime = 3,
27+
// The variance in the round trip time
28+
RoundTripTimeVariance = 4,
29+
// Despite their name, these are only updated once every 5 seconds, you can get the last time this was updated with PacketThrottleEpoch
30+
// The last recorded round trip time of a packet
31+
LastRoundTripTime = 5,
32+
// The last round trip time variance
33+
LastRoundTripTimeVariance = 6,
34+
// The time since the last packet throttle update, relative to the peers connection time
35+
PacketThrottleEpoch = 7,
36+
};
37+
```
38+
39+
These statistics only update once every 10 seconds.
40+
41+
## Parameters
42+
* **playerSrc**: The player to get the stats of
43+
* **peerStatistic**: The statistic to get, this will error if its out of range
44+
45+
## Return value
46+
See `ENetStatisticType` for what this will return.
47+
48+
## Examples
49+
```js
50+
51+
setInterval(() => {
52+
const ENET_PACKET_LOSS_SCALE = 65536;
53+
54+
const PLAYER_SERVER_ID = 1;
55+
56+
const packetLoss = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 0 /* PacketLoss */);
57+
const packetLossVariance = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 1 /* PacketLossVariance */);
58+
const packetLossEpoch = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 2 /* PacketLossEpoch */)
59+
const rtt = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 3 /* RoundTripTime */);
60+
const rttVariance = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 4 /* RoundTripTimeVariance */);
61+
const lastRtt = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 5 /* LastRoundTripTime */);
62+
const lastRttVariance = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 6 /* LastRoundTripTimeVariance */);
63+
const packetThrottleEpoch = GetPlayerPeerStatistics(PLAYER_SERVER_ID, 7 /* PacketThrottleEpoch */);
64+
65+
console.log(`packetLoss: ${packetLoss}`);
66+
console.log(`packetLossVariance: ${packetLossVariance}`);
67+
console.log(`packetLossEpch: ${packetLossEpoch}`);
68+
69+
console.log(`packetLossScaled: ${packetLoss / ENET_PACKET_LOSS_SCALE}`);
70+
console.log(`packetLossVarianceScaled: ${packetLossVariance / ENET_PACKET_LOSS_SCALE}`);
71+
72+
console.log(`rtt: ${rtt}`);
73+
console.log(`rttVariance: ${rttVariance}`);
74+
75+
console.log(`lastRtt: ${lastRtt}`);
76+
console.log(`lastRttVariance: ${lastRttVariance}`);
77+
console.log(`packetThrottleEpoch: ${packetThrottleEpoch}`);
78+
}, 10000)
79+
```

ext/native-decls/GetPlayerPing.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ apiset: server
88
int GET_PLAYER_PING(char* playerSrc);
99
```
1010
11+
See [GET_PLAYER_PEER_STATISTICS](#_0x9A928294) if you want more detailed information, like packet loss, and packet/rtt variance
1112
1213
## Parameters
1314
* **playerSrc**:
1415
1516
## Return value
17+
Returns the mean amount of time a packet takes to get to the client

0 commit comments

Comments
 (0)