const mc = require('minecraft-protocol') const { EventEmitter } = require('events') const pluginLoader = require('./plugin_loader') const plugins = { bed: require('./plugins/bed'), title: require('./plugins/title'), block_actions: require('./plugins/block_actions'), blocks: require('./plugins/blocks'), book: require('./plugins/book'), boss_bar: require('./plugins/boss_bar'), breath: require('./plugins/breath'), chat: require('./plugins/chat'), chest: require('./plugins/chest'), command_block: require('./plugins/command_block'), craft: require('./plugins/craft'), creative: require('./plugins/creative'), digging: require('./plugins/digging'), enchantment_table: require('./plugins/enchantment_table'), entities: require('./plugins/entities'), experience: require('./plugins/experience'), explosion: require('./plugins/explosion'), fishing: require('./plugins/fishing'), furnace: require('./plugins/furnace'), game: require('./plugins/game'), health: require('./plugins/health'), inventory: require('./plugins/inventory'), kick: require('./plugins/kick'), physics: require('./plugins/physics'), place_block: require('./plugins/place_block'), rain: require('./plugins/rain'), ray_trace: require('./plugins/ray_trace'), resource_pack: require('./plugins/resource_pack'), scoreboard: require('./plugins/scoreboard'), team: require('./plugins/team'), settings: require('./plugins/settings'), simple_inventory: require('./plugins/simple_inventory'), sound: require('./plugins/sound'), spawn_point: require('./plugins/spawn_point'), tablist: require('./plugins/tablist'), time: require('./plugins/time'), villager: require('./plugins/villager'), anvil: require('./plugins/anvil'), place_entity: require('./plugins/place_entity'), generic_place: require('./plugins/generic_place'), particle: require('./plugins/particle') } const supportedVersions = require('./version').supportedVersions const testedVersions = require('./version').testedVersions module.exports = { createBot, Location: require('./location'), Painting: require('./painting'), ScoreBoard: require('./scoreboard'), BossBar: require('./bossbar'), Particle: require('./particle'), supportedVersions, testedVersions, supportFeature: (feature, version) => require('prismarine-registry')(version).supportFeature(feature) } function createBot (options = {}) { options.username = options.username ?? 'Player' options.version = options.version ?? false options.plugins = options.plugins ?? {} options.hideErrors = options.hideErrors ?? false options.logErrors = options.logErrors ?? true options.loadInternalPlugins = options.loadInternalPlugins ?? true options.client = options.client ?? null options.brand = options.brand ?? 'vanilla' options.respawn = options.respawn ?? true const bot = new EventEmitter() bot._client = options.client bot.end = (reason) => bot._client.end(reason) if (options.logErrors) { bot.on('error', err => { if (!options.hideErrors) { console.log(err) } }) } pluginLoader(bot, options) const internalPlugins = Object.keys(plugins) .filter(key => { if (typeof options.plugins[key] === 'function') return false if (options.plugins[key] === false) return false return options.plugins[key] || options.loadInternalPlugins }).map(key => plugins[key]) const externalPlugins = Object.keys(options.plugins) .filter(key => { return typeof options.plugins[key] === 'function' }).map(key => options.plugins[key]) bot.loadPlugins([...internalPlugins, ...externalPlugins]) bot._client = bot._client ?? mc.createClient(options) bot._client.on('connect', () => { bot.emit('connect') }) bot._client.on('error', (err) => { bot.emit('error', err) }) bot._client.on('end', (reason) => { bot.emit('end', reason) }) if (!bot._client.wait_connect) next() else bot._client.once('connect_allowed', next) function next () { bot.registry = require('prismarine-registry')(bot._client.version) const version = bot.registry.version if (supportedVersions.indexOf(version.majorVersion) === -1) { throw new Error(`Version ${version.minecraftVersion} is not supported.`) } const latestTestedVersion = testedVersions[testedVersions.length - 1] const latestProtocolVersion = require('prismarine-registry')(latestTestedVersion).protocolVersion if (version.protocolVersion > latestProtocolVersion) { throw new Error(`Version ${version.minecraftVersion} is not supported. Latest supported version is ${latestTestedVersion}.`) } bot.protocolVersion = version.version bot.majorVersion = version.majorVersion bot.version = version.minecraftVersion options.version = version.minecraftVersion bot.supportFeature = bot.registry.supportFeature setTimeout(() => bot.emit('inject_allowed'), 0) } return bot }