UNPKG

@emberglaze/mineflayer-anti-afk

Version:

Add anti-afk capabilities to your mineflayer bot

199 lines (194 loc) 8.32 kB
import { pathfinder, goals } from 'mineflayer-pathfinder' import { Bot } from 'mineflayer' // bot.loadPlugin(antiAfk) export function antiAfk(bot: Bot) { if (!bot.pathfinder) bot.loadPlugin(pathfinder) let status = { rotate: false, autoMessage: false, circleWalk: false, sneak: false, jump: false, hit: false } bot.antiAfk = { get status() { return {...status} }, off(module) { status[module] = false }, autoMessage(messages, delay, random, chat = bot.chat) { status.autoMessage = true let i = 0 const intervalId = setInterval(() => { if (!status.autoMessage) { clearInterval(intervalId) return } if (random) { const randomIndex = Math.floor(Math.random() * messages.length); chat(messages[randomIndex]); } else { chat(messages[i]); if (i + 1 === messages.length) i = 0 else i++ } }, delay) }, rotate(direction, increment = 1, interval = 100) { status.rotate = true let yaw = bot.entity.yaw let pitch = bot.entity.pitch const intervalId = setInterval(() => { if (!status.rotate) { clearInterval(intervalId) return } switch (direction) { case 'up': pitch -= increment break case 'down': pitch += increment break case 'left': yaw -= increment break case 'right': yaw += increment break } bot.look(yaw, pitch, true) }, interval) }, circleWalk(radius, points, pos = bot.entity.position) { status.circleWalk = true const angleStep = (2 * Math.PI) / points const result: Coordinates[] = [] for (let i = 0; i < points; i++) { const angle = i * angleStep const x = pos.x + radius * Math.cos(angle) const y = pos.y const z = pos.z + radius * Math.sin(angle) result.push({ x, y, z }) } let i = 0 const intervalId = setInterval(() => { if (!status.circleWalk) { clearInterval(intervalId); return; } if (i === result.length) i = 0 bot.pathfinder.setGoal(new goals.GoalXZ(result[i].x, result[i].z)) i++ }, 1000) }, sneak(sneakTime = 500, interval = 500) { status.sneak = true let sneakIntervalId = setInterval(() => { if (!status.sneak) { clearInterval(sneakIntervalId) return } bot.setControlState('sneak', true) setTimeout(() => { bot.setControlState('sneak', false) }, sneakTime) }, interval + sneakTime) }, jump(interval) { status.jump = true let jumpIntervalId = setInterval(() => { if (!status.jump) { clearInterval(jumpIntervalId) return } bot.setControlState('jump', true) bot.setControlState('jump', false) }, interval) }, hit({ attackMobs, interval = 1000 }) { status.hit = true if (attackMobs) { const excludedTypes = ['object', 'player', 'global', 'orb', 'other'] const closestMob = bot.nearestEntity(entity => !excludedTypes.includes(entity.type)) if (closestMob) { bot.pathfinder.setGoal(new goals.GoalFollow(closestMob, 1)) bot.attack(closestMob) } } else { const hitIntervalId = setInterval(() => { if (!status.hit) { clearInterval(hitIntervalId) return } bot.swingArm('right', true) }, interval) } } } } // for intellisense after inject after loading this as plugin declare module 'mineflayer' { interface Bot { antiAfk: { /** Status of mineflayer-anti-afk's "modules". true = running. use `bot.antiAfk.off(module)` to toggle them off */ readonly status: { autoMessage: boolean rotate: boolean circleWalk: boolean sneak: boolean jump: boolean hit: boolean } /** * Turns off the specified module * @param {Module} module The module to turn off */ off: (module: Module) => void /** * Automatically send messages every once in *delay* milliseconds * @param {string[]} messages Array of messages * @param {number} delay Delay inbetween each message (in milliseconds) * @param {function} chat Function to send chat messages, must accept a string as first parameter. Defaults to `bot.chat`. */ autoMessage: (messages: string[], delay: number, random: boolean, chat?: (msg: string) => any) => void /** * Rotates the bot in the specified direction every *interval* milliseconds * @param {RotateDirection} direction Direction to rotate * @param {number} increment Amount to rotate each interval (default: 1) * @param {number} interval Delay between each rotation (in milliseconds) (default: 100) */ rotate: (direction: RotateDirection, increment?: number, interval?: number) => void /** * Makes the bot walk in a circle with the specified radius, number of points, and position * @param {number} radius The radius of the circle * @param {number} points The number of points in the circle * @param {Coordinates} pos The position of the circle's center. Defaults to `bot.entity.position` */ circleWalk: (radius: number, points: number, pos?: Coordinates) => void /** * Make the bot sneak for "sneakTime" every "interval" milliseconds * @param sneakTime How long for the bot to sneak every time * @param interval Frequency of the sneaking, in milliseconds */ sneak: (sneakTime?: number, interval?: number) => void /** * Makes the bot jump every *interval* milliseconds * @param {number} interval Delay between each jump (in milliseconds) */ jump: (interval: number) => void /** * Makes the bot hit mobs or swing arm based on the parameters provided * @param {Object} options Options for the hit function * @param {boolean} options.attackMobs If true, the bot will attack the nearest mob * @param {number} options.interval If attackMobs is false, the bot will swing its arm every interval milliseconds. Defaults to 1000 if neither parameters were provided. */ hit: ({ attackMobs, interval = 1000 }: { attackMobs?: boolean, interval?: number }) => void } } } type Coordinates = { x: number, y: number, z: number } type RotateDirection = 'up' | 'down' | 'left' | 'right' type Module = 'autoMessage' | 'rotate' | 'circleWalk' | 'sneak' | 'jump' | 'hit'