PrismarineJS / mineflayer

Create Minecraft bots with a powerful, stable, and high level JavaScript API.
https://prismarinejs.github.io/mineflayer/
MIT License
4.87k stars 894 forks source link

"socketClosed" is not valid JSON #3098

Closed saom88n closed 1 year ago

saom88n commented 1 year ago

Versions

Detailed description of a problem

I`m trying to create bot, that will connect and just stay afk. Server have restarts at 00 04, 10, 16, 20. Im trying to catch it and go throw antibot system.

What did you try yet?

Restart Mac, try on another server.

Your current code

const mineflayer = require('mineflayer')
const { mineflayer: mineflayerViewer } = require('prismarine-viewer')

var testoptions = {
}

var options = {
}

// Useless; Parse DMC kick message (Anti-Bot) and return value of reconnects needed.

function reconnecttimes(message) {
    let parsed = JSON.parse(JSON.stringify(message.replace(/(\r\n|\n|\r)/gm, ""))).match(/\d+/, "")[0]
    print("-", "Reconnect to the server \033[33m" + parsed + "\033[0m times.")
    return parseInt(parsed);
}

// Pretty print logs.

function print (c, message) {
    switch (c) {
        case "+": console.log("\033[32m + \033[0m" + message); break;
        case "-": console.log("\033[33m - \033[0m" + message); break;
        case "!": console.log("\033[31m ! \033[0m" + message); break;
        default:  console.log("\033[97m * \033[0m" + message); break;
    }
}

// Main loop function for bot.

function mainloop () {
    let bot = mineflayer.createBot(testoptions)
    let temp = 0;
    // Print log for successfull connection.
    bot.on('respawn', () => {
        if (temp === 1) {
            print("!", "RESPAWNED")
            mainloop()
        }
    })
    bot.once('spawn', () => {
        temp = 1;
        print("+", "Connected to the server successfully!")
    })
    // Print chat messages.
    bot.on('chat', (username, message) => {
        if (process.argv.includes("-c")) {
            print("", "\033[35m" + username + "\033[0m: " + message)
        }
    })
    bot.on('end', (kicked) => {
        //let date = new Date()
        if (process.argv.includes("-r")) {
            print("!", "Kicked from the server with reason: \n\033[31m" + JSON.stringify(JSON.parse(kicked), null, 2) + "\033[0m")
        } else {
            print("!", "Kicked from the server! For more details run with \"\033[31mnode index.js -r\033[0m\".")
        }
        if (kicked === '{"translate":"multiplayer.disconnect.duplicate_login"}' ||
            kicked === '{"text":"Connection throttled! Please wait before reconnecting."}') {
                print("!", "Catched duplicate login kick message.")
                return;
            //} else if (["Перезагрузка", "Рестарт"].some(word => kicked.includes(word))) {
             // else if ([4, 10, 16, 20, 0].includes(date.getHours()) &&
               //        (5 - date.getMinutes()) > 0)
                 // {
                   //   print("-", "Server is reloading!")
                     // setTimeout(mainloop, 4*60*1000)
            } else if (kicked.includes("\"text\": \"Error? Contact us on discord.gg/gF36AT3\"")) {
                // Generate random interval between reconnecting for anti anti-bot ( 3-6 seconds ).
                let interval = Math.random() * (6000-3000) + 3000
                print("-", interval/1000)
                setTimeout(mainloop, interval)
            } else {
                print("!", "Catched unexpected kick message.")
                print("-", kicked)
                setTimeout(mainloop, 1000)
            }

    })
    bot.on('error', console.log)
}

mainloop()

Expected behavior

Connect to the server, go throw antibot (reconnect 3 times with random interval, stay afk and wait for restart, leave and connect after 4 minutes)

Additional context

➜  dmc node index.js -c -r
 * Performer: Material
 + Connected to the server successfully!
undefined:1
socketClosed
^

SyntaxError: Unexpected token 's', "socketClosed" is not valid JSON
    at JSON.parse (<anonymous>)
    at EventEmitter.<anonymous> (/Users/hk/dmc/index.js:65:95)
    at EventEmitter.emit (node:events:523:35)
    at Client.<anonymous> (/Users/hk/node_modules/mineflayer/lib/loader.js:105:9)
    at Client.emit (node:events:523:35)
    at Socket.endSocket (/Users/hk/node_modules/minecraft-protocol/src/client.js:159:12)
    at Socket.emit (node:events:523:35)
    at endReadableNT (node:internal/streams/readable:1367:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

Node.js v20.3.0
Error: RateLimiter disallowed request
    at call (/Users/hk/node_modules/yggdrasil/src/utils.js:35:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async join (/Users/hk/node_modules/yggdrasil/src/Server.js:20:12)
Error: RateLimiter disallowed request
    at call (/Users/hk/node_modules/yggdrasil/src/utils.js:35:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async join (/Users/hk/node_modules/yggdrasil/src/Server.js:20:12
PondWader commented 1 year ago

You are using JSON.parse on the end reason but is it is a string

saom88n commented 1 year ago

image @PondWader Yea it is a string, if I add log with typeof its always a string.

also in server console I see lost connection: Timed out

PondWader commented 1 year ago

That's the reason you're getting that error because you are trying to parse a string which isn't in JSON format as JSON

saom88n commented 1 year ago

image

@PondWader even without this JSON parse I have the same error.

saom88n commented 1 year ago

The problem was on 65 line with 'end', I should put 'kicked' instead