first commit
This commit is contained in:
commit
ebde071dae
92 changed files with 69324 additions and 0 deletions
115
.gitignore
vendored
Normal file
115
.gitignore
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Config files
|
||||
config.js
|
||||
config.json
|
||||
|
||||
# Other
|
||||
logs
|
||||
music
|
||||
images
|
||||
videos
|
||||
functions
|
24
LICENSE
Normal file
24
LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
19
ban.js
Normal file
19
ban.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
const name = 'exploit'
|
||||
const description = 'Uses exploits.'
|
||||
const usage = '{prefix}exploit'
|
||||
const aliases = ['exploit']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const exploit = args.shift()
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ text: 'Attempting exploit ', color: bot.colors.primary },
|
||||
{ text: exploit, color: bot.colors.secondary },
|
||||
'.'
|
||||
])}`)
|
||||
bot.exploits[exploit](args.join(' '))
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
141
bot.js
Normal file
141
bot.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
const mc = require('minecraft-protocol')
|
||||
const { EventEmitter } = require('events')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
function createBots (servers = ['localhost'], options = {}) {
|
||||
const bots = []
|
||||
servers.forEach((server) => {
|
||||
const a = server.split(':')
|
||||
options.host = a[0]
|
||||
options.port = parseInt(a[1])
|
||||
options.brand = a[2]
|
||||
|
||||
const bot = createBot({ ...options })
|
||||
bot.getBots = () => bots
|
||||
bot.on('error', console.error) // "fix"
|
||||
bots.push(bot)
|
||||
})
|
||||
return bots
|
||||
}
|
||||
|
||||
function createBot (options = {}) {
|
||||
// defaults
|
||||
options.username ??= 'Bot'
|
||||
// options.password = options.password ?? null
|
||||
options.prefix ??= '!'
|
||||
options.brand ??= 'vanilla' // found that mineflayer has this so i added it here lol
|
||||
|
||||
options.plugins ??= {}
|
||||
fs.readdirSync(
|
||||
'plugins'
|
||||
).forEach((file) => { // populate plugins array
|
||||
if (file.endsWith('.js') && options.plugins[file] == null) {
|
||||
options.plugins[file] = require(path.resolve('plugins', file))
|
||||
}
|
||||
})
|
||||
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.randomizeUsername ??= false
|
||||
|
||||
options['online-mode'] ??= {}
|
||||
options['online-mode'].enabled ??= false
|
||||
options['online-mode'].username ??= null
|
||||
options['online-mode'].password ??= null
|
||||
|
||||
// fard
|
||||
if (options.randomizeUsername) {
|
||||
options.username += '\u00a7' + String.fromCharCode(Math.floor(Math.random() * 65535))
|
||||
}
|
||||
if (options['online-mode'].enabled) {
|
||||
options.username = options['online-mode'].username
|
||||
options.password = options['online-mode'].password
|
||||
}
|
||||
|
||||
// actually create the bot lol
|
||||
const bot = new EventEmitter()
|
||||
bot.plugins = plugins
|
||||
bot.loadPlugin = loadPlugin
|
||||
|
||||
// add fards
|
||||
bot.host = options.host
|
||||
bot.port = options.port
|
||||
/* bot._client.on('set_protocol', (packet) => {
|
||||
bot.host = packet.serverHost
|
||||
bot.port = packet.serverPort
|
||||
}) */
|
||||
// bot.username = () => bot._client.username
|
||||
// bot.uuid = () => bot._client.uuid
|
||||
bot.prefix = options.prefix
|
||||
bot.brand = options.brand
|
||||
bot.colors = options.colors
|
||||
bot.autoReconnect = options.autoReconnect
|
||||
bot.randomizeUsername = options.randomizeUsername
|
||||
bot['online-mode'] = options['online-mode']
|
||||
// set the client and add listeners
|
||||
bot.on('set_client', (client) => {
|
||||
client.on('connect', () => bot.emit('connect'))
|
||||
client.on('error', (err) => bot.emit('error', err))
|
||||
|
||||
bot.end = (...r) => bot._client.end(...r)
|
||||
client.on('end', (reason) => {
|
||||
bot.loggedIn = false
|
||||
bot.emit('end', reason)
|
||||
// auto reconnect
|
||||
if (bot.autoReconnect) {
|
||||
setTimeout(() => {
|
||||
if (bot.randomizeUsername && !bot['online-mode'].enabled) { options.username = options.username.slice(0, -2) + '\u00a7' + String.fromCharCode(Math.floor(Math.random() * 65535)) }
|
||||
|
||||
bot._client = mc.createClient(options)
|
||||
bot.emit('set_client', bot._client)
|
||||
}, 6000)
|
||||
}
|
||||
})
|
||||
|
||||
// more fard listeners
|
||||
bot.loggedIn = false
|
||||
bot._client.on('login', () => {
|
||||
bot.loggedIn = true
|
||||
bot.emit('login')
|
||||
})
|
||||
|
||||
// position code
|
||||
bot.position = { x: null, y: null, z: null } // to prevent errors i guess
|
||||
bot._client.on('position', (position) => (bot.position = position))
|
||||
|
||||
// plugin injection
|
||||
bot.plugins.forEach((plugin) => {
|
||||
if (typeof plugin.client === 'function') plugin.client(bot, bot._client)
|
||||
})
|
||||
})
|
||||
bot._client = options.client ?? mc.createClient(options)
|
||||
bot.emit('set_client', bot._client)
|
||||
|
||||
bot.plugins.forEach((plugin) => {
|
||||
if (typeof plugin.bot === 'function') plugin.bot(bot)
|
||||
})
|
||||
|
||||
function loadPlugin (plugin) {
|
||||
try {
|
||||
if (typeof plugin.bot === 'function') plugin.bot(bot)
|
||||
if (typeof plugin.client === 'function') plugin.client(bot, bot._client)
|
||||
bot.plugins.push(plugin)
|
||||
} catch (e) {
|
||||
console.log(`Error loading ${plugin}:`)
|
||||
console.log(require('util').inspect(e))
|
||||
}
|
||||
}
|
||||
|
||||
return bot
|
||||
}
|
||||
|
||||
module.exports = { createBot, createBots }
|
96
commands.js
Normal file
96
commands.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const cperms = require('./cperms2.js')
|
||||
|
||||
let commands = {}
|
||||
|
||||
function addCommand (command) {
|
||||
if (!isValid(command)) throw new Error(`Command ${command} is invalid.`)
|
||||
|
||||
if (commands[command] == null) { commands[command] = command }
|
||||
command.aliases.forEach((alias) => {
|
||||
alias = alias.toLowerCase()
|
||||
if (commands[alias] == null) commands[alias] = command
|
||||
})
|
||||
}
|
||||
|
||||
function load () {
|
||||
fs.readdirSync(
|
||||
path.join(__dirname, 'commands')
|
||||
).forEach((file) => {
|
||||
if (file.endsWith('.js')) {
|
||||
const command = path.join(__dirname, 'commands', file)
|
||||
try {
|
||||
const cmd = require(command)
|
||||
addCommand(cmd)
|
||||
} catch (e) {
|
||||
console.log(`Error loading command ${command}:`)
|
||||
console.log(require('util').inspect(e))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function reload () {
|
||||
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)
|
||||
if (!cmd.enabled) { return bot.core.run(`/bcraw &cThe command ${bot.prefix}${command} is disabled.`) }
|
||||
|
||||
if (cmd.permLevel > 0) {
|
||||
if (args.length < 1) {
|
||||
bot.core.run('/bcraw &cYou must provide a code to run this command.')
|
||||
return
|
||||
}
|
||||
|
||||
const code = args.splice(-1, 1)[0].replace(/\u00a7.?/g, '')
|
||||
|
||||
if (!cperms.validate(cmd.permLevel, player.name, code)) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ text: `Invalid code: ${code}.`, color: bot.colors.error }
|
||||
])}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return cmd.execute(bot, command, player, args, module.exports, ...custom)
|
||||
} catch (err) {
|
||||
console.log(`Error executing command ${command}:`)
|
||||
console.log(err)
|
||||
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify({ text: err.message, color: bot.colors.error })}`)
|
||||
}
|
||||
}
|
||||
|
||||
function info (command) {
|
||||
return commands[command]
|
||||
}
|
||||
|
||||
function isCommand (command) {
|
||||
return commands[command] != null
|
||||
}
|
||||
|
||||
function isValid (command) {
|
||||
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 = { addCommand, load, reload, execute, info, isCommand, isValid, commands }
|
23
commands/badapple.js
Normal file
23
commands/badapple.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
const name = 'badapple'
|
||||
const description = 'Plays a badapple video.'
|
||||
const usages = ['[stop]']
|
||||
const aliases = ['badapple']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args) {
|
||||
if (args[0] === 'stop') {
|
||||
bot.video.stop()
|
||||
bot.music.skip()
|
||||
return
|
||||
}
|
||||
|
||||
bot.video.summon(player.UUID, (uuids) => {
|
||||
bot.music.stop()
|
||||
bot.music.queue.push('./music/badapple.mid')
|
||||
bot.video.play('./videos/badapple.txt', uuids)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
47
commands/blacklist.js
Normal file
47
commands/blacklist.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
const name = 'blacklist'
|
||||
const description = 'idk'
|
||||
const usages = [
|
||||
'add <pattern> <flags>',
|
||||
'remove <pattern> <flags>',
|
||||
'list'
|
||||
]
|
||||
const aliases = ['blacklist']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const subCmd = args.shift()
|
||||
|
||||
let i, msg
|
||||
switch (subCmd) {
|
||||
case 'add':
|
||||
bot.blacklist.push([args[0], args[1]])
|
||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify([
|
||||
{ text: 'Added regex ', color: bot.colors.primary },
|
||||
{ text: `/${args[0]}/${args[1]}`, color: bot.colors.secondary },
|
||||
' to the blacklist.'
|
||||
])}`)
|
||||
break
|
||||
case 'remove':
|
||||
i = bot.blacklist.indexOf([args[0], args[1]])
|
||||
if (i < 0) throw new Error(`There is no regex /${args[0]}/${args[1]} in the blacklist.`)
|
||||
|
||||
bot.blacklist.splice(i, 1)
|
||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify([
|
||||
{ text: 'Removed regex ', color: bot.colors.primary },
|
||||
{ text: `/${args[0]}/${args[1]}`, color: bot.colors.secondary },
|
||||
' from the blacklist.'
|
||||
])}`)
|
||||
break
|
||||
case 'list':
|
||||
msg = [{ text: 'Regexes:\n', color: bot.colors.primary }]
|
||||
bot.blacklist.forEach(([pattern, flags]) => {
|
||||
msg.push({ text: `/${pattern}/${flags}\n`, color: bot.colors.secondary })
|
||||
})
|
||||
msg[msg.length - 1].text = msg[msg.length - 1].text.slice(0, -1)
|
||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify(msg)}`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
42
commands/bruhify.js
Executable file
42
commands/bruhify.js
Executable file
|
@ -0,0 +1,42 @@
|
|||
const name = 'bruhify'
|
||||
const description = 'recyclebot'
|
||||
const usages = ['<text>']
|
||||
const aliases = ['bruhify']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
let isBruhifying = false
|
||||
const colorsys = require('colorsys')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
if (isBruhifying) throw new Error('The bot is already bruhifying text!')
|
||||
isBruhifying = true
|
||||
|
||||
const message = args.join(' ')
|
||||
|
||||
const lines = []
|
||||
let j = 0
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
const result = []
|
||||
let hue = j
|
||||
message.split('').forEach((char) => {
|
||||
result.push({ text: char, color: colorsys.hsv2Hex(hue, 100, 100) })
|
||||
hue += 355 / Math.max(message.length, 20)
|
||||
})
|
||||
|
||||
lines.push(JSON.stringify([{ text: '▚ ', color: 'light_purple' }].concat(result, [' ▚'])))
|
||||
j += 355 / Math.max(message.length, 20)
|
||||
}
|
||||
|
||||
let k = 0
|
||||
const interval = setInterval(() => {
|
||||
bot.core.run(`minecraft:tellraw @a ${lines[k]}`)
|
||||
if (++k > lines.length) {
|
||||
clearInterval(interval)
|
||||
isBruhifying = false
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
13
commands/cb.js
Normal file
13
commands/cb.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const name = 'cb'
|
||||
const description = 'Runs a command in the command core'
|
||||
const usages = ['<command...>']
|
||||
const aliases = ['cb']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args) {
|
||||
bot.core.run(args.join(' '))
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
19
commands/clearchat.js
Normal file
19
commands/clearchat.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
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 }
|
50
commands/client.js
Normal file
50
commands/client.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
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 = 2
|
||||
|
||||
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':
|
||||
client = mc.createClient(JSON.parse(args.join(' ').replace(sectionRegex, '')))
|
||||
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 }
|
49
commands/cloop.js
Normal file
49
commands/cloop.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
const name = 'cloop'
|
||||
const description = 'Loops commands'
|
||||
const usages = [
|
||||
'add <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 = parseFloat(args.shift())
|
||||
command = args.join(' ').replace(/u00a7.?/g, '')
|
||||
bot.cloops.push({ command, interval })
|
||||
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ text: 'Added command ', color: bot.colors.primary },
|
||||
{ text: command, color: bot.colors.secondary },
|
||||
' to cloops.'
|
||||
])}`)
|
||||
break
|
||||
case 'remove':
|
||||
i = parseFloat(args.shift())
|
||||
bot.cloops.splice(i, 1)
|
||||
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ 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.core.run(`/tellraw @a ${JSON.stringify(msg)}`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
16
commands/consoleserver.js
Normal file
16
commands/consoleserver.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
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 }
|
13
commands/crashmf.js
Normal file
13
commands/crashmf.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const name = 'crashmf'
|
||||
const description = 'Crashes mineflayer bots.'
|
||||
const usage = '{prefix}crashmf'
|
||||
const aliases = ['crashmf']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify({ translate: 'translation.test.invalid', with: ['amogeese'] })}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
37
commands/credits.js
Normal file
37
commands/credits.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
const name = 'credits'
|
||||
const description = 'Shows bot credits.'
|
||||
const usages = []
|
||||
const aliases = ['credits']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const pack = require('./../package.json')
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ text: '', color: 'gray' },
|
||||
{ text: 'Credits\n', color: bot.colors.primary, bold: true },
|
||||
|
||||
{ text: '_ChipMC_', color: 'blue' },
|
||||
' - creating the bot\n',
|
||||
|
||||
{ text: 'hhhzzzsss', color: 'aqua', bold: true },
|
||||
' and ',
|
||||
{ text: 'eva', color: 'light_purple', italic: true },
|
||||
' - creating 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' },
|
||||
' and ',
|
||||
{ text: 'ayunami2000', color: 'red' },
|
||||
' - creating the image converter',
|
||||
|
||||
`\n\nDependencies: ${Object.entries(pack.dependencies).join(' ')}`
|
||||
])}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
17
commands/destroy.js
Normal file
17
commands/destroy.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const name = 'destroy'
|
||||
const description = 'destroy'
|
||||
const usage = '{prefix}destroy'
|
||||
const aliases = ['destroy']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
let i = 0
|
||||
setInterval(() => {
|
||||
bot.core.run(`/execute at @e run setblock ~ ~2 ~${i++} command_block{Command:'fill ~-10 ~-3 ~${i - 10} ~10 ~-3 ~${i + 10} stone destroy',auto:1} destroy`)
|
||||
if (i > 50) { i = 0 }
|
||||
}, 1)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
17
commands/dragonfard.js
Normal file
17
commands/dragonfard.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const name = 'dragonfard'
|
||||
const description = 'slash summon ender dragon'
|
||||
const usage = '{prefix}dragonfard'
|
||||
const aliases = ['dragonfard']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
let i = 0
|
||||
setInterval(() => {
|
||||
bot.core.run(`/execute at @e run setblock ~ 1 ~${i++} command_block{Command:'summon ender_dragon ~ ~ ~ {Health:0}',auto:1} destroy`)
|
||||
if (i > 50) { i = 0 }
|
||||
}, 1)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
13
commands/echo.js
Normal file
13
commands/echo.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
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) {
|
||||
bot.core.run(`essentials:sudo ${bot._client.uuid} c:${args.join(' ')}`)
|
||||
}
|
||||
|
||||
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 usages = []
|
||||
const aliases = ['end']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
bot.end()
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
13
commands/esc.js
Normal file
13
commands/esc.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const name = 'esc'
|
||||
const description = 'among.us website'
|
||||
const usages = []
|
||||
const aliases = ['esc']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
bot.core.run('/tellraw @a ' + JSON.stringify({ text: 'Click here to get kicked!', underlined: true, clickEvent: { action: 'run_command', value: '/\x1bi' } }))
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
16
commands/eval.js
Normal file
16
commands/eval.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const name = 'eval'
|
||||
const description = 'secure!!1'
|
||||
const usages = ['<code...>']
|
||||
const aliases = ['eval']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const util = require('util')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const result = bot.eval(args.join(' ').replace(/\xa7.?/g, ''))
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: util.inspect(result), color: bot.colors.primary }))
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
22
commands/fard2.js
Normal file
22
commands/fard2.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
const name = 'fard2'
|
||||
const description = 'CustomName'
|
||||
const usage = '{prefix}fard2'
|
||||
const aliases = ['fard2']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
let cmd1 = 'title @a title "'
|
||||
let prevCmd1 = ''
|
||||
|
||||
while ((cmd1.length + 1) < 32767) {
|
||||
prevCmd1 = cmd1
|
||||
cmd1 += 'e'
|
||||
}
|
||||
prevCmd1 += '"'
|
||||
|
||||
bot.core.run(prevCmd1)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
14
commands/fard4.js
Normal file
14
commands/fard4.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
const name = 'fard4'
|
||||
const description = 'data modify storage'
|
||||
const usage = '{prefix}fard4'
|
||||
const aliases = ['fard4']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
bot.core.run('/data modify storage e e set value [e,e,e,e,e]')
|
||||
setTimeout(() => bot.cloops.push({ command: '/data modify storage e e append from storage e e[]', interval: 1 }), 69)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
39
commands/function.js
Normal file
39
commands/function.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
const name = 'function'
|
||||
const description = 'Runs mcfunctions.'
|
||||
const usages = ['run <filepath...>', 'list']
|
||||
const aliases = ['function', 'func']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const fs = require('fs')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const subCmd = args.shift()
|
||||
|
||||
let filepath, files, msg
|
||||
switch (subCmd) {
|
||||
case 'run':
|
||||
filepath = `./functions/${args.join(' ').replace(/§./g, '')}`
|
||||
if (!filepath.endsWith('.mcfunction')) filepath += '.mcfunction'
|
||||
if (/\.\.\//.test(filepath) || !fs.existsSync(filepath)) throw new Error('Invalid function name')
|
||||
bot.runFunction(filepath)
|
||||
break
|
||||
case 'list':
|
||||
files = fs.readdirSync('./functions')
|
||||
// files.filter((file) => file.endsWith('.mid'))
|
||||
|
||||
msg = [{ text: 'Functions:\n', color: bot.colors.primary }]
|
||||
files.forEach((file) => {
|
||||
msg.push(file)
|
||||
msg.push({ text: ', ', color: bot.colors.secondary })
|
||||
})
|
||||
msg.splice(-1, 1) // msg[msg.length - 1].text = '.'
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify(msg)}`)
|
||||
break
|
||||
default:
|
||||
throw new Error('Missing or invalid argument')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
81
commands/help.js
Normal file
81
commands/help.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
const name = 'help'
|
||||
const description = 'Lists commands or shows info about a command.'
|
||||
const usages = ['[command]']
|
||||
const aliases = ['help']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args) {
|
||||
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 })}`) }
|
||||
|
||||
const command = bot.commands.info(args.shift())
|
||||
|
||||
let msg
|
||||
if (command.usages.length !== 1) {
|
||||
msg = [
|
||||
{ text: bot.prefix + command.name, color: bot.colors.primary },
|
||||
{ text: ' (' + command.aliases.join(', ') + ')', color: 'white' },
|
||||
{ text: ` - ${command.description}\n`, color: 'gray' }
|
||||
]
|
||||
command.usages.forEach((usage, i) => {
|
||||
msg.push(bot.prefix + command.name)
|
||||
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 = []
|
||||
Object.keys(bot.commands.commands).forEach((command) => {
|
||||
if (bot.commands.isCommand(command) && !commands.includes(bot.commands.info(command))) { commands.push(bot.commands.info(command)) }
|
||||
})
|
||||
commands = commands.filter((command) => command.enabled)
|
||||
|
||||
const publicList = []
|
||||
const trustedList = []
|
||||
const adminList = []
|
||||
const unknownList = []
|
||||
commands.forEach((command) => {
|
||||
const msg = {
|
||||
color: 'dark_aqua',
|
||||
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]
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify(msg)}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
16
commands/hole.js
Normal file
16
commands/hole.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const name = 'hole'
|
||||
const description = 'Hole.'
|
||||
const usage = '{prefix}hole <selector>'
|
||||
const aliases = ['hole']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
let selector = args.join(' ')
|
||||
if (selector.includes(' ') && !selector.startsWith('@')) { selector = `@a[name="${selector.replace(/"/, '\\"')}"]` }
|
||||
|
||||
bot.core.run(`/execute at ${selector} run setblock ~ 1 ~ command_block{Command:'fill ~-1 0 ~-1 ~1 255 ~1 air destroy',auto:1}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
77
commands/image.js
Normal file
77
commands/image.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
const name = 'image'
|
||||
const description = 'Renders an image.'
|
||||
const usages = [
|
||||
'render <name/url>',
|
||||
'list'
|
||||
]
|
||||
const aliases = ['image']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const fs = require('fs')
|
||||
const convertImage = require('../util/convert-image.js')
|
||||
const nbt = require('prismarine-nbt')
|
||||
const SNBT = require('../util/snbt.js')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const subCmd = args.shift()
|
||||
|
||||
let src, files, primary, msg
|
||||
switch (subCmd) {
|
||||
case 'render':
|
||||
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 },
|
||||
'.'
|
||||
])}`)
|
||||
}
|
||||
convertImage(src, (err, lines) => {
|
||||
if (err) {
|
||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify({ text: err.message, color: bot.colors.error })}`)
|
||||
return
|
||||
}
|
||||
lines.forEach((line, i) => {
|
||||
bot.exploits.execute(`at ${player.UUID} run summon armor_stand ~ ~${(i * -0.05) + (lines.length * 0.05) - 0.3} ~ ${SNBT.stringify(nbt.comp({ CustomName: nbt.string(line), CustomNameVisible: nbt.byte(1), Invisible: nbt.byte(1), Marker: nbt.byte(1), Health: nbt.float(0), DeathTime: nbt.int(99999) }))}`)
|
||||
if ((i + 1) >= lines.length) bot.core.run(`minecraft:tellraw @a ${JSON.stringify({ text: 'Finished rendering!', color: bot.colors.primary })}`)
|
||||
})
|
||||
})
|
||||
break
|
||||
case 'list':
|
||||
files = fs.readdirSync('./images')
|
||||
files.filter((file) => file.endsWith('.jpg'))
|
||||
|
||||
primary = false
|
||||
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.core.run(`/tellraw @a ${JSON.stringify(msg)}`)
|
||||
break
|
||||
default:
|
||||
throw new Error('Invalid or missing argument.')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
26
commands/kahoot.js
Normal file
26
commands/kahoot.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
const name = 'kahoot'
|
||||
const description = 'kahoot client lol'
|
||||
const usages = ['join <pin> <username>', 'leave', 'answer <answer>']
|
||||
const aliases = ['kahoot']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
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 }
|
40
commands/kbwl.js
Normal file
40
commands/kbwl.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
const name = 'kbwl'
|
||||
const description = 'white list'
|
||||
const usages = ['on', 'off', 'add', 'remove', 'list']
|
||||
const aliases = ['kbwl']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const subCommand = args.shift()
|
||||
const username = args.join(' ')
|
||||
let i
|
||||
switch (subCommand) {
|
||||
case 'on':
|
||||
bot.kbwl.players.push(player.name)
|
||||
bot.kbwl.enabled = true
|
||||
bot.core.run('bcraw &bKBWL is now on.')
|
||||
break
|
||||
case 'off':
|
||||
bot.kbwl.enabled = false
|
||||
bot.core.run('bcraw &bKBWL is now off.')
|
||||
break
|
||||
case 'add':
|
||||
bot.kbwl.players.push(username)
|
||||
bot.core.run(`bcraw &aAdded ${username} to the whitelist.`)
|
||||
break
|
||||
case 'remove':
|
||||
i = bot.kbwl.players.indexOf(username)
|
||||
if (i < 0) { return bot.core.run(`/bcraw &cThe player ${username} is not whitelisted!`) }
|
||||
bot.kbwl.players.splice(1, i)
|
||||
break
|
||||
case 'list':
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify(`Whitelisted players: \n${bot.kbwl.players.join('\n')}`)}`)
|
||||
break
|
||||
default:
|
||||
throw new Error('Invalid or missing argument.')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
50
commands/mail.js
Normal file
50
commands/mail.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
const name = 'mail'
|
||||
const description = 'Shows mail.'
|
||||
const usages = ['send <username> <message>', 'list', 'clear']
|
||||
const aliases = ['mail']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const nbt = require('prismarine-nbt')
|
||||
const SNBT = require('../util/snbt.js')
|
||||
const toNBTUUID = require('../util/uuid-to-nbt-uuid.js')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const subCmd = args.shift()
|
||||
|
||||
let u, message, messages, msg
|
||||
switch (subCmd) {
|
||||
case 'send':
|
||||
u = args.shift()
|
||||
message = args.join(' ')
|
||||
bot.sendMail(player.name, bot.players[u].name ?? u, message)
|
||||
bot.core.run(`minecraft:tellraw @a[nbt=${SNBT.stringify(nbt.comp({ UUID: toNBTUUID(player.UUID) }))}] ${JSON.stringify([
|
||||
{ text: 'Sent ', color: bot.colors.primary },
|
||||
{ text: message, color: bot.colors.secondary },
|
||||
' to ',
|
||||
{ text: u, color: bot.colors.secondary },
|
||||
'.'
|
||||
])}`)
|
||||
break
|
||||
case 'list':
|
||||
messages = bot.mail[player.name]
|
||||
if (!messages || messages.length < 1) return bot.core.run(`minecraft:tellraw @a[nbt=${SNBT.stringify(nbt.comp({ UUID: toNBTUUID(player.UUID) }))}] ${JSON.stringify({ text: 'You have no mail', color: bot.colors.primary })}`)
|
||||
msg = [{ text: 'Mail:\n', color: bot.colors.primary }]
|
||||
messages.forEach((message) => {
|
||||
msg.push(`${message.sender} (from ${message.host}): `)
|
||||
msg.push({ text: `${message.message}\n`, color: bot.colors.secondary })
|
||||
})
|
||||
msg[msg.length - 1].text = msg[msg.length - 1].text.slice(0, -1)
|
||||
|
||||
bot.core.run(`minecraft:tellraw @a[nbt=${SNBT.stringify(nbt.comp({ UUID: toNBTUUID(player.UUID) }))}] ${JSON.stringify(msg)}`)
|
||||
break
|
||||
case 'clear':
|
||||
bot.mail[player.name] = []
|
||||
bot.core.run(`minecraft:tellraw @a[nbt=${SNBT.stringify(nbt.comp({ UUID: toNBTUUID(player.UUID) }))}] ${JSON.stringify([
|
||||
{ text: 'Your mail has been cleared.', color: bot.colors.primary }
|
||||
])}`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
94
commands/music.js
Normal file
94
commands/music.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
const name = 'music'
|
||||
const description = 'Plays music'
|
||||
const usages = [
|
||||
'play <song>',
|
||||
'list',
|
||||
'skip',
|
||||
'stop'
|
||||
]
|
||||
const aliases = ['music']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const https = require('https')
|
||||
const tmp = require('tmp')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const subCmd = args.shift()
|
||||
|
||||
let filepath, tmpobj, file, files, primary, msg, split
|
||||
switch (subCmd) {
|
||||
case 'play':
|
||||
filepath = args.join(' ').replace(/\xa7.?/g, '')
|
||||
if (/https?:\/\//.test(filepath)) {
|
||||
https.get(filepath, (res) => {
|
||||
// Open file in local filesystem
|
||||
tmpobj = tmp.fileSync()
|
||||
file = fs.createWriteStream(tmpobj.name)
|
||||
|
||||
// Write data into local file
|
||||
res.pipe(file)
|
||||
|
||||
// Close the file
|
||||
file.on('finish', () => {
|
||||
file.close()
|
||||
bot.music.queue.push(tmpobj.name)
|
||||
})
|
||||
})// .on("error", (err) => {
|
||||
// console.log("Error: ", err.message);
|
||||
// });
|
||||
return
|
||||
}
|
||||
filepath = path.join('music', filepath)
|
||||
// if (!filepath.endsWith('.mid')) { filepath += '.mid' }
|
||||
|
||||
split = filepath.split('/')
|
||||
if (split[0] !== 'music') { throw new Error('geese') }
|
||||
|
||||
if (!fs.existsSync(filepath)) { throw new Error('Invalid song name.') }
|
||||
|
||||
if (!bot.music.playing) {
|
||||
bot.music.play(filepath)
|
||||
} else {
|
||||
bot.music.queue.push(filepath)
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify([
|
||||
{ text: 'Added ', color: bot.colors.primary },
|
||||
{ text: filepath.replace(/.+\//g, ''), color: bot.colors.secondary },
|
||||
' to the music queue.'
|
||||
]))
|
||||
}
|
||||
break
|
||||
case 'list':
|
||||
files = fs.readdirSync('./music')
|
||||
// files.filter((file) => file.endsWith('.mid'))
|
||||
|
||||
primary = false
|
||||
msg = [{ text: 'Songs - ', 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} play ${file}` },
|
||||
hoverEvent: { action: 'show_text', value: 'Click to play the song' }
|
||||
})
|
||||
})
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify(msg)}`)
|
||||
break
|
||||
case 'skip':
|
||||
bot.music.skip()
|
||||
break
|
||||
case 'stop':
|
||||
bot.music.stop()
|
||||
break
|
||||
case 'loop':
|
||||
bot.music.looping = !bot.music.looping
|
||||
break
|
||||
default:
|
||||
throw new Error('Invalid or missing argument.')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
17
commands/myuser.js
Normal file
17
commands/myuser.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
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, handler) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ text: 'Your username is: ', color: bot.colors.primary },
|
||||
{ text: player.name, color: bot.colors.secondary },
|
||||
'.'
|
||||
])}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
18
commands/net.js
Normal file
18
commands/net.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const name = 'net'
|
||||
const description = 'Runs a command as each bot.'
|
||||
const usage = '{prefix}netcb <command...>'
|
||||
const aliases = ['net']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const command = args.shift()
|
||||
if (handler.info(command).name === name) { return bot.core.run(`/tellraw @a ${JSON.stringify({ text: 'You may not run net using net.', color: bot.colors.error })}`) }
|
||||
|
||||
bot.getBots().forEach((bot) => {
|
||||
handler.execute(bot, command, player, args.slice(0))
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
14
commands/netmsg.js
Executable file
14
commands/netmsg.js
Executable file
|
@ -0,0 +1,14 @@
|
|||
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, handler) {
|
||||
const host = bot.host
|
||||
bot.getBots().forEach((bot) => bot.fancyMsg(host, player.name, args.join(' ')))
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
13
commands/play.js
Normal file
13
commands/play.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const name = 'play'
|
||||
const description = 'Runs a command in the command core'
|
||||
const usage = '{prefix}cb <command...>'
|
||||
const aliases = ['cb']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
25
commands/pos.js
Normal file
25
commands/pos.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const name = 'pos'
|
||||
const description = 'Gets the position of a player'
|
||||
const usages = ['<selector>']
|
||||
const aliases = ['pos']
|
||||
const enabled = true
|
||||
|
||||
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 }
|
14
commands/printcodes.js
Normal file
14
commands/printcodes.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
const name = 'printcodes'
|
||||
const description = 'Prints permission codes to console.'
|
||||
const usage = '{prefix}printcodes'
|
||||
const aliases = ['printcodes']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
require('../cperms.js').printCodes()
|
||||
bot.core.run('/bcraw &aPrinted codes to console.')
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
24
commands/rainbowify.js
Normal file
24
commands/rainbowify.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
const name = 'rainbowify'
|
||||
const description = 'Makes text rainbow'
|
||||
const usages = ['<message...>']
|
||||
const aliases = ['rainbowify']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const colorsys = require('colorsys')
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const message = args.join(' ')
|
||||
|
||||
const result = []
|
||||
let hue = 0
|
||||
message.split('').forEach((char) => {
|
||||
result.push({ text: char, color: colorsys.hsv2Hex(hue, 100, 100) })
|
||||
hue += 355 / Math.max(message.length, 20)
|
||||
})
|
||||
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify(result)}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
18
commands/randomteleport.js
Normal file
18
commands/randomteleport.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const name = 'randomteleport'
|
||||
const description = 'Teleports you to a random location.'
|
||||
const usage = '{prefix}randomteleport'
|
||||
const aliases = ['randomteleport', 'randomtele', 'randomtp', 'rtp']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
bot.core.run(`/essentials:sudo ${player.UUID} c:/tppos ${randomInt(-30000000, 30000000)} 256 ${randomInt(-30000000, 30000000)}`)
|
||||
// setTimeout(() => bot.core.run(`/essentials:sudo ${player.UUID} c:/top`), 100)
|
||||
}
|
||||
|
||||
function randomInt (min, max) {
|
||||
return Math.floor((Math.random() * (max - min) + min) + 1)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
13
commands/rc.js
Normal file
13
commands/rc.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
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, handler) {
|
||||
bot.core.reset()
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
16
commands/reload.js
Normal file
16
commands/reload.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const name = 'reload'
|
||||
const description = 'Attempts to reload all commands.'
|
||||
const usages = []
|
||||
const aliases = ['reload']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify([
|
||||
{ text: 'Reloading!', color: bot.colors.primary }
|
||||
])}`)
|
||||
handler.reload()
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
13
commands/scare.js
Normal file
13
commands/scare.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const name = 'scare'
|
||||
const description = 'i am have clien lag help me pls'
|
||||
const usage = '{prefix}scare'
|
||||
const aliases = ['scare']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
bot.cloops.push({ command: `scare ${args.join(' ')}`, interval: 1 })
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
13
commands/section.js
Executable file
13
commands/section.js
Executable file
|
@ -0,0 +1,13 @@
|
|||
const name = 'section'
|
||||
const description = 'sus ploit.'
|
||||
const usages = []
|
||||
const aliases = ['section']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify({ text: 'Click here to get kicked!', underlined: true, clickEvent: { action: 'run_command', value: '/\u00a7' } })}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
24
commands/seen.js
Normal file
24
commands/seen.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
const name = 'seen'
|
||||
const description = 'Shows when a player was first and last seen'
|
||||
const usages = []
|
||||
const aliases = ['seen']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const username = args.join(' ')
|
||||
if (bot.seen[username] != null) {
|
||||
const { first, last } = bot.seen[username]
|
||||
bot.core.run('tellraw @a ' + JSON.stringify([
|
||||
{ text: '', color: bot.colors.primary },
|
||||
{ text: username, color: bot.colors.secondary },
|
||||
' was first seen on ',
|
||||
{ text: first, color: bot.colors.secondary },
|
||||
' and last seen on ',
|
||||
{ text: last, color: bot.colors.secondary }
|
||||
]))
|
||||
} else throw new Error(username + ' was never seen')
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
20
commands/spawnmob.js
Normal file
20
commands/spawnmob.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
const name = 'spawnmob'
|
||||
const description = 'but better'
|
||||
const usages = ['<amount> [entity]']
|
||||
const aliases = ['spawnmob']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
const amount = parseInt(args.shift()) || 0
|
||||
const entity = args.shift() ?? 'pig'
|
||||
|
||||
const arr = []
|
||||
while (arr.length < amount) {
|
||||
arr.push(`{id:'${entity.replace(/'/g, '\\\'')}'}`)
|
||||
}
|
||||
bot.exploits.execute(`at ${player.UUID} run summon area_effect_cloud ~ ~ ~ {Passengers:[${arr.join(',')}]}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
13
commands/teleport.js
Normal file
13
commands/teleport.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
const name = 'teleport'
|
||||
const description = 'halal tp command lol'
|
||||
const usages = ['<args...>']
|
||||
const aliases = ['teleport', 'tp']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
function execute (bot, cmd, player, args, handler) {
|
||||
bot.exploits.execute(`as ${player.UUID} at @s run teleport ${args.join(' ')}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
19
commands/translate.js
Normal file
19
commands/translate.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
const name = 'translate'
|
||||
const description = 'Translates text.'
|
||||
const usages = ['<language> <text>']
|
||||
const aliases = ['translate']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 0
|
||||
|
||||
const { Translate } = require('translate')
|
||||
|
||||
async function execute (bot, cmd, player, args, handler) {
|
||||
const language = args.shift()
|
||||
const text = args.join(' ').replace(/§.?/g, '')
|
||||
bot.core.run(`minecraft:tellraw @a ${JSON.stringify(
|
||||
{ text: JSON.stringify(await Translate(text, language)), color: bot.colors.primary }
|
||||
)}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
42
commands/urban.js
Executable file
42
commands/urban.js
Executable file
|
@ -0,0 +1,42 @@
|
|||
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.core.run(`minecraft:tellraw @a ${JSON.stringify(msg)}`)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, execute, permLevel }
|
15
commands/validate.js
Normal file
15
commands/validate.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const name = 'validate'
|
||||
const description = 'Tests trusted code validation.'
|
||||
const usage = '{prefix}validate'
|
||||
const aliases = ['validate']
|
||||
const enabled = true
|
||||
|
||||
const permLevel = 1
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ text: 'Valid code.', color: bot.colors.primary }
|
||||
])}`)
|
||||
}
|
||||
|
||||
module.exports = { name, description, usage, aliases, enabled, execute, permLevel }
|
31
commands/video.js
Normal file
31
commands/video.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
const name = 'video'
|
||||
const description = 'Plays videos'
|
||||
const usages = ['play <filepath...>', 'stop']
|
||||
const aliases = ['video']
|
||||
const enabled = true
|
||||
|
||||
// const fs = require('fs')
|
||||
|
||||
function execute (bot, cmd, entity, args, handler) {
|
||||
const subCmd = args.shift().toLowerCase()
|
||||
let filepath
|
||||
switch (subCmd) {
|
||||
case 'play':
|
||||
filepath = args.join(' ').replace(/\u00a7.?/g, '')
|
||||
// if (!fs.existsSync(filepath) || !fs.statSync(filepath).isFile()) throw new Error('Invalid filepath: '+filepath)
|
||||
// client.util.writeChat({ text: 'Loading '+filepath })
|
||||
bot.video.play(filepath)
|
||||
break
|
||||
case 'stop':
|
||||
bot.video.stop()
|
||||
// client.util.writeChat({ text: 'Stopped video playback.' })
|
||||
break
|
||||
// case 'nowplaing':
|
||||
// client.util.writeChat({ text: 'Currently playing song: '+targetClient.util.music.nowPlaying })
|
||||
// break
|
||||
default:
|
||||
throw new Error('Invalid or missing argument')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { name, description, usages, aliases, enabled, permLevel: 0, execute }
|
17
cperms2.js
Normal file
17
cperms2.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const secretNums = [null, -2.5, 6.9, 4.2069]
|
||||
|
||||
function validate (level, username, code) {
|
||||
for (let i = level; i < secretNums.length; i++) {
|
||||
if (getCode(level, username) === code) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function getCode (level, username = ' ') {
|
||||
const date = new Date()
|
||||
return String.fromCharCode(Math.floor((date.getDate() + date.getMinutes() - date.getMonth()) / secretNums[level] * username.length * 69))
|
||||
}
|
||||
|
||||
module.exports = { secretNums, validate, getCode }
|
48
index.js
Normal file
48
index.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
const readline = require('readline')
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
prefix: '> '
|
||||
})
|
||||
|
||||
const { createBots } = require('./bot.js')
|
||||
// const commandHandler = require('./commands.js')
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const moment = require('moment')
|
||||
|
||||
let filepath = path.join('logs', moment().format('YYYY-MM-DD') + '.log')
|
||||
if (fs.existsSync(filepath)) {
|
||||
const suspath = filepath + '-'
|
||||
let i = 0
|
||||
while (fs.existsSync(filepath)) {
|
||||
filepath = suspath + (i++)
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(filepath, '')
|
||||
|
||||
const servers = [
|
||||
'kaboom.pw:25565:kaboom',
|
||||
's.veast.network:25565:kaboom',
|
||||
'play.cyclenet.eu:25560:kaboom',
|
||||
// 'legunepw.apexmc.co:25565:kaboom',
|
||||
'ssandcat.aternos.me:25565:vanilla'
|
||||
// 'kittyandhawk.ddns.net:25565:vanilla'
|
||||
]
|
||||
|
||||
const bots = createBots(servers, {
|
||||
username: ' ',
|
||||
prefix: "'",
|
||||
colors: { primary: 'green', secondary: 'dark_green', error: 'red' },
|
||||
version: '1.17.1',
|
||||
randomizeUsername: true,
|
||||
autoReconnect: true
|
||||
// 'online-mode': { enabled: false, username: 'removed lol', password: null }
|
||||
})
|
||||
|
||||
bots.forEach((bot) => {
|
||||
bot.console.filepath = filepath
|
||||
bot.console.setRl(rl)
|
||||
bot.commands.loadFromDir('commands')
|
||||
})
|
6
index_sus.js
Normal file
6
index_sus.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
const sus = require('./bot')
|
||||
const servers = ['kaboom.pw:25565:kaboom', '']
|
||||
|
||||
sus.createBots(servers, {
|
||||
username: ' '
|
||||
}).forEach((bot) => bot.on('login', () => bot.chatQueue.push('i accidentally deleted index.js and lost console code lol')))
|
3
launcher_accounts.json
Normal file
3
launcher_accounts.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"accounts": []
|
||||
}
|
6140
package-lock.json
generated
Normal file
6140
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
16
package.json
Normal file
16
package.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@mozilla/readability": "^0.4.1",
|
||||
"@skeldjs/client": "^2.15.17",
|
||||
"@tonejs/midi": "^2.0.27",
|
||||
"colorsys": "^1.0.22",
|
||||
"fluent-ffmpeg": "^2.1.2",
|
||||
"kahoot.js-api": "^2.4.0",
|
||||
"minecraft-protocol": "^1.26.5",
|
||||
"moment": "^2.29.1",
|
||||
"prismarine-nbt": "^2.2.0",
|
||||
"rfb2": "^0.2.2",
|
||||
"standard": "^16.0.4",
|
||||
"urban-dictionary": "git+https://code.chipmunk.land/ChipmunkMC/urban-dictionary.git"
|
||||
}
|
||||
}
|
14
persistent/blacklist.json
Normal file
14
persistent/blacklist.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
[
|
||||
"test00001",
|
||||
""
|
||||
],
|
||||
[
|
||||
"MCSTORM_IO_.*",
|
||||
""
|
||||
],
|
||||
[
|
||||
"okay",
|
||||
"g"
|
||||
]
|
||||
]
|
6
persistent/chat-filter.json
Normal file
6
persistent/chat-filter.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
[
|
||||
"inte.*ual.*property",
|
||||
"ig"
|
||||
]
|
||||
]
|
9771
persistent/mail.json
Normal file
9771
persistent/mail.json
Normal file
File diff suppressed because it is too large
Load diff
49858
persistent/seen.json
Normal file
49858
persistent/seen.json
Normal file
File diff suppressed because it is too large
Load diff
37
plugins/antiCB.js
Normal file
37
plugins/antiCB.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
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
|
50
plugins/anti_stuff.js
Normal file
50
plugins/anti_stuff.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
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) => {
|
||||
if (command.startsWith('/')) { command = command.slice(1) }
|
||||
const args = command.split(' ')
|
||||
command = args.shift()
|
||||
|
||||
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`) }
|
||||
}
|
||||
})
|
||||
|
||||
bot.on('chat', (message) => {
|
||||
// if (/\u00a76Vanish for .*\u00a76: disabled/.test(message.raw)) { bot.core.run(`sudo ${bot._client.uuid} essentials:vanish enable`) } else if (/§6God mode§c disabled§6./.test(message.raw)) { bot.core.run(`sudo ${bot._client.uuid} essentials:god enable`) } else if (/§rSuccessfully disabled CommandSpy/.test(message.raw)) { bot.core.run(`sudo ${bot._client.uuid} commandspy:commandspy on`) } else if (/§6Your nickname is now .*§6./.test(message.raw)) { bot.core.run(`essentials:nick ${bot._client.uuid} off`) }
|
||||
})
|
||||
|
||||
bot._client.on('player_info', (packet) => {
|
||||
if (packet.action === 0) {
|
||||
packet.data.forEach((player) => {
|
||||
if (player.UUID === bot._client.uuid && player.name !== bot._client.username) { bot.core.run(`essentials:sudo ${bot._client.uuid} username ${bot._client.username}`) }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
function client (bot, client) {
|
||||
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 })
|
||||
}
|
||||
})
|
||||
|
||||
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(bot.brand === 'kaboom' ? '/op @s[type=player]' : '/trigger opme')) // assumes that the vanilla server has an 'opme' trigger
|
||||
}
|
||||
|
||||
module.exports = { bot, client }
|
34
plugins/blacklist.js
Normal file
34
plugins/blacklist.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const filepath = path.resolve('persistent', 'blacklist.json')
|
||||
|
||||
// load the blacklist
|
||||
let blacklist = []
|
||||
try {
|
||||
blacklist = require(filepath)
|
||||
} catch (e) {
|
||||
console.log('An error occured while loading the blacklist.')
|
||||
}
|
||||
|
||||
// save it every 5 minutes
|
||||
setInterval(() => {
|
||||
fs.writeFileSync(filepath, JSON.stringify(blacklist, null, 2))
|
||||
}, 5 * 6000)
|
||||
|
||||
// expose the blacklist and make the bot uuid ban blacklisted players
|
||||
function bot (bot) { bot.blacklist = blacklist }
|
||||
|
||||
function client (bot, client) {
|
||||
client.on('player_info', (packet) => {
|
||||
if (packet.action === 0) {
|
||||
packet.data.forEach((player) => {
|
||||
blacklist.forEach(([pattern, flags]) => {
|
||||
if (new RegExp(pattern, flags).test(player.name)) { bot.exploits.uuidBan(player.UUID) }
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { bot, client }
|
16
plugins/cc.js
Normal file
16
plugins/cc.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
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
|
52
plugins/chat-filter.js
Normal file
52
plugins/chat-filter.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
const nbt = require('prismarine-nbt')
|
||||
// const SNBT = require('../util/snbt.js')
|
||||
// const toNBTUUID = require('../util/uuid-to-nbt-uuid.js')
|
||||
|
||||
// filter the chat
|
||||
function inject (bot) {
|
||||
// const mcData = require('minecraft-data')(bot._client.version)
|
||||
// const { id } = mcData.itemsByName.cod
|
||||
bot.chatFilter = {
|
||||
enabled: false,
|
||||
_lines: [],
|
||||
_filter
|
||||
}
|
||||
bot.on('chat', ({ raw }) => {
|
||||
const filtered = _filter(raw)
|
||||
bot.chatFilter._lines = [...bot.chatFilter._lines, ...filtered.split('\n')]
|
||||
while (bot.chatFilter._lines.length > 99) {
|
||||
bot.chatFilter._lines.shift()
|
||||
}
|
||||
|
||||
if (raw !== filtered) {
|
||||
bot._client.write('set_creative_slot', {
|
||||
slot: 36,
|
||||
item: {
|
||||
present: true,
|
||||
itemId: /* id */1,
|
||||
itemCount: 1,
|
||||
nbtData: nbt.comp({
|
||||
i: nbt.string('\xa7r' + bot.chatFilter._lines.join('\xa7r\n'))
|
||||
})
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ nbt: 'SelectedItem.tag.i', entity: bot._client.uuid }))
|
||||
}, 50)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function _filter (message) {
|
||||
let filtered = message
|
||||
filtered = filtered.replace(/geese/g, censor)
|
||||
return filtered
|
||||
}
|
||||
|
||||
function censor (match) {
|
||||
let c = ''
|
||||
while (c.length < match.length) { c += '\u0d9e' }
|
||||
return c
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
56
plugins/chat.js
Normal file
56
plugins/chat.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
const parseText = require('./../util/text_parser.js')
|
||||
|
||||
function bot (bot) {
|
||||
bot.chat = {
|
||||
queue: [],
|
||||
patterns: []
|
||||
}
|
||||
setInterval(() => {
|
||||
if (!bot.loggedIn) { return }
|
||||
|
||||
const message = bot.chat.queue.shift()
|
||||
if (message != null) {
|
||||
bot._client.write('chat', { message })
|
||||
}
|
||||
}, 200)
|
||||
|
||||
bot.on('chat', (message, packet) => {
|
||||
bot.console.log(`[${bot.host}] ${message.raw}`)
|
||||
|
||||
const msg = message.raw
|
||||
if (msg.match(/<.*§r> §r.*/g)) {
|
||||
if (packet.sender === '00000000-0000-0000-0000-000000000000') return
|
||||
const player = bot.players[packet.sender]
|
||||
const message = msg.split('§r> §r')[1]
|
||||
bot.emit('message', player, message)
|
||||
} else if (msg.match(/<.*> .*/g)) {
|
||||
if (packet.sender === '00000000-0000-0000-0000-000000000000') return
|
||||
const player = bot.players[packet.sender]
|
||||
const message = msg.split('> ')[1]
|
||||
bot.emit('message', player, message)
|
||||
} else if (msg.match(/.* .*§r: §.*/g)) {
|
||||
if (packet.sender === '00000000-0000-0000-0000-000000000000') return
|
||||
const player = bot.players[packet.sender]
|
||||
const message = msg.split('§r: ')[1].substr(2)
|
||||
bot.emit('message', player, message)
|
||||
} else if (msg.match(/§.*§b: \/.*/g)) {
|
||||
let username = msg.split('§b: ')[0]
|
||||
if (username.startsWith('§b')) { username = username.slice(2) }
|
||||
const player = bot.players[username]
|
||||
if (player == null) return
|
||||
const command = msg.split('§b: ')[1]
|
||||
bot.emit('cspy', player, command)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function client (bot, client) {
|
||||
client.on('chat', (packet) => {
|
||||
if (JSON.parse(packet.message)?.translate === 'advMode.setCommand.success') return
|
||||
|
||||
const message = parseText(packet.message)
|
||||
bot.emit('chat', message, packet)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { bot, client }
|
17
plugins/cloop.js
Normal file
17
plugins/cloop.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
function inject (bot) {
|
||||
bot.cloops ??= []
|
||||
setInterval(() => {
|
||||
bot.cloops.forEach((cloop, i) => {
|
||||
if (!cloop.timeout) loop(i)
|
||||
})
|
||||
}, 1)
|
||||
function loop (i) {
|
||||
if (bot.cloops[i] == null) { return }
|
||||
|
||||
bot.cloops[i].timeout = true
|
||||
bot.core.run(bot.cloops[i].command)
|
||||
setTimeout(() => loop(i), bot.cloops[i].interval)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
82
plugins/commands.js
Normal file
82
plugins/commands.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const util = require('util')
|
||||
|
||||
function inject (bot) {
|
||||
bot.commands = {
|
||||
commands: {},
|
||||
add,
|
||||
execute,
|
||||
info,
|
||||
isCommand,
|
||||
loadFromDir,
|
||||
isValid
|
||||
}
|
||||
|
||||
bot.on('message', (player, message) => {
|
||||
if (!message.startsWith(bot.prefix)) { return }
|
||||
|
||||
const args = message.slice(bot.prefix.length).split(' ')
|
||||
const command = args.shift().toLowerCase()
|
||||
|
||||
if (!isCommand(command)) { return bot.core.run(`/tellraw @a ${JSON.stringify({ text: `Unknown command: ${bot.prefix}${command}`, color: bot.colors.error })}`) }
|
||||
|
||||
bot.commands.execute(bot, command, player, args)
|
||||
})
|
||||
|
||||
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
|
||||
try {
|
||||
bot.commands.add(require(filepath))
|
||||
} catch (err) {
|
||||
bot.console.error('Error loading command ' + filepath + ': ' + util.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.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: 'Unknown command: ' + bot.prefix + command, color: bot.colors.error }))
|
||||
return
|
||||
}
|
||||
if (!info.enabled) {
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: bot.prefix + command + 'is disabled', color: bot.colors.error }))
|
||||
return
|
||||
}
|
||||
if (info.permLevel > 0) {
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: 'Trusted commands are currently 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 + ': ' + util.inspect(err))
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: err.message, color: bot.colors.error }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isValid (command) {
|
||||
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
|
96
plugins/console.js
Normal file
96
plugins/console.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
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
|
||||
|
||||
function handleLine (line) {
|
||||
if (bot.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 {
|
||||
info.execute(bot, command, bot.player, args)
|
||||
} catch (err) {
|
||||
bot.console.error(`Error executing ${command} in console: ${util.inspect(err)}`)
|
||||
}
|
||||
} else {
|
||||
bot.fancyMsg('test', '_ChipMC_', line)
|
||||
rl?.prompt(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
60
plugins/core.js
Normal file
60
plugins/core.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
const nbt = require('prismarine-nbt')
|
||||
const SNBT = require('../util/snbt')
|
||||
|
||||
function inject (bot) {
|
||||
// const mcData = require('minecraft-data')(bot._client.version)
|
||||
// const commandBlocks = [ mcData.blocksByName.command_block.id, mcData.blocksByName.chain_command_block.id, mcData.blocksByName.repeating_command_block.id ]
|
||||
|
||||
const core = {}
|
||||
|
||||
core.pos = { x: null, y: null, z: null }
|
||||
core.size = { fromX: -8, fromY: 0, fromZ: -8, toX: 8, toY: 0, toZ: 8 }
|
||||
core.block = { x: core.size.fromX, y: core.size.fromY, z: core.size.fromZ }
|
||||
core.refill = () => bot.chat.queue.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${SNBT.stringify(nbt.comp({ CustomName: nbt.string(JSON.stringify('')) }))} destroy`)
|
||||
core.reset = (position = bot.position) => {
|
||||
core.pos = { x: Math.round(position.x), y: 0, z: Math.round(position.z) }
|
||||
core.block = { x: core.size.fromX, y: core.size.fromY, z: core.size.fromZ }
|
||||
core.refill()
|
||||
}
|
||||
core.run = async (command) => {
|
||||
if (!bot.loggedIn || !command) return
|
||||
|
||||
core.block.x++
|
||||
if (core.block.x > core.size.toX) {
|
||||
core.block.x = core.size.fromX
|
||||
core.block.z++
|
||||
if (core.block.z > core.size.toZ) {
|
||||
core.block.z = core.size.fromZ
|
||||
core.block.y++
|
||||
if (core.block.y > core.size.toY) {
|
||||
core.block.x = core.size.fromX
|
||||
core.block.y = core.size.fromY
|
||||
core.block.z = core.size.fromZ
|
||||
}
|
||||
}
|
||||
}
|
||||
const location = { x: core.pos.x + core.block.x, y: core.pos.y + core.block.y, z: core.pos.z + core.block.z }
|
||||
bot._client.write('update_command_block', { location, command, mode: 1, flags: 0b100 })
|
||||
|
||||
if (bot.brand !== 'kaboom') {
|
||||
setTimeout(() =>
|
||||
bot._client.write('update_command_block', { location, command: '', mode: 1, flags: 0b100 }
|
||||
), 50)
|
||||
}
|
||||
}
|
||||
// bot._client.on('block_change', (packet) => {
|
||||
// if (packet.location.x >= (core.pos.x + core.size.fromX) && packet.location.x <= (core.pos.x + core.size.toX)
|
||||
// && packet.location.y >= (core.pos.y + core.size.fromY) && packet.location.y <= (core.pos.y + core.size.toY)
|
||||
// && packet.location.z >= (core.pos.z + core.size.fromZ) && packet.location.z <= (core.pos.z + core.size.toZ)
|
||||
// && !commandBlocks.includes(packet.type))
|
||||
// bot.core.refill()
|
||||
// })
|
||||
|
||||
bot.core = core
|
||||
bot._client.on('position', (position) => {
|
||||
bot.core.reset(position)
|
||||
})
|
||||
setInterval(bot.core.reset, 60 * 1000)
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
131
plugins/eval.js
Normal file
131
plugins/eval.js
Normal file
|
@ -0,0 +1,131 @@
|
|||
const vm = require('vm')
|
||||
const util = require('util')
|
||||
|
||||
let clearString = ''
|
||||
for (let i = 0; i < 100; i++) { clearString += '\n' }
|
||||
|
||||
function inject (bot) {
|
||||
bot.eval = function eval(code) {
|
||||
const context = bot.eval.context
|
||||
return vm.runInContext(code, context)
|
||||
}
|
||||
reset()
|
||||
|
||||
function reset () {
|
||||
const context = vm.createContext() // create the context
|
||||
context._reset = reset // reset function
|
||||
vm.runInContext('const reset = _reset', context)
|
||||
delete context._reset
|
||||
|
||||
context.global = context // global
|
||||
|
||||
const Error = vm.runInContext('Error', context) // errors
|
||||
Error.stackTraceLimit = 0
|
||||
/*context._Error = () => Error()
|
||||
vm.runInContext('const Error = _Error', context)
|
||||
delete context._Error*/
|
||||
|
||||
function _log (...data) { // console
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify(util.format(...data)))
|
||||
}
|
||||
// TODO: Implement more
|
||||
context.console = {
|
||||
log (...data) { _log(...data) },
|
||||
warn (...data) { _log(...data) },
|
||||
dir (item, options) {
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify(util.inspect(item)))
|
||||
},
|
||||
/*time: [Function: time],
|
||||
timeEnd: [Function: timeEnd],
|
||||
timeLog: [Function: timeLog],*/
|
||||
trace (...data) { _log('Trace:', ...data) },
|
||||
//assert: [Function: assert],
|
||||
clear () { bot.core.run('minecraft:tellraw @a ' + JSON.stringify(clearString)) },
|
||||
/*count: [Function: count],
|
||||
countReset: [Function: countReset],
|
||||
group: [Function: group],
|
||||
groupEnd: [Function: groupEnd],
|
||||
table: [Function: table],*/
|
||||
debug (...data) { _log(...data) },
|
||||
info (...data) { _log(...data) },
|
||||
// dirxml: [Function: dirxml],
|
||||
error (...data) { _log(...data) },
|
||||
/*groupCollapsed: [Function: groupCollapsed],
|
||||
profile: [Function: profile],
|
||||
profileEnd: [Function: profileEnd],
|
||||
timeStamp: [Function: timeStamp],*/
|
||||
context () { return context.console }
|
||||
}
|
||||
|
||||
context.core = bot.core.run // core function
|
||||
|
||||
// set/clear interval/timeout/immediate
|
||||
//context.clearInterval = clearInterval
|
||||
context.clearTimeout = clearTimeout
|
||||
//context.setInterval = setInterval
|
||||
context.setTimeout = setTimeout
|
||||
//context.clearImmediate = clearImmediate
|
||||
//context.setImmediate = setImmediate
|
||||
|
||||
bot.eval.context = context
|
||||
}
|
||||
}
|
||||
|
||||
/*function coloredInspect (func) {
|
||||
const oldColors = util.inspect.colors
|
||||
const prefix = '\x1b['
|
||||
|
||||
|
||||
util.inspect.colors = {
|
||||
reset: [ '\xa7', 'r' ],
|
||||
bold: [ '\xa7', 'l' ],
|
||||
dim: [ '', '' ],
|
||||
italic: [ '\xa7', 'o' ],
|
||||
underline: [ '\xa7', 'n' ],
|
||||
blink: [ '\xa7', 'k' ],
|
||||
inverse: [ '', '' ],
|
||||
hidden: [ '', '' ],
|
||||
strikethrough: [ '\xa7', 'm' ],
|
||||
doubleunderline: [ '\xa7', 'n' ],
|
||||
black: [ '\xa7', '0' ],
|
||||
red: [ '\xa7', '4' ],
|
||||
green: [ '\xa7', '2' ],
|
||||
yellow: [ '\xa7', '6' ],
|
||||
blue: [ '\xa7', '1' ],
|
||||
magenta: [ '\xa7', '6' ],
|
||||
cyan: [ '\xa7', '3' ],
|
||||
white: [ '\xa7', 'f' ],
|
||||
bgBlack: [ '\xa7', '0' ],
|
||||
bgRed: [ '\xa7', '4' ],
|
||||
bgGreen: [ '\xa7', '2' ],
|
||||
bgYellow: [ '\xa7', '6' ],
|
||||
bgBlue: [ '\xa7', '1' ],
|
||||
bgMagenta: [ '\xa7', '6' ],
|
||||
bgCyan: [ '\xa7', '3' ],
|
||||
bgWhite: [ '\xa7', 'f' ],
|
||||
framed: [ '', '' ],
|
||||
overlined: [ '\xa7', 'n' ],
|
||||
gray: [ '\xa7', '7' ],
|
||||
redBright: [ '\xa7', 'c' ],
|
||||
greenBright: [ '\xa7', 'a' ],
|
||||
yellowBright: [ '\xa7', 'e' ],
|
||||
blueBright: [ '\xa7', '9' ],
|
||||
magentaBright: [ '\xa7', 'd' ],
|
||||
cyanBright: [ '\xa7', 'b' ],
|
||||
whiteBright: [ '\xa7', 'f' ],
|
||||
bgGray: [ '\xa7', '7' ],
|
||||
bgRedBright: [ '\xa7', 'c' ],
|
||||
bgGreenBright: [ '\xa7', 'a' ],
|
||||
bgYellowBright: [ '\xa7', 'e' ],
|
||||
bgBlueBright: [ '\xa7', '9' ],
|
||||
bgMagentaBright: [ '\xa7', 'd' ],
|
||||
bgCyanBright: [ '\xa7', 'b' ],
|
||||
bgWhiteBright: [ '\xa7', 'f' ],
|
||||
}
|
||||
const result = func().replace(/\x1b\[\xa7.?/, m => m.slice(prefix.length))
|
||||
|
||||
util.inspect.colors = oldColors
|
||||
return result
|
||||
}*/
|
||||
|
||||
module.exports.bot = inject
|
40
plugins/exploits.js
Normal file
40
plugins/exploits.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
const nbt = require('prismarine-nbt')
|
||||
const SNBT = require('../util/snbt.js')
|
||||
const toNBTUUID = require('./../util/uuid-to-nbt-uuid.js')
|
||||
|
||||
const kick = [{ nbt: '', entity: '@e' }, { nbt: '', entity: '@e' }, { nbt: '', entity: '@e' }, { nbt: '', entity: '@e' }, { nbt: '', entity: '@e' }]
|
||||
|
||||
let lootTable = 'minecraft:'
|
||||
while (lootTable.length <= 256) { lootTable += 'i' }
|
||||
|
||||
function inject (bot) {
|
||||
bot.exploits = {
|
||||
titleKick: function (selector) {
|
||||
return new Promise((resolve) => {
|
||||
bot.core.run(`minecraft:title ${selector} title ${JSON.stringify(kick)}`)
|
||||
bot.once('player_info', resolve)
|
||||
})
|
||||
},
|
||||
uuidBan: function (UUID) {
|
||||
return new Promise((resolve) => {
|
||||
const nbtUUID = toNBTUUID(UUID)
|
||||
bot.exploits.titleKick(`@p[nbt=${SNBT.stringify(nbt.comp({ UUID: nbtUUID }))}]`).then((packet) => {
|
||||
bot.core.run('minecraft:summon chest_minecart ~ ~ ~ ' + SNBT.stringify(nbt.comp({ UUID: nbtUUID, LootTable: nbt.string(lootTable), NoGravity: nbt.byte(1) })))
|
||||
resolve(packet)
|
||||
})
|
||||
})
|
||||
},
|
||||
bossbarBan: function (selector) {
|
||||
bot.core.run(`/bossbar add ban title ${JSON.stringify(kick)}`)
|
||||
setTimeout(() => bot.core.run(`/minecraft:bossbar set ban players ${selector}`), 50)
|
||||
},
|
||||
chunkBan: function () {
|
||||
// i will add code later
|
||||
},
|
||||
execute: function (args) {
|
||||
bot.core.run(`minecraft:execute unless data entity @p run ${args}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
15
plugins/fancyMsg.js
Normal file
15
plugins/fancyMsg.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
function inject (bot) {
|
||||
bot.fancyMsg = function (rank, username, message) {
|
||||
bot.core.run(`/tellraw @a ${JSON.stringify([
|
||||
{ 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
|
14
plugins/function.js
Normal file
14
plugins/function.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
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
|
16
plugins/get-entity-pos.js
Normal file
16
plugins/get-entity-pos.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// const nbt = require('prismarine-nbt')
|
||||
// const SNBT = require('../util/snbt.js')
|
||||
// const toNBTUUID = require('./../util/uuid-to-nbt-uuid.js')
|
||||
|
||||
function inject (bot) {
|
||||
bot.getEntityPos = function getEntityPos (selector, callback) {
|
||||
if (typeof callback !== 'function') throw new Error('the callback must be a function lol')
|
||||
bot.exploits.execute(`run teleport ${bot._client.uuid} ${selector}`)
|
||||
bot._client.once('position', callback)
|
||||
setTimeout(() =>
|
||||
bot._client.removeListener('position', callback)
|
||||
, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
85
plugins/kahoot.js
Normal file
85
plugins/kahoot.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
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
|
15
plugins/kbwl.js
Normal file
15
plugins/kbwl.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
function inject (bot) {
|
||||
bot.kbwl = {}
|
||||
bot.kbwl.enabled = false
|
||||
bot.kbwl.players = ['_ChipMC_']
|
||||
|
||||
bot._client.on('player_info', (packet) => {
|
||||
if (bot.kbwl.enabled && packet.action === 0) {
|
||||
packet.data.forEach((player) => {
|
||||
if (player.UUID !== bot._client.uuid && !bot.kbwl.players.includes(player.name)) { bot.exploits.titleKick(`@a[name="${player.name.replace(/"/, '\\"')}"]`) }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
28
plugins/mail.js
Normal file
28
plugins/mail.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const filepath = path.resolve('persistent', 'mail.json')
|
||||
|
||||
// load the blacklist
|
||||
let mail = {}
|
||||
try {
|
||||
mail = require(filepath)
|
||||
} catch (e) {
|
||||
console.log('An error occured while loading the mail.')
|
||||
}
|
||||
|
||||
// save it every 5 minutes
|
||||
setInterval(() => {
|
||||
fs.writeFileSync(filepath, JSON.stringify(mail, null, 2))
|
||||
}, 5 * 6000)
|
||||
|
||||
// make the bot uuid ban blacklisted players
|
||||
function inject (bot) {
|
||||
bot.mail = mail
|
||||
bot.sendMail = (sender, reciever, message) => {
|
||||
if (!mail[reciever]) mail[reciever] = []
|
||||
mail[reciever].push({ sender: sender, message, host: bot.host })
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
131
plugins/music.js
Normal file
131
plugins/music.js
Normal file
|
@ -0,0 +1,131 @@
|
|||
const fs = require('fs')
|
||||
const convertMidi = require('../util/convert-midi.js')
|
||||
const convertNBS = require('../util/nbs-converter.js')
|
||||
|
||||
function inject (bot) {
|
||||
bot.music = {
|
||||
playing: false,
|
||||
queue: [],
|
||||
nowPlaying: undefined,
|
||||
looping: false,
|
||||
_interval: null,
|
||||
_playNextSong,
|
||||
skip,
|
||||
stop,
|
||||
play
|
||||
}
|
||||
|
||||
bot.music.nowPlaying = {
|
||||
name: '',
|
||||
tick: {
|
||||
current: null,
|
||||
total: null
|
||||
// npt: null
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
if (!bot.music.playing) return
|
||||
const msg = [
|
||||
{ text: 'Now Playing', color: bot.colors.primary },
|
||||
{ text: ' | ', color: 'dark_gray' },
|
||||
{ text: bot.music.nowPlaying.name, color: bot.colors.secondary, bold: true },
|
||||
{ text: ' | ', color: 'dark_gray' },
|
||||
format(bot.music.nowPlaying.time),
|
||||
{ text: ' / ', color: 'gray' },
|
||||
format(bot.music.nowPlaying.length)
|
||||
// { text: ' (', color: 'dark_gray' },
|
||||
// bot.music.nowPlaying.note.npt + ' npt',
|
||||
// { text: ')', color: 'dark_gray' }
|
||||
]
|
||||
if (bot.music.looping) {
|
||||
msg.push({ text: ' | ', color: 'dark_gray' })
|
||||
msg.push({ text: 'Looping', color: bot.colors.secondary })
|
||||
}
|
||||
bot.core.run('/title @a actionbar ' + JSON.stringify(msg))
|
||||
}, 500)
|
||||
|
||||
function _playNextSong () {
|
||||
const song = bot.music.queue.shift()
|
||||
if (song != null) play(song)
|
||||
}
|
||||
|
||||
function skip () {
|
||||
clearInterval(bot.music._interval)
|
||||
bot.music.playing = false
|
||||
if (bot.music.queue.length !== 0) _playNextSong()
|
||||
}
|
||||
|
||||
function stop () {
|
||||
bot.music.queue = []
|
||||
clearInterval(bot.music._interval)
|
||||
bot.music.playing = false
|
||||
}
|
||||
|
||||
function play (filepath) {
|
||||
// set stuff up
|
||||
let song
|
||||
try {
|
||||
if (filepath.endsWith('.nbs')) {
|
||||
song = convertNBS(fs.readFileSync(filepath), filepath)
|
||||
} else song = convertMidi(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.name, color: bot.colors.secondary },
|
||||
'.'
|
||||
])}`)
|
||||
bot.music.playing = true
|
||||
bot.music.looping = song.loop
|
||||
let startTime = (new Date()).valueOf()
|
||||
let notes = [ ...song.notes ]
|
||||
bot.music._interval = setInterval(async () => {
|
||||
const time = (new Date()).valueOf() - startTime
|
||||
song.time = time
|
||||
notes.forEach(async (note, i) => {
|
||||
if (time >= note.time) {
|
||||
const floatingpitch = Math.pow(2, (note.pitch - 12) / 12.0)
|
||||
bot.core.run(`minecraft:execute at @a run playsound block.note_block.${note.instrument} record @p ^1 ^ ^ 99 ${floatingpitch}`)
|
||||
bot.core.run(`minecraft:execute at @a run playsound block.note_block.${note.instrument} record @p ^-1 ^ ^ 99 ${floatingpitch}`)
|
||||
notes.splice(i, 1)
|
||||
}
|
||||
})
|
||||
song.time++
|
||||
|
||||
if (time > song.length) {
|
||||
if (bot.music.looping) {
|
||||
notes = [ ...song.notes ]
|
||||
startTime = (new Date()).valueOf() + song.loopPosition
|
||||
return
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
15
plugins/players.js
Normal file
15
plugins/players.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
function inject (bot, client) {
|
||||
bot.players ??= {}
|
||||
|
||||
client.on('player_info', (packet) => {
|
||||
if (packet.action === 0) {
|
||||
packet.data.forEach((player) => {
|
||||
bot.players[player.name] = player
|
||||
bot.players[player.UUID] = player
|
||||
if (player.UUID === bot._client.uuid) { bot.player = player }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.client = inject
|
49
plugins/seen.js
Normal file
49
plugins/seen.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const filepath = path.resolve('persistent', 'seen.json')
|
||||
|
||||
// load the seen data
|
||||
let seen = {}
|
||||
try {
|
||||
seen = require(filepath)
|
||||
} catch (e) {
|
||||
console.log('An error occured while loading seen players.')
|
||||
}
|
||||
|
||||
// save it every 5 minutes
|
||||
setInterval(() => {
|
||||
fs.writeFileSync(filepath, JSON.stringify(seen, null, 2))
|
||||
}, 5 * 6000)
|
||||
|
||||
// expose the data to the bot
|
||||
function bot (bot) {
|
||||
bot.seen = seen
|
||||
}
|
||||
|
||||
// add players to it
|
||||
function client (bot, client) {
|
||||
client.on('player_info', (packet) => {
|
||||
packet.data.forEach((player) => {
|
||||
if (player.UUID === client.uuid) return
|
||||
if (packet.action !== 0) {
|
||||
const name = bot.players[player.UUID]?.name
|
||||
if (seen[name] != null) seen[name].last = new Date()
|
||||
return
|
||||
}
|
||||
|
||||
seen[player.name] ??= {}
|
||||
if (seen[player.name].first == null) {
|
||||
seen[player.name].first = new Date()
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify([
|
||||
{ text: 'Welcome ', color: bot.colors.primary },
|
||||
{ text: player.name, color: bot.colors.secondary },
|
||||
' to the server!'
|
||||
]))
|
||||
}
|
||||
seen[player.name].last = new Date()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { bot, client }
|
98
plugins/video.js
Normal file
98
plugins/video.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
const ffmpeg = require('fluent-ffmpeg')
|
||||
const tmp = require('tmp')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const canvas = require('canvas')
|
||||
const colorsys = require('colorsys')
|
||||
const { randomUUID } = require('crypto')
|
||||
const nbt = require('prismarine-nbt')
|
||||
const SNBT = require('../util/snbt.js')
|
||||
const toNBTUUID = require('./../util/uuid-to-nbt-uuid.js')
|
||||
|
||||
const cnv = canvas.createCanvas(256, 144)
|
||||
const ctx = cnv.getContext('2d')
|
||||
|
||||
function inject (bot) {
|
||||
const video = {
|
||||
nowPlaying: null,
|
||||
_interval: null,
|
||||
_tmpobj: null,
|
||||
play,
|
||||
stop,
|
||||
summon
|
||||
}
|
||||
bot.video = video
|
||||
|
||||
async function play (input, uuids) {
|
||||
uuids ??= await summon(cnv.height)
|
||||
video._tmpobj = tmp.dirSync()
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify('Extracting frames from the video...'))
|
||||
ffmpeg(input)
|
||||
.output(path.join(video._tmpobj.name, '%01d.bmp'))
|
||||
.fps(30)
|
||||
.size(cnv.width + 'x' + cnv.height)
|
||||
.on('error', (err) => bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: require('util').inspect(err).replace(/\n.*/g, ''), color: 'red' })))
|
||||
.on('end', playVideo)
|
||||
.run()
|
||||
|
||||
function playVideo () {
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify('Now playing the video'))
|
||||
|
||||
const frames = []
|
||||
fs.readdirSync(video._tmpobj.name).forEach((filename) => {
|
||||
const filepath = path.join(video._tmpobj.name, filename)
|
||||
let num = filename
|
||||
// while (num.length !== 0 && !/\d/.test(num[0])) {
|
||||
// num = num.slice(1)
|
||||
// }
|
||||
num = parseInt(num)
|
||||
frames[num] = filepath
|
||||
})
|
||||
|
||||
let i = 0
|
||||
video._interval = setInterval(async () => {
|
||||
const img = await canvas.loadImage(frames[i++]).catch(({ message }) => bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: message, color: 'red' })))
|
||||
if (!(img ?? false)) return
|
||||
fs.unlink(frames[i - 1], () => {})
|
||||
ctx.drawImage(img, 0, 0, cnv.width, cnv.height)
|
||||
const rgba = ctx.getImageData(0, 0, cnv.width, cnv.height).data
|
||||
let line = []
|
||||
let k = 0
|
||||
for (let j = 0; j < rgba.length; j += 4) {
|
||||
const r = rgba[j]
|
||||
const g = rgba[j + 1]
|
||||
const b = rgba[j + 2]
|
||||
const hex = colorsys.rgbToHex(r, g, b)
|
||||
if (line.length >= 1 && line[line.length - 1].color === hex) line[line.length - 1].text += '╷'
|
||||
else line.push({ text: '╷', color: hex })
|
||||
if (((j / 4) % cnv.width) === 0) {
|
||||
bot.core.run(`minecraft:data modify entity ${uuids[k++]} CustomName set value ${SNBT.stringify(nbt.string(JSON.stringify(line)))}`)
|
||||
line = []
|
||||
}
|
||||
}
|
||||
if (i >= frames.length) stop()
|
||||
}, 33.33333)
|
||||
}
|
||||
}
|
||||
function stop () {
|
||||
clearInterval(video._interval)
|
||||
video._tmpobj?.removeCallback()
|
||||
}
|
||||
function summon (amount) {
|
||||
return new Promise((resolve) => {
|
||||
const uuids = []
|
||||
bot.core.run('minecraft:tellraw @a ' + JSON.stringify({ text: 'Summoning armor stands...' }))
|
||||
video._interval = setInterval(() => {
|
||||
const uuid = randomUUID()
|
||||
bot.exploits.execute(`at _ChipMC_ run summon armor_stand ~ ~${uuids.length * -0.1} ~ ${SNBT.stringify(nbt.comp({ UUID: toNBTUUID(uuid), CustomNameVisible: nbt.byte(1), Invisible: nbt.byte(1), Marker: nbt.byte(1) }))}`)
|
||||
uuids.push(uuid)
|
||||
if (uuids.length >= amount) {
|
||||
clearInterval(video._interval)
|
||||
resolve(uuids)
|
||||
}
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.bot = inject
|
7
start.sh
Executable file
7
start.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
while true
|
||||
do
|
||||
echo Starting Bot
|
||||
node .
|
||||
echo Restarting Bot in 6 Seconds...
|
||||
sleep 6
|
||||
done
|
30
util/convert-image.js
Normal file
30
util/convert-image.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
const canvas = require('canvas')
|
||||
const cnv = canvas.createCanvas(426.6, 240)
|
||||
const ctx = cnv.getContext('2d')
|
||||
|
||||
const colorsys = require('colorsys')
|
||||
|
||||
async function convertImage (src, callback) {
|
||||
const img = await canvas.loadImage(src).catch(callback)
|
||||
if (!(img ?? false)) return
|
||||
ctx.drawImage(img, 0, 0, cnv.width, cnv.height)
|
||||
const rgba = ctx.getImageData(0, 0, cnv.width, cnv.height).data
|
||||
const lines = []
|
||||
let line = []
|
||||
for (let i = 0; i < rgba.length; i += 4) {
|
||||
const r = rgba[i]
|
||||
const g = rgba[i + 1]
|
||||
const b = rgba[i + 2]
|
||||
// const a = rgba[i + 3];
|
||||
const hex = colorsys.rgbToHex(r, g, b)
|
||||
if (line.length >= 1 && line[line.length - 1].color === hex) { line[line.length - 1].text += '.' } else { line.push({ text: '.', color: hex }) }
|
||||
|
||||
if (((i / 4) % cnv.width) === 0) {
|
||||
lines.push(JSON.stringify(line))
|
||||
line = []
|
||||
}
|
||||
}
|
||||
callback(undefined, lines)
|
||||
}
|
||||
|
||||
module.exports = convertImage
|
151
util/convert-midi.js
Normal file
151
util/convert-midi.js
Normal file
|
@ -0,0 +1,151 @@
|
|||
const fs = require('fs')
|
||||
const { Midi } = require('@tonejs/midi')
|
||||
|
||||
const instrumentOffsets = [
|
||||
54, // harp
|
||||
0, // basedrum
|
||||
0, // snare
|
||||
0, // hat
|
||||
30, // bass
|
||||
66, // flute
|
||||
78, // bell
|
||||
42, // guitar
|
||||
78, // chime
|
||||
78, // xylophone
|
||||
54, // iron xylophone
|
||||
66, // cow bell
|
||||
30, // didgeridoo
|
||||
54, // bit
|
||||
54, // banjo
|
||||
54 // electric piano
|
||||
]
|
||||
|
||||
const instrumentNames = require('./instrument-names.json')
|
||||
const path = require('path/posix')
|
||||
|
||||
function convertMidi (filepath, lyrics = undefined) {
|
||||
const midiData = fs.readFileSync(filepath)
|
||||
const midi = new Midi(midiData)
|
||||
|
||||
const noteList = []
|
||||
let length = 0
|
||||
for (const track of midi.tracks) {
|
||||
for (const note of track.notes) {
|
||||
const mcNote = convertNote(track, note)
|
||||
if (mcNote !== undefined) {
|
||||
noteList.push(mcNote)
|
||||
length = Math.max(length, mcNote.tick)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
noteList.sort((a, b) => {
|
||||
return a.tick - b.tick
|
||||
})
|
||||
|
||||
// normalize volume
|
||||
let maxVolume = 0.001
|
||||
for (const note of noteList) {
|
||||
if (note.volume > maxVolume) {
|
||||
maxVolume = note.volume
|
||||
}
|
||||
}
|
||||
for (const note of noteList) {
|
||||
note.volume /= maxVolume
|
||||
}
|
||||
|
||||
if (lyrics) {
|
||||
parseLyrics(midiData, midi, lyrics)
|
||||
}
|
||||
|
||||
return {
|
||||
name: midi?.meta?.name ?? path.basename(filepath),
|
||||
notes: noteList,
|
||||
loop: false,
|
||||
loopPosition: 0,
|
||||
length
|
||||
}
|
||||
}
|
||||
|
||||
function convertNote (track, note) {
|
||||
const midiPitch = note.midi
|
||||
const midiInstrument = track.instrument.number
|
||||
let mcInstrumentID = 0
|
||||
let mcPitchID = 0
|
||||
if (track.instrument.percussion) {
|
||||
if (midiPitch === 35 || midiPitch === 36 || midiPitch === 41 || midiPitch === 43 || midiPitch === 45 || midiPitch === 57) {
|
||||
mcInstrumentID = 1 // bass drum
|
||||
} else if (midiPitch === 38 || midiPitch === 39 || midiPitch === 40 || midiPitch === 54 || midiPitch === 69 || midiPitch === 70 || midiPitch === 73 || midiPitch === 74 || midiPitch === 78 || midiPitch === 79) {
|
||||
mcInstrumentID = 2 // snare
|
||||
} else if (midiPitch === 37 || midiPitch === 42 || midiPitch === 44 || midiPitch === 46 || midiPitch === 49 || midiPitch === 51 || midiPitch === 52 || midiPitch === 55 || midiPitch === 57 || midiPitch === 59) {
|
||||
mcInstrumentID = 3 // hat
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
mcPitchID = 0
|
||||
} else {
|
||||
if ((midiInstrument >= 0 && midiInstrument <= 7) || (midiInstrument >= 24 && midiInstrument <= 31)) { // normal
|
||||
if (midiPitch >= 54 && midiPitch <= 78) {
|
||||
mcInstrumentID = 0 // piano
|
||||
} else if (midiPitch >= 30 && midiPitch <= 54) {
|
||||
mcInstrumentID = 4 // bass
|
||||
} else if (midiPitch >= 78 && midiPitch <= 102) {
|
||||
mcInstrumentID = 6 // bells
|
||||
}
|
||||
} else if (midiInstrument >= 8 && midiInstrument <= 15) { // chromatic percussion
|
||||
if (midiPitch >= 54 && midiPitch <= 78) {
|
||||
mcInstrumentID = 10 // iron xylophone
|
||||
} else if (midiPitch >= 78 && midiPitch <= 102) {
|
||||
mcInstrumentID = 9 // xylophone
|
||||
} else if (midiPitch >= 30 && midiPitch <= 54) {
|
||||
mcInstrumentID = 4 // bass
|
||||
}
|
||||
} else if ((midiInstrument >= 16 && midiInstrument <= 23) || (midiInstrument >= 32 && midiInstrument <= 71) || (midiInstrument >= 80 && midiInstrument <= 111)) { // synth
|
||||
if (midiPitch >= 54 && midiPitch <= 78) { // bit
|
||||
mcInstrumentID = 13
|
||||
} else if (midiPitch >= 30 && midiPitch <= 54) { // didgeridoo
|
||||
mcInstrumentID = 12
|
||||
} else if (midiPitch >= 78 && midiPitch <= 102) { // bells
|
||||
mcInstrumentID = 6
|
||||
}
|
||||
} else if (midiInstrument >= 72 && midiInstrument <= 79) { // woodwind
|
||||
if (midiPitch >= 66 && midiPitch <= 90) {
|
||||
mcInstrumentID = 5 // flute
|
||||
} else if (midiPitch >= 30 && midiPitch <= 54) { // didgeridoo
|
||||
mcInstrumentID = 12
|
||||
} else if (midiPitch >= 54 && midiPitch <= 78) { // bit
|
||||
mcInstrumentID = 13
|
||||
}
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
mcPitchID = midiPitch - instrumentOffsets[mcInstrumentID]
|
||||
}
|
||||
|
||||
return { time: Math.floor(note.time * 1000), instrument: instrumentNames[mcInstrumentID], pitch: mcPitchID, volume: note.velocity }
|
||||
}
|
||||
|
||||
function parseLyrics (midiArray, midi, lyrics) {
|
||||
midiArray = new Uint8Array(midiArray)
|
||||
const midiData = require('midi-file').parseMidi(midiArray)
|
||||
|
||||
midiData.tracks.forEach(track => {
|
||||
let lastTick = 0
|
||||
let currentTicks = 0
|
||||
track.forEach(event => {
|
||||
currentTicks += event.deltaTime
|
||||
if (event.meta && event.type === 'lyrics') {
|
||||
const time = midi.header.ticksToSeconds(currentTicks)
|
||||
const tick = Math.floor(time * 20)
|
||||
if (!lyrics[tick]) {
|
||||
lyrics[tick] = event.text
|
||||
} else if (tick === lastTick) {
|
||||
lyrics[tick] += event.text
|
||||
}
|
||||
lastTick = tick
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = convertMidi
|
18
util/instrument-names.json
Normal file
18
util/instrument-names.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
"harp",
|
||||
"basedrum",
|
||||
"snare",
|
||||
"hat",
|
||||
"bass",
|
||||
"flute",
|
||||
"bell",
|
||||
"guitar",
|
||||
"chime",
|
||||
"xylophone",
|
||||
"iron_xylophone",
|
||||
"cow_bell",
|
||||
"didgeridoo",
|
||||
"bit",
|
||||
"banjo",
|
||||
"pling"
|
||||
]
|
63
util/nbs-converter.js
Normal file
63
util/nbs-converter.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
const nbs = require('./nbs-file.js')
|
||||
const path = require('path')
|
||||
const instrumentNames = [
|
||||
'harp',
|
||||
'bass',
|
||||
'basedrum',
|
||||
'snare',
|
||||
'hat',
|
||||
'guitar',
|
||||
'flute',
|
||||
'bell',
|
||||
'chime',
|
||||
'xylophone',
|
||||
'iron_xylophone',
|
||||
'cow_bell',
|
||||
'didgeridoo',
|
||||
'bit',
|
||||
'banjo',
|
||||
'pling'
|
||||
]
|
||||
|
||||
function convertNBS (buf, filename = 'unknown') {
|
||||
const parsed = nbs.parse(buf)
|
||||
const song = {
|
||||
name: parsed.songName.trim().length > 0 ? parsed.songName : path.basename(filename),
|
||||
notes: [],
|
||||
loop: false,
|
||||
loopPosition: 0,
|
||||
length: 0
|
||||
}
|
||||
if (parsed.loop > 0) {
|
||||
song.loop = true
|
||||
song.loopPosition = parsed.loopStartTick
|
||||
}
|
||||
for (const note of parsed.nbsNotes) {
|
||||
let instrument = note.instrument
|
||||
if (note.instrument < instrumentNames.length) {
|
||||
instrument = instrumentNames[note.instrument]
|
||||
} else continue
|
||||
|
||||
if (note.key < 33 || note.key > 55) continue
|
||||
|
||||
const layerVolume = 100
|
||||
// will add layer volume later
|
||||
|
||||
const time = tickToMs(note.tick, parsed.tempo)
|
||||
song.length = Math.max(song.length, time)
|
||||
|
||||
song.notes.push({
|
||||
instrument,
|
||||
pitch: note.key - 33,
|
||||
volume: note.velocity * layerVolume / 10000,
|
||||
time
|
||||
})
|
||||
}
|
||||
return song
|
||||
}
|
||||
|
||||
function tickToMs (tick = 1, tempo) {
|
||||
return Math.floor(1000 * tick * 100 / tempo)
|
||||
}
|
||||
|
||||
module.exports = convertNBS
|
170
util/nbs-file.js
Normal file
170
util/nbs-file.js
Normal file
|
@ -0,0 +1,170 @@
|
|||
// const fs = require('fs')
|
||||
// const path = require('path')
|
||||
// const instrumentNames = require('./instrument-names.json')
|
||||
|
||||
function parse (buf) {
|
||||
// const buf = fs.readFileSync(filepath)
|
||||
let i = 0
|
||||
|
||||
let songLength = 0
|
||||
let format = 0
|
||||
let vanillaInstrumentCount = 0
|
||||
songLength = readShort()
|
||||
if (songLength === 0) {
|
||||
format = readByte()
|
||||
}
|
||||
|
||||
if (format >= 1) {
|
||||
vanillaInstrumentCount = readByte()
|
||||
}
|
||||
if (format >= 3) {
|
||||
songLength = readShort()
|
||||
}
|
||||
|
||||
const layerCount = readShort()
|
||||
const songName = readString()
|
||||
const songAuthor = readString()
|
||||
const songOriginalAuthor = readString()
|
||||
const songDescription = readString()
|
||||
const tempo = readShort()
|
||||
const autoSaving = readByte()
|
||||
const autoSavingDuration = readByte()
|
||||
const timeSignature = readByte()
|
||||
const minutesSpent = readInt()
|
||||
const leftClicks = readInt()
|
||||
const rightClicks = readInt()
|
||||
const blocksAdded = readInt()
|
||||
const blocksRemoved = readInt()
|
||||
const origFileName = readString()
|
||||
|
||||
let loop = 0
|
||||
let maxLoopCount = 0
|
||||
let loopStartTick = 0
|
||||
if (format >= 4) {
|
||||
loop = readByte()
|
||||
maxLoopCount = readByte()
|
||||
loopStartTick = readShort()
|
||||
}
|
||||
|
||||
const nbsNotes = []
|
||||
let tick = -1
|
||||
while (true) {
|
||||
const tickJumps = readShort()
|
||||
if (tickJumps === 0) break
|
||||
tick += tickJumps
|
||||
|
||||
let layer = -1
|
||||
while (true) {
|
||||
const layerJumps = readShort()
|
||||
if (layerJumps === 0) break
|
||||
layer += layerJumps
|
||||
const note = NBSNote()
|
||||
note.tick = tick
|
||||
note.layer = layer
|
||||
note.instrument = readByte()
|
||||
note.key = readByte()
|
||||
if (format >= 4) {
|
||||
note.velocity = readByte()
|
||||
note.panning = readByte()
|
||||
note.pitch = readShort()
|
||||
}
|
||||
nbsNotes.push(note)
|
||||
}
|
||||
}
|
||||
|
||||
const nbsLayers = []
|
||||
if (i <= buf.length) {
|
||||
for (let j = 0; j < layerCount; j++) {
|
||||
const layer = NBSLayer()
|
||||
layer.name = readString()
|
||||
if (format >= 4) {
|
||||
layer.lock = readByte()
|
||||
}
|
||||
layer.volume = readByte()
|
||||
if (format >= 2) {
|
||||
layer.stereo = readByte()
|
||||
}
|
||||
nbsLayers.push(layer)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
songLength,
|
||||
format,
|
||||
vanillaInstrumentCount,
|
||||
layerCount,
|
||||
songName,
|
||||
songAuthor,
|
||||
songOriginalAuthor,
|
||||
songDescription,
|
||||
tempo,
|
||||
autoSaving,
|
||||
autoSavingDuration,
|
||||
timeSignature,
|
||||
minutesSpent,
|
||||
leftClicks,
|
||||
rightClicks,
|
||||
blocksAdded,
|
||||
blocksRemoved,
|
||||
origFileName,
|
||||
loop,
|
||||
maxLoopCount,
|
||||
loopStartTick,
|
||||
nbsNotes,
|
||||
nbsLayers
|
||||
}
|
||||
|
||||
function readByte () {
|
||||
return buf.readInt8(i++)
|
||||
}
|
||||
|
||||
function readShort () {
|
||||
const byte1 = buf.readUint8(i++)
|
||||
const byte2 = buf.readUint8(i++)
|
||||
return (byte1 + (byte2 << 8))
|
||||
}
|
||||
|
||||
function readInt () {
|
||||
const byte1 = buf.readUint8(i++)
|
||||
const byte2 = buf.readUint8(i++)
|
||||
const byte3 = buf.readUint8(i++)
|
||||
const byte4 = buf.readUint8(i++)
|
||||
return (byte1 + (byte2 << 8) + (byte3 << 16) + (byte4 << 24))
|
||||
}
|
||||
|
||||
function readString () {
|
||||
let length = readInt()
|
||||
let str = ''
|
||||
for (; length > 0; --length) {
|
||||
let c = String.fromCharCode(readByte())
|
||||
if (c === String.fromCharCode(0x0D)) {
|
||||
c = ' '
|
||||
}
|
||||
str += c
|
||||
}
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
function NBSNote () {
|
||||
return {
|
||||
tick: null,
|
||||
layer: null,
|
||||
instrument: null,
|
||||
key: null,
|
||||
velocity: 100,
|
||||
panning: 100,
|
||||
pitch: 0
|
||||
}
|
||||
}
|
||||
|
||||
function NBSLayer () {
|
||||
return {
|
||||
name: null,
|
||||
lock: 0,
|
||||
volume: null,
|
||||
stereo: 100
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { parse, NBSNote, NBSLayer }
|
117
util/snbt.js
Normal file
117
util/snbt.js
Normal file
|
@ -0,0 +1,117 @@
|
|||
const quotes = ['"', "'"]
|
||||
function stringify (nbt, space = false) {
|
||||
const sep = ',' + (space ? ' ' : '')
|
||||
switch (nbt.type) {
|
||||
case 'byte':
|
||||
return nbt.value + 'b'
|
||||
case 'short':
|
||||
return nbt.value + 's'
|
||||
case 'int':
|
||||
return nbt.value.toString()
|
||||
case 'long':
|
||||
return nbt.value + 'l'
|
||||
case 'float':
|
||||
return nbt.value + 'f'
|
||||
case 'double':
|
||||
return nbt.value + 'd'
|
||||
case 'string':
|
||||
return stringifyStr(nbt.value, true)
|
||||
case 'list':
|
||||
return `[${
|
||||
nbt.value.value
|
||||
.map((tag) => stringify({ type: nbt.value.type, value: tag }, space))
|
||||
.join(sep)
|
||||
}]`
|
||||
case 'compound':
|
||||
return `{${Object.entries(nbt.value).map(([key, prop]) =>
|
||||
stringifyStr(key, false) + ':' + (space ? ' ' : '') + stringify(prop)
|
||||
).join(sep)}}`
|
||||
case 'byteArray':
|
||||
return `[B;${space ? ' ' : ''}${
|
||||
nbt.value
|
||||
.map((value) => stringify({ type: 'byte', value }))
|
||||
.join(sep)
|
||||
}]`
|
||||
case 'intArray':
|
||||
return `[I;${space ? ' ' : ''}${
|
||||
nbt.value
|
||||
.map((value) => stringify({ type: 'int', value }))
|
||||
.join(sep)
|
||||
}]`
|
||||
case 'longArray':
|
||||
return `[L;${space ? ' ' : ''}${
|
||||
nbt.value
|
||||
.map((value) => stringify({ type: 'long', value }))
|
||||
.join(sep)
|
||||
}]`
|
||||
case 'bool':
|
||||
return nbt.value.toString()
|
||||
default:
|
||||
throw new Error('Unknown type: ' + nbt.type)
|
||||
}
|
||||
|
||||
function stringifyStr (str, forceQuotes = false) {
|
||||
const regex = /['\\]/g
|
||||
if (regex.test(str) || /[\s|"]/g.test(str) || forceQuotes) {
|
||||
str = `'${str.replace(regex, (m) => '\\' + m)}'`
|
||||
}
|
||||
return str
|
||||
}
|
||||
}
|
||||
function parse (snbt) {
|
||||
const num = parseInt(snbt)
|
||||
if (!isNaN(num)) {
|
||||
if (snbt.endsWith('b')) {
|
||||
return { type: 'byte', value: num }
|
||||
} else if (snbt.endsWith('s')) {
|
||||
return { type: 'short', value: num }
|
||||
} else if (snbt.endsWith('l')) {
|
||||
return { type: 'long', value: num }
|
||||
} else if (snbt.endsWith('f')) {
|
||||
return { type: 'float', value: num }
|
||||
} else if (snbt.endsWith('d')) {
|
||||
return { type: 'double', value: num }
|
||||
} else {
|
||||
return { type: 'int', value: num }
|
||||
}
|
||||
} else if (snbt === 'true') { return true } else if (snbt === 'false') { return false } else if (snbt.startsWith('{') && snbt.endsWith('}')) {
|
||||
const entries = split(snbt.slice(1, -1), ',').map(e => split(e, ':')).map(([key, prop]) => [parseStr(key), parse(prop)])
|
||||
|
||||
const obj = {}
|
||||
entries.forEach(([key, prop]) => (obj[key] = prop))
|
||||
return { type: 'compound', value: obj }
|
||||
// } else if (snbt.startsWith('[') && snbt.endsWith(']')) {
|
||||
} else {
|
||||
return { type: 'string', value: parseStr(snbt) }
|
||||
}
|
||||
// worst string parser ever
|
||||
function parseStr (str) {
|
||||
const unquotedWl = /[a-zA-Z0-9+\-.]/g
|
||||
// check quotes
|
||||
for (const quote of quotes) {
|
||||
if (str.startsWith(quote) && str.startsWith(quote)) {
|
||||
return str.replace(new RegExp(`\\\\|\\${quote}`, 'g'), (m) => m.slice(1))
|
||||
}
|
||||
}
|
||||
// if (!unquotedWl.test(str)) throw new Error('Invalid character in unquoted string: ' + str)
|
||||
return str
|
||||
}
|
||||
function split (str, char, times = Infinity) {
|
||||
let quote = null
|
||||
let split = ''
|
||||
const result = []
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
if (quotes.includes(str[i]) && str[i - 1] !== '\\') {
|
||||
if (!quote) { quote = str[i] } else if (str[i] === quote) { quote = null }
|
||||
} else if (str[i] === char || !quote) {
|
||||
result.push(split.trim())
|
||||
split = ''
|
||||
} else {
|
||||
split += str[i]
|
||||
}
|
||||
}
|
||||
return [...result, split]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { stringify, parse }
|
124
util/text_parser.js
Normal file
124
util/text_parser.js
Normal file
|
@ -0,0 +1,124 @@
|
|||
const { language } = require('minecraft-data')('1.17.1')
|
||||
|
||||
const colormap = {
|
||||
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'
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a native minecraft text component in string form.
|
||||
* @param {string} json_string - A text component string, such as the chat packet's 'message' property.
|
||||
* @returns {object} Parsed message in { raw, clean, ansi } form.
|
||||
*/
|
||||
function parseText (jsonString) {
|
||||
const json = JSON.parse(jsonString)
|
||||
|
||||
let raw = parseJson(json, { color: 'reset' })
|
||||
if (raw.startsWith('§r')) {
|
||||
raw = raw.substring(2)
|
||||
}
|
||||
const clean = raw.replace(/§./g, '').replace(/§/g, '')
|
||||
const ansi = raw.replace(/§[a-f0-9rlonmk]/g, (m) => ansimap[m])
|
||||
return { raw, clean, ansi }
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a native minecraft text component in JSON form.
|
||||
* @param {object} json - The json message.
|
||||
* @param {object} parent - The parent json.
|
||||
* @returns {string} The parsed raw string.
|
||||
*/
|
||||
function parseJson (json, parent) {
|
||||
if (typeof json === 'string') {
|
||||
json = { text: json }
|
||||
}
|
||||
|
||||
json.color ??= parent.color
|
||||
json.bold ??= parent.bold
|
||||
json.italic ??= parent.italic
|
||||
json.underlined ??= parent.underlined
|
||||
json.strikethrough ??= parent.strikethrough
|
||||
json.obfuscated ??= parent.obfuscated
|
||||
|
||||
let raw = ''
|
||||
// if (json.color.startsWith('#'))
|
||||
// raw += '§' + color
|
||||
// else
|
||||
raw += colormap[json.color] || ''
|
||||
if (json.bold) raw += '§l'
|
||||
if (json.italic) raw += '§o'
|
||||
if (json.underlined) raw += '§n'
|
||||
if (json.strikethrough) raw += '§m'
|
||||
if (json.obfuscated) raw += '§k'
|
||||
if (json.text) {
|
||||
raw += json.text
|
||||
}
|
||||
if (json.translate) { // I checked with the native minecraft code. This is how Minecraft does the matching and group indexing. -hhhzzzsss
|
||||
if (language[json.translate]) {
|
||||
const _with = json.with ?? []
|
||||
let i = 0
|
||||
raw += language[json.translate].replace(/%(?:(\\d+)\\$)?(s|%)/g, (g0, g1) => {
|
||||
if (g0 === '%%') {
|
||||
return '%'
|
||||
} else {
|
||||
const idx = g1 ? parseInt(g1) : i++
|
||||
if (_with[idx]) {
|
||||
return parseJson(_with[idx], json)
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
raw += json.translate
|
||||
}
|
||||
}
|
||||
if (json.extra) {
|
||||
json.extra.forEach((extra) => {
|
||||
raw += parseJson(extra, json)
|
||||
})
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
module.exports = parseText
|
6
util/ticks-to-m-ss.js
Normal file
6
util/ticks-to-m-ss.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
function convertTicks (ticks) {
|
||||
const s = (Math.floor(ticks / 20) % 60).toString()
|
||||
return `${Math.floor((ticks / 20) / 60)}:${s.length >= 2 ? s : '0' + s}`
|
||||
}
|
||||
|
||||
module.exports = convertTicks
|
8
util/uuid-to-nbt-uuid.js
Normal file
8
util/uuid-to-nbt-uuid.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
// originally from https://gist.github.com/storycraft/7813dd0186e85daa393e1df9cfa19f2a
|
||||
const nbt = require('prismarine-nbt')
|
||||
|
||||
function toNBTUUID (uuid) {
|
||||
return nbt.intArray(uuid.replace(/-/g, '').match(/.{8}/g).map(str => Number.parseInt(str, 16)).map(num => num & 0x80000000 ? num - 0xffffffff - 1 : num))
|
||||
}
|
||||
|
||||
module.exports = toNBTUUID
|
Loading…
Reference in a new issue