2024-02-11 21:23:41 -05:00
|
|
|
const mc = require('minecraft-protocol')
|
2024-11-05 23:53:18 -05:00
|
|
|
const nbt = require('prismarine-nbt')
|
2024-02-11 21:23:41 -05:00
|
|
|
const { EventEmitter } = require('events')
|
|
|
|
const fs = require('fs')
|
|
|
|
const path = require('path')
|
2024-11-05 23:53:18 -05:00
|
|
|
const fileExists = require('./util/file_exists')
|
|
|
|
const crypto = require('crypto')
|
2024-02-11 21:23:41 -05:00
|
|
|
|
2024-02-29 20:39:21 -05:00
|
|
|
const plugins = []
|
2024-04-04 22:00:51 -04:00
|
|
|
for (const filename of fs.readdirSync(path.resolve(__dirname, 'plugins'))) {
|
2024-02-29 20:39:21 -05:00
|
|
|
if (!filename.endsWith('.js')) return
|
2024-04-04 22:00:51 -04:00
|
|
|
plugins.push(require(path.resolve(__dirname, 'plugins', filename)))
|
2024-02-29 20:39:21 -05:00
|
|
|
}
|
|
|
|
|
2024-11-05 23:53:18 -05:00
|
|
|
const usernameSchemes = {
|
|
|
|
async random_playerdata (bot, options) {
|
|
|
|
const playerDataDir = await path.join(bot.paths.persistent, 'playerdata')
|
|
|
|
if (!await fileExists(playerDataDir)) return undefined
|
|
|
|
|
|
|
|
let subdir
|
|
|
|
try {
|
|
|
|
const subdirs = (await fs.promises.readdir(playerDataDir)).filter(filename => !filename.endsWith('_old'))
|
|
|
|
subdir = path.join(playerDataDir, subdirs[crypto.randomInt(0, subdirs.length)])
|
|
|
|
} catch {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
let data
|
|
|
|
try {
|
|
|
|
const files = await fs.promises.readdir(subdir)
|
|
|
|
const raw = await fs.promises.readFile(path.join(subdir, files[crypto.randomInt(0, files.length)]))
|
|
|
|
data = await nbt.parse(raw)
|
|
|
|
} catch {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
return data?.parsed?.value?.username?.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-11 21:23:41 -05:00
|
|
|
function createBot (options = {}) {
|
|
|
|
// defaults
|
|
|
|
options.username ??= 'Bot'
|
|
|
|
// options.password = options.password ?? null
|
|
|
|
options.brand ??= 'vanilla' // found that mineflayer has this so i added it here lol
|
|
|
|
|
2024-04-02 17:53:10 -04:00
|
|
|
options.styles ??= {}
|
|
|
|
options.styles.primary ??= { color: 'white' }
|
|
|
|
options.styles.secondary ??= { color: 'green' }
|
2024-02-11 21:23:41 -05:00
|
|
|
|
|
|
|
options.autoReconnect ??= false
|
|
|
|
options.randomizeUsername ??= false
|
|
|
|
|
|
|
|
options['online-mode'] ??= {}
|
|
|
|
options['online-mode'].enabled ??= false
|
|
|
|
options['online-mode'].username ??= null
|
|
|
|
options['online-mode'].password ??= null
|
|
|
|
|
2024-11-05 23:53:18 -05:00
|
|
|
options.paths ??= {}
|
2024-04-05 20:54:10 -04:00
|
|
|
options.paths.logs ??= 'logs'
|
|
|
|
options.paths.music ??= 'music'
|
|
|
|
options.paths.images ??= 'images'
|
|
|
|
options.paths.persistent ??= 'persistent'
|
|
|
|
|
2024-02-11 21:23:41 -05:00
|
|
|
// fard
|
|
|
|
if (options.randomizeUsername) {
|
|
|
|
options.username += '\u00a7' + String.fromCharCode(Math.floor(Math.random() * 65535))
|
|
|
|
}
|
|
|
|
if (options['online-mode'].enabled) {
|
|
|
|
options.username = options['online-mode'].username
|
|
|
|
options.password = options['online-mode'].password
|
|
|
|
}
|
|
|
|
|
|
|
|
// actually create the bot lol
|
|
|
|
const bot = new EventEmitter()
|
|
|
|
bot.plugins = plugins
|
|
|
|
bot.loadPlugin = loadPlugin
|
|
|
|
|
2024-02-29 22:58:11 -05:00
|
|
|
// properties
|
2024-02-11 21:23:41 -05:00
|
|
|
bot.host = options.host
|
2024-09-30 20:56:05 -04:00
|
|
|
bot.port = options.port ?? 25565
|
|
|
|
bot.hostPortPair = bot.port !== 25565 ? bot.host + ':' + bot.port : bot.host
|
2024-02-29 22:58:11 -05:00
|
|
|
|
2024-02-11 21:23:41 -05:00
|
|
|
bot.brand = options.brand
|
2024-04-02 17:53:10 -04:00
|
|
|
bot.styles = options.styles
|
2024-04-05 20:54:10 -04:00
|
|
|
bot.paths = options.paths
|
2024-02-11 21:23:41 -05:00
|
|
|
bot.autoReconnect = options.autoReconnect
|
|
|
|
bot.randomizeUsername = options.randomizeUsername
|
|
|
|
bot['online-mode'] = options['online-mode']
|
2024-04-04 21:44:45 -04:00
|
|
|
|
2024-02-11 21:23:41 -05:00
|
|
|
// set the client and add listeners
|
|
|
|
bot.on('set_client', (client) => {
|
|
|
|
client.on('connect', () => bot.emit('connect'))
|
|
|
|
client.on('error', (err) => bot.emit('error', err))
|
|
|
|
|
|
|
|
bot.end = (...r) => bot._client.end(...r)
|
|
|
|
client.on('end', (reason) => {
|
|
|
|
bot.loggedIn = false
|
|
|
|
bot.emit('end', reason)
|
|
|
|
// auto reconnect
|
2024-11-05 23:53:18 -05:00
|
|
|
if (bot.autoReconnect && !options.client) {
|
2024-02-11 21:23:41 -05:00
|
|
|
setTimeout(() => {
|
2024-11-05 23:53:18 -05:00
|
|
|
bot._initClient()
|
2024-11-07 00:09:40 -05:00
|
|
|
}, 6000)
|
2024-02-11 21:23:41 -05:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// more fard listeners
|
|
|
|
bot.loggedIn = false
|
|
|
|
bot._client.on('login', () => {
|
|
|
|
bot.loggedIn = true
|
2024-02-29 22:58:11 -05:00
|
|
|
bot.username = bot._client.username
|
|
|
|
bot.uuid = bot._client.uuid
|
2024-02-11 21:23:41 -05:00
|
|
|
bot.emit('login')
|
|
|
|
})
|
|
|
|
|
2024-02-29 20:39:21 -05:00
|
|
|
bot._client.on('packet', (data, meta) => {
|
|
|
|
bot.emit('packet', data, meta);
|
|
|
|
bot.emit('packet.' + meta.name, data);
|
2024-02-11 21:23:41 -05:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2024-11-05 23:53:18 -05:00
|
|
|
async function _initClient () {
|
|
|
|
const usernameScheme = typeof options.usernameScheme === 'function' ? options.usernameScheme : usernameSchemes[options.usernameScheme]
|
|
|
|
const username = await usernameScheme?.(bot, options)
|
|
|
|
if (username) options.username = username
|
2024-03-16 16:03:36 -04:00
|
|
|
|
2024-11-05 23:53:18 -05:00
|
|
|
bot._client = mc.createClient(options)
|
|
|
|
bot.emit('set_client', bot._client)
|
|
|
|
}
|
|
|
|
bot._initClient = _initClient
|
|
|
|
|
|
|
|
for (const plugin of plugins) plugin(bot, options)
|
|
|
|
|
|
|
|
if (options.client) {
|
|
|
|
bot._client = options.client
|
|
|
|
bot.emit('set_client', bot._client)
|
|
|
|
} else {
|
|
|
|
bot._initClient()
|
|
|
|
}
|
2024-02-11 21:23:41 -05:00
|
|
|
|
|
|
|
function loadPlugin (plugin) {
|
|
|
|
try {
|
2024-02-29 22:15:16 -05:00
|
|
|
plugin(bot, options)
|
2024-02-11 21:23:41 -05:00
|
|
|
} catch (e) {
|
|
|
|
console.log(`Error loading ${plugin}:`)
|
|
|
|
console.log(require('util').inspect(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bot
|
|
|
|
}
|
|
|
|
|
2024-02-16 22:59:09 -05:00
|
|
|
module.exports = createBot
|