gamedig / node-gamedig

Query game servers and not only! Node.JS/Deno/Bun or Bash (via the CLI).
https://www.npmjs.com/package/gamedig
MIT License
607 stars 146 forks source link

DayZ player count inaccurate? #440

Closed podrivo closed 10 months ago

podrivo commented 10 months ago

Hello!

I was testing DayZ player count on some servers and noticed something odd, when comparing it to BattleMetrics. Take for example this server: 194.147.90.234:27023

In BattleMetrics it says 0/127, but on gamedig it says 124/127.

I'm not sure if this is a bug or just different implementations, but it would be good to have other people take a look to help me understand what is going on. I'm not sure, but I think gamedig uses A2S_INFO to query player data, but perhaps a more accurate way of querying is to use A2S_PLAYER? Just thinking out loud here.

Here are images for comparison:

image image

Thank you!

CosminPerRam commented 10 months ago

The GameDig implementation queries both A2S_INFO and A2S_PLAYER but the numplayers field is gotten from A2S_INFO and not A2S_PLAYER. As some games implement the protocol with subtle changes, there are instances of games that provide the correct numplayers amount in both INFO and PLAYER, but some reports the correct one in INFO, some in PLAYER and sometimes even none, reporting no players-related data at all.

For DayZ (or this server at least), it seems that they provide the correct one in the A2S_PLAYER query (which I guess is what BattleMetrics does), but further research is needed to be done to establish this for sure.

Leaving this open until we'll figure it out. Feel free to give in some more thoughts, thanks!

podrivo commented 10 months ago

Thank you so much for the reply @CosminPerRam!

I did some testing around the queryPlayers() and I can confirm that, for DayZ, the best way to set player count is via A2S_PLAYER and not A2S_INFO. I've compared with BattleMetrics, and the numbers matched.

You can get the exact player count via const num = reader.uint(1):

https://github.com/gamedig/node-gamedig/blob/26a6ee1c08ea72297c695d52339e62ed8ee4f49c/protocols/valve.js#L220

CosminPerRam commented 10 months ago

Hmm, this might be a problem on BattleMetric's side, on dayz-servers.or it lists this server as being 126/127, gamedig says 125/127 (a margin this small might indicate that the server did the query some time ago and isn't real time).

This could be verified for sure if you join the server on the game, but I don't have it, I'll around some friends to check it.

I've also tested some other servers (with the #449 patch): IP Battlemetrics state.numplayers state.raw.players.length
189.127.165.21 78 60 60
172.111.51.48 60 63 0 (A2S_PLAYER query didn't respond)
172.111.51.133 89 93 92
168.100.161.42 88 89 89
189.127.164.116 75 67 67
172.111.51.132 54 54 54

Numbers look alright to me (4 out of 6 are very close (again, battlemetrics does queries every 5 minutes so we can't get their exact reported players count)).

podrivo commented 10 months ago

Thank you for getting more info about it! 🙌

It appears that there's an exploit on how servers handle player count on DayZ, and some server owners are using this to make it seems their player count is larger than it is. BattleMetrics seems to be the one that found a way around it. I've asked about this in their discord, but they didn't want to share more info, as to avoid a new exploit being developed.

Found this on: https://www.reddit.com/r/dayz/comments/13wlbxf/server_botting_is_on_an_all_time_high_list/

I wonder if dayz-servers.org is also using the same A2S_INFO method. It's an extra call for A2S_PLAYER, with no apparent win, since DayZ doesn't provide player names (https://github.com/gamedig/node-gamedig/issues/240). So they all use the same exploited A2S_INFO, including the official launcher. Definitely need more input, but I feel that's the case.

CosminPerRam commented 10 months ago

image DayZ Client: 126/127 GameDig Response: 126/127 Battlemetrics: 0/127

So I guess everything is fine on the gamedig's side, guess this issue is safe to close, thoughts?

CosminPerRam commented 10 months ago

Apparently we commented at the same time haha.

BattleMetrics seems to be the one that found a way around it. I've asked about this in their discord, but they didn't want to share more info, as to avoid a new exploit being developed.

Well, I guess that goes for it.

wonder if dayz-servers.org is also using the same A2S_INFO method.

Most likely.

podrivo commented 10 months ago

We hit "Comment" at the same second haha. 😅

I guess this is safe to close, as it's more of a DayZ side of things than GameDig's. I have a separate implementation that is built on top of GameDig, that I'll test other ways to fetch this info.

Thank you so much for you support @CosminPerRam! 🙌

CosminPerRam commented 10 months ago

I guess this is safe to close, as it's more of a DayZ side of things than GameDig's.

That's the case, if eventually we find a way to report more realistic player counts we will add it. Have a great day and happy new year! 😀

podrivo commented 10 months ago

Hello @CosminPerRam! I was testing the latest version in master, that has a new commit (https://github.com/gamedig/node-gamedig/commit/90e26bb442e120fb499d0d429e8c477d44e1935e) around player count, and the same server we were testing is now showing different data. I'm not sure if this is related, but when testing on some servers with the --debug flag on, you can see a discrepancy in data, when checking for the found player log, like this: Q#1 Found player: 0 12.277772903442383.

So for example, this server 194.147.90.234:27023 has no logs for Q#1 Found player..., but says "numplayers": 120. And this server I hear has a bad reputation around botting player count. I found this to be true for other servers known for botting player count, like this other one: 213.248.7.183:27023.

But this other one 135.148.36.25:2303 has lots of logs for Q#1 Found player..., and it matches the "numplayers": 39. Perhaps a more accurate way of telling the number of players for dayz, is using the same log method used to print Q#1 Found player...?

What do you think? Thank you! 🙏

I've added logs inside valve.js to help me navigate, and here are some prints:

Screenshot 2024-01-03 at 21 57 43 Screenshot 2024-01-03 at 22 01 40
podrivo commented 10 months ago

Taking a closer look, it looks like that DayZ doesn't provide an ingame name in the server query (https://github.com/gamedig/node-gamedig/issues/240), so gamedig excludes them here:

https://github.com/gamedig/node-gamedig/blob/90b3c6044b265a654e39801f61bdefcfd32f2fe9/protocols/valve.js#L192

That's why there's a gap between : and 0 in the debug log Q#1 Found player: 0 12.277772903442383. And that's why state.raw.players.length = 0, even though DayZ accounts for them.

Edit: Just saw that there's a branch and commit (https://github.com/gamedig/node-gamedig/commit/fc2791f2b95c60e77b2fd530674f7e890c50063b) specifically about this. I think this might be way to go! 😃

podrivo commented 10 months ago

I'm sorry @CosminPerRam, I just realized you mentioned this in your reply (https://github.com/gamedig/node-gamedig/issues/440#issuecomment-1874242395) days ago and somehow it slipped through me. This patch (https://github.com/gamedig/node-gamedig/pull/449) makes it obvious to see a difference in player count.

By testing the same server 194.147.90.234:27023 in this branch you can see that players array is empty, but numplayers is not 0. You'll notice that these servers botting player count, will have an empty players array and a "numplayers" near max capacity. I've tested with the servers you provided in your comment and they are all respected servers in the community and the players array was not empty, matching the "numplayers".

Servers botting player count will look something like this:

"players": [], // 0 or lower than 'numplayers'
"numplayers": 120, // this will always vary between 120 and 125, sometimes goes higher than max
"maxplayers": 127

Other servers to test: 194.147.90.234:27023, 79.119.178.110:27018, 92.38.222.17:2315, 185.189.255.58:27027.

Well, considering all this, I think if having the players array filled with the players encountered in the servers, I can just count this array and use this instead of "numplayers". And can I also eventually compare these two and create alerts of potential fake player count servers.

So yeah, I think this solves it! Fantastic! ✨ And now I'm wondering, when will this patch be rolled out?

Thank you! 🙌

CosminPerRam commented 10 months ago

And now I'm wondering, when will this patch be rolled out?

Not sure of it, will notify you.

podrivo commented 10 months ago

Awesome! Thank you! (: