Skip to content

Commit

Permalink
Merge pull request #15 from Slord6/typescriptify
Browse files Browse the repository at this point in the history
Typescriptify
  • Loading branch information
Slord6 authored Nov 2, 2024
2 parents 812aa46 + 6359567 commit 385175f
Show file tree
Hide file tree
Showing 15 changed files with 1,148 additions and 1,456 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

- git clone
- npm i
- npx tsc
- node .\index.js \<server\> \<port\> \<password> \<master\>

`master` is the name of the account you want to control the bots from. `password` is the password used in `/login` and `/register` commands to join most 'cracked' servers (ie. the ones without online mode on)
Expand Down
29 changes: 0 additions & 29 deletions chat.js

This file was deleted.

35 changes: 35 additions & 0 deletions chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Bot } from "mineflayer";

interface Message {
bot: Bot;
message: string;
}

export class ChatBuffer {
private chatStack: Message[] = [];
private messageWaitTime: number;

constructor(messageWaitTime: number = 2000) {
this.messageWaitTime = messageWaitTime;
}

public start() {
if (this.chatStack.length > 0) {
let info = this.chatStack.shift() as Message;
console.log(`${info.bot.player.username} sending>>>`, info.message);
info.bot.chat(info.message);
}
setTimeout(this.start.bind(this), this.messageWaitTime);
}

public addChat(bot: Bot, message: string, directTo: string | null = null) {
message.split('\n').forEach(message => {
if (!directTo) {
this.chatStack.push({ bot, message });
} else {
this.chatStack.push({ bot, message: `/msg ${directTo} ` + message });
}
});

}
}
40 changes: 0 additions & 40 deletions followBot.js

This file was deleted.

80 changes: 41 additions & 39 deletions index.js → index.ts
Original file line number Diff line number Diff line change
@@ -1,102 +1,104 @@
import { IndexedData } from "minecraft-data";
import { Bot } from "mineflayer";
import { Behaviours } from "./utils";
import { ChatBuffer } from "./chat";
import { Individual } from "./individual";
import { Swarm, SwarmConfig } from "./swarm";

const mineflayer = require('mineflayer');
const { Movements } = require('mineflayer-pathfinder');
const { GoalNear, GoalBlock, GoalXZ, GoalY, GoalInvert, GoalFollow } = require('mineflayer-pathfinder').goals;
const { createSwarm } = require('./swarm');
const chat = require('./chat');
const jobSelector = require('./individual').handleChat;
const Utils = require('./utils');

let botNames = [
// 'Annie',
// 'Baldwin',
// 'Claire',

const utils = new Behaviours();
const chat = new ChatBuffer();
const botNames: string[] = [
'QuailBotherer'
];
const host = process.argv[2];
const port = parseInt(process.argv[3], 10);
let password = process.argv[4];
const masters = [process.argv[5]];
const host: string = process.argv[2];
const port: number = parseInt(process.argv[3], 10);
const password: string = process.argv[4];
const masters: string[] = [process.argv[5]];

console.log(`Starting: Bots: ${botNames}, ${host}:${port}. Controllers: ${masters}. Pass set = ${!!password}`);

function sleep(ms) {
function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

const autoLogin = async (bot) => {
const autoLogin = async (bot: Bot) => {
await sleep(3000);
console.log("Auto logging in...");
chat.addChat(bot, `/register ${password} ${password}`);
chat.addChat(bot, `/login ${password}`);
};

const newBots = (names) => {
const newBots = createSwarm(names, config, mineflayer);
console.log(`Created ${names} (${newBots.map(nb => nb.username)}). Waiting for spawns..`);
const newBots = (names: string[]) => {
const newBots = Swarm.Create(names, botConfig);
console.log(`Created ${names} (${newBots.map((nb: Bot) => nb.username)}). Waiting for spawns..`);

let counter = 0;
newBots.forEach(bot => {
newBots.forEach((bot: Bot) => {
bot.once('spawn', () => {
counter++;
console.log("Spawned", bot.username, `(${counter}/${newBots.length})`);
if(counter === newBots.length) {
newBots.forEach(b => swarm.push(b));
console.log("All bots now:", swarm.map(b => b.username));
newBots.forEach((b: Bot) => swarm.push(b));
console.log("All bots now:", swarm.map((b: Bot) => b.username));
}
});
});
}

const botInit = (bot) => {
const botInit = (bot: Bot) => {
console.log(`[${bot.username}] Loading plugins...`);
bot.loadPlugins([require('mineflayer-pathfinder').pathfinder, require('mineflayer-armor-manager'), require('mineflayer-blockfinder')(mineflayer)]);
console.log(bot.username, 'initalised');

// Once we've spawn, it is safe to access mcData because we know the version
const mcData = require('minecraft-data')(bot.version);
const mcData: IndexedData = require('minecraft-data')(bot.version);
prepFriendlyProtection(mcData, swarm);

const defaultMove = new Movements(bot, mcData);
defaultMove.allowFreeMotion = true

bot.on('chat', (username, message, x, y, z) => {
const individual: Individual = new Individual(bot, chat);
bot.on('chat', (username: string, message: string) => {
console.log(`[Msg>${bot.username}]`, username, message);
try {
jobSelector(username, message, bot, masters, chat, false, newBots)
individual.handleChat(username, message, bot, masters, false, newBots)
} catch (err) {
console.log(err);
chat.addChat(bot, `Can't, sorry`, username);
}
});
bot.on('whisper', (username, message) => {
bot.on('whisper', (username: string, message: string) => {
console.log(`[Whisper>${bot.username}]`, username, message);
try {
jobSelector(username, message, bot, masters, chat, true, newBots)
individual.handleChat(username, message, bot, masters, true, newBots)
} catch (err) {
console.log(err);
chat.addChat(bot, `Can't, sorry`, username);
}
});
bot.on("end", (reason) => {
bot.on("end", (reason: string) => {
console.warn(`${bot.player.username} disconnected! (${reason})`);
});
const startTime = Date.now();
const startTime: number = Date.now();
bot.on('health', () => {
if (Date.now() - startTime < 500) return;
Utils.attackNearestMob(bot, defaultMove)
utils.attackNearestMob(bot, defaultMove, () => {});
});
bot.on('kicked', (reason) => console.log("kicked", reason));
bot.on('error', console.log);
bot.on('kicked', (reason: string) => console.log("kicked", reason));
bot.on('error', console.error);

autoLogin(bot);

masters.forEach(master => {
chat.addChat(bot, `I'm online`, master);
});
};;
};

let haveSetupProtection = false;
const prepFriendlyProtection = (mcData, swarm) => {
const prepFriendlyProtection = (mcData: IndexedData, swarm: Bot[]) => {
if (haveSetupProtection) return;
swarm[swarm.length - 1].once('spawn', () => {
swarm.forEach(bot => {
Expand All @@ -105,7 +107,7 @@ const prepFriendlyProtection = (mcData, swarm) => {

swarm.forEach(other => {
if (other.username != bot.username) {
other.on('health', () => Utils.protectFriendly(bot, other, defaultMove));
other.on('health', () => utils.protectFriendly(bot, other, defaultMove));
}
});
masters.forEach(m => {
Expand All @@ -114,20 +116,20 @@ const prepFriendlyProtection = (mcData, swarm) => {
console.warn("No player found for auto protect");
} else {
while (!player.entity) { }
player.entity.on('health', () => Utils.protectFriendly(bot, player, defaultMove));
player.entity.on('health', () => utils.protectFriendly(bot, player, defaultMove));
}
});
});
});
haveSetupProtection = true;
}

const config = {
const botConfig: SwarmConfig = {
host,
port,
version: '1.20.1',
initCallback: botInit
};

chat.start();
const swarm = createSwarm(botNames, config, mineflayer);
const swarm = Swarm.Create(botNames, botConfig);
Loading

0 comments on commit 385175f

Please sign in to comment.