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 147 forks source link

Minecraft - early return on valid response #370

Open Douile opened 1 year ago

Douile commented 1 year ago

In the current minecraft implementation we make queries with 3 different protocols and wait for them all to return before checking them. This causes slow down as you have to wait for the 2 failed requests to time out. And will also cause your request to timeout if socketTimeout and attemptTimeout are the same even when in theory we have received a valid response.

Example given by xCausxn on discord

gamedig --type minecraft --host mc.hypixel.net --port 25565 --socketTimeout 10000 --attemptTimeout 10000

To fix we could return as soon as one of the queries returns which means the other 2 requests get cancelled.

Note: Promise.race would most likely work as we're waiting on timeouts for the failed requests but if one of the unsuccessful queries fails before a successful it would return the error making it not the best solution in my opinion.

You could also think of this as a feature not a bug because we collect all the queries the server responds to and thereby by changing this we are changing expected behaviour: early returning wouldn't give the other queries a chance to complete. If that is the case there are other solutions.

podrivo commented 9 months ago

So basically, running a minecraft query with --socketTimeout 10000 will timeout, even if successful. Wondering if this is specific to minecraft or if other protocols could work the same.

// Success
gamedig --type minecraft mc.hypixel.net

// Fail
gamedig --type minecraft mc.hypixel.net --socketTimeout 10000
Douile commented 9 months ago

As far as I know minecraft is the only "protocol" that works in this way: sends queries using multiple different protocols ans collates the responses.

CosminPerRam commented 5 months ago

You could also think of this as a feature not a bug

It is a feature.

The problem with "returning the first response" is that we can't really know if it is valid or not, some Minecraft servers (although rare) are protected by service X that returns a dummy response but could still respond to the other queries, as you said here:

early returning wouldn't give the other queries a chance to complete

CosminPerRam commented 5 months ago

So basically, running a minecraft query with --socketTimeout 10000 will timeout, even if successful.

This is expected behaviour, the default attemptTimeout is also 10000 (ms), so after a socket times out, there is no time left for processing the received data (in this case the first successful query).

CosminPerRam commented 5 months ago

I don't think we can manage to return the first successful query and also make sure that all possible edge cases still work (maybe after we add tests?). I'd leave this as it is: try all 3 protocols. Although we can note that using this is a bit slower than just using minecraftvanilla or minecraftbedrock or gamespy3 or a custom solution that fits an individual's needs.

If that is the case there are other solutions.

What do you think? Got other ideas?