@soymaycol/mayaternos
Version:
Módulo para crear bots de Minecraft 24/7 con movimientos aleatorios usando MinePlayer
311 lines (257 loc) • 9.5 kB
JavaScript
const mineflayer = require('mineflayer');
class MayAternos {
constructor(options = {}) {
this.defaultOptions = {
host: 'localhost',
port: 25565,
username: 'Bot',
version: '1.19.2',
auth: 'offline',
reconnectDelay: 3000,
maxReconnectAttempts: -1,
movementInterval: 5000,
chatInterval: 30000,
randomMovement: true,
randomChat: false,
chatMessages: ['Hola', 'Como están?', 'Buenas'],
verbose: true
};
this.options = { ...this.defaultOptions, ...options };
this.bots = [];
this.movementIntervals = [];
this.chatIntervals = [];
this.reconnectAttempts = 0;
}
// Crear un bot individual
createBot(botOptions = {}) {
const config = { ...this.options, ...botOptions };
if (this.options.verbose) {
console.log(`🤖 Creando bot: ${config.username} en ${config.host}:${config.port}`);
}
const bot = mineflayer.createBot(config);
// Eventos del bot
bot.on('login', () => {
if (this.options.verbose) {
console.log(`✅ Bot ${bot.username} conectado exitosamente`);
}
this.reconnectAttempts = 0;
this.startBotBehavior(bot);
});
bot.on('spawn', () => {
if (this.options.verbose) {
console.log(`🎯 Bot ${bot.username} spawneado en el mundo`);
}
});
bot.on('error', (err) => {
if (this.options.verbose) {
console.error(`❌ Error en bot ${bot.username}:`, err.message);
}
});
bot.on('end', () => {
if (this.options.verbose) {
console.log(`🔌 Bot ${bot.username} desconectado`);
}
this.handleReconnect(bot, config);
});
bot.on('kicked', (reason) => {
if (this.options.verbose) {
console.log(`👢 Bot ${bot.username} fue kickeado: ${reason}`);
}
});
bot.on('death', () => {
if (this.options.verbose) {
console.log(`💀 Bot ${bot.username} murió, respawneando...`);
}
setTimeout(() => {
bot.respawn();
}, 2000);
});
this.bots.push(bot);
return bot;
}
// Crear múltiples bots
createMultipleBots(count, baseOptions = {}) {
const bots = [];
for (let i = 0; i < count; i++) {
const botOptions = {
...baseOptions,
username: baseOptions.username ? `${baseOptions.username}_${i + 1}` : `Bot_${i + 1}`
};
// Delay entre creación de bots para evitar problemas
setTimeout(() => {
const bot = this.createBot(botOptions);
bots.push(bot);
}, i * 1000);
}
return bots;
}
// Iniciar comportamientos del bot
startBotBehavior(bot) {
if (this.options.randomMovement) {
this.startRandomMovement(bot);
}
if (this.options.randomChat) {
this.startRandomChat(bot);
}
// Comportamientos anti-detección
this.startAntiDetectionBehavior(bot);
}
// Movimientos aleatorios
startRandomMovement(bot) {
const movementInterval = setInterval(() => {
if (!bot.entity || bot.health <= 0) return;
const actions = [
() => this.randomWalk(bot),
() => this.randomLook(bot),
() => this.randomJump(bot),
() => this.randomSprint(bot),
() => this.randomSneak(bot),
() => this.stopMovement(bot)
];
const randomAction = actions[Math.floor(Math.random() * actions.length)];
randomAction();
}, this.options.movementInterval + Math.random() * 2000);
this.movementIntervals.push(movementInterval);
}
// Chat aleatorio
startRandomChat(bot) {
const chatInterval = setInterval(() => {
if (!bot.entity || this.options.chatMessages.length === 0) return;
const randomMessage = this.options.chatMessages[Math.floor(Math.random() * this.options.chatMessages.length)];
bot.chat(randomMessage);
}, this.options.chatInterval + Math.random() * 10000);
this.chatIntervals.push(chatInterval);
}
// Comportamientos anti-detección
startAntiDetectionBehavior(bot) {
// Movimiento de cabeza aleatorio
setInterval(() => {
if (!bot.entity) return;
const yaw = (Math.random() - 0.5) * Math.PI;
const pitch = (Math.random() - 0.5) * Math.PI * 0.5;
bot.look(yaw, pitch);
}, 8000 + Math.random() * 5000);
// Interacción con el entorno
setInterval(() => {
if (!bot.entity) return;
// Intentar interactuar con bloques cercanos ocasionalmente
const nearbyBlocks = bot.findBlocks({
matching: (block) => block.type !== 0,
maxDistance: 3,
count: 5
});
if (nearbyBlocks.length > 0) {
const randomBlock = nearbyBlocks[Math.floor(Math.random() * nearbyBlocks.length)];
bot.lookAt(randomBlock);
}
}, 15000 + Math.random() * 10000);
}
// Funciones de movimiento
randomWalk(bot) {
const directions = ['forward', 'back', 'left', 'right'];
const direction = directions[Math.floor(Math.random() * directions.length)];
bot.setControlState(direction, true);
setTimeout(() => {
bot.setControlState(direction, false);
}, 1000 + Math.random() * 2000);
}
randomLook(bot) {
const yaw = Math.random() * 2 * Math.PI;
const pitch = (Math.random() - 0.5) * Math.PI;
bot.look(yaw, pitch);
}
randomJump(bot) {
if (Math.random() < 0.3) {
bot.setControlState('jump', true);
setTimeout(() => {
bot.setControlState('jump', false);
}, 500);
}
}
randomSprint(bot) {
if (Math.random() < 0.2) {
bot.setControlState('sprint', true);
setTimeout(() => {
bot.setControlState('sprint', false);
}, 2000 + Math.random() * 3000);
}
}
randomSneak(bot) {
if (Math.random() < 0.1) {
bot.setControlState('sneak', true);
setTimeout(() => {
bot.setControlState('sneak', false);
}, 1000 + Math.random() * 2000);
}
}
stopMovement(bot) {
const controls = ['forward', 'back', 'left', 'right', 'jump', 'sprint', 'sneak'];
controls.forEach(control => {
bot.setControlState(control, false);
});
}
// Manejo de reconexión
handleReconnect(bot, config) {
if (this.options.maxReconnectAttempts === -1 || this.reconnectAttempts < this.options.maxReconnectAttempts) {
this.reconnectAttempts++;
if (this.options.verbose) {
console.log(`🔄 Intentando reconectar bot ${config.username} (intento ${this.reconnectAttempts})`);
}
setTimeout(() => {
const newBot = this.createBot(config);
const botIndex = this.bots.indexOf(bot);
if (botIndex !== -1) {
this.bots[botIndex] = newBot;
}
}, this.options.reconnectDelay);
} else {
if (this.options.verbose) {
console.log(`❌ Máximo de intentos de reconexión alcanzado para bot ${config.username}`);
}
}
}
// Obtener todos los bots
getBots() {
return this.bots;
}
// Obtener bot por nombre
getBotByName(username) {
return this.bots.find(bot => bot.username === username);
}
// Desconectar todos los bots
disconnectAll() {
if (this.options.verbose) {
console.log('🔌 Desconectando todos los bots...');
}
this.bots.forEach(bot => {
bot.quit();
});
this.movementIntervals.forEach(interval => clearInterval(interval));
this.chatIntervals.forEach(interval => clearInterval(interval));
this.bots = [];
this.movementIntervals = [];
this.chatIntervals = [];
}
// Desconectar bot específico
disconnectBot(username) {
const bot = this.getBotByName(username);
if (bot) {
bot.quit();
this.bots = this.bots.filter(b => b.username !== username);
if (this.options.verbose) {
console.log(`🔌 Bot ${username} desconectado`);
}
}
}
// Obtener estado de los bots
getBotsStatus() {
return this.bots.map(bot => ({
username: bot.username,
online: bot.player ? true : false,
health: bot.health,
position: bot.entity ? bot.entity.position : null,
server: `${bot.options.host}:${bot.options.port}`
}));
}
}
module.exports = MayAternos;