PassTheMayo / minecraft-server-util

A Node.js library for Minecraft servers that can retrieve status, query, RCON, and send Votifier votes.
https://passthemayo.gitbook.io/minecraft-server-util/
MIT License
141 stars 24 forks source link

bug: Some definite (FML) modded servers returning 'null' or 'undefined' for modInfo #32

Closed Synthetic-Dev closed 3 years ago

Synthetic-Dev commented 3 years ago

Describe the bug: I have implemented the module into my discord bot code, I used to use minecraft-protocol (-forge) but this seemed like a better module, however it seems that for modded minecraft servers (using FML) some do return modInfo containing the mods on the server and some servers don't return any modInfo at all. This issue (from my testing) is especially prominent for 1.16.x minecraft servers. I tried experimenting with timeout timings to see if the result just needed more time to send the entire mod packet but it seems that even with a timeout of 10000 milliseconds (which is insane for use purposes) does not receive any modInfo.

Code: This is what I use to getInfo from any server 1.4.2+

let [success, result] = await new Promise((resolve, reject) => {
    let args = [ip, {port: port}]

    function query(statusResponse) {
        statusResponse.bedrock = statusResponse.bedrock ? true : false
        args[1].timeout = 6000
        MinecraftUtil.queryFull(...args).then(queryResponse => {
            queryResponse.bedrock = statusResponse.bedrock;
            queryResponse.query = true;
            queryResponse.modInfo = queryResponse.modInfo ? queryResponse.modInfo : statusResponse.modInfo ? statusResponse.modInfo : null
            queryResponse.favicon = queryResponse.favicon ? queryResponse.favicon : statusResponse.favicon ? statusResponse.favicon : null
            resolve([true, queryResponse])
        }).catch(e => {
            statusResponse.query = false;
            resolve([true, statusResponse])
        })
    }

    MinecraftUtil.status(...args).then(response => {
        query(response)
    }).catch(e => {
        if (!e) e = new Error("Unknown error") //Sometimes promise rejects with a 'null' value
        if (e == "Failed to retrieve the status of the server within time") {
            MinecraftUtil.statusFE01(...args).then(response => {
                query(response)
            }).catch(e => {
                resolve([false, e])
            })
        } else if (e.code == "ECONNREFUSED") {
            MinecraftUtil.statusBedrock(...args).then(response => {
                response.bedrock = true;
                query(response)
            }).catch(e => {
                resolve([false, e])
            })
        } else {
            resolve([false, e])
        }
    })
})

Expected behavior: For all the .status methods and .query methods to return modInfo for modded servers

Additional context No additional context

PassTheMayo commented 3 years ago

This module was never intended to be used with a modded server, or retrieve any information that Mojang doesn't send natively. The modInfo property was only added as a pull request due to user requests. If you are not receiving this property in your response, it is due to the server not sending it. I can't provide any more support beyond this.

Also, you mention that you are increasing the timeout to give it time to receive another packet, but this is not how modInfo is sent. FML modifies the response packet to include this property, so increasing the timeout time will not resolve this issue.