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

Issues querying ark and csgo #85

Closed Murgator closed 6 years ago

Murgator commented 6 years ago

Hi, I use your gamedig librairy on my top servers list https://www.trackyserver.com (unturned, csgo, ark, minecraft, rust...) and some servers are offline while they are online.

here are two examples of online servers that you can test:

Gamedig.query({ type: 'arkse', host: '176.57.140.49', port: 30100 }, 22991a1dc5a8641adbd194e67bf23938 Gamedig returns the "UDP Watchdog Timeout" error while the server is online.

Gamedig.query({ type: 'csgo', host: '45.121.185.212', port: 27052 }, f74c8be51982a399a3745a64f8370465 For this cs go server: list of players is problematic, and gamedig can not get it back (queryPlayers function in valve.js)

There are about 20% of the servers that are not compatible with gamedig... Is it possible to remedy that ? I tried to find the problem but nothing...

Thank you in advance !

mmorrisontx commented 6 years ago

For your issue with arkse, it appears that 30100 is not the proper query port for the server you provided. Beware that arkse uses a completely different query port than the game port (by default, the game port is 7777, while the query port is 27015). If the query port is not 27015 for a certain server, you will need to pass it to gamedig with the port_query parameter.

mmorrisontx commented 6 years ago

For your issue with csgo, beware that csgo will not return a server list unless the cvar host_players_show 2 is set on the server. Previously, it would return an empty player list packet, but it's possible that recently the csgo protocol has stopped returning a player packet at all if the cvar is not set.

Could you try replacing queryPlayers in valve.js with this?:

    queryPlayers(state,c) {
        return c();
        this.sendPacket(0x55,true,false,0x44,(b) => {
            const reader = this.reader(b);
            const num = reader.uint(1);
            for(let i = 0; i < num; i++) {
                reader.skip(1);
                const name = reader.string();
                const score = reader.int(4);
                const time = reader.float();

                if(this.debug) console.log("Found player: "+name+" "+score+" "+time);

                // connecting players don't count as players.
                if(!name) continue;

                (time === -1 ? state.bots : state.players).push({
                    name:name, score:score, time:time
                });
            }

            if(this.isCsGo && state.players.length === 1 && state.players[0].name === 'Max Players') {
                if(this.debug) console.log("CSGO server using limited player details");
                state.players = [];
                for(let i = 0; i < state.raw.numplayers; i++) {
                    state.players.push({});
                }
            }

            // if we didn't find the bots, iterate
            // through and guess which ones they are
            if(!state.bots.length && state.raw.numbots) {
                let maxTime = 0;
                for (const player of state.players) {
                    maxTime = Math.max(player.time,maxTime);
                }
                for(let i = 0; i < state.players.length; i++) {
                    const player = state.players[i];
                    if(state.bots.length >= state.raw.numbots) continue;
                    if(player.time !== maxTime) continue;
                    state.bots.push(player);
                    state.players.splice(i, 1);
                    i--;
                }
            }

            c();
        }, () => {
            // no players were returned after timeout --
            // the server probably has them disabled
            // ignore the timeout
            c();
            return true;
        });
    }
Murgator commented 6 years ago

Everything working fine ! Thank you very much !

Murgator commented 6 years ago

You can close this topic