Compare commits
1 commit
main
...
2022-01-15
Author | SHA1 | Date | |
---|---|---|---|
4e1855ce1d |
118 changed files with 634 additions and 12472 deletions
|
@ -1,2 +0,0 @@
|
||||||
# chipmunkbot-archive
|
|
||||||
Archive of ChipmunkBot, a [kaboom](https://kaboom.pw) bot from 2022 (before the rewrite). The code should run with all modules installed, however, continue at your own risk, as the bot has a (sandboxed) public eval command, the security of which cannot be guaranteed. The bot's current chat parser is known to be broken on modern minecraft servers.
|
|
172
bot.js
172
bot.js
|
@ -1,139 +1,65 @@
|
||||||
const mc = require('minecraft-protocol')
|
const mc = require('minecraft-protocol')
|
||||||
const { states } = mc
|
|
||||||
const { EventEmitter } = require('events')
|
const { EventEmitter } = require('events')
|
||||||
|
const parseText = require('./util/text_parser.js')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const randomUsername = require('./util/random-username.js')
|
|
||||||
|
|
||||||
function createBot (options = {}) {
|
function createBot (options = {}) {
|
||||||
// defaults
|
options.username = options.username ?? 'Bot'
|
||||||
options.username ??= 'Bot'
|
//options.password = options.password ?? null
|
||||||
// options.password = options.password ?? null
|
options.prefix = options.prefix ?? '!'
|
||||||
options.prefix ??= '!'
|
options.brand = options.brand ?? 'vanilla' //found that mineflayer has this so i added it here lol
|
||||||
options.isBukkit ??= false
|
options.colors = options.colors ?? { primary: 'white', secondary: 'gray', error: 'red' }
|
||||||
options.isKaboom ??= false
|
options.autoReconnect = options.autoReconnect ?? true
|
||||||
options.isScissors ??= false
|
options.randomizeUsername = options.randomizeUsername ?? true;
|
||||||
|
if (options.randomizeUsername)
|
||||||
options.plugins ??= {}
|
options.username += `§${String.fromCharCode(Math.floor(Math.random() * 65535))}`
|
||||||
fs.readdirSync(
|
|
||||||
'plugins'
|
let bot = new EventEmitter()
|
||||||
).forEach(filename => { // populate plugins array
|
|
||||||
if (typeof require.extensions[path.extname(filename)] && options.plugins[filename] == null) {
|
bot._client = options.client ?? mc.createClient(options)
|
||||||
options.plugins[filename] = require(path.resolve('plugins', filename))
|
//bot.host = function () { return bot._client.host }
|
||||||
}
|
//bot.username = function () { return bot._client.username }
|
||||||
})
|
//bot.uuid = function () { return bot._client.uuid }
|
||||||
const plugins = []
|
|
||||||
Object.keys(options.plugins).forEach((key) => {
|
|
||||||
const plugin = options.plugins[key]
|
|
||||||
if (plugin) plugins.push(plugin)
|
|
||||||
})
|
|
||||||
|
|
||||||
options.colors ??= {}
|
|
||||||
options.colors.primary ??= 'white'
|
|
||||||
options.colors.secondary ??= 'green'
|
|
||||||
|
|
||||||
options.autoReconnect ??= false
|
|
||||||
options.autoReconnectDelay ??= 1000
|
|
||||||
options.randomizeUsername ??= false
|
|
||||||
|
|
||||||
options['online-mode'] ??= {}
|
|
||||||
options['online-mode'].enabled ??= false
|
|
||||||
options['online-mode'].username ??= null
|
|
||||||
options['online-mode'].password ??= null
|
|
||||||
options['online-mode'].auth ??= 'mojang'
|
|
||||||
|
|
||||||
const clientOptions = { // TODO: More options
|
|
||||||
connect: options.connect,
|
|
||||||
host: options.server.host,
|
|
||||||
port: options.server.port,
|
|
||||||
version: options.version,
|
|
||||||
username: options['online-mode'].enabled ? options['online-mode'].username : options.username,
|
|
||||||
password: options['online-mode'].enabled ? options['online-mode'].username : null,
|
|
||||||
auth: options['online-mode'].enabled ? options['online-mode'].auth : null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.randomizeUsername) {
|
|
||||||
clientOptions.username += randomUsername()
|
|
||||||
}
|
|
||||||
|
|
||||||
// actually create the bot
|
|
||||||
const bot = new EventEmitter()
|
|
||||||
bot.plugins = plugins
|
|
||||||
bot.loadPlugin = loadPlugin
|
|
||||||
|
|
||||||
// add some properties to the bot
|
|
||||||
bot.server = options.server
|
|
||||||
/* bot._client.on('set_protocol', (packet) => {
|
|
||||||
bot.host = packet.serverHost
|
|
||||||
bot.port = packet.serverPort
|
|
||||||
}) */
|
|
||||||
bot.prefix = options.prefix
|
bot.prefix = options.prefix
|
||||||
bot.colors = options.colors
|
bot.colors = options.colors
|
||||||
bot.autoReconnect = options.autoReconnect
|
bot.autoReconnect = options.autoReconnect
|
||||||
bot.randomizeUsername = options.randomizeUsername
|
|
||||||
bot['online-mode'] = options['online-mode']
|
bot._client.on('connect', () => bot.emit('connect'))
|
||||||
// set the client and add listeners
|
|
||||||
bot.on('set_client', (client) => {
|
bot._client.on('error', (err) => bot.emit('error', err))
|
||||||
client.on('connect', () => bot.emit('connect'))
|
bot.on('error', () => {}) // idc about errors lol
|
||||||
client.on('error', (err) => bot.emit('error', err))
|
|
||||||
|
bot.end = () => bot._client.end()
|
||||||
bot.disconnect = reason => bot._client.end(reason)
|
bot._client.on('end', (reason) => {
|
||||||
bot.end = reason => {
|
bot.emit('end', reason)
|
||||||
bot.autoReconnect = false
|
setTimeout(() => bot = createBot(options), 6400)
|
||||||
bot.disconnect()
|
})
|
||||||
|
|
||||||
|
//amogus
|
||||||
|
bot._client.on('login', () => bot.emit('login'))
|
||||||
|
|
||||||
|
bot.position = { x: null, y: null, z: null } //to prevent errors i guess
|
||||||
|
bot._client.on('position', (position) => bot.position = position)
|
||||||
|
|
||||||
|
bot.sendChat = (message) => bot._client.write('chat', { message })
|
||||||
|
|
||||||
|
const plugins = []
|
||||||
|
fs.readdirSync(
|
||||||
|
path.join(__dirname, 'plugins')
|
||||||
|
).forEach((file) => { // populate plugins array
|
||||||
|
if (file.endsWith(".js")) {
|
||||||
|
plugins.push(path.join(__dirname, 'plugins', file));
|
||||||
}
|
}
|
||||||
client.on('end', (reason) => {
|
|
||||||
bot.loggedIn = false
|
|
||||||
bot.emit('disconnect', reason)
|
|
||||||
// auto reconnect
|
|
||||||
if (bot.autoReconnect) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (bot.randomizeUsername && !bot['online-mode'].enabled) clientOptions.username = randomUsername()
|
|
||||||
|
|
||||||
bot._client = mc.createClient(clientOptions)
|
|
||||||
bot.emit('set_client', bot._client)
|
|
||||||
}, options.autoReconnectDelay)
|
|
||||||
} else {
|
|
||||||
bot.emit('end', reason)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// more event listeners
|
|
||||||
bot._client.on('state', state => {
|
|
||||||
bot.state = state
|
|
||||||
bot.emit('state', state)
|
|
||||||
})
|
|
||||||
bot._client.on('login', data => bot.emit('login', data))
|
|
||||||
|
|
||||||
// plugin injection
|
|
||||||
bot.plugins.forEach(plugin => {
|
|
||||||
if (typeof plugin.client === 'function') plugin.client(bot, options)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
bot._client = options.client ?? mc.createClient(clientOptions)
|
plugins.forEach((plugin) => {
|
||||||
bot.emit('set_client', bot._client)
|
|
||||||
|
|
||||||
bot.on('login', () => {
|
|
||||||
bot.username = bot._client.username
|
|
||||||
bot.uuid = bot._client.uuid
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.plugins.forEach(plugin => {
|
|
||||||
if (typeof plugin.bot === 'function') plugin.bot(bot, options)
|
|
||||||
})
|
|
||||||
|
|
||||||
function loadPlugin (plugin) {
|
|
||||||
try {
|
try {
|
||||||
if (typeof plugin.bot === 'function') plugin.bot(bot, options)
|
require(plugin)(bot)
|
||||||
if (typeof plugin.client === 'function') plugin.client(bot, options)
|
} catch (e) {
|
||||||
bot.plugins.push(plugin)
|
|
||||||
} catch (err) {
|
|
||||||
console.log(`Error loading ${plugin}:`)
|
console.log(`Error loading ${plugin}:`)
|
||||||
console.log(err)
|
console.log(require('util').inspect(e))
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
return bot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = createBot
|
module.exports = createBot
|
75
commands.js
75
commands.js
|
@ -1,17 +1,19 @@
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
const cperms = require('./cperms2.js')
|
const cperms = require('./cperms.js')
|
||||||
|
|
||||||
let commands = {}
|
commands = {}
|
||||||
|
|
||||||
function addCommand (command) {
|
function addCommand (command) {
|
||||||
if (!isValid(command)) throw new Error(`Command ${command} is invalid.`)
|
if (!isValid(command))
|
||||||
|
return//throw new Error(`Command ${command} is invalid.`)
|
||||||
if (commands[command] == null) { commands[command] = command }
|
|
||||||
|
if (commands[command] == null)
|
||||||
|
commands[command] = command
|
||||||
command.aliases.forEach((alias) => {
|
command.aliases.forEach((alias) => {
|
||||||
alias = alias.toLowerCase()
|
if (commands[alias] == null)
|
||||||
if (commands[alias] == null) commands[alias] = command
|
commands[alias] = command
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +21,8 @@ function load () {
|
||||||
fs.readdirSync(
|
fs.readdirSync(
|
||||||
path.join(__dirname, 'commands')
|
path.join(__dirname, 'commands')
|
||||||
).forEach((file) => {
|
).forEach((file) => {
|
||||||
if (file.endsWith('.js')) {
|
if (file.endsWith(".js")) {
|
||||||
const command = path.join(__dirname, 'commands', file)
|
const command = path.join(__dirname, 'commands', file)
|
||||||
try {
|
try {
|
||||||
const cmd = require(command)
|
const cmd = require(command)
|
||||||
addCommand(cmd)
|
addCommand(cmd)
|
||||||
|
@ -32,44 +34,29 @@ function load () {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function reload () {
|
function execute (bot, command, entity, args, ...custom) {
|
||||||
try {
|
|
||||||
Object.keys(commands).forEach(key => {
|
|
||||||
const command = commands[key]
|
|
||||||
delete require.cache[command.path]
|
|
||||||
})
|
|
||||||
} catch (err) { }
|
|
||||||
commands = {}
|
|
||||||
load()
|
|
||||||
}
|
|
||||||
|
|
||||||
function execute (bot, command, player, args, ...custom) {
|
|
||||||
const cmd = info(command)
|
const cmd = info(command)
|
||||||
if (!cmd.enabled) { return bot.core.run(`/bcraw &cThe command ${bot.prefix}${command} is disabled.`) }
|
if (!cmd.enabled)
|
||||||
|
return bot.core.run(`/bcraw &cThe command ${bot.prefix}${command} is disabled.`)
|
||||||
|
|
||||||
if (cmd.permLevel > 0) {
|
if (cmd.permLevel > 0) {
|
||||||
if (args.length < 1) {
|
if (args.length < 1)
|
||||||
bot.core.run('/bcraw &cYou must provide a code to run this command.')
|
return bot.core.run(`/bcraw &cYou must provide a code to run this command.`)
|
||||||
return
|
|
||||||
}
|
const code = parseFloat(args.splice(-1, 1)[0].replace(/§./g, ''))
|
||||||
|
|
||||||
const code = args.splice(-1, 1)[0].replace(/\u00a7.?/g, '')
|
if (!cperms.validate(cmd.permLevel, code))
|
||||||
|
return bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||||
if (!cperms.validate(cmd.permLevel, player.name, code)) {
|
|
||||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
|
||||||
{ text: `Invalid code: ${code}.`, color: bot.colors.error }
|
{ text: `Invalid code: ${code}.`, color: bot.colors.error }
|
||||||
])}`)
|
])}`)
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return cmd.execute(bot, command, player, args, module.exports, ...custom)
|
return cmd.execute(bot, command, entity, args, module.exports, ...custom)
|
||||||
} catch (err) {
|
} catch (e) {
|
||||||
console.log(`Error executing command ${command}:`)
|
console.log(`Error executing command ${command}:`)
|
||||||
console.log(err)
|
console.log(require('util').inspect(e))
|
||||||
|
|
||||||
bot.core.run(`/tellraw @a ${JSON.stringify({ text: err.message, color: bot.colors.error })}`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,16 +68,16 @@ function isCommand (command) {
|
||||||
return commands[command] != null
|
return commands[command] != null
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValid (command) {
|
function isValid(command) {
|
||||||
return command != null &&
|
return command != null &&
|
||||||
typeof command.execute === 'function' &&
|
typeof command.execute === 'function' &&
|
||||||
typeof command.name === 'string' &&
|
typeof command.name === 'string' &&
|
||||||
typeof command.description === 'string' &&
|
typeof command.description === 'string' &&
|
||||||
Array.isArray(command.usages) &&
|
typeof command.usage === 'string' &&
|
||||||
Array.isArray(command.aliases) &&
|
|
||||||
typeof command.enabled === 'boolean' &&
|
typeof command.enabled === 'boolean' &&
|
||||||
|
Array.isArray(command.aliases) &&
|
||||||
command.aliases.length > 0 &&
|
command.aliases.length > 0 &&
|
||||||
typeof command.permLevel === 'number'
|
typeof command.permLevel === 'number'
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { addCommand, load, reload, execute, info, isCommand, isValid, commands }
|
module.exports = { addCommand, load, execute, info, isCommand, isValid, commands }
|
|
@ -1,16 +0,0 @@
|
||||||
const name = '_eval'
|
|
||||||
const description = 'disabled command, ignore'
|
|
||||||
const usages = ['<code...>']
|
|
||||||
const aliases = ['_eval']
|
|
||||||
const enabled = false
|
|
||||||
|
|
||||||
const permLevel = 2
|
|
||||||
|
|
||||||
const { inspect } = require('util')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const result = eval(args.join(' ').replace(/\xa7.?/g, ''))
|
|
||||||
console.log(inspect(result)) // bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: inspect(result), color: bot.colors.primary }))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,13 +0,0 @@
|
||||||
const name = 'actionbar'
|
|
||||||
const description = 'exists for some reason'
|
|
||||||
const usages = ['<message...>']
|
|
||||||
const aliases = ['actionbar']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const text = args.join(' ')
|
|
||||||
bot.core.run('minecraft:title @a actionbar ' + JSON.stringify({ text }))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,36 +0,0 @@
|
||||||
const name = 'antitnt'
|
|
||||||
const description = 'Prevents explosions'
|
|
||||||
const usages = [
|
|
||||||
'on',
|
|
||||||
'off'
|
|
||||||
]
|
|
||||||
const aliases = ['antitnt', 'antiexplosion']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
function sendState () {
|
|
||||||
bot.tellraw([{ text: 'antiTNT is now ', color: bot.colors.primary }, { text: bot.antiTNT.enabled ? 'on' : 'off', color: bot.colors.secondary }])
|
|
||||||
}
|
|
||||||
|
|
||||||
const subCommand = args.shift()
|
|
||||||
if (subCommand === undefined) {
|
|
||||||
throw new Error('ok')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (subCommand.toLowerCase()) {
|
|
||||||
case 'on':
|
|
||||||
bot.antiTNT.enabled = true
|
|
||||||
sendState()
|
|
||||||
break
|
|
||||||
case 'off':
|
|
||||||
bot.antiTNT.enabled = false
|
|
||||||
sendState()
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new Error('ok')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,23 +0,0 @@
|
||||||
const name = 'bruhify'
|
|
||||||
const description = 'recyclebot'
|
|
||||||
const usages = ['<text>']
|
|
||||||
const aliases = ['bruhify']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
if (args[0] === 'format') {
|
|
||||||
args.shift()
|
|
||||||
const code = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
const format = code ? bot.eval(code) : bot.bruhify._format
|
|
||||||
|
|
||||||
if (typeof format !== 'function') throw new TypeError('format must be a function')
|
|
||||||
|
|
||||||
bot.bruhify.format = format
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bot.bruhify.text = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,23 +0,0 @@
|
||||||
const name = 'bruhify'
|
|
||||||
const description = 'recyclebot'
|
|
||||||
const usages = ['<text>']
|
|
||||||
const aliases = ['bruhify']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
if (args[0] === 'format') {
|
|
||||||
args.shift()
|
|
||||||
const code = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
const format = code ? bot.eval(code) : bot.bruhify._format
|
|
||||||
|
|
||||||
if (typeof format !== 'function') throw new TypeError('format must be a function')
|
|
||||||
|
|
||||||
bot.bruhify.format = format
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bot.bruhify.text = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,13 +1,13 @@
|
||||||
const name = 'cb'
|
const name = 'cb'
|
||||||
const description = 'Runs a command in the command core'
|
const description = 'Runs a command in the command core'
|
||||||
const usages = ['<command...>']
|
const usage = '{prefix}cb <command...>'
|
||||||
const aliases = ['cb']
|
const aliases = ['cb']
|
||||||
const enabled = true
|
const enabled = true
|
||||||
|
|
||||||
const permLevel = 0
|
const permLevel = 0
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
function execute (bot, cmd, entity, args, handler) {
|
||||||
bot.core.run(args.join(' '))
|
bot.core.run(args.join(' '))
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
|
@ -1,19 +0,0 @@
|
||||||
const name = 'clearchat'
|
|
||||||
const description = 'Clears the chat'
|
|
||||||
const usages = ['[selector]']
|
|
||||||
const aliases = ['clearchat', 'cc']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const text = []
|
|
||||||
while (text.length < 100) {
|
|
||||||
text.push('\n')
|
|
||||||
}
|
|
||||||
text.push({ text: 'The chat has been cleared', color: 'dark_green' })
|
|
||||||
|
|
||||||
bot.core.run(`/minecraft:tellraw ${args.join(' ') || '@a'} ${JSON.stringify(text)}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,13 +0,0 @@
|
||||||
const name = 'clearchatqueue'
|
|
||||||
const description = 'Clears the chat queue of the bot'
|
|
||||||
const usages = []
|
|
||||||
const aliases = ['clearchatqueue', 'ccq']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
bot.chat.queue.splice(0, bot.chat.queue)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,53 +0,0 @@
|
||||||
const name = 'client'
|
|
||||||
const description = 'Creates and manages clients using minecraft-protocol.'
|
|
||||||
const usages = ['create <options (json)>', 'end <i>', 'write <i> <name> <data (json)>', 'list']
|
|
||||||
const aliases = ['client']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const mc = require('minecraft-protocol')
|
|
||||||
const clients = []
|
|
||||||
const sectionRegex = /\u00a7.?/g
|
|
||||||
const util = require('util')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const subCmd = args.shift()
|
|
||||||
|
|
||||||
let client, i, name, data
|
|
||||||
switch (subCmd) {
|
|
||||||
case 'create':
|
|
||||||
const options = JSON.parse(args.join(' ').replace(sectionRegex, ''))
|
|
||||||
options.host = bot.server.host
|
|
||||||
options.port = bot.server.port
|
|
||||||
client = mc.createClient(options)
|
|
||||||
i = clients.length
|
|
||||||
client.on('login', () => bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: client.username + '\u00a7r logged in.', color: bot.colors.primary })))
|
|
||||||
client.on('end', () => {
|
|
||||||
clients.splice(i, 1)
|
|
||||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: client.username + '\u00a7r ended.', color: bot.colors.primary }))
|
|
||||||
})
|
|
||||||
client.on('error', (err) => bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: util.inspect(err).replace(/\n.*/g, ''), color: bot.colors.error })))
|
|
||||||
clients.push(client)
|
|
||||||
break
|
|
||||||
case 'end':
|
|
||||||
i = parseInt(args.join(' '))
|
|
||||||
clients[i].end()
|
|
||||||
clients.splice(i, 1)
|
|
||||||
break
|
|
||||||
case 'write':
|
|
||||||
i = parseInt(args.shift())
|
|
||||||
name = args.shift()
|
|
||||||
data = JSON.parse(args.join(' ').replace(sectionRegex, ''))
|
|
||||||
|
|
||||||
clients[i].write(name, data)
|
|
||||||
break
|
|
||||||
case 'list':
|
|
||||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: 'Clients: ' + clients.map(client => client.username).join('\u00a7r, '), color: bot.colors.primary }))
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new Error('Invalid or missing argument')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,54 +0,0 @@
|
||||||
const name = 'cloop'
|
|
||||||
const description = 'Loops commands'
|
|
||||||
const usages = [
|
|
||||||
'add <interval> <command...>',
|
|
||||||
'remove <index>',
|
|
||||||
'list'
|
|
||||||
]
|
|
||||||
const aliases = ['cloop']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const subCommand = args.shift()
|
|
||||||
|
|
||||||
let interval, command, i, msg
|
|
||||||
switch (subCommand) {
|
|
||||||
case 'add':
|
|
||||||
interval = Number(args.shift())
|
|
||||||
if (Number.isNaN(interval)) throw new Error('Interval must be a number')
|
|
||||||
|
|
||||||
command = args.join(' ').replace(/xa7.?/g, '')
|
|
||||||
bot.cloops.push({ command, interval })
|
|
||||||
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Added command ', color: bot.colors.primary },
|
|
||||||
{ text: command, color: bot.colors.secondary },
|
|
||||||
' to cloops.'
|
|
||||||
])
|
|
||||||
break
|
|
||||||
case 'remove':
|
|
||||||
i = Number(args.shift())
|
|
||||||
if (Number.isNaN(i)) throw new Error('Index must be a number')
|
|
||||||
bot.cloops.splice(i, 1)
|
|
||||||
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Removed cloop ', color: bot.colors.primary },
|
|
||||||
{ text: i, color: bot.colors.secondary }
|
|
||||||
])
|
|
||||||
break
|
|
||||||
case 'list':
|
|
||||||
msg = [{ text: 'Cloops: \n', color: bot.colors.primary }]
|
|
||||||
for (const i in bot.cloops) {
|
|
||||||
msg.push({ text: `${i}: ` })
|
|
||||||
msg.push({ text: `${bot.cloops[i].command}\n`, color: bot.colors.secondary })
|
|
||||||
}
|
|
||||||
bot.tellraw(msg)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new SyntaxError('Invalid or missing argument' + (subCommand ? ': ' + subCommand : ''))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,42 +0,0 @@
|
||||||
const name = 'color'
|
|
||||||
const description = 'Changes your color (useless)'
|
|
||||||
const usages = ['<color>']
|
|
||||||
const aliases = ['color']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const colors = {
|
|
||||||
black: '§0',
|
|
||||||
dark_blue: '§1',
|
|
||||||
dark_green: '§2',
|
|
||||||
dark_aqua: '§3',
|
|
||||||
dark_red: '§4',
|
|
||||||
dark_purple: '§5',
|
|
||||||
gold: '§6',
|
|
||||||
gray: '§7',
|
|
||||||
dark_gray: '§8',
|
|
||||||
blue: '§9',
|
|
||||||
green: '§a',
|
|
||||||
aqua: '§b',
|
|
||||||
red: '§c',
|
|
||||||
light_purple: '§d',
|
|
||||||
yellow: '§e',
|
|
||||||
white: '§f',
|
|
||||||
reset: '§r'
|
|
||||||
}
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const { Team } = bot
|
|
||||||
|
|
||||||
const color = args.join(' ')
|
|
||||||
if (!(color in colors)) throw new Error('Invalid color: ' + color)
|
|
||||||
|
|
||||||
new Team(`chipmunk_${player.UUID}`)
|
|
||||||
.setColor(color)
|
|
||||||
.setSeeFriendlyInvisibles(false)
|
|
||||||
.add(player.UUID)
|
|
||||||
|
|
||||||
bot.core.run(`essentials:nick ${player.UUID} ${colors[color]}${player.name}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,13 +0,0 @@
|
||||||
const name = 'colortest'
|
|
||||||
const description = 'Sends the arguments with \\u00a7 escaped'
|
|
||||||
const usages = ['<message...>']
|
|
||||||
const aliases = ['colortest']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
bot.tellraw({ text: args.join(' ').replace(/\xa7/g, '\\u00a7') }, player.UUID)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,16 +0,0 @@
|
||||||
const name = 'consoleserver'
|
|
||||||
const description = 'sets the console server'
|
|
||||||
const usages = ['<host...>']
|
|
||||||
const aliases = ['consoleserver', 'consolesvr', 'csvr']
|
|
||||||
const enabled = false
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const host = args.join(' ')
|
|
||||||
bot.getBots().forEach(bot => {
|
|
||||||
bot.console.host = host
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,39 +1,26 @@
|
||||||
const name = 'credits'
|
const name = 'credits'
|
||||||
const description = 'Shows bot credits.'
|
const description = 'Shows bot credits.'
|
||||||
const usages = []
|
const usage = '{prefix}credits'
|
||||||
const aliases = ['credits']
|
const aliases = ['credits']
|
||||||
const enabled = true
|
const enabled = true
|
||||||
|
|
||||||
const permLevel = 0
|
const permLevel = 0
|
||||||
|
|
||||||
const { dependencies } = require('./../package.json')
|
function execute(bot, cmd, entity, args, handler) {
|
||||||
|
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||||
function execute (bot, cmd, entity, args, handler) {
|
'',
|
||||||
bot.tellraw([
|
|
||||||
{ text: '', color: 'gray' },
|
|
||||||
{ text: 'Credits\n', color: bot.colors.primary, bold: true },
|
{ text: 'Credits\n', color: bot.colors.primary, bold: true },
|
||||||
|
|
||||||
{ text: '_ChipMC_', color: 'blue' },
|
{ text: '_ChipMC_', color: 'blue' },
|
||||||
' - creating the bot\n',
|
'created the bot.\n',
|
||||||
|
|
||||||
{ text: 'hhhzzzsss', color: 'aqua', bold: true },
|
{ text: 'hhhzzzsss', color: 'aqua', bold: true },
|
||||||
' - creating the original midi converter\n',
|
' and ',
|
||||||
|
|
||||||
{ text: 'eva', color: 'light_purple', italic: true },
|
{ text: 'eva', color: 'light_purple', italic: true },
|
||||||
' - creating the original midi converter\n',
|
' created the midi converter.\n'//,
|
||||||
|
|
||||||
{ text: 'ma', color: 'aqua' },
|
|
||||||
{ text: 'ni', color: 'light_purple' },
|
])}`)
|
||||||
{ text: 'a', color: 'white' },
|
|
||||||
{ text: 'pl', color: 'light_purple' },
|
|
||||||
{ text: 'ay', color: 'aqua' },
|
|
||||||
' - creating the original image converter',
|
|
||||||
|
|
||||||
{ text: 'ayunami2000', color: 'red' },
|
|
||||||
' - creating the image converter\n',
|
|
||||||
|
|
||||||
`\nDependencies: ${Object.entries(dependencies).map([key, value] => key + ' ' + value).join(' ')}`
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
|
@ -1,13 +0,0 @@
|
||||||
const name = 'disconnect'
|
|
||||||
const description = 'Ends the bot\'s client.'
|
|
||||||
const usages = []
|
|
||||||
const aliases = ['disconnect']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
bot.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,17 +0,0 @@
|
||||||
const name = 'discord'
|
|
||||||
const description = 'totally real discord command!11'
|
|
||||||
const usages = []
|
|
||||||
const aliases = ['discord']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Join the ', color: 'gray' },
|
|
||||||
{ text: 'totally real ChipmunkBot Discord', color: bot.colors.primary },
|
|
||||||
' at ',
|
|
||||||
{ text: 'https://discord.gg/asIwmNwC', color: bot.colors.primary, underlined: true, clickEvent: { action: 'open_url', value: 'https://sus.red' } }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,16 +0,0 @@
|
||||||
const name = 'echo'
|
|
||||||
const description = 'Echoes text'
|
|
||||||
const usages = ['<message...>']
|
|
||||||
const aliases = ['echo']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const raw = args
|
|
||||||
.join(' ')
|
|
||||||
.replace(/&([0-9a-fkl-or]|#[0-9a-f]{6})/gi, m => '\xa7' + m.substring(1))
|
|
||||||
bot.core.run(`essentials:sudo ${bot._client.uuid} ${raw.startsWith('/') ? raw.substring(1) : 'c:' + raw}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
13
commands/end.js
Normal file
13
commands/end.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
const name = 'end'
|
||||||
|
const description = `Ends the bot's client.`
|
||||||
|
const usage = '{prefix}end'
|
||||||
|
const aliases = ['end']
|
||||||
|
const enabled = true
|
||||||
|
|
||||||
|
const permLevel = 0
|
||||||
|
|
||||||
|
function execute (bot, cmd, entity, args, handler) {
|
||||||
|
bot.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
|
@ -1,40 +1,20 @@
|
||||||
const name = 'eval'
|
var name = 'eval'
|
||||||
const description = 'secure!!1'
|
var aliases = ['eval']
|
||||||
const usages = ['<code...>']
|
var description = "Runs code using eval()."
|
||||||
const aliases = ['eval']
|
var usage = "{prefix}eval <code...>"
|
||||||
const enabled = true
|
var enabled = false
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const { inspect } = require('util')
|
const permLevel = 2
|
||||||
const dineval = require('../util/dineval.js')
|
|
||||||
const { stylizeWithColor } = require('../util/stylize_with_color.js')
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args) {
|
function execute(bot, cmd, username, args, handler) {
|
||||||
const getCode = () => args.join(' ').replace(/\xa7.?/g, '')
|
new Promise((resolve, reject) => {
|
||||||
|
resolve(eval(args.join(' ')))
|
||||||
switch (args.shift()) {
|
}).then((output) => {
|
||||||
case 'run': {
|
bot.core.run(`/tellraw @a ${JSON.stringify({ text: `>${output}`, color: 'green' })}`)
|
||||||
let result
|
}).catch((err) => {
|
||||||
try {
|
//console.log(err);
|
||||||
result = await bot.eval(getCode(), { inspect: true })
|
bot.core.run(`/tellraw @a ${JSON.stringify({ text: `>${err}`, color: 'red' })}`)
|
||||||
} catch (err) {
|
})
|
||||||
result = err
|
|
||||||
}
|
|
||||||
bot.tellraw(result)
|
|
||||||
} break
|
|
||||||
case 'reset': {
|
|
||||||
bot.eval._worker.terminate()
|
|
||||||
} break
|
|
||||||
case 'dineval': {
|
|
||||||
const result = await dineval(getCode(), { colors: 'minecraft' })
|
|
||||||
const resultStr = typeof result === 'string' ? result : inspect(result, { stylize: stylizeWithColor })
|
|
||||||
|
|
||||||
bot.tellraw(resultStr)
|
|
||||||
} break
|
|
||||||
default: {
|
|
||||||
throw new SyntaxError('Invalid or missing argument')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel}
|
|
@ -1,27 +0,0 @@
|
||||||
const name = 'execute'
|
|
||||||
const description = 'Very normal execute command :)'
|
|
||||||
const usages = [ // TODO: Improve
|
|
||||||
'align <axes> -> execute',
|
|
||||||
'anchored <anchor> -> execute',
|
|
||||||
'/execute as <targets> -> execute',
|
|
||||||
'at <targets> -> execute',
|
|
||||||
'facing (entity|<pos>)',
|
|
||||||
'if (block|blocks|data|entity|predicate|score)',
|
|
||||||
'in <dimension> -> execute',
|
|
||||||
'positioned (as|<pos>)',
|
|
||||||
'rotated (as|<rot>)',
|
|
||||||
'run ...',
|
|
||||||
'store (result|success)',
|
|
||||||
'unless (block|blocks|data|entity|predicate|score)'
|
|
||||||
]
|
|
||||||
const aliases = ['execute']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
if (!bot.execute) throw new Error('Execute is not supported by the bot')
|
|
||||||
|
|
||||||
bot.execute(`as ${player.UUID} at @s ${args.join(' ')}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,34 +0,0 @@
|
||||||
const name = 'grainbowify'
|
|
||||||
const description = 'Makes text green rainbow'
|
|
||||||
const usages = ['<message...>']
|
|
||||||
const aliases = ['grainbowify']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const colorsys = require('colorsys')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const message = args.join(' ')
|
|
||||||
|
|
||||||
const result = []
|
|
||||||
let val = 0
|
|
||||||
let backwards = false
|
|
||||||
message.split('').forEach((char) => {
|
|
||||||
result.push({ text: char, color: colorsys.hsv2Hex(100, 100, val) })
|
|
||||||
incr()
|
|
||||||
if (val <= 0 || val >= 100) {
|
|
||||||
backwards = !backwards
|
|
||||||
incr()
|
|
||||||
}
|
|
||||||
|
|
||||||
function incr () {
|
|
||||||
const incr = 100 / Math.max(message.length, 20)
|
|
||||||
if (!backwards) { val += incr } else { val -= incr }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.tellraw(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,81 +1,49 @@
|
||||||
const name = 'help'
|
const name = 'help'
|
||||||
const description = 'Lists commands or shows info about a command.'
|
const description = 'Lists commands or shows info about a command.'
|
||||||
const usages = ['[command]']
|
const usage = '{prefix}help <command>'
|
||||||
const aliases = ['help']
|
const aliases = ['help']
|
||||||
const enabled = true
|
const enabled = true
|
||||||
|
|
||||||
const permLevel = 0
|
const permLevel = 0
|
||||||
|
|
||||||
function execute (bot, cmd, entity, args) {
|
function execute (bot, cmd, entity, args, handler) {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
if (!bot.commands.isCommand(args[0])) { return bot.core.run(`/tellraw @a ${JSON.stringify({ text: `Unknown command: ${bot.prefix}${args[0]}`, color: bot.colors.error })}`) }
|
if (!handler.isCommand(args[0]))
|
||||||
|
return bot.core.run(`/tellraw @a ${JSON.stringify({ text: `Unknown command: ${bot.prefix}${args[0]}`, color: bot.colors.error })}`)
|
||||||
|
|
||||||
const command = bot.commands.info(args.shift())
|
const command = handler.info(args.shift())
|
||||||
|
|
||||||
let msg
|
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||||
if (command.usages.length !== 1) {
|
{ text: 'Name: ', color: bot.colors.primary }, { text: `${command.name}\n`, color: bot.colors.secondary },
|
||||||
msg = [
|
{ text: 'Description: ' }, { text: `${command.description}\n`, color: bot.colors.secondary },
|
||||||
{ text: bot.prefix + command.name, color: bot.colors.primary },
|
{ text: 'Usage: ' }, { text: `${command.usage.replace(/{prefix}/g, bot.prefix)}\n`, color: bot.colors.secondary },
|
||||||
{ text: ' (' + command.aliases.join(', ') + ')', color: 'white' },
|
{ text: 'Aliases: ' }, { text: `${command.name}\n`, color: bot.colors.secondary },
|
||||||
{ text: ` - ${command.description}\n`, color: 'gray' }
|
{ text: 'Enabled: ' }, { text: `${command.enabled}\n`, color: bot.colors.secondary },
|
||||||
]
|
{ text: 'Permission Level: ' }, { text: command.permLevel, color: bot.colors.secondary }
|
||||||
command.usages.forEach((usage, i) => {
|
])}`)
|
||||||
msg.push(bot.prefix + command.name)
|
return
|
||||||
msg.push({
|
|
||||||
text: ` ${usage}\n`,
|
|
||||||
color: bot.colors.secondary,
|
|
||||||
clickEvent: { action: 'suggest_command', value: command.name + ' ' + usage }
|
|
||||||
// hoverEvent: { action: 'show_text', value: 'Click to teleport' }
|
|
||||||
})
|
|
||||||
})
|
|
||||||
msg[msg.length - 1].text = msg[msg.length - 1].text.slice(0, -1)
|
|
||||||
} else {
|
|
||||||
msg = [
|
|
||||||
{ text: bot.prefix + command.name, color: bot.colors.primary },
|
|
||||||
{ text: ' (' + command.aliases.join(', ') + ')', color: 'white' },
|
|
||||||
{
|
|
||||||
text: ` ${command.usages[0]}`,
|
|
||||||
color: bot.colors.secondary,
|
|
||||||
clickEvent: { action: 'suggest_command', value: command.name + ' ' + command.usages[0] }
|
|
||||||
},
|
|
||||||
{ text: ` - ${command.description}`, color: 'gray' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
return bot.core.run(`minecraft:tellraw @a ${JSON.stringify(msg)}`)
|
|
||||||
}
|
}
|
||||||
let commands = []
|
let commands = []
|
||||||
Object.keys(bot.commands.commands).forEach((command) => {
|
Object.keys(handler.commands).forEach((command) => {
|
||||||
if (bot.commands.isCommand(command) && !commands.includes(bot.commands.info(command))) { commands.push(bot.commands.info(command)) }
|
if (handler.isCommand(command))
|
||||||
|
commands.push(handler.info(command))
|
||||||
})
|
})
|
||||||
commands = commands.filter((command) => command.enabled)
|
commands = commands.filter((command) => command.enabled)
|
||||||
|
|
||||||
const publicList = []
|
const commandNames = []
|
||||||
const trustedList = []
|
|
||||||
const adminList = []
|
|
||||||
const unknownList = []
|
|
||||||
commands.forEach((command) => {
|
commands.forEach((command) => {
|
||||||
const msg = {
|
if (!commandNames.includes(command.name))
|
||||||
color: 'dark_aqua',
|
commandNames.push(command.name)
|
||||||
text: bot.prefix + command.name + ' ',
|
|
||||||
clickEvent: { action: 'run_command', value: bot.prefix + aliases[0] + ' ' + command.name },
|
|
||||||
hoverEvent: { action: 'show_text', value: 'Click to see info about the command' }
|
|
||||||
}
|
|
||||||
if (command.permLevel === 0) {
|
|
||||||
msg.color = 'green'
|
|
||||||
publicList.push(msg)
|
|
||||||
} else if (command.permLevel === 1) {
|
|
||||||
msg.color = 'red'
|
|
||||||
trustedList.push(msg)
|
|
||||||
} else if (command.permLevel === 2) {
|
|
||||||
msg.color = 'dark_red'
|
|
||||||
adminList.push(msg)
|
|
||||||
} else {
|
|
||||||
unknownList.push(msg)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const msg = [{ text: 'Commands - ', color: 'gray' }, ...publicList, ...trustedList, ...adminList, ...unknownList]
|
text = [{ text: 'Commands:\n', color: bot.colors.primary }]
|
||||||
bot.core.run(`/tellraw @a ${JSON.stringify(msg)}`)
|
commandNames.forEach((cmdName) => {
|
||||||
|
text.push(cmdName)
|
||||||
|
text.push({ text: ', ', color: bot.colors.secondary })
|
||||||
|
})
|
||||||
|
text.splice(-1, 1)
|
||||||
|
|
||||||
|
bot.core.run(`/tellraw @a ${JSON.stringify(text)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
|
@ -1,70 +0,0 @@
|
||||||
const name = 'image'
|
|
||||||
const description = 'Renders an image.'
|
|
||||||
const usages = [
|
|
||||||
'render <name/url>',
|
|
||||||
'list'
|
|
||||||
]
|
|
||||||
const aliases = ['image']
|
|
||||||
const enabled = false
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const fs = require('fs')
|
|
||||||
const { loadImage } = require('canvas')
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args, handler) {
|
|
||||||
const subCmd = args.shift()
|
|
||||||
|
|
||||||
switch (subCmd) {
|
|
||||||
case 'render': {
|
|
||||||
let src = args.join(' ').replace(/§.?/g, '')
|
|
||||||
if (/^https?:\/\//.test(src)) {
|
|
||||||
bot.core.run(`/minecraft:tellraw @a ${JSON.stringify([
|
|
||||||
{ text: 'Attempting to convert image at ', color: bot.colors.primary },
|
|
||||||
{ text: src, color: bot.colors.secondary }
|
|
||||||
])}`)
|
|
||||||
} else {
|
|
||||||
src = `./images/${src}`
|
|
||||||
|
|
||||||
if (!src.endsWith('.jpg')) { src += '.jpg' }
|
|
||||||
|
|
||||||
if (src.match(/\//g).length > 2) { throw new Error('Invalid image name.') }
|
|
||||||
|
|
||||||
if (!fs.existsSync(src)) { throw new Error('Invalid image name.') }
|
|
||||||
|
|
||||||
bot.core.run(`/minecraft:tellraw @a ${JSON.stringify([
|
|
||||||
{ text: 'Attempting to convert image ', color: bot.colors.primary },
|
|
||||||
{ text: args.join(' ').replace(/§.?/g, ''), color: bot.colors.secondary },
|
|
||||||
'.'
|
|
||||||
])}`)
|
|
||||||
}
|
|
||||||
const canvas = new bot.ChatCanvas()
|
|
||||||
const ctx = canvas.getContext('2d')
|
|
||||||
|
|
||||||
const img = await loadImage(src)
|
|
||||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
|
|
||||||
canvas.render()
|
|
||||||
} break
|
|
||||||
case 'list': {
|
|
||||||
const files = fs.readdirSync('./images')
|
|
||||||
files.filter((file) => file.endsWith('.jpg'))
|
|
||||||
|
|
||||||
let primary = false
|
|
||||||
const msg = [{ text: 'Images - ', color: 'gray' }]
|
|
||||||
files.forEach((file) => {
|
|
||||||
msg.push({
|
|
||||||
text: `${file} `,
|
|
||||||
color: (((primary = !primary)) ? bot.colors.primary : bot.colors.secondary),
|
|
||||||
clickEvent: { action: 'run_command', value: `${bot.prefix}${name} render ${file}` },
|
|
||||||
hoverEvent: { action: 'show_text', value: 'Click to render the image' }
|
|
||||||
})
|
|
||||||
})
|
|
||||||
bot.tellraw(msg)
|
|
||||||
} break
|
|
||||||
default: {
|
|
||||||
throw new Error('Invalid or missing argument.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,25 +0,0 @@
|
||||||
const name = 'kahoot'
|
|
||||||
const description = 'kahoot client lol'
|
|
||||||
const usages = ['join <pin> <username>', 'leave', 'answer <answer>']
|
|
||||||
const aliases = ['kahoot']
|
|
||||||
const enabled = false
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const subCmd = args.shift()
|
|
||||||
switch (subCmd) {
|
|
||||||
case 'join':
|
|
||||||
bot.kahoot.join(parseFloat(args.shift()), args.join(' '))
|
|
||||||
break
|
|
||||||
case 'leave':
|
|
||||||
bot.kahoot.leave()
|
|
||||||
break
|
|
||||||
case 'answer':
|
|
||||||
bot.kahoot.answer(parseFloat(args.join(' ')))
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new Error('Invalid or missing argument.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,40 +0,0 @@
|
||||||
const name = 'kbwl'
|
|
||||||
const description = 'kaboom whitelist real'
|
|
||||||
const usages = ['enable', 'disable', 'add <player>', 'remove <player>', 'list']
|
|
||||||
const aliases = ['kbwl']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
switch (args.shift()) {
|
|
||||||
case 'enable':
|
|
||||||
bot.kbwl.players.push(player.name)
|
|
||||||
bot.kbwl.enabled = true
|
|
||||||
bot.tellraw([{ text: 'Enabled KBWL Mode', color: bot.colors.primary }], player.UUID)
|
|
||||||
break
|
|
||||||
case 'disable':
|
|
||||||
bot.kbwl.enabled = false
|
|
||||||
bot.tellraw([{ text: 'Disabled KBWL Mode', color: bot.colors.primary }], player.UUID)
|
|
||||||
break
|
|
||||||
case 'add': {
|
|
||||||
const username = args.join(' ')
|
|
||||||
if (bot.kbwl.players.includes(username)) throw new Error(username + ' is already whitelisted')
|
|
||||||
bot.kbwl.players.push(username)
|
|
||||||
bot.tellraw([{ text: 'Added ', color: bot.colors.primary }, { text: username, color: bot.colors.secondary }, 'to the whitelist'], player.UUID)
|
|
||||||
} break
|
|
||||||
case 'remove': {
|
|
||||||
const username = args.join(' ')
|
|
||||||
const index = bot.kbwl.players.indexOf(username)
|
|
||||||
if (index === -1) throw new Error(username + ' is not whitelisted')
|
|
||||||
bot.kbwl.players.splice(index, 1)
|
|
||||||
bot.tellraw([{ text: 'Removed ', color: bot.colors.primary }, { text: username, color: bot.colors.secondary }, 'from the whitelist'], player.UUID)
|
|
||||||
} break
|
|
||||||
case 'list':
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Players - ', color: bot.colors.primary },
|
|
||||||
...bot.kbwl.players.map((username, i) => ({ text: username + ' ', color: i % 2 === 0 ? bot.colors.secondary : bot.colors.primary }))
|
|
||||||
], player.UUID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,16 +0,0 @@
|
||||||
const name = 'kick'
|
|
||||||
const description = 'Kicks a player'
|
|
||||||
const usages = [ // TODO: Improve
|
|
||||||
'<target>'
|
|
||||||
]
|
|
||||||
const aliases = ['kick']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
if (!bot.kick) throw new Error('Kicking is not supported by the bot')
|
|
||||||
|
|
||||||
bot.kick(args.join(' '))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,29 +0,0 @@
|
||||||
const name = 'lint'
|
|
||||||
const description = 'Lints code using standard'
|
|
||||||
const usages = ['<code...>']
|
|
||||||
const aliases = ['lint']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const standard = require('standard')
|
|
||||||
|
|
||||||
async function execute (bot, cmd, entity, args) {
|
|
||||||
let fix = false
|
|
||||||
if (args[0] === 'fix') {
|
|
||||||
fix = true
|
|
||||||
args.shift()
|
|
||||||
}
|
|
||||||
const result = standard.lintTextSync(
|
|
||||||
args.join(' ').replace(/\xa7.?/g, '') + '\n',
|
|
||||||
{ fix }
|
|
||||||
).results[0]
|
|
||||||
let resultText = ''
|
|
||||||
result.messages.forEach(message => {
|
|
||||||
resultText += message.line + ':' + message.column + ': ' + message.message + '\n'
|
|
||||||
})
|
|
||||||
if (result.output != null) resultText += 'Output: ' + result.output
|
|
||||||
bot.tellraw(resultText)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,29 +0,0 @@
|
||||||
const name = 'linteval'
|
|
||||||
const description = 'lints and evaluates javascript'
|
|
||||||
const usages = ['<code...>']
|
|
||||||
const aliases = ['linteval', 'leval']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const { inspect } = require('util')
|
|
||||||
const standard = require('standard')
|
|
||||||
|
|
||||||
const colormap = ['white', 'yellow', 'red']
|
|
||||||
const lintOpts = {
|
|
||||||
usePackageJson: false
|
|
||||||
}
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args) {
|
|
||||||
const code = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
|
|
||||||
const { results: [ lintResult ] } = standard.lintTextSync(code + '\n', lintOpts)
|
|
||||||
const resultMsg = lintResult.messages.map(
|
|
||||||
({ line, column, message, severity }) => ({ text: `${line}:${column}: ${message}`, color: colormap[severity] })
|
|
||||||
)
|
|
||||||
bot.tellraw(resultMsg)
|
|
||||||
|
|
||||||
const evalResult = await bot.eval(code)
|
|
||||||
bot.tellraw({ text: inspect(evalResult), color: bot.colors.primary })
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,20 +0,0 @@
|
||||||
const name = 'list'
|
|
||||||
const description = 'Lists Entities (test command)'
|
|
||||||
const usages = ['[target]']
|
|
||||||
const aliases = ['list']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const parseSelectorComponent = require('../util/parse-selector-component.js')
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args, handler) {
|
|
||||||
const selector = args.join(' ').replace(/\xa7.?/g, '') || '@e'
|
|
||||||
const entities = parseSelectorComponent((await bot.resolveComponent({ selector }))[0])
|
|
||||||
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Entities - ', color: bot.colors.primary },
|
|
||||||
...entities.flatMap((e, i) => [{ ...e.name, color: (i % 2) ? bot.colors.primary : bot.colors.secondary }, ' '])
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,35 +0,0 @@
|
||||||
const name = 'lock'
|
|
||||||
const description = 'real'
|
|
||||||
const usages = ['add <username>', 'remove <username>']
|
|
||||||
const aliases = ['lock']
|
|
||||||
const enabled = false
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
const nbt = require('prismarine-nbt')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const subCommand = args.shift()?.toLowerCase()
|
|
||||||
const username = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
|
|
||||||
switch (subCommand) {
|
|
||||||
case 'add':
|
|
||||||
bot.locked.push(username)
|
|
||||||
bot.tellraw([{ text: 'Added ', color: bot.colors.primary }, { text: username, color: bot.colors.secondary }, ' to the lock list'])
|
|
||||||
break
|
|
||||||
case 'remove':
|
|
||||||
const index = bot.locked.indexOf(username)
|
|
||||||
if (index === -1) {
|
|
||||||
throw new ReferenceError(username + ' is not locked')
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Unlock them
|
|
||||||
|
|
||||||
bot.locked.splice(index, 1)
|
|
||||||
bot.tellraw([{ text: 'Removed ', color: bot.colors.primary }, { text: username, color: bot.colors.secondary }, ' from the lock list'])
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new SyntaxError('ok')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,49 +0,0 @@
|
||||||
const name = 'mail'
|
|
||||||
const description = 'Shows mail'
|
|
||||||
const usages = ['send <username> <message>', 'list', 'clear']
|
|
||||||
const aliases = ['mail']
|
|
||||||
const enabled = false
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const subCmd = args.shift()
|
|
||||||
|
|
||||||
switch (subCmd) {
|
|
||||||
case 'send': {
|
|
||||||
const u = args.shift()
|
|
||||||
const message = args.join(' ')
|
|
||||||
bot.sendMail(player.name, bot.players[u].name ?? u, message)
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Sent ', color: bot.colors.primary },
|
|
||||||
{ text: message, color: bot.colors.secondary },
|
|
||||||
' to ',
|
|
||||||
{ text: u, color: bot.colors.secondary },
|
|
||||||
'.'
|
|
||||||
], player.UUID)
|
|
||||||
} break
|
|
||||||
case 'list': {
|
|
||||||
const messages = bot.mail[player.name]
|
|
||||||
if (!messages || messages.length < 1) {
|
|
||||||
bot.tellraw({ text: 'You have no mail', color: bot.colors.primary }, player.UUID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const msg = [{ text: 'Mail:', color: bot.colors.primary }]
|
|
||||||
messages.forEach(message => {
|
|
||||||
msg.push(`\n${message.sender} (from ${message.host}): `)
|
|
||||||
msg.push({ text: message.message, color: bot.colors.secondary })
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.tellraw(msg, player.UUID)
|
|
||||||
} break
|
|
||||||
case 'clear': {
|
|
||||||
bot.mail[player.name].splice(0, bot.mail[player.name].length)
|
|
||||||
bot.tellraw({ text: 'Your mail has been cleared.', color: bot.colors.primary }, player.UUID)
|
|
||||||
} break
|
|
||||||
default: {
|
|
||||||
throw new SyntaxError('TODO: add correct error message')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,94 +0,0 @@
|
||||||
const name = 'music'
|
|
||||||
const description = 'Plays music'
|
|
||||||
const usages = [
|
|
||||||
'play <song>',
|
|
||||||
'list',
|
|
||||||
'skip',
|
|
||||||
'stop'
|
|
||||||
// 'goto <m>:<ss>'
|
|
||||||
]
|
|
||||||
const aliases = ['music']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const fs = require('fs/promises')
|
|
||||||
const path = require('path')
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args) {
|
|
||||||
const subCmd = args.shift()
|
|
||||||
|
|
||||||
switch (subCmd) {
|
|
||||||
case 'play': {
|
|
||||||
let filepath = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
filepath = path.join('music', filepath)
|
|
||||||
// if (!filepath.endsWith('.mid')) { filepath += '.mid' }
|
|
||||||
|
|
||||||
if (!checkPath(filepath)) throw new Error('among us')
|
|
||||||
|
|
||||||
try {
|
|
||||||
const stats = await fs.lstat(filepath)
|
|
||||||
if (stats.isDirectory()) {
|
|
||||||
const files = await fs.readdir(filepath)
|
|
||||||
filepath = path.join(filepath, files[Math.floor(Math.random() * files.length)])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bot.music.playing) {
|
|
||||||
bot.music.play(filepath)
|
|
||||||
} else {
|
|
||||||
bot.music.queue.push(filepath)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error('File does not exist')
|
|
||||||
}
|
|
||||||
} break
|
|
||||||
case 'list': {
|
|
||||||
const clean = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
const filepath = path.join('music', clean)
|
|
||||||
if (!checkPath(filepath)) throw new Error('among us')
|
|
||||||
|
|
||||||
const files = await fs.readdir(filepath)
|
|
||||||
|
|
||||||
let primary = true
|
|
||||||
const msg = [{ text: 'Songs - ', color: bot.colors.secondary }]
|
|
||||||
for (const file of files) { // TODO: Make this code better
|
|
||||||
const isFile = (await fs.lstat(path.join(filepath, file))).isFile()
|
|
||||||
msg.push({
|
|
||||||
text: file + ' ',
|
|
||||||
color: (!((primary = !primary)) ? bot.colors.primary : bot.colors.secondary),
|
|
||||||
clickEvent: { action: 'run_command', value: `${bot.prefix}${cmd} ${isFile ? 'play' : 'list'} ${path.join(clean, file)}` }
|
|
||||||
// hoverEvent: { action: 'show_text', value: 'Click to play the song' }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
bot.tellraw(msg)
|
|
||||||
} break
|
|
||||||
case 'skip':
|
|
||||||
bot.music.skip()
|
|
||||||
break
|
|
||||||
case 'stop':
|
|
||||||
throw new Error('trold')
|
|
||||||
// bot.music.stop()
|
|
||||||
break
|
|
||||||
case 'loop':
|
|
||||||
bot.music.looping = !bot.music.looping
|
|
||||||
break
|
|
||||||
// case 'goto': {
|
|
||||||
// const [minutes, seconds] = args.split(':').map(Number)
|
|
||||||
//
|
|
||||||
// } break
|
|
||||||
default:
|
|
||||||
throw new SyntaxError('Invalid or missing argument')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkPath (filepath) { // TODO: Make this code better
|
|
||||||
return filepath.startsWith('music')
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function randomFile (dirpath) {
|
|
||||||
const paths = fs.readdirSync(dirpath)
|
|
||||||
.map(filename => path.join(dirpath, filename))
|
|
||||||
.filter(file)
|
|
||||||
} */
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,15 +0,0 @@
|
||||||
const name = 'myuser'
|
|
||||||
const description = 'Shows your username'
|
|
||||||
const usages = []
|
|
||||||
const aliases = ['myuser']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: 'Your username is: ', color: bot.colors.primary },
|
|
||||||
{ text: player.name, color: bot.colors.secondary }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,41 +0,0 @@
|
||||||
const name = 'netmsg'
|
|
||||||
const description = 'Sends a message as each bot'
|
|
||||||
const usages = ['<message...>']
|
|
||||||
const aliases = ['netmsg']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const { host, port = 25565 } = bot.server
|
|
||||||
|
|
||||||
let displayNameArr = player.displayName
|
|
||||||
if (!Array.isArray(displayNameArr)) {
|
|
||||||
if (typeof displayNameArr === 'object') {
|
|
||||||
const arr = [displayNameArr, ...(Array.isArray(displayNameArr.extra) ? displayNameArr.extra : [])]
|
|
||||||
delete displayNameArr.extra
|
|
||||||
displayNameArr = arr
|
|
||||||
} else if (typeof displayNameArr === 'string') {
|
|
||||||
displayNameArr = [displayNameArr]
|
|
||||||
} else {
|
|
||||||
displayNameArr = [player.name]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
displayNameArr[0].color ??= bot.colors.secondary
|
|
||||||
|
|
||||||
const msg = JSON.stringify([
|
|
||||||
{ text: '', color: 'gray' },
|
|
||||||
{ text: '[', color: 'dark_gray' },
|
|
||||||
{ text: host, clickEvent: { action: 'copy_to_clipboard', value: host + ':' + port }, hoverEvent: { action: 'show_text', value: { text: host + ':' + port + '\nClick to copy the ip to your clipboard', color: bot.colors.primary } } },
|
|
||||||
{ text: '] ', color: 'dark_gray' },
|
|
||||||
...displayNameArr,
|
|
||||||
{ text: ' › ', color: 'dark_gray' },
|
|
||||||
args.join(' ')
|
|
||||||
])
|
|
||||||
|
|
||||||
bot.getBots().forEach((bot) => {
|
|
||||||
bot.core.run('minecraft:tellraw @a ' + msg)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,15 +0,0 @@
|
||||||
const name = 'parsetest'
|
|
||||||
const description = 'Displays a chat message (can be colored with %)'
|
|
||||||
const usages = ['<message...>']
|
|
||||||
const aliases = ['parsetest']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const parseString = require('../util/bukkit_chat_parse.js')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const message = args.join(' ').replace(/%[0123456789a-fk-orx]/gi, m => '\xa7' + m[1])
|
|
||||||
parseString(message, false, false).forEach(m => bot.tellraw(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,25 +0,0 @@
|
||||||
const name = 'pos'
|
|
||||||
const description = 'Gets the position of a player'
|
|
||||||
const usages = ['<selector>']
|
|
||||||
const aliases = ['pos']
|
|
||||||
const enabled = false
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
bot.getEntityPos(args.join(' '), (position) => {
|
|
||||||
const { x, y, z } = position
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify([
|
|
||||||
{ text: 'Position: ', color: bot.colors.primary },
|
|
||||||
{
|
|
||||||
text: `[${x}, ${y}, ${z}]`,
|
|
||||||
color: bot.colors.secondary,
|
|
||||||
clickEvent: { action: 'run_command', value: `/essentials:tp ${x} ${y} ${z}` },
|
|
||||||
hoverEvent: { action: 'show_text', value: 'Click to teleport' }
|
|
||||||
}
|
|
||||||
])}`)
|
|
||||||
// bot.chatQueue.push(`&aPosition: &2${x} ${y} ${z}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,6 +1,6 @@
|
||||||
const name = 'rainbowify'
|
const name = 'rainbowify'
|
||||||
const description = 'Makes text rainbow'
|
const description = 'Rainbowifys text'
|
||||||
const usages = ['<message...>']
|
const usage = '{prefix}rainbowify'
|
||||||
const aliases = ['rainbowify']
|
const aliases = ['rainbowify']
|
||||||
const enabled = true
|
const enabled = true
|
||||||
|
|
||||||
|
@ -8,19 +8,17 @@ const permLevel = 0
|
||||||
|
|
||||||
const colorsys = require('colorsys')
|
const colorsys = require('colorsys')
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
function execute (bot, cmd, entity, args, handler) {
|
||||||
const message = args.join(' ')
|
const message = args.join(' ')
|
||||||
|
|
||||||
|
const result = []
|
||||||
let hue = 0
|
let hue = 0
|
||||||
|
message.split('').forEach((char) => {
|
||||||
|
result.push({ text: char, color: colorsys.hsv2Hex(hue, 100, 100) })
|
||||||
|
hue += 355 / Math.max(message.length, 20)//; console.log(hue)
|
||||||
|
})
|
||||||
|
|
||||||
const rainbowified = message
|
bot.core.run(`/tellraw @a ${JSON.stringify(result)}`)
|
||||||
.split('')
|
|
||||||
.map((char) => {
|
|
||||||
const component = { text: char, color: colorsys.hsv2Hex(hue, 100, 100) }
|
|
||||||
hue = (hue + (360 / Math.max(message.length, 20))) % 360
|
|
||||||
return component
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.tellraw(rainbowified)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
|
@ -1,13 +0,0 @@
|
||||||
const name = 'rc'
|
|
||||||
const description = 'Resets the bot\'s command core'
|
|
||||||
const usages = []
|
|
||||||
const aliases = ['rc']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, entity, args) {
|
|
||||||
bot.core.reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,16 +0,0 @@
|
||||||
const name = 'resolve'
|
|
||||||
const description = 'Resolves a text component' // '\xa7mUseless\xa7r backwards-compatible tellraw command'
|
|
||||||
const usages = ['<component (JSON)...>']
|
|
||||||
const aliases = ['resolve']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args, handler) {
|
|
||||||
const component = JSON.parse(args.join(' ').replace(/\xa7.?/g)
|
|
||||||
const resolved = await bot.resolveComponent(component)
|
|
||||||
|
|
||||||
bot.tellraw(JSON.stringify(resolved))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,19 +0,0 @@
|
||||||
const name = 'runjson'
|
|
||||||
const description = 'Runs a command from a JSON string'
|
|
||||||
const usages = ['<command (JSON)...>']
|
|
||||||
const aliases = ['runjson']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const command = JSON.parse(args
|
|
||||||
.join(' ')
|
|
||||||
.replace(/\xa7.?/g, '')
|
|
||||||
)
|
|
||||||
if (typeof command !== 'string') throw new TypeError('command must be a string')
|
|
||||||
|
|
||||||
bot.core.run(command)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,25 +0,0 @@
|
||||||
const name = 'spawnmob'
|
|
||||||
const description = 'but better'
|
|
||||||
const usages = ['<entity> <amount> [nbt]']
|
|
||||||
const aliases = ['spawnmob']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const snbt = require('mojangson')
|
|
||||||
const nbt = require('prismarine-nbt')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
const entity = nbt.string(args.shift())
|
|
||||||
if (entity === undefined) throw new Error('Expected an entity')
|
|
||||||
const amount = parseInt(args.shift()) || 0
|
|
||||||
if (Number.isNaN(amount) || amount > 2000) throw new Error('Invalid amount')
|
|
||||||
|
|
||||||
const optionalNbt = args.length === 0 ? undefined : snbt.parse(args.join(' '))
|
|
||||||
if (optionalNbt !== undefined && optionalNbt.type !== 'compound') throw new Error('Invalid optional nbt')
|
|
||||||
|
|
||||||
const Passengers = nbt.list(nbt.comp(new Array(amount).fill(optionalNbt ? { id: entity, ...optionalNbt.value } : { id: entity })))
|
|
||||||
|
|
||||||
bot.execute(`at ${player.UUID} run summon area_effect_cloud ~ ~ ~ ${snbt.stringify(nbt.comp({ Passengers }))}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,24 +0,0 @@
|
||||||
const name = 'sudo'
|
|
||||||
const description = 'Forces a player to send a chat message'
|
|
||||||
const usages = ['<target> <command>', '<target> c:<message>']
|
|
||||||
const aliases = ['sudo']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 1
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
|
||||||
let target = args.shift()
|
|
||||||
if (!target) throw new Error('Expected a target')
|
|
||||||
|
|
||||||
let command = args.join(' ').replace(/\xa7.?/g, '')
|
|
||||||
if (!command) throw new Error('Expected a command to run')
|
|
||||||
if (command.startsWith('c:/')) command = command.substring(3)
|
|
||||||
|
|
||||||
if (bot.server.isAyunBoom && (target === '*' || target === '**')) {
|
|
||||||
// Object.values(bot.players).forEach(({ UUID }) => bot.core.run('essentials:sudo ' + UUID + ' ' + command))
|
|
||||||
// return
|
|
||||||
target = ' ' + target
|
|
||||||
}
|
|
||||||
bot.core.run('essentials:sudo ' + target + ' ' + command)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,14 +0,0 @@
|
||||||
const name = 'tellraw'
|
|
||||||
const description = 'Tellraw command' // '\xa7mUseless\xa7r backwards-compatible tellraw command'
|
|
||||||
const usages = ['<target> <component (JSON)...>']
|
|
||||||
const aliases = ['tellraw']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const target = args.shift()
|
|
||||||
bot.tellraw(JSON.parse(args.join(' ').replace(/\xa7.?/g, '')), target)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,42 +0,0 @@
|
||||||
const name = 'urban'
|
|
||||||
const description = 'Shows word definitions from the Urban Dictionary'
|
|
||||||
const usages = ['<word...>']
|
|
||||||
const aliases = ['urban']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const ud = require('urban-dictionary')
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
// Callback
|
|
||||||
ud.define(args.join(' ').replace(/§./, ''), (error, results) => {
|
|
||||||
if (error) {
|
|
||||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
|
||||||
{ text: error.message, color: bot.colors.error }
|
|
||||||
])}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const msg = [{ text: '', color: 'gray' }]
|
|
||||||
results.forEach((result) => {
|
|
||||||
msg.push({ text: '[', color: 'dark_gray' })
|
|
||||||
msg.push({ text: 'Urban', color: 'red' })
|
|
||||||
msg.push({ text: '] ', color: 'dark_gray' })
|
|
||||||
msg.push({ text: `${result.word} `, bold: true })
|
|
||||||
const a = result.definition.replace(/\r\n?/g, '\n').split(/\[|\]/)
|
|
||||||
for (let i = 0; i < a.length; i += 2) {
|
|
||||||
msg.push({ text: a[i] })
|
|
||||||
if (a[i + 1] != null) {
|
|
||||||
msg.push(
|
|
||||||
{ text: a[i + 1], underlined: true, clickEvent: { action: 'run_command', value: `${bot.prefix}${name} ${a[i + 1]}` } }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msg[msg.length - 1].text += '\n'
|
|
||||||
})
|
|
||||||
bot.tellraw(msg)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,13 +1,15 @@
|
||||||
const name = 'validate'
|
const name = 'validate'
|
||||||
const description = 'Tests trusted hash validation.'
|
const description = 'Tests trusted code validation.'
|
||||||
const usages = ['<hash>']
|
const usage = '{prefix}validate'
|
||||||
const aliases = ['validate']
|
const aliases = ['validate']
|
||||||
const enabled = true
|
const enabled = true
|
||||||
|
|
||||||
const permLevel = 1
|
const permLevel = 1
|
||||||
|
|
||||||
function execute (bot, cmd, player, args) {
|
function execute (bot, cmd, entity, args, handler) {
|
||||||
bot.tellraw({ text: 'Valid hash', color: bot.colors.primary })
|
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||||
|
{ text: 'Valid code.', color: bot.colors.primary }
|
||||||
|
])}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
|
@ -1,31 +0,0 @@
|
||||||
const name = 'vnc'
|
|
||||||
const description = 'fard'
|
|
||||||
const usages = [
|
|
||||||
'connect \xa7m<host> <port> [password]\xa7r',
|
|
||||||
'mouse <x> <y> [state]',
|
|
||||||
'update',
|
|
||||||
'end'
|
|
||||||
]
|
|
||||||
const aliases = ['vnc']
|
|
||||||
const enabled = true
|
|
||||||
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
function execute (bot, cmd, player, args, handler) {
|
|
||||||
const subCmd = args.shift().toLowerCase()
|
|
||||||
|
|
||||||
if (subCmd === 'connect') {
|
|
||||||
bot.vnc.connect({ host: 'localhost', port: 5900 })
|
|
||||||
} else if (subCmd === 'clear') {
|
|
||||||
bot.vnc.display.clearEntities()
|
|
||||||
} else if (subCmd === 'mouse') {
|
|
||||||
const [x, y, state = 1] = args.map(Number)
|
|
||||||
bot.vnc._client?.pointerEvent(x, y, state)
|
|
||||||
} else if (subCmd === 'update') {
|
|
||||||
bot.vnc._client?.requestUpdate()
|
|
||||||
} else if (subCmd === 'end') {
|
|
||||||
bot.vnc._client.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
|
@ -1,17 +0,0 @@
|
||||||
const name = 'wikipedia'
|
|
||||||
const description = 'Shows summaries of wikipedia pages'
|
|
||||||
const usages = []
|
|
||||||
const aliases = ['wikipedia', 'wiki']
|
|
||||||
const enabled = true
|
|
||||||
const permLevel = 0
|
|
||||||
|
|
||||||
const wiki = require('wikipedia')
|
|
||||||
|
|
||||||
async function execute (bot, cmd, player, args) {
|
|
||||||
const page = await wiki.page(args.join(' ').replace(/\xa7.?/g, ''))
|
|
||||||
const summary = await page.summary()
|
|
||||||
|
|
||||||
bot.tellraw(summary.extract, player.UUID)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
|
23
cperms.js
Normal file
23
cperms.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
let codes = [null, Math.random(), Math.random()]
|
||||||
|
printCodes()
|
||||||
|
|
||||||
|
function validate(level, code) {
|
||||||
|
for (let i = level; i < codes.length; i++) {
|
||||||
|
if (codes[i] === code) {
|
||||||
|
codes[i] = Math.random()
|
||||||
|
console.log(`New code for level ${i}: ${codes[i]}`)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function printCodes() {
|
||||||
|
console.log('Codes: ')
|
||||||
|
for (const i in codes) {
|
||||||
|
console.log(`Permission level ${i}: ${codes[i]}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { codes, validate, printCodes }
|
20
default.js
20
default.js
|
@ -1,20 +0,0 @@
|
||||||
module.exports = [
|
|
||||||
{
|
|
||||||
username: 'ChipmunkBot',
|
|
||||||
prefix: "'",
|
|
||||||
colors: { primary: 'green', secondary: 'dark_green', error: 'red' },
|
|
||||||
version: '1.18.2',
|
|
||||||
randomizeUsername: true,
|
|
||||||
autoReconnect: true,
|
|
||||||
autoReconnectDelay: 6000,
|
|
||||||
server: {
|
|
||||||
host: 'localhost',
|
|
||||||
port: 25565,
|
|
||||||
isBukkit: true,
|
|
||||||
isKaboom: true,
|
|
||||||
isScissors: true,
|
|
||||||
isAyunBoom: false
|
|
||||||
},
|
|
||||||
trustedKey: 'among us'
|
|
||||||
}
|
|
||||||
]
|
|
68
index.js
68
index.js
|
@ -1,62 +1,10 @@
|
||||||
const readline = require('readline')
|
|
||||||
const rl = readline.createInterface({
|
|
||||||
input: process.stdin,
|
|
||||||
output: process.stdout,
|
|
||||||
prefix: '> '
|
|
||||||
})
|
|
||||||
|
|
||||||
const createBot = require('./bot.js')
|
const createBot = require('./bot.js')
|
||||||
// const commandHandler = require('./commands.js')
|
|
||||||
|
|
||||||
const fs = require('fs/promises')
|
const bot = createBot({
|
||||||
const path = require('path')
|
host: process.argv[2] ?? 'kaboom.pw',
|
||||||
const moment = require('moment')
|
port: 25565,
|
||||||
|
username: 'fard',
|
||||||
async function exists (filepath) {
|
prefix: `'`,
|
||||||
try {
|
brand: 'kaboom',
|
||||||
await fs.access(filepath)
|
colors: { primary: 'green', secondary: 'dark_green', error: 'red' }
|
||||||
return true
|
})
|
||||||
} catch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main () {
|
|
||||||
let logPath = path.join('logs', moment().format('YYYY-MM-DD'))
|
|
||||||
if (await exists(logPath)) {
|
|
||||||
const suffixed = logPath + '-'
|
|
||||||
let i = 0
|
|
||||||
while (await exists(logPath)) {
|
|
||||||
logPath = suffixed + (i++)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await fs.writeFile(logPath, '')
|
|
||||||
|
|
||||||
const absolutePath = path.resolve('config')
|
|
||||||
let optionsArray
|
|
||||||
|
|
||||||
try {
|
|
||||||
optionsArray = require(absolutePath)
|
|
||||||
} catch {
|
|
||||||
await fs.copyFile(path.join(__dirname, 'default.js'), 'config.js')
|
|
||||||
console.info('No config file was found, so a default one was created.')
|
|
||||||
|
|
||||||
optionsArray = require(absolutePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
const bots = []
|
|
||||||
|
|
||||||
optionsArray.forEach((options, index) => {
|
|
||||||
const bot = createBot(options)
|
|
||||||
|
|
||||||
bot.getBots = () => bots
|
|
||||||
bot.on('error', console.error)
|
|
||||||
bot.console.filepath = logPath
|
|
||||||
bot.console.setRl(rl)
|
|
||||||
bot.commands.loadFromDir('commands')
|
|
||||||
|
|
||||||
bots.push(bot)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
1
launcher_accounts.json
Normal file
1
launcher_accounts.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
8378
package-lock.json
generated
8378
package-lock.json
generated
File diff suppressed because it is too large
Load diff
22
package.json
22
package.json
|
@ -1,28 +1,12 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mozilla/readability": "^0.4.1",
|
"@mozilla/readability": "^0.4.1",
|
||||||
"@skeldjs/client": "^2.15.17",
|
|
||||||
"@tonejs/midi": "^2.0.27",
|
"@tonejs/midi": "^2.0.27",
|
||||||
"axios": "^0.27.2",
|
"canvas": "^2.8.0",
|
||||||
"badwords": "^1.0.0",
|
|
||||||
"canvas": "^2.9.1",
|
|
||||||
"colorsys": "^1.0.22",
|
"colorsys": "^1.0.22",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
"kahoot.js-api": "^2.4.0",
|
"kahoot.js-api": "^2.4.0",
|
||||||
"minecraft-protocol": "^1.35.0",
|
"minecraft-protocol": "^1.30.0",
|
||||||
"mojangson": "^2.0.2",
|
"path": "^0.12.7"
|
||||||
"moment": "^2.29.1",
|
|
||||||
"namemc": "^1.8.16",
|
|
||||||
"node-fetch": "^3.2.3",
|
|
||||||
"path": "^0.12.7",
|
|
||||||
"prismarine-nbt": "^2.2.0",
|
|
||||||
"rfb2": "^0.2.2",
|
|
||||||
"standard": "^16.0.4",
|
|
||||||
"tmp": "^0.2.1",
|
|
||||||
"translate": "^1.4.1",
|
|
||||||
"urban-dictionary": "^3.0.2",
|
|
||||||
"vm2": "^3.9.9",
|
|
||||||
"wikipedia": "^1.1.9"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,19 +0,0 @@
|
||||||
// I had to make this plugin because of skids (ab)using tnt
|
|
||||||
const { states } = require('minecraft-protocol')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
bot.antiTNT = {
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
if (!bot.antiTNT.enabled || bot.state !== states.PLAY) return // do nothing if antiTNT is disabled or the bot is not logged in
|
|
||||||
|
|
||||||
bot.core.run('minecraft:gamerule mobGriefing false') // disable mobGriefing
|
|
||||||
bot.core.run('minecraft:kill @e[type=tnt]') // remove tnt entities
|
|
||||||
bot.core.run('minecraft:kill @e[type=tnt_minecart]') // remove tnt minecart entities
|
|
||||||
bot.core.run('minecraft:execute as @e[name=WeaponGrenade] run data merge entity @s {CustomName: ""}') // change grenades to normal eggs
|
|
||||||
}, 25)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,37 +0,0 @@
|
||||||
function inject (bot) {
|
|
||||||
bot.antiCB ??= false
|
|
||||||
setInterval(() => {
|
|
||||||
if (!bot.antiCB) return
|
|
||||||
let offsets
|
|
||||||
|
|
||||||
offsets = { x: randomInt(-8, 8), /* y: 0, */ z: randomInt(-8, 8) }
|
|
||||||
bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${(-3) - offsets.x} 0 ~${(-3) - offsets.z} ~${(3) - offsets.x} 255 ${3 - offsets.z} chain_command_block replace command_block', auto: 1b} destroy`)
|
|
||||||
offsets = { x: randomInt(-8, 8), /* y: 0, */ z: randomInt(-8, 8) }
|
|
||||||
bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${(-3) - offsets.x} 0 ~${(-3) - offsets.z} ~${(3) - offsets.x} 255 ${3 - offsets.z} chain_command_block replace repeating_command_block', auto: 1b} destroy`)
|
|
||||||
}, 50)
|
|
||||||
|
|
||||||
// setInterval(() => {
|
|
||||||
// if (!bot.antiCB) return
|
|
||||||
// let offsets
|
|
||||||
//
|
|
||||||
// offsets = { x: randomInt(-8, 8), /*y: 0,*/ z: randomInt(-8, 8) }
|
|
||||||
// bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${-8 - offsets.x} 0 ~${-8 - offsets.z} ~${8 - offsets.x} 112 ${8 - offsets.z} chain_command_block replace command_block', auto: 1b} destroy`)
|
|
||||||
// offsets = { x: randomInt(-8, 8), /*y: 0,*/ z: randomInt(-8, 8) }
|
|
||||||
// bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${-8 - offsets.x} 113 ~${-8 - offsets.z} ~${8 - offsets.x} 225 ${8 - offsets.z} chain_command_block replace command_block', auto: 1b} destroy`)
|
|
||||||
// offsets = { x: randomInt(-8, 8), /*y: 0,*/ z: randomInt(-8, 8) }
|
|
||||||
// bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${-8 - offsets.x} 226 ~${-8 - offsets.z} ~${8 - offsets.x} 255 ${8 - offsets.z} chain_command_block replace command_block', auto: 1b} destroy`)
|
|
||||||
//
|
|
||||||
// offsets = { x: randomInt(-8, 8), /*y: 0,*/ z: randomInt(-8, 8) }
|
|
||||||
// bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${-8 - offsets.x} 0 ~${-8 - offsets.z} ~${8 - offsets.z} 112 ${8 - offsets.z} chain_command_block replace repeating_command_block', auto: 1b} destroy`)
|
|
||||||
// offsets = { x: randomInt(-8, 8), /*y: 0,*/ z: randomInt(-8, 8) }
|
|
||||||
// bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${-8 - offsets.x} 113 ~${-8 - offsets.z} ~${8 - offsets.z} 225 ${8 - offsets.z} chain_command_block replace repeating_command_block', auto: 1b} destroy`)
|
|
||||||
// offsets = { x: randomInt(-8, 8), /*y: 0,*/ z: randomInt(-8, 8) }
|
|
||||||
// bot.core.run(`minecraft:execute at @a run setblock ~${offsets.x} 0 ~${offsets.z} command_block{Command: 'minecraft:fill ~${-8 - offsets.x} 226 ~${-8 - offsets.z} ~${8 - offsets.x} 255 ${8 - offsets.z} chain_command_block replace repeating_command_block', auto: 1b} destroy`)
|
|
||||||
// }, 50)
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomInt (min, max) {
|
|
||||||
return Math.floor((Math.random() * (max - min) + min) + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = inject
|
|
|
@ -1,31 +0,0 @@
|
||||||
const { hsv2Hex } = require('colorsys')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
bot.bruhify = {
|
|
||||||
text: '',
|
|
||||||
_format: comp => 'minecraft:title @a actionbar ' + comp
|
|
||||||
}
|
|
||||||
bot.bruhify.format = bot.bruhify._format
|
|
||||||
|
|
||||||
let startHue = 0
|
|
||||||
setInterval(() => {
|
|
||||||
const { text, format } = bot.bruhify
|
|
||||||
if (!text) return
|
|
||||||
|
|
||||||
let hue = startHue
|
|
||||||
const increment = (360 / Math.max(text.length, 20)) % 360
|
|
||||||
|
|
||||||
const _component = text
|
|
||||||
.split('')
|
|
||||||
.map(char => {
|
|
||||||
const text = { text: char, color: hsv2Hex(hue, 100, 100) }
|
|
||||||
hue = (hue + increment) % 360
|
|
||||||
return text
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.core.run(format(JSON.stringify([{ text: '▚ ', color: 'light_purple' }, ..._component, ' ▚'])))
|
|
||||||
startHue = (startHue + increment) % 360
|
|
||||||
}, 50)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,16 +0,0 @@
|
||||||
function inject (bot) {
|
|
||||||
bot.on('cspy', (player, command) => {
|
|
||||||
if (command.startsWith('/')) { command = command.slice(1) }
|
|
||||||
const args = command.split(' ')
|
|
||||||
command = args.shift()
|
|
||||||
|
|
||||||
if (command === 'cc' || command === 'clearchat' || command === 'extras:cc' || command === 'extras:clearchat') {
|
|
||||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
|
||||||
{ text: '', color: 'dark_green' },
|
|
||||||
`${player.name} cleared the chat`
|
|
||||||
])}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
|
@ -1,48 +1,44 @@
|
||||||
const { waterfowl } = require('../util/waterfowl.js')
|
const parseText = require('./../util/text_parser.js')
|
||||||
const { normalize, parseText } = require('../util/text_parser.js')
|
|
||||||
const commandSet = 'advMode.setCommand.success'
|
|
||||||
const commandSetStr = 'Command set: '
|
|
||||||
const { states } = require('minecraft-protocol')
|
|
||||||
|
|
||||||
function bot (bot) {
|
function inject (bot) {
|
||||||
bot.chat = {
|
bot.chatQueue = []
|
||||||
queue: []
|
|
||||||
}
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (bot.state !== states.PLAY) return
|
const message = bot.chatQueue.shift()
|
||||||
|
if (message != null && message.length < 256) {
|
||||||
const message = bot.chat.queue.shift()
|
bot._client.write('chat', { message })
|
||||||
if (message) bot._client.write('chat', { message: String(message) })
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
bot.on('chat', ({ message, sender, position }) => {
|
|
||||||
const waterfowlMessage = waterfowl(message, position, sender, { Extras: bot.server.isKaboom, CommandSpy: bot.server.isKaboom })
|
|
||||||
if (waterfowlMessage != null) {
|
|
||||||
bot.emit('waterfowl_message', waterfowlMessage, { message, sender, position })
|
|
||||||
bot.emit(waterfowlMessage.type, waterfowlMessage, { message, sender, position })
|
|
||||||
}
|
}
|
||||||
|
}, 200)
|
||||||
bot.emit('chat_motd', parseText(message).raw, { message, sender, position })
|
|
||||||
|
bot._client.on('chat', (packet) => {
|
||||||
|
const message = parseText(packet.message)
|
||||||
|
bot.emit('chat', message, packet)
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.on('chat_motd', (message, { sender }) => {
|
bot.on('chat', (message, data) => {
|
||||||
bot.console.log(`[${bot.server.host}] ${message.replace(/\n+/g, '\n')}`)
|
console.log(message.ansi)
|
||||||
|
|
||||||
|
let msg = message.raw;
|
||||||
|
if (msg.match(/<.*§r> .*/g)) {
|
||||||
|
if (data.sender === '00000000-0000-0000-0000-000000000000') return
|
||||||
|
let username = bot.uuidMap[data.sender]//msg.substr(3).split('§r>')[0]
|
||||||
|
let message = msg.split('§r> §r')[1]
|
||||||
|
bot.emit("message", { username: username, uuid: data.sender }, message)
|
||||||
|
} else if (msg.match(/<.*> .*/g)) {
|
||||||
|
if (data.sender === '00000000-0000-0000-0000-000000000000') return
|
||||||
|
let username = bot.uuidMap[data.sender]//msg.substr(3).split(">")[0]
|
||||||
|
let message = msg.split('> ')[1]
|
||||||
|
bot.emit("message", { username: username, uuid: data.sender }, message)
|
||||||
|
} else if (msg.match(/.* .*§r: §.*/g)) {
|
||||||
|
if(data.sender === '00000000-0000-0000-0000-000000000000') return;
|
||||||
|
let username = bot.uuidMap[data.sender]//msg.split(' ')[1].split("§r:")[0]
|
||||||
|
let message = msg.split('§r: ')[1].substr(2)
|
||||||
|
bot.emit("message", { username: username, uuid: data.sender }, message)
|
||||||
|
} else if (msg.match(/§.*§b: \/.*/g)) {
|
||||||
|
let username = msg.split('§b: ')[0]
|
||||||
|
let command = msg.split('§b: ')[1]
|
||||||
|
bot.emit("cspy", username, command)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function client (bot) {
|
module.exports = inject
|
||||||
bot._client.on('chat', ({ message, sender, position }) => {
|
|
||||||
message = JSON.parse(message)
|
|
||||||
if (isCommandSet(message)) return
|
|
||||||
|
|
||||||
bot.emit(position === 2 ? 'actionbar' : 'chat', { message, sender, position })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function isCommandSet (message) {
|
|
||||||
message = normalize(message)
|
|
||||||
let firstExtra = message?.extra?.length ? message?.extra[0] : {}
|
|
||||||
return (message?.translate === commandSet || firstExtra?.translate === commandSet || message?.text === commandSetStr || firstExtra?.text === commandSetStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot, client }
|
|
|
@ -1,27 +0,0 @@
|
||||||
const { Canvas } = require('canvas')
|
|
||||||
const convertImageData = require('../util/image_data_converter.js')
|
|
||||||
const { states } = require('minecraft-protocol')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
const canvas = new Canvas(320, 20)
|
|
||||||
bot.chatCanvas = canvas
|
|
||||||
|
|
||||||
const _renderCtx = canvas.getContext('2d')
|
|
||||||
canvas.render = function render (options = {}) {
|
|
||||||
const { data } = _renderCtx.getImageData(0, 0, canvas.width, canvas.height)
|
|
||||||
const components = convertImageData(data, canvas.width, options)
|
|
||||||
|
|
||||||
components.forEach(c => bot.tellrawJSON(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.renderOnTick = false
|
|
||||||
setInterval(() => {
|
|
||||||
if (!canvas.renderOnTick || bot.state !== states.PLAY) return
|
|
||||||
canvas.render()
|
|
||||||
}, 50)
|
|
||||||
bot.on('chat_motd', (motd, { position }) => {
|
|
||||||
if (!canvas.renderOnTick || position !== 0) return
|
|
||||||
bot.core.run('minecraft:title @a actionbar ' + JSON.stringify(motd))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,50 +0,0 @@
|
||||||
const nbt = require('prismarine-nbt')
|
|
||||||
const filter = require('badwords/regexp')
|
|
||||||
|
|
||||||
// filter the chat
|
|
||||||
function inject (bot) {
|
|
||||||
bot.chatFilter = {
|
|
||||||
enabled: false,
|
|
||||||
_lines: [],
|
|
||||||
_filter
|
|
||||||
}
|
|
||||||
bot.on('chat_motd', (motd) => {
|
|
||||||
const filtered = _filter(motd)
|
|
||||||
bot.chatFilter._lines = [...bot.chatFilter._lines, ...filtered.split('\n')]
|
|
||||||
while (bot.chatFilter._lines.length > 99) {
|
|
||||||
bot.chatFilter._lines.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (motd !== filtered) {
|
|
||||||
bot._client.write('set_creative_slot', {
|
|
||||||
slot: 36,
|
|
||||||
item: {
|
|
||||||
present: true,
|
|
||||||
itemId: 1,
|
|
||||||
itemCount: 1,
|
|
||||||
nbtData: nbt.comp({
|
|
||||||
'': nbt.string('\xa7r' + bot.chatFilter._lines.join('\xa7r\n'))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (bot.server.isScissors) {
|
|
||||||
const storage = Math.random().toString()
|
|
||||||
bot.core.run('minecraft:data modify storage ' + storage + ' "" set from entity ' + bot._client.uuid + ' Inventory[0].tag.""')
|
|
||||||
bot.tellraw({ nbt: '""', storage }, '@a[tag=chatfilter]')
|
|
||||||
bot.core.run('minecraft:data remove storage ' + storage + ' i')
|
|
||||||
} else bot.tellraw({ nbt: 'Inventory[0].tag.""', entity: bot._client.uuid }, '@a[tag=chatfilter]')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function _filter (message) {
|
|
||||||
let filtered = message
|
|
||||||
filtered = filtered.replace(filter, mogus)
|
|
||||||
return filtered
|
|
||||||
}
|
|
||||||
|
|
||||||
function mogus (match) {
|
|
||||||
return new Array(match.length).fill('\u0d9e').join('')
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
|
@ -1,17 +0,0 @@
|
||||||
function inject (bot) {
|
|
||||||
bot.cloops = []
|
|
||||||
setInterval(() => {
|
|
||||||
bot.cloops.forEach((cloop, i) => {
|
|
||||||
if (!cloop._looping) loop(i)
|
|
||||||
})
|
|
||||||
}, 1)
|
|
||||||
function loop (i) {
|
|
||||||
if (bot.cloops[i] == null) { return }
|
|
||||||
|
|
||||||
bot.cloops[i]._looping = true
|
|
||||||
bot.core.run(bot.cloops[i].command)
|
|
||||||
setTimeout(() => loop(i), bot.cloops[i].interval)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
|
@ -1,133 +1,19 @@
|
||||||
const fs = require('fs')
|
const handler = require('../commands.js')
|
||||||
const path = require('path')
|
|
||||||
const { inspect } = require('util')
|
|
||||||
const { parseText } = require('../util/text_parser.js')
|
|
||||||
const { getHash } = require('../util/cval.js')
|
|
||||||
|
|
||||||
const sectionRegex = /\xa7.?/g
|
function inject (bot) {
|
||||||
|
handler.load()
|
||||||
function inject (bot, options) {
|
|
||||||
bot.commands = {
|
bot.on('message', (entity, message) => {
|
||||||
commands: {},
|
if (!message.startsWith(bot.prefix))
|
||||||
add,
|
|
||||||
execute,
|
|
||||||
info,
|
|
||||||
isCommand,
|
|
||||||
loadFromDir,
|
|
||||||
isValid
|
|
||||||
}
|
|
||||||
const listener = ({ message }, { sender }) => {
|
|
||||||
message = parseText(message).raw // fard
|
|
||||||
const player = bot.players[sender]
|
|
||||||
|
|
||||||
if (!message.startsWith(bot.prefix)) return
|
|
||||||
|
|
||||||
const args = message.slice(bot.prefix.length).trim().split(' ')
|
|
||||||
const command = args.shift().toLowerCase()
|
|
||||||
|
|
||||||
if (!isCommand(command)) {
|
|
||||||
bot.tellraw({ text: `Unknown command: ${bot.prefix}${command}`, color: bot.colors.error })
|
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
const args = message.slice(bot.prefix.length).split(' ')
|
||||||
if (args[args.length - 1]?.endsWith('\\')) {
|
const command = args.shift()
|
||||||
bot.tellraw({ text: 'This will be added... idk when.' })
|
if (!handler.isCommand(command))
|
||||||
return
|
return bot.core.run(`bcraw &cUnknown command: ${bot.prefix}${command}`)
|
||||||
}
|
|
||||||
|
|
||||||
const { permLevel } = bot.commands.info(command)
|
|
||||||
if (permLevel) {
|
|
||||||
if (args.length === 0) {
|
|
||||||
bot.tellraw({ text: 'Expected a hash', color: bot.colors.error })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO: Don't use a bad argument parser
|
|
||||||
const commandHashLength = message.charCodeAt(message.length - 2) * 2
|
|
||||||
if (commandHashLength >= message.length) {
|
|
||||||
bot.tellraw({ text: `Length of the hash (${commandHashLength}) is longer than the message's length (${message.length})`, color: bot.colors.error })
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
handler.execute(bot, command, entity, args)
|
||||||
const originalCommand = message.substring(0, message.length - commandHashLength - 4)
|
})
|
||||||
let commandHash = ''
|
|
||||||
for (let i = message.length - commandHashLength - 2; i < message.length - 3; i += 2) {console.log(i, message[i])
|
|
||||||
if (message[i - 1] !== '\xa7') {
|
|
||||||
bot.tellraw(`Expected an escape character at ${i - 1}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
commandHash += message[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = getHash(originalCommand, player.UUID, options.trustedKey)
|
|
||||||
|
|
||||||
console.log({ message, commandHash, commandHashLength, hash, originalCommand })
|
|
||||||
|
|
||||||
if (commandHash !== hash) {
|
|
||||||
bot.tellraw({ text: 'Invalid hash', color: bot.colors.error })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
args.splice(-1, hash.split(' ').length) // TODO: Make this less bad
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.commands.execute(bot, command, player, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.on('emote', listener)
|
|
||||||
bot.on('whisper', listener)
|
|
||||||
bot.on('announcement', listener)
|
|
||||||
|
|
||||||
function add (command) {
|
|
||||||
if (!isValid(command)) throw new Error('Invalid command', 'invalid_command')
|
|
||||||
command.aliases.forEach(alias => (bot.commands.commands[alias.toLowerCase()] = command))
|
|
||||||
}
|
|
||||||
function loadFromDir (dirpath) {
|
|
||||||
fs.readdirSync(dirpath).forEach(filename => {
|
|
||||||
const filepath = path.resolve(dirpath, filename)
|
|
||||||
if (!filepath.endsWith('js') || !fs.statSync(filepath).isFile()) return // TODO: Use require.extensions
|
|
||||||
try {
|
|
||||||
bot.commands.add(require(filepath))
|
|
||||||
} catch (err) {
|
|
||||||
bot.console.error('Error loading command ' + filepath + ': ' + inspect(err))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function info (command) {
|
|
||||||
const info = bot.commands.commands[command] ?? command
|
|
||||||
if (isValid(info)) return info
|
|
||||||
}
|
|
||||||
function isCommand (command) { return bot.commands.info(command) != null }
|
|
||||||
async function execute (bot, command, player, args, ...custom) {
|
|
||||||
const info = bot.commands.info(command)
|
|
||||||
if (info == null) {
|
|
||||||
bot.tellraw({ text: 'Unknown command: ' + bot.prefix + command, color: bot.colors.error })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!info.enabled) {
|
|
||||||
bot.tellraw({ text: bot.prefix + command + ' is disabled', color: bot.colors.error })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
return await info.execute(bot, command, player, args, ...custom)
|
|
||||||
} catch (err) {
|
|
||||||
bot.console.error('Error executing command ' + command + ': ' + inspect(err))
|
|
||||||
bot.tellraw({ text: err?.name + ': ' + err?.message, color: bot.colors.error })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValid (command) {
|
module.exports = inject
|
||||||
return command != null &&
|
|
||||||
typeof command.execute === 'function' &&
|
|
||||||
typeof command.name === 'string' &&
|
|
||||||
typeof command.description === 'string' &&
|
|
||||||
Array.isArray(command.usages) &&
|
|
||||||
Array.isArray(command.aliases) &&
|
|
||||||
typeof command.enabled === 'boolean' &&
|
|
||||||
command.aliases.length > 0 &&
|
|
||||||
typeof command.permLevel === 'number'
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
|
@ -1,35 +0,0 @@
|
||||||
const parseString = require('../util/bukkit_chat_parse.js')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
const players = []
|
|
||||||
|
|
||||||
bot.on('player_added', player => {
|
|
||||||
const existing = players.findIndex(e => e.player.UUID === player.UUID)
|
|
||||||
if (existing !== -1) players.splice(existing, 1)
|
|
||||||
|
|
||||||
players.push({
|
|
||||||
player,
|
|
||||||
components: [
|
|
||||||
...parseString(`\xa7b${player.name}\xa7b: /`, true, false),
|
|
||||||
...parseString(`\xa7e${player.name}\xa7e: /`, true, false)
|
|
||||||
]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('chat', ({ message, sender }) => {
|
|
||||||
if (sender !== '00000000-0000-0000-0000-000000000000' || typeof message !== 'object') return
|
|
||||||
|
|
||||||
for (const { player, components } of players) {
|
|
||||||
for (const component of components) {
|
|
||||||
/* const command = parseCommandSpy(message, component)
|
|
||||||
if (command != null) {
|
|
||||||
bot.emit('commandspy', player, command)
|
|
||||||
bot.core.run('minecraft:say ' + player.name + ' ran ' + command)
|
|
||||||
return
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,96 +0,0 @@
|
||||||
const fs = require('fs')
|
|
||||||
const util = require('util')
|
|
||||||
const moment = require('moment')
|
|
||||||
const ansimap = {
|
|
||||||
0: '\x1b[0m\x1b[30m',
|
|
||||||
1: '\x1b[0m\x1b[34m',
|
|
||||||
2: '\x1b[0m\x1b[32m',
|
|
||||||
3: '\x1b[0m\x1b[36m',
|
|
||||||
4: '\x1b[0m\x1b[31m',
|
|
||||||
5: '\x1b[0m\x1b[35m',
|
|
||||||
6: '\x1b[0m\x1b[33m',
|
|
||||||
7: '\x1b[0m\x1b[37m',
|
|
||||||
8: '\x1b[0m\x1b[90m',
|
|
||||||
9: '\x1b[0m\x1b[94m',
|
|
||||||
a: '\x1b[0m\x1b[92m',
|
|
||||||
b: '\x1b[0m\x1b[96m',
|
|
||||||
c: '\x1b[0m\x1b[91m',
|
|
||||||
d: '\x1b[0m\x1b[95m',
|
|
||||||
e: '\x1b[0m\x1b[93m',
|
|
||||||
f: '\x1b[0m\x1b[97m',
|
|
||||||
r: '\x1b[0m',
|
|
||||||
l: '\x1b[1m',
|
|
||||||
o: '\x1b[3m',
|
|
||||||
n: '\x1b[4m',
|
|
||||||
m: '\x1b[9m',
|
|
||||||
k: '\x1b[6m'
|
|
||||||
}
|
|
||||||
|
|
||||||
function inject (bot) {
|
|
||||||
bot.console = {
|
|
||||||
filepath: null,
|
|
||||||
host: 'all',
|
|
||||||
log,
|
|
||||||
warn,
|
|
||||||
error,
|
|
||||||
_log,
|
|
||||||
setRl,
|
|
||||||
_rl: null
|
|
||||||
}
|
|
||||||
function log (data) {
|
|
||||||
_log('\u00a72INFO', process.stdout, data)
|
|
||||||
}
|
|
||||||
function warn (data) {
|
|
||||||
_log('\u00a7eWARN', process.stderr, data)
|
|
||||||
}
|
|
||||||
function error (data) {
|
|
||||||
_log('\u00a7cERROR', process.stderr, data)
|
|
||||||
}
|
|
||||||
function _log (prefix, stdout, data) {
|
|
||||||
// format it
|
|
||||||
data = `[${moment().format('HH:mm:ss')} ${prefix}\u00a7r] ${data}\n`
|
|
||||||
|
|
||||||
// log to file
|
|
||||||
const filepath = bot.console.filepath
|
|
||||||
if (filepath != null) {
|
|
||||||
fs.appendFile(filepath, data, err => {
|
|
||||||
if (err) console.error(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// log to stdout
|
|
||||||
data = data.replace(/\u00a7.?/g, m => ansimap[m.slice(1)] ?? '') + '\x1b[0m'
|
|
||||||
stdout.write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
function setRl (rl) {
|
|
||||||
rl?.prompt(true)
|
|
||||||
rl?.on('line', handleLine)
|
|
||||||
// bot.console._rl?.removeListener('line', handleLine)
|
|
||||||
bot.console._rl = rl
|
|
||||||
|
|
||||||
async function handleLine (line) {
|
|
||||||
if (bot.server.host !== bot.console.host && bot.console.host !== 'all') return
|
|
||||||
if (line.startsWith('.')) {
|
|
||||||
const args = line.slice(1).trim().split(' ')
|
|
||||||
const command = args.shift()
|
|
||||||
|
|
||||||
if (!bot.commands.isCommand(command)) {
|
|
||||||
bot.console.error('Unknown command: ' + command)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const info = bot.commands.info(command)
|
|
||||||
try {
|
|
||||||
await info.execute(bot, command, bot.players[bot.uuid], args)
|
|
||||||
} catch (err) {
|
|
||||||
bot.console.error(`Error executing ${command} in console: ${util.inspect(err)}`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bot.fancyMsg(bot._client.username + ' Console', '_ChipMC_', line)
|
|
||||||
rl?.prompt(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
116
plugins/core.js
116
plugins/core.js
|
@ -1,89 +1,41 @@
|
||||||
const { states } = require('minecraft-protocol')
|
function inject (bot) {
|
||||||
const nbt = require('prismarine-nbt')
|
const core = {}
|
||||||
const mcNamespace = 'minecraft:'
|
|
||||||
|
core.pos = { x: 0, y: null, z: null }
|
||||||
function bot (bot) {
|
core.size = { fromX: -8, fromY: 0, fromZ: -8, toX: 8, toY: 0, toZ: 8 }
|
||||||
let mcData = require('minecraft-data')('1.17.1')
|
core.block = { x: core.size.fromX, y: core.size.fromY, z: core.size.fromZ }
|
||||||
bot.on('login', () => (mcData = require('minecraft-data')(bot._client.version)))
|
core.refill = () => {
|
||||||
|
core.pos = { x: Math.round(bot.position.x), y: 0, z: Math.round(bot.position.z) }
|
||||||
bot.core = {
|
core.block = { x: core.size.fromX, y: core.size.fromY, z: core.size.fromZ }
|
||||||
size: { from: { x: -8, y: 0, z: -8 }, to: { x: 8, y: 0, z: 8 } },
|
bot.chatQueue.push(`/fill ${core.pos.x + core.size.fromX} ${core.pos.y + core.size.fromY} ${core.pos.z + core.size.fromZ} ${core.pos.x + core.size.toX} ${core.pos.y + core.size.toY} ${core.size.toZ + core.pos.z} repeating_command_block replace`)
|
||||||
|
}
|
||||||
from: { x: null, y: null, z: null },
|
core.run = command => {
|
||||||
to: { x: null, y: null, z: null },
|
core.block.x++
|
||||||
|
if (core.block.x > core.size.toX) {
|
||||||
block: { x: null, y: null, z: null },
|
core.block.x = core.size.fromX;
|
||||||
|
core.block.z++
|
||||||
refill () {
|
if (core.block.z > core.size.toZ) {
|
||||||
const refillCommand = `/fill ${this.from.x} ${this.from.y} ${this.from.z} ${this.to.x} ${this.to.y} ${this.to.z} repeating_command_block{CustomName:'""'}`
|
core.block.z = core.size.fromZ
|
||||||
const location = { x: Math.floor(bot.position.x), y: Math.floor(bot.position.y) - 1, z: Math.floor(bot.position.z) }
|
core.block.y++
|
||||||
const commandBlockId = mcData?.itemsByName.command_block.id
|
if (core.block.y > core.size.toY) {
|
||||||
|
core.block.x = core.size.fromX
|
||||||
bot._client.write('set_creative_slot', {
|
core.block.y = core.size.fromY
|
||||||
slot: 36,
|
core.block.z = core.size.fromZ
|
||||||
item: {
|
|
||||||
present: true,
|
|
||||||
itemId: commandBlockId,
|
|
||||||
itemCount: 1,
|
|
||||||
nbtData: nbt.comp({
|
|
||||||
BlockEntityTag: nbt.comp({
|
|
||||||
auto: nbt.byte(1),
|
|
||||||
Command: nbt.string(refillCommand)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
bot._client.write('block_dig', {
|
|
||||||
status: 0,
|
|
||||||
location,
|
|
||||||
face: 1
|
|
||||||
})
|
|
||||||
|
|
||||||
bot._client.write('block_place', {
|
|
||||||
location,
|
|
||||||
direction: 1,
|
|
||||||
hand: 0,
|
|
||||||
cursorX: 0.5,
|
|
||||||
cursorY: 0.5,
|
|
||||||
cursorZ: 0.5,
|
|
||||||
insideBlock: false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
run (command) {
|
|
||||||
if (bot.state !== states.PLAY) return
|
|
||||||
if (!bot.server.isBukkit && command.startsWith(mcNamespace)) command = command.substring(mcNamespace.length)
|
|
||||||
|
|
||||||
if (!bot.isKaboom) bot._client.write('update_command_block', { location: this.block, command: '', mode: 0, flags: 0b000 })
|
|
||||||
bot._client.write('update_command_block', { location: this.block, command: String(command).substring(0, 32767), mode: bot.server.isKaboom ? 1 : 2, flags: 0b100 })
|
|
||||||
|
|
||||||
this.block.x++
|
|
||||||
if (this.block.x > this.to.x) {
|
|
||||||
this.block.x = this.from.x
|
|
||||||
this.block.z++
|
|
||||||
if (this.block.z > this.to.z) {
|
|
||||||
this.block.z = this.from.z
|
|
||||||
this.block.y++
|
|
||||||
if (this.block.y > this.to.y) {
|
|
||||||
this.block.x = this.from.x
|
|
||||||
this.block.y = this.from.y
|
|
||||||
this.block.z = this.from.z
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
reset () {
|
|
||||||
this.from = { x: Math.floor(this.size.from.x + bot.position.x), y: 0, z: Math.floor(this.size.from.z + bot.position.z) }
|
|
||||||
this.to = { x: Math.floor(this.size.to.x + bot.position.x), y: Math.floor(this.size.to.y), z: Math.floor(this.size.to.z + bot.position.z) }
|
|
||||||
this.block = { ...this.from }
|
|
||||||
this.refill()
|
|
||||||
}
|
}
|
||||||
|
bot._client.write('update_command_block', {
|
||||||
|
location: {
|
||||||
|
x: core.pos.x + core.block.x,
|
||||||
|
y: core.pos.y + core.block.y,
|
||||||
|
z: core.pos.z + core.block.z
|
||||||
|
}, command: command, mode: 1, flags: 0b100 })
|
||||||
}
|
}
|
||||||
bot.on('move', oldPos => {
|
|
||||||
bot.core.run(`minecraft:setblock ${Math.floor(oldPos.x)} ${Math.floor(oldPos.y - 1)} ${Math.floor(oldPos.z)} minecraft:air replace mincecraft:command:block`) // Clean up after refills
|
bot.core = core
|
||||||
bot.core.reset()
|
bot._client.once('position', () => {
|
||||||
|
bot.core.refill()
|
||||||
})
|
})
|
||||||
setInterval(() => bot.core.refill(), 60 * 1000)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { bot }
|
module.exports = inject
|
|
@ -1 +0,0 @@
|
||||||
module.exports = require('./eval/plugin.js')
|
|
|
@ -1,45 +0,0 @@
|
||||||
const {
|
|
||||||
Worker,
|
|
||||||
// isMainThread,
|
|
||||||
parentPort,
|
|
||||||
workerData
|
|
||||||
} = require('worker_threads')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
bot.eval = function (code, options = {}) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const listener = ({ action, data }) => {
|
|
||||||
if (action === 'resolve') resolve(data)
|
|
||||||
else if (action === 'reject') reject(data)
|
|
||||||
else return
|
|
||||||
|
|
||||||
bot.eval._worker.removeListener('message', listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.eval._worker.on('message', listener)
|
|
||||||
bot.eval._worker.postMessage({ action: 'eval', data: { code, ...options } })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function stdoutListener (data) { bot.tellraw({ text: String(data) }) } // TODO: Make it less broken
|
|
||||||
|
|
||||||
function exitListener (exitCode) {
|
|
||||||
if (bot.loggedIn) bot.tellraw([{ text: 'Eval worker exited with code ', color: bot.colors.primary }, { text: exitCode, color: bot.colors.secondary }])
|
|
||||||
|
|
||||||
bot.eval._worker = new Worker(require.resolve('./worker.js'), {
|
|
||||||
env: { among: 'us' }
|
|
||||||
})
|
|
||||||
const worker = bot.eval._worker
|
|
||||||
|
|
||||||
worker.on('message', ({ action, data }) => {
|
|
||||||
if (action === 'run') bot.core.run(data)
|
|
||||||
})
|
|
||||||
worker.stdout.on('data', stdoutListener)
|
|
||||||
worker.stderr.on('data', stdoutListener)
|
|
||||||
worker.on('error', console.error)
|
|
||||||
worker.on('exit', exitListener)
|
|
||||||
}
|
|
||||||
exitListener(-69)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,7 +0,0 @@
|
||||||
const { Module } = require('../util/module.js')
|
|
||||||
|
|
||||||
function inject () {
|
|
||||||
global.module = new Module('<eval>')
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = inject
|
|
|
@ -1,12 +0,0 @@
|
||||||
const _process = require('process')
|
|
||||||
const Process = _process.constructor
|
|
||||||
|
|
||||||
function inject () {
|
|
||||||
const process = new Process()
|
|
||||||
global.process = process
|
|
||||||
|
|
||||||
process.exit = _process.exit
|
|
||||||
process.nextTick = _process.nextTick
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = inject
|
|
|
@ -1,42 +0,0 @@
|
||||||
const path = require('path/posix')
|
|
||||||
|
|
||||||
const _fs = {}
|
|
||||||
|
|
||||||
class SymbolicLink {
|
|
||||||
constructor (filepath = '/') {
|
|
||||||
this.filepath = filepath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _parse (filepath) {
|
|
||||||
const { root, dir, base, ext } = path.parse(filepath)
|
|
||||||
if (root === '') return _parse(path.join('/', filepath))
|
|
||||||
|
|
||||||
let _dir = _fs
|
|
||||||
for (const key of dir.split(path.sep)) {
|
|
||||||
if (_dir[key] == null) throw new Error('no such file or directory, open ' + filepath, 'ENOENT')
|
|
||||||
_dir = _dir[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
return { dir: _dir, filename: base + ext }
|
|
||||||
}
|
|
||||||
|
|
||||||
function existsSync (filepath) {
|
|
||||||
const { dir, filename } = _parse(filepath)
|
|
||||||
return dir[filename] == null
|
|
||||||
}
|
|
||||||
|
|
||||||
function statSync (filepath) {
|
|
||||||
const stats = new fs.Stats()
|
|
||||||
}
|
|
||||||
|
|
||||||
function readFileSync (filepath, options) {
|
|
||||||
const { dir, filename } = _parse(filepath)
|
|
||||||
if (dir[filename] == null) throw new Error('ENOENT: no such file or directory, open ' + filepath, 'ENOENT')
|
|
||||||
|
|
||||||
return dir[filename]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
functi
|
|
|
@ -1,32 +0,0 @@
|
||||||
const _Module = require('module')
|
|
||||||
|
|
||||||
const _builtinModules = {
|
|
||||||
aasert: require('assert'),
|
|
||||||
buffer: require('buffer'),
|
|
||||||
console: require('console'),
|
|
||||||
crypto: require('crypto'),
|
|
||||||
events: require('events'),
|
|
||||||
vm: require('vm'),
|
|
||||||
|
|
||||||
'minecraft-protocol': require('minecraft-protocol')
|
|
||||||
}
|
|
||||||
|
|
||||||
class Module {
|
|
||||||
id = ''
|
|
||||||
path = '.'
|
|
||||||
exports = {}
|
|
||||||
filename = null
|
|
||||||
loaded = false
|
|
||||||
children = []
|
|
||||||
|
|
||||||
constructor (path) {
|
|
||||||
this.id = path
|
|
||||||
}
|
|
||||||
|
|
||||||
require (filepath) {
|
|
||||||
if (filepath in _builtinModules) return _builtinModules[filepath]
|
|
||||||
throw new Error('i will add that whenever i finish the fake fs')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { Module, _builtinModules }
|
|
|
@ -1,31 +0,0 @@
|
||||||
const { parentPort } = require('worker_threads')
|
|
||||||
|
|
||||||
const { runInThisContext, Module } = require('vm')
|
|
||||||
const { inspect } = require('util')
|
|
||||||
const path = require('path')
|
|
||||||
const { stylizeWithColor } = require('../../util/stylize_with_color.js')
|
|
||||||
|
|
||||||
const plugins = {
|
|
||||||
process: require('./plugins/process.js'),
|
|
||||||
cjs: require('./plugins/cjs.js')
|
|
||||||
}
|
|
||||||
|
|
||||||
process = null
|
|
||||||
|
|
||||||
parentPort.on('message', ({ action, data }) => {
|
|
||||||
if (action === 'eval') {
|
|
||||||
try {
|
|
||||||
let result = runInThisContext(data.code, { filename: 'this is totally a real file' })
|
|
||||||
result = data.inspect ? inspect(result, { stylize: stylizeWithColor }) : result
|
|
||||||
|
|
||||||
parentPort.postMessage({ action: 'resolve', data: result })
|
|
||||||
} catch (err) {
|
|
||||||
err = data.inspect ? inspect(err, { stylize: stylizeWithColor }) : err
|
|
||||||
|
|
||||||
parentPort.postMessage({ action: 'reject', data: err })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// plugin injection
|
|
||||||
Object.values(plugins).forEach(inject => inject())
|
|
|
@ -1,23 +0,0 @@
|
||||||
const nbt = require('prismarine-nbt')
|
|
||||||
const snbt = require('mojangson')
|
|
||||||
const toNBTUUID = require('../util/uuid-to-nbt-uuid.js')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
function execute (command) {
|
|
||||||
bot.core.run(`minecraft:execute ${bot.server.isKaboom ? 'unless entity @s[name= run ] ' : ''}${command}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
function kick (target) {
|
|
||||||
if (/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/.test(target)) {
|
|
||||||
target = `@p[nbt=${snbt.stringify(nbt.comp({ UUID: toNBTUUID(target) }))}]`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bot.server.isKaboom) bot.core.run(`minecraft:item replace entity ${target} container.9 with stone{i:"\xa74${'\u0d9e'.repeat(30000)}\xa7r"}`)
|
|
||||||
else bot.core.run('minecraft:kick ' + target)
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.execute = execute
|
|
||||||
bot.kick = kick
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,18 +0,0 @@
|
||||||
/* function bot (bot) {
|
|
||||||
function fakeKaboomMessage (
|
|
||||||
prefix = []
|
|
||||||
) {
|
|
||||||
bot.tellraw({
|
|
||||||
extra: [
|
|
||||||
{ bold: true, color: 'dark_red', text: '['}, { bold: true, color: 'red', text: 'OP'}, {"bold":true,"color":"dark_red","text":"] "},
|
|
||||||
{"color":"red","text":"Enderman"},{"text":": "},
|
|
||||||
{"text":"why do u look like a headchog"}
|
|
||||||
],
|
|
||||||
text: ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.fakeKaboomMessage = fakeKaboomMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot } */
|
|
|
@ -1,15 +0,0 @@
|
||||||
function inject (bot) {
|
|
||||||
bot.fancyMsg = function (rank, username, message) {
|
|
||||||
bot.tellraw([
|
|
||||||
{ text: '', color: 'gray' },
|
|
||||||
{ text: '[', color: 'dark_gray' },
|
|
||||||
rank,
|
|
||||||
{ text: '] ', color: 'dark_gray' },
|
|
||||||
{ text: username, color: bot.colors.secondary },
|
|
||||||
{ text: ' › ', color: 'dark_gray' },
|
|
||||||
message
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
|
@ -1,14 +0,0 @@
|
||||||
const fs = require('fs')
|
|
||||||
|
|
||||||
function inject (bot) {
|
|
||||||
bot.runFunction = function (filepath) {
|
|
||||||
const commands = fs.readFileSync(filepath).toString().replace(/\r\n?/g, '\n').split('\n')
|
|
||||||
let i = 0
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
if (!commands[i]?.startsWith('#')) { bot.exploits.execute('run ' + commands[i]) }
|
|
||||||
if (++i > commands.length) { clearInterval(interval) }
|
|
||||||
}, 50)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = inject
|
|
|
@ -1,24 +0,0 @@
|
||||||
function bot (bot) {
|
|
||||||
function setInventorySlot (slot, item) {
|
|
||||||
bot._client.write('set_creative_slot', { slot, item })
|
|
||||||
}
|
|
||||||
bot.setInventorySlot = setInventorySlot
|
|
||||||
}
|
|
||||||
|
|
||||||
function client (bot) {
|
|
||||||
bot.inventory = new Array(46).fill({ present: false })
|
|
||||||
// TODO: Hotbar slots
|
|
||||||
|
|
||||||
bot._client.on('set_slot', ({ windowId, slot, item }) => {
|
|
||||||
if (windowId !== 0) return // Ignore non-inventory set_slot packets
|
|
||||||
|
|
||||||
bot.inventory[slot] = { ...defaultItem, ...clean(item) } // set the slot
|
|
||||||
})
|
|
||||||
bot._client.on('window_items', ({ windowId, items }) => {
|
|
||||||
if (windowId !== 0) return // Ignore non-inventory window_items packets
|
|
||||||
|
|
||||||
items.forEach((item, slot) => {
|
|
||||||
bot.inventory[slot] = { ...defaultItem, ...clean(item) } // set the slot
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
const Kahoot = require('kahoot.js-api')
|
|
||||||
|
|
||||||
const questionColors = ['red', 'aqua', 'yellow', 'green']
|
|
||||||
const questionSymbols = ['▲', '♦', '●', '■']
|
|
||||||
|
|
||||||
function inject (bot) {
|
|
||||||
const answerError = () => bot.core.run(`minecraft:tellraw @a ${kahootErrMsg('You cannot currently answer.')}`)
|
|
||||||
bot.kahoot ??= {}
|
|
||||||
bot.kahoot.playing ??= false
|
|
||||||
bot.kahoot.answer ??= answerError
|
|
||||||
bot.kahoot.client ??= new Kahoot()
|
|
||||||
bot.kahoot.leave = () => {
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg('Leaving...')}`)
|
|
||||||
bot.kahoot.client?.leave()
|
|
||||||
bot.kahoot.playing = false
|
|
||||||
}
|
|
||||||
bot.kahoot.join = function (pin, username = 'Player') {
|
|
||||||
if (bot.kahoot.playing) {
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootErrMsg('The bot is already playing kahoot.')}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bot.kahoot.playing = true
|
|
||||||
|
|
||||||
bot.kahoot.client = new Kahoot()
|
|
||||||
bot.kahoot.client.join(pin, username).catch((err) => {
|
|
||||||
bot.kahoot.playing = false
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootErrMsg(err.description)}`)
|
|
||||||
})
|
|
||||||
bot.kahoot.client.on('Joined', () =>
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg('Successfully joined the kahoot.')}`)
|
|
||||||
)
|
|
||||||
bot.kahoot.client.on('QuizStart', () =>
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg('The quiz has started.')}`)
|
|
||||||
)
|
|
||||||
bot.kahoot.client.on('QuestionReady', (question) =>
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg(`A ${question.type} question will start in ${question.timeLeft} seconds.`)}`)
|
|
||||||
)
|
|
||||||
bot.kahoot.client.on('QuestionStart', (question) => {
|
|
||||||
bot.kahoot.answer = (answer) => {
|
|
||||||
question.answer(answer)
|
|
||||||
bot.kahoot.answer = answerError
|
|
||||||
}
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg(`A ${question.type} question has started (Time Left: ${question.timeLeft / 1000} seconds).`)}`)
|
|
||||||
const answersMsg = ['']
|
|
||||||
for (let i = 0; i < question.numberOfChoices; i++) {
|
|
||||||
answersMsg.push({ text: '[', color: questionColors[i], clickEvent: { action: 'run_command', value: `${bot.prefix}kahoot answer ${i}` }, hoverEvent: { action: 'show_text', value: 'Click to answer' } })
|
|
||||||
answersMsg.push({ text: questionSymbols[i], clickEvent: { action: 'run_command', value: `${bot.prefix}kahoot answer ${i}` }, hoverEvent: { action: 'show_text', value: 'Click to answer' } })
|
|
||||||
answersMsg.push({ text: '] ', color: questionColors[i], clickEvent: { action: 'run_command', value: `${bot.prefix}kahoot answer ${i}` }, hoverEvent: { action: 'show_text', value: 'Click to answer' } })
|
|
||||||
}
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify(answersMsg)}`)
|
|
||||||
})
|
|
||||||
bot.kahoot.client.on('QuestionEnd', (results) => {
|
|
||||||
bot.kahoot.answer = answerError
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg(`You answered ${results.isCorrect ? '' : 'in'}correctly! You currently have ${results.points} points.`)}`)
|
|
||||||
})
|
|
||||||
bot.kahoot.client.on('QuizEnd', (results) =>
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg(`The quiz has ended! Your rank is: ${results.rank}.`)}`)
|
|
||||||
)
|
|
||||||
bot.kahoot.client.on('Disconnect', (reason) => {
|
|
||||||
bot.core.run(`minecraft:tellraw @a ${kahootMsg(`Disconnected: ${reason}`)}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function kahootMsg (message) {
|
|
||||||
return JSON.stringify([
|
|
||||||
{ text: '', color: 'gray' },
|
|
||||||
{ text: '[', color: 'dark_gray' },
|
|
||||||
{ text: 'Kahoot', color: 'dark_purple' },
|
|
||||||
{ text: '] ', color: 'dark_gray' },
|
|
||||||
message
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
function kahootErrMsg (message) {
|
|
||||||
return JSON.stringify([
|
|
||||||
{ text: '', color: 'red' },
|
|
||||||
{ text: '[', color: 'dark_gray' },
|
|
||||||
{ text: 'Kahoot', color: 'dark_purple' },
|
|
||||||
{ text: '] ', color: 'dark_gray' },
|
|
||||||
message
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
|
@ -1,17 +0,0 @@
|
||||||
// const nbt = require('prismarine-nbt')
|
|
||||||
// const snbt = require('../util/snbt.js')
|
|
||||||
// const toNBTUUID = require('../util/uuid-to-nbt-uuid.js')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
bot.kbwl = {
|
|
||||||
enabled: false,
|
|
||||||
players: []
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.on('player_added', ({ name, UUID }) => {
|
|
||||||
if (!bot.kbwl.enabled || UUID === bot.uuid || bot.kbwl.players.includes(name)) return
|
|
||||||
bot.kick(UUID)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,15 +0,0 @@
|
||||||
/* const nbt = require('prismarine-nbt')
|
|
||||||
const dataPromise = require('../util/persistent-data.js')
|
|
||||||
|
|
||||||
async function inject (bot) {
|
|
||||||
const data = await dataPromise
|
|
||||||
|
|
||||||
bot.mail = mail
|
|
||||||
bot.sendMail = (sender, reciever, message) => {
|
|
||||||
if (!mail[reciever]) mail[reciever] = []
|
|
||||||
mail[reciever].push({ sender: sender, message, host: bot.server.host + ':' + (bot.server.port || 25565) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
||||||
*/
|
|
272
plugins/music.js
272
plugins/music.js
|
@ -1,214 +1,112 @@
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const convertMidi = require('../util/midi_converter.js')
|
||||||
const { Midi } = require('@tonejs/midi')
|
|
||||||
const { convertMidi } = require('../util/midi_converter')
|
|
||||||
const convertNBS = require('../util/nbs-converter.js')
|
|
||||||
const parseTXTSong = require('../util/txt-song-parser')
|
|
||||||
|
|
||||||
const { instruments } = require('minecraft-data')('1.15.2') // fard
|
function inject(bot) {
|
||||||
|
|
||||||
const soundMap = {
|
|
||||||
harp: 'block.note_block.harp',
|
|
||||||
basedrum: 'block.note_block.basedrum',
|
|
||||||
snare: 'block.note_block.snare',
|
|
||||||
hat: 'block.note_block.hat',
|
|
||||||
bass: 'block.note_block.bass',
|
|
||||||
flute: 'block.note_block.flute',
|
|
||||||
bell: 'block.note_block.bell',
|
|
||||||
guiter: 'block.note_block.guiter',
|
|
||||||
chime: 'block.note_block.chime',
|
|
||||||
xylophone: 'block.note_block.xylophone',
|
|
||||||
iron_xylophone: 'block.note_block.iron_xylophone',
|
|
||||||
cow_bell: 'block.note_block.cow_bell',
|
|
||||||
didgeridoo: 'block.note_block.didgeridoo',
|
|
||||||
bit: 'block.note_block.bit',
|
|
||||||
banjo: 'block.note_block.banjo',
|
|
||||||
pling: 'block.note_block.pling'
|
|
||||||
}
|
|
||||||
const oldSoundMap = {
|
|
||||||
harp: 'block.note_block.harp',
|
|
||||||
basedrum: 'block.note_block.basedrum',
|
|
||||||
snare: 'block.note_block.snare',
|
|
||||||
hat: 'block.note_block.hat',
|
|
||||||
bass: 'block.note_block.bass',
|
|
||||||
flute: 'block.note_block.harp',
|
|
||||||
bell: 'block.note_block.harp', // 'entity.experience_orb.pickup'
|
|
||||||
guiter: 'block.note_block.bass',
|
|
||||||
chime: 'block.note_block.harp',
|
|
||||||
xylophone: 'block.note_block.harp',
|
|
||||||
iron_xylophone: 'block.note_block.harp',
|
|
||||||
cow_bell: 'block.note_block.cow_bell',
|
|
||||||
didgeridoo: 'block.note_block.bass',
|
|
||||||
bit: 'block.note_block.harp',
|
|
||||||
banjo: 'block.note_block.bass',
|
|
||||||
pling: 'block.note_block.pling'
|
|
||||||
}
|
|
||||||
|
|
||||||
function inject (bot) {
|
|
||||||
bot.music = {
|
bot.music = {
|
||||||
playing: false,
|
playing: false,
|
||||||
queue: [],
|
queue: [],
|
||||||
nowPlaying: undefined,
|
nowPlaying,
|
||||||
looping: false,
|
|
||||||
_interval: null,
|
|
||||||
_playNextSong,
|
|
||||||
skip,
|
skip,
|
||||||
stop,
|
stop,
|
||||||
play,
|
play
|
||||||
normalize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.music.nowPlaying = {
|
var nowPlaying = {
|
||||||
name: '',
|
name: '',
|
||||||
tick: {
|
note: {
|
||||||
current: null,
|
current: null, total: null
|
||||||
total: null
|
|
||||||
// npt: null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (!bot.music.playing) return
|
if (bot.music.playing)
|
||||||
const msg = [
|
bot.core.run(`/title @a actionbar ${JSON.stringify([
|
||||||
{ text: 'Now Playing', color: bot.colors.primary },
|
{ text: 'Now Playing', color: bot.colors.primary },
|
||||||
{ text: ' | ', color: 'dark_gray' },
|
{ text: ' | ', color: 'dark_gray' },
|
||||||
{ text: bot.music.nowPlaying.displayName, color: bot.colors.secondary, bold: true },
|
{ text: nowPlaying.name, color: bot.colors.secondary, bold: true },
|
||||||
{ text: ' | ', color: 'dark_gray' },
|
{ text: ' | ', color: 'dark_gray' },
|
||||||
format(bot.music.nowPlaying.time),
|
nowPlaying.note.current,
|
||||||
{ text: ' / ', color: 'gray' },
|
{ text: ' / ', color: 'gray' },
|
||||||
format(bot.music.nowPlaying.length)
|
nowPlaying.note.total
|
||||||
// { text: ' (', color: 'dark_gray' },
|
])}`)
|
||||||
// bot.music.nowPlaying.note.npt + ' npt',
|
}, 50)
|
||||||
// { text: ')', color: 'dark_gray' }
|
|
||||||
]
|
setInterval(() => {
|
||||||
if (bot.music.looping) {
|
if (!bot.music.playing) {
|
||||||
msg.push({ text: ' | ', color: 'dark_gray' })
|
const filepath = bot.music.queue.shift()
|
||||||
msg.push({ text: 'Looping', color: bot.colors.secondary })
|
if (filepath != null)
|
||||||
|
play(filepath)
|
||||||
}
|
}
|
||||||
bot.core.run('/title @a actionbar ' + JSON.stringify(msg))
|
}, 1)
|
||||||
}, 500)
|
|
||||||
|
|
||||||
function _playNextSong () {
|
function skip() {
|
||||||
const song = bot.music.queue.shift()
|
cancel = true
|
||||||
if (song != null) play(song)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function skip () {
|
function stop() {
|
||||||
clearInterval(bot.music._interval)
|
|
||||||
bot.music.playing = false
|
|
||||||
if (bot.music.queue.length !== 0) _playNextSong()
|
|
||||||
}
|
|
||||||
|
|
||||||
function stop () {
|
|
||||||
bot.music.queue = []
|
bot.music.queue = []
|
||||||
clearInterval(bot.music._interval)
|
cancel = true
|
||||||
bot.music.playing = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cancel = false
|
||||||
|
function play(filepath) {
|
||||||
|
//set stuff up
|
||||||
|
cancel = false
|
||||||
|
const noteList = convertMidi(filepath)
|
||||||
|
nowPlaying.name = filepath.replace(/.+\//g, '')
|
||||||
|
nowPlaying.note.current = 0
|
||||||
|
nowPlaying.note.total = noteList.length
|
||||||
|
|
||||||
|
//play the music lol
|
||||||
|
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||||
|
{ text: 'Now playing ', color: bot.colors.primary },
|
||||||
|
{ text: nowPlaying.name, color: bot.colors.secondary },
|
||||||
|
'.'
|
||||||
|
])}`)
|
||||||
|
bot.music.playing = true
|
||||||
|
let tick = 0
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
for (const i in noteList) {
|
||||||
|
const note = noteList[i]
|
||||||
|
if (tick >= note.tick) {
|
||||||
|
const floatingpitch = Math.pow(2, (note.pitch - 12) / 12.0)
|
||||||
|
bot.core.run(`/execute at @a positioned ^-2.0 ^ ^ run playsound block.note_block.${note.instrument} record @p ~ ~ ~ 65535 ${floatingpitch}`)
|
||||||
|
|
||||||
function play (filepath) {
|
nowPlaying.note.current++
|
||||||
// set stuff up
|
noteList.splice(i, 1)
|
||||||
filepath = path.resolve(filepath)
|
}
|
||||||
let song
|
|
||||||
try {
|
|
||||||
switch (path.extname(filepath)) {
|
|
||||||
case '.nbs':
|
|
||||||
song = convertNBS(fs.readFileSync(filepath))
|
|
||||||
break
|
|
||||||
case '.js':
|
|
||||||
case '.cjs':
|
|
||||||
case '.json':
|
|
||||||
const requirePath = require.resolve(filepath)
|
|
||||||
delete require.cache[requirePath]
|
|
||||||
song = normalize(require(requirePath))
|
|
||||||
break
|
|
||||||
case '.txt':
|
|
||||||
song = parseTXTSong(fs.readFileSync(filepath).toString())
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
const midi = new Midi(fs.readFileSync(filepath))
|
|
||||||
song = normalize(convertMidi(midi))
|
|
||||||
}
|
|
||||||
song.displayName = song.name.length > 0 ? `${song.name} (${path.basename(filepath)})` : path.basename(filepath)
|
|
||||||
song.time = 0
|
|
||||||
bot.music.nowPlaying = song
|
|
||||||
} catch (err) {
|
|
||||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: err?.message, color: bot.colors.error }))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// play the music lol
|
|
||||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
|
||||||
{ text: 'Now playing ', color: bot.colors.primary },
|
|
||||||
{ text: song.displayName, color: bot.colors.secondary },
|
|
||||||
])}`)
|
|
||||||
bot.music.playing = true
|
|
||||||
bot.music.looping = song.loop
|
|
||||||
let startTime = Date.now()
|
|
||||||
bot.music._interval = setInterval(() => {
|
|
||||||
const intervalTime = song.time + 1
|
|
||||||
song.time = Date.now() - startTime
|
|
||||||
|
|
||||||
song.notes.forEach((note, i) => {
|
|
||||||
const _time = note.time // Math.floor(note.time)
|
|
||||||
if (intervalTime <= _time && song.time >= _time) {
|
|
||||||
const sound = soundMap[note.instrument]
|
|
||||||
// const oldSound = oldSoundMap[note.instrument]
|
|
||||||
const floatingpitch = Math.pow(2, (note.pitch - 12) / 12.0)
|
|
||||||
bot.core.run(`minecraft:execute as @a[tag=!nomusic] at @s run playsound ${sound} record @s ^ ^ ^ ${note.volume} ${floatingpitch}`)
|
|
||||||
}
|
}
|
||||||
})
|
tick++//;bot.core.run(`/bcraw Tick: ${tick}`)
|
||||||
|
|
||||||
if (song.time > song.length) {
|
if (noteList.length == 0 || cancel) {
|
||||||
if (bot.music.looping) {
|
clearInterval(interval)
|
||||||
startTime = Date.now() + song.loopPosition
|
|
||||||
return
|
bot.music.playing = false
|
||||||
|
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||||
|
{ text: 'Finished playing ', color: 'green' },
|
||||||
|
{ text: nowPlaying.name, color: 'dark_green' },
|
||||||
|
'.'
|
||||||
|
])}`)
|
||||||
}
|
}
|
||||||
|
}, 50)
|
||||||
clearInterval(bot.music._interval)
|
|
||||||
bot.music.playing = false
|
|
||||||
|
|
||||||
bot.core.run('/tellraw @a ' + JSON.stringify([
|
|
||||||
{ text: 'Finished playing ', color: 'green' },
|
|
||||||
{ text: bot.music.nowPlaying.name, color: 'dark_green' }
|
|
||||||
]))
|
|
||||||
if (bot.music.queue.length !== 0) _playNextSong()
|
|
||||||
}
|
|
||||||
}, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalize (song) {
|
|
||||||
const normalizeNote = note => { // change notes with tick to notes with time
|
|
||||||
if (note.time == null && note.tick != null) {
|
|
||||||
note.time = note.tick * 50
|
|
||||||
delete note.tick
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const num = Number(note.instrument)
|
|
||||||
if (!Number.isNaN(num)) note.instrument = instruments[num].name
|
|
||||||
}
|
|
||||||
if (Array.isArray(song)) { // if the song is actually an array, convert it to a song
|
|
||||||
let length = 0
|
|
||||||
for (const note of song) {
|
|
||||||
normalizeNote(note)
|
|
||||||
length = Math.max(note.time, length)
|
|
||||||
}
|
|
||||||
return { name: '', notes: song, loop: false, loopPosition: 0, length }
|
|
||||||
}
|
|
||||||
let length = 0
|
|
||||||
for (const note of song.notes ?? []) {
|
|
||||||
normalizeNote(note)
|
|
||||||
length = Math.max(note.time, length)
|
|
||||||
}
|
|
||||||
song.length = length
|
|
||||||
return { name: '', notes: [], loop: false, loopPosition: 0, length, ...song }
|
|
||||||
}
|
|
||||||
function format (ms) {
|
|
||||||
const s = ms / 1000
|
|
||||||
|
|
||||||
const seconds = Math.floor(s / 60).toString()
|
|
||||||
const minutes = Math.floor(s % 60).toString()
|
|
||||||
return seconds + ':' + (minutes.length <= 1 ? '0' : '') + minutes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.bot = inject
|
//module.exports.timeConverter = timeConverter
|
||||||
|
//module.exports.tuneNoteblocks = tuneNoteblocks
|
||||||
|
//module.exports.tuneNoteblock = tuneNoteblock
|
||||||
|
//module.exports.parse = parse
|
||||||
|
//module.exports.play = play
|
||||||
|
//module.exports.songInfo = songInfo
|
||||||
|
//module.exports.isValidFile = isValidFile
|
||||||
|
|
||||||
|
//module.exports.getNowPlaying = () => {return nowPlaying}
|
||||||
|
//module.exports.editNowPlaying = (song_name, current, full, url, addedBy) => {
|
||||||
|
// song_name != undefined ? nowPlaying.song_name = song_name : undefined
|
||||||
|
// current != undefined ? nowPlaying.time.current = current : undefined
|
||||||
|
// full != undefined ? nowPlaying.time.full = full : undefined
|
||||||
|
// url != undefined ? nowPlaying.url = url : undefined
|
||||||
|
// addedBy != undefined ? nowPlaying.addedBy = addedBy : undefined
|
||||||
|
//}
|
||||||
|
|
||||||
|
module.exports = inject
|
|
@ -1,8 +0,0 @@
|
||||||
function bot (bot) {
|
|
||||||
bot.playerFilter = null
|
|
||||||
bot.on('player_added', ({ name, UUID }) => {
|
|
||||||
if (bot.playerFilter != null && bot.playerFilter.test(name)) bot.kick(UUID)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,55 +0,0 @@
|
||||||
const actions = {
|
|
||||||
// doesnt include 0 and 4 because they are special
|
|
||||||
1: 'gamemode',
|
|
||||||
2: 'ping',
|
|
||||||
3: 'displayName'
|
|
||||||
}
|
|
||||||
|
|
||||||
function inject (bot) {
|
|
||||||
bot.players = {}
|
|
||||||
function removePlayer (uuid) {
|
|
||||||
const player = bot.players[uuid]
|
|
||||||
if (!player) return false
|
|
||||||
|
|
||||||
delete bot.players[player.name]
|
|
||||||
delete bot.players[uuid]
|
|
||||||
|
|
||||||
bot.emit('player_removed', player)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
bot._client.on('player_info', ({ action, data }) => {
|
|
||||||
if (actions[action] == null) { // Special cases
|
|
||||||
data.forEach(async player => {
|
|
||||||
if (action === 0) {
|
|
||||||
bot.players[player.name] = player
|
|
||||||
bot.players[player.UUID] = player
|
|
||||||
|
|
||||||
bot.emit('player_added', player)
|
|
||||||
} /* else if (action === 4) {
|
|
||||||
const { UUID } = player
|
|
||||||
try {
|
|
||||||
const [selectorComp] = await bot.resolveComponent({ selector: UUID })
|
|
||||||
if (selectorComp.text === '' && !selectorComp.extra) removePlayer(UUID)
|
|
||||||
} catch (err) {
|
|
||||||
removePlayer(UUID)
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data.forEach(player2 => {
|
|
||||||
const player = bot.players[player2.UUID]
|
|
||||||
if (!player) return
|
|
||||||
|
|
||||||
const info = actions[action]
|
|
||||||
if (player[info] == null || player2[info] == null) return
|
|
||||||
|
|
||||||
player[info] = player2[info]
|
|
||||||
bot.emit('player_updated', info, player)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.client = inject
|
|
|
@ -1,18 +0,0 @@
|
||||||
function bot (bot) { bot.position = { x: null, y: null, z: null } }
|
|
||||||
|
|
||||||
function client (bot) {
|
|
||||||
bot._client.on('position', ({ x, y, z, flags, teleportId }) => {
|
|
||||||
// TODO: Don't ignore yaw, pitch
|
|
||||||
const oldPosition = { ...bot.position }
|
|
||||||
|
|
||||||
bot.position.x = flags & 1 ? (bot.position.x + x) : x
|
|
||||||
bot.position.y = flags & 2 ? (bot.position.y + y) : y
|
|
||||||
bot.position.z = flags & 4 ? (bot.position.z + z) : z
|
|
||||||
|
|
||||||
bot._client.write('teleport_confirm', { teleportId })
|
|
||||||
|
|
||||||
bot.emit('move', oldPosition, true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot, client }
|
|
|
@ -1,34 +0,0 @@
|
||||||
function bot (bot) {
|
|
||||||
bot.on('login', () => {
|
|
||||||
bot.chat.queue.push('/commandspy:commandspy on')
|
|
||||||
// bot.chat.queue.push('/essentials:vanish enable')
|
|
||||||
bot.chat.queue.push('/essentials:god enable')
|
|
||||||
})
|
|
||||||
|
|
||||||
bot.on('cspy', (player, command, args) => {
|
|
||||||
switch (command) {
|
|
||||||
case 'icu':
|
|
||||||
case 'icontrolu:icu':
|
|
||||||
if (args[0] === 'control' && (bot._client.username.startsWith(args[1]) || args[1] === bot._client.uuid)) { bot.core.run(`essentials:sudo ${player.UUID} icontrolu:icu stop`) }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function client (bot, client) {
|
|
||||||
bot._client.on('game_state_change', (packet) => {
|
|
||||||
switch (packet.reason) {
|
|
||||||
case 3:
|
|
||||||
if (packet.gameMode !== 1) { bot.chat.queue.push('/minecraft:gamemode creative @s[type=player]') }
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
bot._client.write('client_command', { payload: 0 })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
bot._client.on('update_health', (packet) => {
|
|
||||||
if (packet.health <= 0) { bot._client.write('client_command', { payload: 0 }) }
|
|
||||||
})
|
|
||||||
|
|
||||||
bot._client.on('declare_commands', () => bot.chat.queue.push('/op @s[type=player]'))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot, client }
|
|
|
@ -1,19 +0,0 @@
|
||||||
function bot (bot) {
|
|
||||||
if (!bot.server.isKaboom) return
|
|
||||||
|
|
||||||
bot.skinQueue = []
|
|
||||||
setInterval(() => {
|
|
||||||
if (!bot.loggedIn) bot.skinQueue.splice(0, bot.skinQueue.length)
|
|
||||||
if (bot.skinQueue.length === 0) return
|
|
||||||
const { UUID, name } = bot.skinQueue.shift()
|
|
||||||
// bot.core.run('minecraft:tellraw @a ' + JSON.stringify([{ text: 'Setting the skin of ', color: bot.colors.primary }, { text: name, color: bot.colors.secondary }]))
|
|
||||||
bot.core.run('essentials:sudo ' + UUID + ' extras:skin ' + name)
|
|
||||||
}, 2250)
|
|
||||||
|
|
||||||
bot.on('player_added', ({ name, UUID, properties }) => {
|
|
||||||
if (UUID === bot._client.uuid || properties.some(({ name }) => name === 'textures')) return
|
|
||||||
bot.skinQueue.push({ name, UUID })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,66 +0,0 @@
|
||||||
// Valid values
|
|
||||||
const visibilityValues = ['never', 'hideForOtherTeams', 'hideForOwnTeam', 'always']
|
|
||||||
const collisionRuleValues = ['always','never', 'pushOtherTeams', 'pushOwnTeam']
|
|
||||||
|
|
||||||
// TODO: Track players
|
|
||||||
function bot (bot) {
|
|
||||||
class Team {
|
|
||||||
destroyed = false
|
|
||||||
constructor (name, displayName, isExistingTeam = false) {
|
|
||||||
this.name = String(name)
|
|
||||||
if (!isExistingTeam) bot.core.run(`minecraft:team add ${this.name}`)
|
|
||||||
}
|
|
||||||
add (target) {
|
|
||||||
bot.core.run(`minecraft:execute at ${bot.uuid} as ${target} run team join ${this.name}`) // execute seems safer than team
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setDisplayName (displayName) {
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} displayName ${JSON.stringify(displayName)}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setColor (color) {
|
|
||||||
// TODO: Check if the color is valid
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} color ${color}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setFriendlyFire (boolean) {
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} friendlyFire ${Boolean(boolean)}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setSeeFriendlyInvisibles (boolean) {
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} seeFriendlyInvisibles ${Boolean(boolean)}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setNametagVisibility (visibility) {
|
|
||||||
if (!visibilityValues.includes(visibility)) throw new TypeError('Value must be ' + visibilityValues.join(', '))
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} nametagVisibility ${visibility}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setDeathMessageVisibility (visibility) {
|
|
||||||
if (!visibilityValues.includes(visibility)) throw new TypeError('Value must be ' + visibilityValues.join(', '))
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} deathMessageVisibility ${visibility}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setCollisionRule (collisionRule) {
|
|
||||||
if (!collisionRuleValues.includes(collisionRule)) throw new TypeError('Value must be ' + collisionRuleValues.join(', '))
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} collisionRule ${collisionRule}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setPrefix (prefix) {
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} prefix ${JSON.stringify(prefix)}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
setSuffix (suffix) {
|
|
||||||
bot.core.run(`minecraft:team modify ${this.name} suffix ${JSON.stringify(suffix)}`)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
destroy () {
|
|
||||||
bot.core.run(`minecraft:team remove ${this.name}`)
|
|
||||||
this.destroyed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.Team = Team
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,73 +0,0 @@
|
||||||
const nbt = require('prismarine-nbt')
|
|
||||||
const snbt = require('mojangson')
|
|
||||||
const toNBTUUID = require('../util/uuid-to-nbt-uuid.js')
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
function _itemTellraw (json, target) {
|
|
||||||
bot._client.write('set_creative_slot', {
|
|
||||||
slot: 36,
|
|
||||||
item: {
|
|
||||||
present: true,
|
|
||||||
itemId: 1,
|
|
||||||
itemCount: 1,
|
|
||||||
nbtData: nbt.comp({
|
|
||||||
'': nbt.string(json)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (bot.server.isScissors) {
|
|
||||||
const storage = Math.random().toString()
|
|
||||||
bot.core.run('minecraft:data modify storage ' + storage + ' "" set from entity ' + bot._client.uuid + ' Inventory[0].tag.""')
|
|
||||||
bot.core.run(`minecraft:tellraw ${target} ${JSON.stringify({ nbt: '""', storage, interpret: true })}`)
|
|
||||||
bot.core.run('minecraft:data remove storage ' + storage + ' i')
|
|
||||||
} else {
|
|
||||||
bot.core.run(`minecraft:tellraw ${target} ${JSON.stringify({ nbt: 'Inventory[0].tag.""', entity: bot._client.uuid, interpret: true })}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function tellrawJSON (json, target = '@a') {
|
|
||||||
if (/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/.test(target)) {
|
|
||||||
target = `@p[nbt=${snbt.stringify(nbt.comp({ UUID: toNBTUUID(target) }))}]`
|
|
||||||
}
|
|
||||||
|
|
||||||
const command = `minecraft:tellraw ${target} ${json}`
|
|
||||||
if (command.length > 32767 || command.includes('selector') || (bot.server.isAyunBoom && /@e|@r\[[^\]]*limit=\d+[^\]]*\]/.test(command))) {
|
|
||||||
_itemTellraw(json, target)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bot.core.run(command)
|
|
||||||
}
|
|
||||||
|
|
||||||
function tellraw (message, target) { tellrawJSON(JSON.stringify(message), target) }
|
|
||||||
|
|
||||||
function resolveComponent (message, timeout = 30000) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (typeof message === 'object' && !Array.isArray(message)) {
|
|
||||||
if (message.extra) message = [message, ...message.extra]
|
|
||||||
else message = [message]
|
|
||||||
} else if (typeof message !== 'object') {
|
|
||||||
message = [message].flat()
|
|
||||||
}
|
|
||||||
|
|
||||||
const char = String.fromCharCode(Math.floor(Math.random() * (0xFFF + 1)))
|
|
||||||
bot.tellraw({ text: char, extra: message }, bot.uuid)
|
|
||||||
|
|
||||||
const listener = ({ message, sender, position }) => {
|
|
||||||
if (message?.text !== char || sender !== '00000000-0000-0000-0000-000000000000' || position !== 1) return
|
|
||||||
resolve(message.extra)
|
|
||||||
bot.removeListener('chat', listener)
|
|
||||||
}
|
|
||||||
bot.on('chat', listener)
|
|
||||||
setInterval(() => {
|
|
||||||
reject(new Error(`Timed out after ${timeout}ms`))
|
|
||||||
bot.removeListener('chat', listener)
|
|
||||||
}, timeout)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.tellrawJSON = tellrawJSON
|
|
||||||
bot.tellraw = tellraw
|
|
||||||
bot.resolveComponent = resolveComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot }
|
|
|
@ -1,45 +0,0 @@
|
||||||
function longToBigInt (array) {
|
|
||||||
return BigInt.asIntN(64, (BigInt(array[0]) << 32n)) | BigInt(array[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
function bot (bot) {
|
|
||||||
bot.time = {
|
|
||||||
doDaylightCycle: null,
|
|
||||||
bigTime: null,
|
|
||||||
time: null,
|
|
||||||
timeOfDay: null,
|
|
||||||
day: null,
|
|
||||||
isDay: null,
|
|
||||||
moonPhase: null,
|
|
||||||
bigAge: null,
|
|
||||||
age: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function client (bot) {
|
|
||||||
bot._client.on('update_time', (packet) => {
|
|
||||||
const oldTime = { ...bot.time }
|
|
||||||
|
|
||||||
let time = longToBigInt(packet.time)
|
|
||||||
|
|
||||||
if (time < 0) {
|
|
||||||
bot.time.doDaylightCycle = false
|
|
||||||
time *= -1n
|
|
||||||
} else {
|
|
||||||
bot.time.doDaylightCycle = true
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.time.bigTime = time
|
|
||||||
bot.time.time = Number(time)
|
|
||||||
bot.time.timeOfDay = bot.time.time % 24000
|
|
||||||
bot.time.day = Math.floor(bot.time.time / 24000)
|
|
||||||
bot.time.isDay = bot.time.timeOfDay < 13000 || bot.time.timeOfDay >= 23000
|
|
||||||
bot.time.moonPhase = bot.time.day % 8
|
|
||||||
bot.time.bigAge = longToBigInt(packet.age)
|
|
||||||
bot.time.age = Number(bot.time.bigAge)
|
|
||||||
|
|
||||||
bot.emit('update_time', oldTime)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { bot, client }
|
|
12
plugins/uuid_map.js
Normal file
12
plugins/uuid_map.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
function inject (bot) {
|
||||||
|
bot.uuidMap = {}
|
||||||
|
|
||||||
|
bot._client.on('player_info', (packet) => {
|
||||||
|
if (packet.action === 0)
|
||||||
|
packet.data.forEach((player) => {
|
||||||
|
bot.uuidMap[player.UUID] = player.name
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = inject
|
|
@ -1,59 +0,0 @@
|
||||||
const rfb = require('rfb2')
|
|
||||||
|
|
||||||
function inject (bot) {
|
|
||||||
const display = bot.chatCanvas
|
|
||||||
const displayCtx = display.getContext('2d')
|
|
||||||
const canvas = new display.constructor(640, 480)
|
|
||||||
const ctx = canvas.getContext('2d')
|
|
||||||
|
|
||||||
bot.vnc = {
|
|
||||||
connect,
|
|
||||||
connected: false,
|
|
||||||
display,
|
|
||||||
_client: null
|
|
||||||
}
|
|
||||||
|
|
||||||
function connect (options = {}) {
|
|
||||||
const r = rfb.createConnection(options)
|
|
||||||
bot.vnc.ended = false
|
|
||||||
r.on('connect', () => {
|
|
||||||
bot.vnc.connected = true
|
|
||||||
canvas.width = r.width
|
|
||||||
canvas.height = r.height
|
|
||||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify([
|
|
||||||
{ text: 'Connected to ', color: bot.colors.primary },
|
|
||||||
{ text: r.title, color: bot.colors.secondary }
|
|
||||||
]))
|
|
||||||
})
|
|
||||||
r.on('rect', rect => setImmediate(() => {
|
|
||||||
if (rect.encoding === rfb.encodings.raw) {
|
|
||||||
const id = ctx.createImageData(rect.width, rect.height)
|
|
||||||
for (let i = 0; i < id.data.length; i += 4) {
|
|
||||||
id.data[i] = rect.data[i + 2]
|
|
||||||
id.data[i + 1] = rect.data[i + 1]
|
|
||||||
id.data[i + 2] = rect.data[i]
|
|
||||||
id.data[i + 3] = 255
|
|
||||||
}
|
|
||||||
ctx.putImageData(id, rect.x, rect.y)
|
|
||||||
render()
|
|
||||||
} else if (rect.encoding === rfb.encodings.copyRect) {
|
|
||||||
ctx.drawImage(canvas, rect.src.x, rect.src.y, rect.width, rect.height, rect.x, rect.y)
|
|
||||||
// render()
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
r.on('resize', ({ width, height }) => {
|
|
||||||
canvas.width = width
|
|
||||||
canvas.height = height
|
|
||||||
})
|
|
||||||
r.on('error', err => bot.tellraw({ text: 'VNC ' + err, color: bot.colors.error }))
|
|
||||||
r.on('end', () => (bot.vnc.ended = true))
|
|
||||||
|
|
||||||
bot.vnc._client = r
|
|
||||||
function render () {
|
|
||||||
displayCtx.drawImage(canvas, 0, 0, display.width, display.height) // draw image
|
|
||||||
display.render() // render it in mc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.bot = inject
|
|
7
start.sh
7
start.sh
|
@ -1,7 +0,0 @@
|
||||||
while true
|
|
||||||
do
|
|
||||||
echo Starting Bot
|
|
||||||
node .
|
|
||||||
echo Restarting Bot in 6 Seconds...
|
|
||||||
sleep 6
|
|
||||||
done
|
|
|
@ -1,101 +0,0 @@
|
||||||
// totallynotskidded™ from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
|
|
||||||
const incrementalPattern = /(?<colorCode>\xa7[0-9a-fk-orx])|(?<url>(?:(?:https?):\/\/)?(?:[-\w_\.]{2,}\.[a-z]{2,4}.*?(?=[\.\?!,;:]?(?:[\xa7 \n]|$))))|(?<newline>\n)/gi
|
|
||||||
const incrementalPatternKeepNewlines = /(?<colorCode>\xa7[0-9a-fk-orx])|(?<url>(?:(?:https?):\/\/)?(?:[-\w_\.]{2,}\.[a-z]{2,4}.*?(?=[\.\?!,;:]?(?:[\xa7 ]|$))))/gi
|
|
||||||
|
|
||||||
const colors = {
|
|
||||||
0: 'black',
|
|
||||||
1: 'dark_blue',
|
|
||||||
2: 'dark_green',
|
|
||||||
3: 'dark_aqua',
|
|
||||||
4: 'dark_red',
|
|
||||||
5: 'dark_purple',
|
|
||||||
6: 'gold',
|
|
||||||
7: 'gray',
|
|
||||||
8: 'dark_gray',
|
|
||||||
9: 'blue',
|
|
||||||
a: 'green',
|
|
||||||
b: 'aqua',
|
|
||||||
c: 'red',
|
|
||||||
d: 'light_purple',
|
|
||||||
e: 'yellow',
|
|
||||||
f: 'white',
|
|
||||||
r: 'reset'
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatting = {
|
|
||||||
l: 'bold',
|
|
||||||
o: 'italic',
|
|
||||||
n: 'underline',
|
|
||||||
m: 'strikethrough',
|
|
||||||
k: 'obfuscated'
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseString (message, keepNewlines, plain) {
|
|
||||||
const list = []
|
|
||||||
let currentChatComponent = { text: '' }
|
|
||||||
let modifier = {}
|
|
||||||
let currentIndex = 0
|
|
||||||
let hex = null
|
|
||||||
|
|
||||||
if (message == null) return currentChatComponent
|
|
||||||
list.push(currentChatComponent)
|
|
||||||
|
|
||||||
const pattern = keepNewlines ? incrementalPatternKeepNewlines : incrementalPattern
|
|
||||||
let needsAdd = false
|
|
||||||
for (const match of message.matchAll(pattern)) {
|
|
||||||
if (match.index > currentIndex) {
|
|
||||||
needsAdd = false
|
|
||||||
appendNewComponent(match.index)
|
|
||||||
}
|
|
||||||
|
|
||||||
const group = Object.keys(match.groups).find(key => match.groups[key] !== undefined)
|
|
||||||
switch (group) {
|
|
||||||
case 'colorCode': {
|
|
||||||
const c = match[0].toLowerCase().charAt(1)
|
|
||||||
|
|
||||||
if (c === 'x') hex = '#'
|
|
||||||
else if (hex != null) {
|
|
||||||
hex += c
|
|
||||||
|
|
||||||
if (hex.length === 7) {
|
|
||||||
modifier = { color: hex }
|
|
||||||
hex = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (formatting[c] != null) modifier[formatting[c]] = true
|
|
||||||
else modifier = { color: colors[c] }
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'url':
|
|
||||||
if (plain) appendNewComponent(match.index + match[0].length)
|
|
||||||
else {
|
|
||||||
let url = match[0]
|
|
||||||
if (!(url.startsWith("http://") || url.startsWith("https://"))) url = 'http://' + url
|
|
||||||
modifier.clickEvent = { action: 'open_url', value: url }
|
|
||||||
appendNewComponent(match.index + match[0].length)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'newline':
|
|
||||||
if (needsAdd) appendNewComponent(match.index)
|
|
||||||
currentChatComponent = null
|
|
||||||
}
|
|
||||||
currentIndex = match.index + match[0].length
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentIndex < message.length || needsAdd) appendNewComponent(message.length)
|
|
||||||
|
|
||||||
return list
|
|
||||||
|
|
||||||
function appendNewComponent (index) {
|
|
||||||
const addition = { text: message.substring(currentIndex, index), ...modifier }
|
|
||||||
currentIndex = index
|
|
||||||
if (currentChatComponent == null) {
|
|
||||||
currentChatComponent = { text: '' }
|
|
||||||
list.push(currentChatComponent)
|
|
||||||
}
|
|
||||||
currentChatComponent.extra ??= []
|
|
||||||
currentChatComponent.extra.push(addition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = parseString
|
|
23
util/cval.js
23
util/cval.js
|
@ -1,23 +0,0 @@
|
||||||
const { createHmac } = require('crypto')
|
|
||||||
|
|
||||||
function uuidToIntArray (uuid) {
|
|
||||||
return uuid.replace(/-/g, '').match(/.{8}/g).map(str => Number.parseInt(str, 16)).map(num => num & 0x80000000 ? num - 0xffffffff - 1 : num)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHash (message, uuid, key) {
|
|
||||||
const hmac = createHmac('sha256', uuid, key)
|
|
||||||
const time = Math.floor(new Date().getTime() / 6942)
|
|
||||||
const raw = message + '\\' + uuidToIntArray(uuid).join(';') + '\\' + time + '\\' + key
|
|
||||||
const hash = hmac.update(raw).digest()
|
|
||||||
const strHash = hash.toString('utf-8')
|
|
||||||
|
|
||||||
return strHash
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCommand (message, uuid, key) {
|
|
||||||
const strHash = getHash(message.replace(/[\xa7&][0-9a-fkl-or]/g, ''), uuid, key)
|
|
||||||
|
|
||||||
return `${message} ${strHash.split('').map(c => '\xa7' + c).join('')}\xa7${String.fromCharCode(strHash.length)}\xa7`
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { getHash, getCommand }
|
|
|
@ -1,16 +0,0 @@
|
||||||
const axios = require('axios')
|
|
||||||
|
|
||||||
async function dineval (code, options = {}) {
|
|
||||||
options.server ??= 'http://eval.dinhero21.repl.co'
|
|
||||||
options.colors ??= 'none'
|
|
||||||
|
|
||||||
const { data } = await axios.get(options.server, {
|
|
||||||
headers: {
|
|
||||||
data: code,
|
|
||||||
colors: options.colors
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = dineval
|
|
|
@ -1,37 +0,0 @@
|
||||||
const { Buffer } = require('buffer')
|
|
||||||
|
|
||||||
function convertImageData (data, width, options = {}) {
|
|
||||||
// Default options
|
|
||||||
options.char ??= '⎮'
|
|
||||||
options.optimized ??= true
|
|
||||||
|
|
||||||
const components = ['[{"text":"']
|
|
||||||
|
|
||||||
const _jsonChar = options.char.replace(/[\\"]/g, m => '\\' + m)
|
|
||||||
let _lastColor = null
|
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i += 4) {
|
|
||||||
const r = data[i]
|
|
||||||
const g = data[i + 1]
|
|
||||||
const b = data[i + 2]
|
|
||||||
|
|
||||||
let color = ''
|
|
||||||
if (r !== 0) color += r.toString(16)
|
|
||||||
if (g !== 0) color = color.padStart(2, '0') + g.toString(16).padStart(2, '0')
|
|
||||||
if (b !== 0) color = color.padStart(4, '0') + b.toString(16).padStart(2, '0')
|
|
||||||
color ||= '0'
|
|
||||||
|
|
||||||
if (_lastColor === color) components[components.length - 1] += _jsonChar
|
|
||||||
else components[components.length - 1] += `","color":"#${color}"},{"text":"${_jsonChar}`
|
|
||||||
_lastColor = color
|
|
||||||
|
|
||||||
if (((i / 4) % width) === 0) {
|
|
||||||
components[components.length - 1] += `","color":"#${color}"}]`
|
|
||||||
components.push('[{"text":"')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return components
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = convertImageData
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue