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

feat: Add support for The Isle Evrima #500

Closed guilhermewerner closed 10 months ago

guilhermewerner commented 10 months ago

What is this feature about? Add support for The Isle Evrima game using the EOS protocol

Additional context/references We were able to obtain the credentials to perform the query on The Isle Evrima servers, which is a variation of the legacy game.

I did some tests on random public servers like this:

IP: 50.18.155.230 Port: 7777

node .\examples\simple.js > eos.json
{
    "name": "",
    "raw": {
        "deployment": "6db6bea492f94b1bbdfcdfe3e4f898dc",
        "id": "c73409012a5b410fa4c7fc77ff96e7d8",
        "bucket": "<None>:<None>:<None>",
        "settings": {
            "maxPublicPlayers": 115,
            "allowInvites": true,
            "shouldAdvertise": true,
            "allowReadById": true,
            "allowJoinViaPresence": true,
            "allowJoinInProgress": true,
            "allowConferenceRoom": false,
            "checkSanctions": false,
            "allowMigration": false,
            "rejoinAfterKick": "",
            "platforms": null
        },
        "totalPlayers": 41,
        "openPublicPlayers": 74,
        "publicPlayers": [],
        "started": true,
        "lastUpdated": "2024-01-21T18:54:30.054Z",
        "attributes": {
            "SERVERNAME_s": "Official Evrima - NA 6",
            "PASSWORD_s": "E04EE3DC8923189B92455EC2807284AF1FD372F5",
            "QUEUE_ENABLED_b": true,
            "PAGINATION_s": "0",
            "SERVER_VERSION_s": "0.13.21.23",
            "PASSWORD_ENABLED_b": false,
            "QUEUE_PORT_s": "10000",
            "ADDRESS_s": "50.18.155.230",
            "__EOS_BLISTENING_b": true,
            "MAP_NAME_s": "Gateway",
            "ADDRESSBOUND_s": "0.0.0.0:7777",
            "IP_s": "50.18.155.230",
            "__EOS_BUSESPRESENCE_b": true,
            "DISCORD_s": "https://discord.gg/KPtBfwD7qw",
            "OFFICIAL_b": true
        },
        "owner": "Client_xyza78910qHhuFMTLERSgsk7E97WeHom",
        "ownerPlatformId": null
    },
    "maxplayers": 115,
    "numplayers": 41,
    "players": [],
    "bots": [],
    "queryPort": 7777,
    "connect": "50.18.155.230:7777",
    "ping": 0
}

However, there are still some problems, such as the server name, which does not use the same attribute as ASA CUSTOMSERVERNAME_s or Palworld NAME_s #497.

Given the variation from game to game, perhaps it would be better to pass this part of obtaining the correct attributes to the protocol for each game, where the base protocol returns the raw response to the game then populates the stable values.

guilhermewerner commented 10 months ago

Or do something like this, check the possible attributes that contain the server name:

const namesToCheck = ['CUSTOMSERVERNAME_s', 'NAME_s', 'SERVERNAME_s']
const nonEmptyName = namesToCheck
    .map(attribute => desiredServer.attributes[attribute])
    .find(name => name !== undefined && name !== null)

state.name = nonEmptyName

Testing on the previous server:

{
    "name": "Official Evrima - NA 6",
    // ...
}    
CosminPerRam commented 10 months ago

As just mentioned in #497, seeing that there are 3 fields to choose from, it would be better to make this per game, as to avoid having game-specific logic in the protocol files (like this name field (could also apply to other fields!)). If these responses come in an unstable form (lets say X responds with name on B and Y on P but sometimes it could be swapped, then this could be in the protocol file (with the solution being what you've written)).