PrismarineJS / mineflayer

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

Is it possible to reconnect automatically after being kicked? #164

Closed JonnyD closed 10 years ago

JonnyD commented 10 years ago

Here's what I have tried so far:

var mineflayer = require('mineflayer');
var options = {
  host: "192.227.244.15", // optional
  port: 25565,       // optional
  username: "", // email and password are required only for
  password: "",          // online-mode=true servers
};
var bot = mineflayer.createBot(options);

bot.on('login', function() {
  console.log("I logged in.");
  console.log("settings", bot.settings);
});

bot.on('kicked', function(reason) {
  console.log("I got kicked for", reason, "lol");
  bot.end;
  bot.connect(options);
});

but all I got was this error:

(using Cloud9ide)

I got kicked for Kicked by an operator. lol

/var/lib/stickshift/5295aab1e0b8cd5eaa0000d5/app-root/data/694471/node_modules/mineflayer/node_modules/minecraft-protocol/lib/client.js:96
  this.socket.write(out);
              ^
TypeError: Cannot call method 'write' of null
    at Client.write (/var/lib/stickshift/5295aab1e0b8cd5eaa0000d5/app-root/data/694471/node_modules/mineflayer/node_modules/minecraft-protocol/lib/client.js:96:15)
    at sendPositionAndLook (/var/lib/stickshift/5295aab1e0b8cd5eaa0000d5/app-root/data/694471/node_modules/mineflayer/lib/plugins/physics.js:228:16)
    at sendPosition (/var/lib/stickshift/5295aab1e0b8cd5eaa0000d5/app-root/data/694471/node_modules/mineflayer/lib/plugins/physics.js:256:5)
    at wrapper [as _onTimeout] (timers.js:252:14)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
JonnyD commented 10 years ago

Using this reconnects but the events stop working, could anyone point me in the right direction?

bot.on('kicked', function(reason) {
  console.log("I got kicked for", reason, "lol");
  bot.quit
  bot.end
  bot = mineflayer.createBot(options);
});
andrewrk commented 10 years ago

Seems like that code should work, although keep in mind that in JavaScript, bot.quit and bot.end do nothing - what you want are bot.quit() and bot.end().

andrewrk commented 10 years ago

That error above looks like maybe if you get kicked, you're already disconnected, so you can't call bot.quit(). Try only calling bot.end() or calling neither and skip straight to the bot = mineflayer.createBot(options) part.

JonnyD commented 10 years ago

Thanks for your response. I have tried this but it only works once. After being kicked the first time it reconnects but it then stops triggering events and because it stops triggering events (e.g. bot.on('kicked'..)) the next kick disconnects the bot forever. Any idea?

var mineflayer = require('mineflayer');

var options = {
  host: "192.227.244.15", // optional
  port: 25565,       // optional
  username: "", // email and password are required only for
  password: "",          // online-mode=true servers
};

var bot = mineflayer.createBot(options);

bot.on('login', function() {
  console.log("I logged in.");
  console.log("settings", bot.settings);
});

bot.on('playerJoined', function(player) {
  console.log(player.username + " joined");
});

bot.on('playerLeft', function(player) {
  console.log(player.username + " left");
});

bot.on('kicked', function(reason) {
  console.log("I got kicked for", reason, "lol");
  bot = mineflayer.createBot(options);
});

bot.on('spawn', function() {
  console.log("I have spawned");
  console.log("game", bot.game);
});

bot.on('death', function() {
  bot.chat("I died x.x");
});
andrewrk commented 10 years ago

You're replacing the bot variable with a new object. The handlers you attached are all attached to the old reference. You need to attach your handlers to the new instances as well.

JonnyD commented 10 years ago

Got it working like this but is it best practice? Coming from a Java & PHP background node.js isn't as intuitive to me.

var mineflayer = require('mineflayer');
var options = {
  //host: "mc.civcraft.vg",
  host: "192.227.244.15",
  port: 25565,
  username: "",
  password: "",
};

var bot = mineflayer.createBot(options);

bindEvents(bot);

function bindEvents(bot) {
    bot.on('login', function() {
      console.log("I logged in.");
      console.log("settings", bot.settings);
    });

    bot.on('kicked', function(reason) {
      console.log("I got kicked for", reason, "lol");

      bot = mineflayer.createBot(options);
      bindEvents(bot);
    });
}
andrewrk commented 10 years ago

Seems fine to me. As your code base grows you'll figure out what organization works best for you.

nevercast commented 10 years ago

Closed, issue seems fixed, comment if this needs a re-open