This better not say 0 commits

This commit is contained in:
7cc5c4f330d47060 2024-08-12 04:33:43 -04:00
commit a2b623a8a6
Signed by: 7cc5c4f330d47060
SSH key fingerprint: SHA256:e+4tcZut1nBpe10PqjaO+Rvie0Q7W4qIvFzcUw+7riA
50 changed files with 3247 additions and 0 deletions

159
.gitignore vendored Normal file
View file

@ -0,0 +1,159 @@
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# ---> Kate
# Swap Files #
.*.kate-swp
.swp.*
# ---> Node
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-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/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# 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 variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# 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
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# Bot Settings
settings.json
# Default secret file
secret.json
# botvX user settings
userPref/

9
LICENSE Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 7cc5c4f330d47060
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
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 OR COPYRIGHT HOLDERS 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.

43
README.md Normal file
View file

@ -0,0 +1,43 @@
# botvX
## What is it?
botvX is a Minecraft bot for [Kaboom](https://kaboom.pw/) and its clones. It has many of the features that you would expect in a modern Kaboom bot:
- commands (obviously)
- a self care system
- a command core, to run commands quickly
- a hashing system, to enable trusted users to securely run certain commands in chat
## What does "botvX" mean?
"botvX" means "bot version 10". The v is used to signify that whatever after it is a version, as was done with previous versions (botv4, botv6, botv8, botv9), and the X is the Roman numeral for 10, since this is the 10th major version.
## How to install?
1. Install [Node.js](https://nodejs.org/) for your operating system.
2. Download the latest release, or alternatively, download the latest development version using <code>git clone https://code.chipmunk.land/7cc5c4f330d47060/botvX/</code>.
3. Extract the files if necessary.
4. Run <code>npm install</code> in the bot's directory. If it doesn't work, try using the Node.js command prompt, or adding Node.js to your PATH.
5. Copy <code>settings_example.json</code> to <code>settings.json</code> , and adjust the settings to fit your needs. Do not forget to also create a secrets file. An example secrets file is provided as <code>secret_example.json</code>. Do not forget, if you use the secrets template, to change the keys (the ones in there are public after all!).
6. Run ./launch.sh (macOS, Linux, FreeBSD) or ./launch.cmd (Windows) to start a bot launcher, which will reload the bot when the process closes. Alternatively, you can run <code>node index.js</code> to start the bot only once (it will still rejoin when kicked). If it displays an error saying Node is not a command, please make sure Node.js is on your PATH.
## Command list
| Name | Usage | Description |
|-|-|-|
| about | | About the bot |
| cb | \<command\> | Run a command in a command block |
| cloop | add <rate> <command>, remove <index>, list, clear | Manage command loops |
| eval | \<code\> | Run JavaScript code (must run through console)|
| help | [cmd] | Shows command help |
| logoff | | Disconnect and reconnect the bot from a server |
| netmsg | \<message\> | Send a message to all servers the bot is connected to |
| refill | | Refill core |
| say | \<message\> | Sends a message to chat |
| serverinfo | | Get system/bot info, similar to Kaboom's <code>serverinfo</code> command |
| stop | | Restart bot |
| template | | Used in development, does nothing |
| tpr | | Teleport to a random location |
| verify | | Check the hashing system |

190
commands/about.js Normal file
View file

@ -0,0 +1,190 @@
const os = require('os')
const cp = require('child_process')
const { getMessage, formatTime } = require('../util/lang.js')
const fs = require('fs')
const botVersion = require('../util/version.js')
const version = require('../version.json')
const aboutBot = function (c) {
c.reply({
translate: getMessage(c.lang, 'command.about.author'),
color: c.colors.secondary,
with: [
{
text: version.botName,
color: c.colors.primary
},
{
text: version.botAuthor,
color: c.colors.primary
}
]
})
if (version.isPreRelease) {
c.reply({
text: getMessage(c.lang, 'command.about.preRelease'),
color: c.colors.secondary
})
}
c.reply({ text: '' })
c.reply({
translate: getMessage(c.lang, 'command.about.sourceCode'),
color: c.colors.secondary,
with: [
{
text: version.sourceURL,
color: c.colors.primary,
clickEvent: {
action: 'open_url',
value: version.sourceURL
},
hoverEvent: {
action: 'show_text',
contents: {
text: getMessage(c.lang, 'command.about.sourceCode.openInBrowser')
},
value: { // Added twice for backwards compatibility
text: getMessage(c.lang, 'command.about.sourceCode.openInBrowser')
}
}
}
]
})
}
const os2 = function (o2, l) {
switch (o2) {
case 'win32':
return `${os.version()} (${os.release})`
case 'android':{
try {
const version = cp.execSync('getprop ro.build.version.release').toString('UTF-8').split('\n')[0]
return getMessage(l, 'command.about.serverInfo.os.android', [version])
} catch (e) {
getMessage(l, 'command.about.serverInfo.os.android.noVersion')
}
}
case 'linux':
case 'freebsd':{
if (fs.readdirSync('/etc').includes('os-release')) {
const osrelease = fs.readFileSync('/etc/os-release').toString('UTF-8').split('\n')
const osrelease2 = {}
for (const i in osrelease) {
if (!osrelease[i].includes('=')) continue
let osrvalue = osrelease[i].split('=')[1]
if (osrvalue.startsWith('"') && osrvalue.endsWith('"')) { osrvalue = osrvalue.slice(1, osrvalue.length - 1) };
osrelease2[osrelease[i].split('=')[0]] = osrvalue
}
if (osrelease2.PRETTY_NAME) {
return getMessage(l, '%s %s', [osrelease2.PRETTY_NAME, os.release()])
} else {
return getMessage(l, `command.about.serverInfo.os.${o2}`, [os.release()])
}
} else {
return getMessage(l, `command.about.serverInfo.os.${o2}`, [os.release()])
}
}
default:
return o2
}
}
const aboutServer = function (c) {
const displayInfo = function (name, infoFunc) {
let thisItem
try {
thisItem = infoFunc()
} catch (e) {
console.error(e)
thisItem = 'Error! (check console)'
}
c.reply({
translate: '%s: %s',
color: c.colors.primary,
with: [
{
text: getMessage(c.lang, name),
color: c.colors.secondary
},
{
text: thisItem,
color: c.colors.primary
}
]
})
}
// Operating system
displayInfo('command.about.serverInfo.os', () => {
return os2(process.platform, c.lang)
})
// Processor
if (os.cpus()[0]) {
displayInfo('command.about.serverInfo.processor', () => {
return os.cpus()[0].model
})
}
if (os.cpus()[0]) {
// Processor architecture
displayInfo('command.about.serverInfo.arch', () => {
return os.machine()
})
}
// Username and UID
displayInfo('command.about.serverInfo.osUsername', () => {
return `${os.userInfo().username} (${os.userInfo().uid})`
})
// Hostname
displayInfo('command.about.serverInfo.hostName', () => {
return os.hostname()
})
// Current working directory
displayInfo('command.about.serverInfo.workingDir', () => {
return process.cwd()
})
// Node.js® version
displayInfo('command.about.serverInfo.nodeVersion', () => {
return process.version
})
// Bot uptime
displayInfo('command.about.serverInfo.runTime', () => {
return formatTime(process.uptime() * 1000, c.lang)
})
// System uptime
displayInfo('command.about.serverInfo.upTime', () => {
return formatTime(os.uptime() * 1000, c.lang)
})
if (process.platform === 'android') {
// Device model
displayInfo('command.about.serverInfo.os.android.model', () => {
const brand = cp.execSync('getprop ro.product.brand').toString('UTF-8').split('\n')[0]
const model = cp.execSync('getprop ro.product.model').toString('UTF-8').split('\n')[0]
return `${brand} ${model}`
})
}
// Bot version
displayInfo('command.about.serverInfo.botVer', () => {
return botVersion
})
}
module.exports = {
execute: function (c) {
if (c.args[0] === 'server') {
aboutServer(c)
} else {
aboutBot(c)
}
},
aliases: ['info']
}

7
commands/cb.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
execute: (c) => {
c.bot.ccq.push(c.args.join(' '))
},
consoleIndex: true,
aliases: ['commandblock', 'cmdblock']
}

90
commands/cloop.js Normal file
View file

@ -0,0 +1,90 @@
const { getMessage } = require('../util/lang.js')
module.exports = {
execute: (c) => {
const subcmd = c.args.splice(0, 1)[0]
switch (subcmd) {
case 'add': {
const rate = +(c.args.splice(0, 1)[0])
const command = c.args.join(' ')
if (rate < 20) {
c.reply({
text: getMessage(c.lang, 'command.cloop.error.tooShort')
})
}
c.bot.addCloop(command, rate)
c.reply({
translate: getMessage(c.lang, 'command.cloop.success.add'),
color: c.colors.secondary,
with: [
{
text: command,
color: c.colors.primary
},
{
text: rate + '',
color: c.colors.primary
}
]
})
break
}
case 'remove': {
const index = +c.args[0]
c.bot.removeCloop(c.args[0])
c.reply({
translate: getMessage(c.lang, 'command.cloop.success.remove'),
color: c.colors.secondary,
with: [
{
text: index + '',
color: c.colors.primary
}
]
})
break
}
case 'list':
for (const i in c.bot.cloops) {
c.reply({
translate: getMessage(c.lang, 'command.cloop.list'),
color: c.colors.secondary,
with: [
{
text: i,
color: c.colors.primary
},
{
text: c.bot.cloops[i].command,
color: c.colors.primary
},
{
text: c.bot.cloops[i].rate + '',
color: c.colors.primary
}
]
})
}
break
case 'clear':
c.bot.clearCloops()
c.reply({
text: getMessage(c.lang, 'command.cloop.success.clear'),
color: c.colors.secondary
})
break
default:
c.reply({
translate: getMessage(c.lang, 'command.cloop.error.subcommand'),
color: c.colors.secondary,
with: [
{
text: `${c.prefix}help cloop`,
color: c.colors.primary
}
]
})
}
},
consoleIndex: true,
level: 1
}

11
commands/eval.js Normal file
View file

@ -0,0 +1,11 @@
const index = require('../index.js') // Not used in the code, but may be used by users of the command
module.exports = {
execute: (c) => {
try {
console.log(eval(c.args.join(' ')))
} catch (e) {
console.error(e)
}
},
level: 3
}

165
commands/help.js Normal file
View file

@ -0,0 +1,165 @@
const fs = require('fs')
const cmds = Object.create(null)
const { getMessage } = require('../util/lang.js')
const sortHelp = function sortHelp (c1, c2) {
const level1 = cmds[c1.with[0]].level ? cmds[c1.with[0]].level : 0
const level2 = cmds[c2.with[0]].level ? cmds[c2.with[0]].level : 0
return level1 - level2
}
const bpl = fs.readdirSync('./commands')
for (const i in bpl) { // Built-in loadCMD to the help command, to prevent circular require
if (!bpl[i].endsWith('.js')) {
continue
}
try {
const commandName = bpl[i].split('.js')[0]
if (commandName !== 'help') {
cmds[commandName] = require(`./${bpl[i]}`)
if (cmds[commandName].level === undefined) {
cmds[commandName].level = 0
}
}
} catch (e) { console.log(e) }
}
const printHelp = (c) => {
const commandList = []
for (const i in cmds) {
if (cmds[i].hidden) continue
let cmdColor
switch (cmds[i].level) {
case 0:
cmdColor = 'green'
break
case 1:
cmdColor = 'red'
break
case 2:
cmdColor = 'dark_red'
break
case 3:
cmdColor = 'dark_red'
break
default:
cmdColor = 'green'
}
commandList.push(
{
translate: '%s ',
color: cmdColor,
with: [
i
]
}
)
}
c.reply({
translate: '%s %s',
with: [
getMessage(c.lang, 'command.help.cmdList'),
commandList.sort(sortHelp)
]
})
}
const printCmdHelp = (c) => {
const cmd = c.args[0]
if (!cmds[cmd]) {
c.reply({ text: getMessage(c.lang, 'command.help.noCommand') })
return
}
let usage = getMessage(c.lang, `command.${cmd}.usage`).split('||')
let desc = getMessage(c.lang, `command.${cmd}.desc`)
if (cmds[cmd].usage) {
usage = cmds[cmd].usage.split('||')
}
if (cmds[cmd].desc) {
desc = cmds[cmd].desc
}
if (cmds[cmd].alias) {
console.log(cmds[cmds[cmd].alias])
usage = getMessage(c.lang, `command.${cmds[cmd].alias}.usage`).split('||')
desc = getMessage(c.lang, 'command.help.alias', [cmds[cmd].alias])
if (cmds[cmds[cmd].alias].usage) {
usage = cmds[cmds[cmd].alias].usage.split('||')
}
if (cmds[cmds[cmd].alias].desc) {
desc = cmds[cmds[cmd].alias].desc
}
}
for (const i in usage) {
c.reply({
translate: getMessage(c.lang, 'command.help.commandUsage'),
color: c.colors.secondary,
with: [
{
text: cmd,
color: c.colors.primary
},
{
text: usage[i],
color: c.colors.primary
}
]
})
}
c.reply({
translate: getMessage(c.lang, 'command.help.commandDesc'),
color: c.colors.secondary,
with: [
{
text: desc,
color: c.colors.primary
}
]
})
const permsN = getMessage(c.lang, 'command.help.permsNormal')
const permsT = getMessage(c.lang, 'command.help.permsTrusted')
const permsO = getMessage(c.lang, 'command.help.permsOwner')
const permsC = getMessage(c.lang, 'command.help.permsConsole')
const rPerms = cmds[cmd].level ? cmds[cmd].level : 0
c.reply({
translate: getMessage(c.lang, 'command.help.commandPerms'),
color: c.colors.secondary,
with: [
{
text: [permsN, permsT, permsO, permsC][rPerms],
color: c.colors.primary
}
]
})
}
module.exports = {
execute: (c) => {
if (c.args.length > 0) {
printCmdHelp(c)
} else {
printHelp(c)
}
},
aliases: [
'heko' // Parker2991 request
]
}
cmds.help = module.exports // Placed after to ensure that the correct values are added to cmds
if (cmds.help.level === undefined) {
cmds.help.level = 0
}
for (const i in cmds) {
if (cmds[i].aliases) {
for (const j in cmds[i].aliases) {
cmds[cmds[i].aliases[j]] = {
alias: i,
usage: cmds[i].usage,
level: cmds[i].level,
hidden: true,
consoleIndex: cmds[i].consoleIndex
}
}
}
}

7
commands/logoff.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
execute: (c) => {
c.bot._client.end()
},
consoleIndex: true,
level: 2
}

44
commands/netmsg.js Normal file
View file

@ -0,0 +1,44 @@
const { bot } = require('../index.js')
const { getMessage } = require('../util/lang.js')
module.exports = {
execute: (c) => {
if(c.bot.host && c.bot.host.options.netmsgDisabled){
c.reply({
text: getMessage(c.lang, "command.netmsg.disabled"),
color: c.colors.secondary
})
return
}
const json = {
translate: '[%s] %s: %s',
with: [
{
translate: '%s:%s',
with: [
{
text: c.host,
color: c.colors.primary
},
{
text: c.port + '',
color: c.colors.primary
}
],
color: c.colors.secondary
},
{
text: c.username,
color: c.colors.primary
},
{
text: c.args.join(' ')
}
],
color: 'white'
}
for (const i in bot) {
if(bot[i].host.options.netmsgDisabled) continue
bot[i].tellraw('@a', json)
}
}
}

7
commands/refill.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
execute: (c) => {
c.bot.chat(c.bot.refillCoreCmd)
},
consoleIndex: true,
aliases: ['refillcore', 'rc']
}

7
commands/restart.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
execute: (c) => {
process.exit(0)
},
aliases: ['reboot'],
level: 2
}

8
commands/say.js Normal file
View file

@ -0,0 +1,8 @@
module.exports = {
execute: (c) => {
if (c.args[0].startsWith('/') && c.verify < 1) return
c.bot.chat(c.args.join(' '))
},
consoleIndex: true,
aliases: ['echo']
}

140
commands/settings.js Normal file
View file

@ -0,0 +1,140 @@
const { languages, getMessage } = require('../util/lang.js')
const fs = require('fs')
module.exports = {
execute: (c) => {
const subcmd = c.args.splice(0, 1)[0]
switch (subcmd) {
case 'set':
const allowedKeys = ["colorPrimary", "colorSecondary", "lang"]
const key = c.args.splice(0, 1)[0]
if(!allowedKeys.includes(key)){
c.reply({
text: getMessage(c.lang, 'command.settings.error.invalidKey'),
color: c.colors.secondary
});
return;
}
const value = c.args.join(" ")
if(value === "" && key==="lang"){
// Show all valid languages to user
for(const i in languages){
c.reply({
translate: "%s (%s)",
color: c.colors.secondary,
with:[
{
text: getMessage(languages[i], 'language.name'),
color: c.colors.primary
},
{
text: getMessage(languages[i], 'language.region'),
color: c.colors.primary
}
],
hoverEvent:{
action: "show_text",
value: {
translate: getMessage(languages[i], 'command.settings.setLanguage'),
with:[
{
text: `${c.prefix}settings set lang ${languages[i]}`,
color: c.colors.secondary
}
]
}
}
})
}
return
}
if(value === ""){
c.reply({
text: getMessage(c.lang, 'command.settings.error.mustProvideValue'),
color: c.colors.secondary
});
return;
}
if(key==="lang" && !languages.includes(value)){
c.reply({
text: getMessage(c.lang, 'command.settings.error.invalidLanguage'),
color: c.colors.secondary
});
return;
}
c.prefs[key] = value
// Save to file
fs.writeFileSync(`userPref/${c.uuid}.json`, JSON.stringify(c.prefs))
// Delete require cache
for(const i in require.cache){
if(i.endsWith(`${c.uuid}.json`)) delete require.cache[i]
}
c.reply({
text: getMessage(c.lang, 'command.settings.saved'),
color: c.colors.secondary
});
break;
case 'get':{
c.reply({
translate: "%s: %s",
color: c.colors.secondary,
with:[
{
text: getMessage(c.lang, 'command.settings.get.colorPrimary'),
color: c.colors.secondary
},
{
text: c.colors.primary,
color: c.colors.primary
}
]
})
c.reply({
translate: "%s: %s",
color: c.colors.secondary,
with:[
{
text: getMessage(c.lang, 'command.settings.get.colorSecondary'),
color: c.colors.secondary
},
{
text: c.colors.secondary,
color: c.colors.secondary
}
]
})
c.reply({
translate: "%s: %s (%s)",
color: c.colors.secondary,
with:[
{
text: getMessage(c.lang, 'command.settings.get.language'),
color: c.colors.primary
},
{
text: getMessage(c.lang, 'language.name'),
color: c.colors.primary
},
{
text: getMessage(c.lang, 'language.region'),
color: c.colors.primary
}
]
})
break
}
default:
c.reply({
translate: getMessage(c.lang, 'command.cloop.error.subcommand'),
color: c.colors.secondary,
with: [
{
text: `${c.prefix}help settings`,
color: c.colors.primary
}
]
})
}
}
}

7
commands/stop.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
execute: (c) => {
process.exit(1)
},
aliases: ['exit'],
level: 2
}

42
commands/template.js Normal file
View file

@ -0,0 +1,42 @@
module.exports = {
execute: (c) => {
// Blank template
/*
c.send(text, user?): Send text to all ("/tellraw @a")
c.reply(text): Send text to command sender
c.uuid: Unique identifier (UUID for Minecraft, Discord ID for Discord)
c.username: Username of sender
c.nickname: Nickname of sender when applicable
c.command: Command string
c.args: Arguments of command (above without the first section, and split at every space)
c.prefix: Prefix being used to send the command (when applicable)
c.bot: Bot that received the command. Will be different type based on where it was received
c.type: Type of bot receiving the command ("minecraft", "console", "discord")
c.lang: The language the player has selected, or the default if none
c.colors: The color palette the player has selected, or the default if none
*/
},
/*
Command description and usage have been moved to the message files. The format for a basic command is:
"command.(name).usage": " <required> [optional]",
"command.(name).desc": "Insert description here...",
replacing (name) with the name of the new command.
Some more complex commands may have messages of their own, which should be placed there too.
First, insert the following line near the top of the command's file (not in the execute function):
const { getMessage } = require('../../util/lang.js')
Then, to get a specific message:
getMessage(c.lang,"(message key)",[(arguments, in an array (optional))])
For example, this will show the "about" command's redirection to "serverinfo":
getMessage(c.lang,"command.about.serverinfo")
The with array can be used to add information to a message. For example:
getMessage(lang,"command.help.commandInfo",["cmd","usage","desc"])
shows the "help" command's formatting for command information, with some strings as items.
That message would render as (in en-US):
cmdusage - desc
Extra information is inserted wherever there is a "%s" or a "%n$s", with n being the index of the item in the array.
*/
hidden: true, // To show the command on the help command list, remove this line (optional)
consoleIndex: true, // When run from console, the second argument will be a bot ID (optional)
aliases: ['example', 'testing'], // Other command names that will work the same (optional)
level: 0 // Permission level required to run this command (optional)
}

43
commands/tpr.js Executable file
View file

@ -0,0 +1,43 @@
const { getMessage } = require('../util/lang.js')
module.exports = {
execute: function (c) {
let uuid
if (c.type === 'console') {
uuid = c.bot._client.uuid
} else {
uuid = c.uuid
}
const originalPos = {
x: Math.floor(Math.random() * 2000000) - 1000000,
y: 100,
z: Math.floor(Math.random() * 2000000) - 1000000
}
c.reply(
{
translate: getMessage(c.lang, 'command.tpr.success'),
color: c.colors.secondary,
with: [
{
text: c.username,
color: c.colors.primary
},
{
text: originalPos.x.toString(),
color: c.colors.primary
},
{
text: originalPos.y.toString(),
color: c.colors.primary
},
{
text: originalPos.z.toString(),
color: c.colors.primary
}
]
}
)
c.bot.ccq.push(`/essentials:tp ${uuid} ${originalPos.x}.0 ${originalPos.y} ${originalPos.z}.0`)
},
consoleIndex: true,
aliases: ['rtp']
}

21
commands/verify.js Normal file
View file

@ -0,0 +1,21 @@
const { getMessage } = require('../util/lang.js')
module.exports = {
execute: (c) => {
const permsN = getMessage(c.lang, 'command.help.permsNormal')
const permsT = getMessage(c.lang, 'command.help.permsTrusted')
const permsO = getMessage(c.lang, 'command.help.permsOwner')
const permsC = getMessage(c.lang, 'command.help.permsConsole')
c.reply({
translate: getMessage(c.lang, 'command.verify.success'),
color: c.colors.secondary,
with: [
{
text: [permsN, permsT, permsO, permsC][c.verify],
color: c.colors.primary
}
]
})
},
aliases: ['validate'],
level: 1
}

73
index.js Executable file
View file

@ -0,0 +1,73 @@
const m = require('minecraft-protocol')
const settings = require('./settings.json')
const generateUser = require('./util/usergen.js')
const EventEmitter = require('node:events')
const fs = require('fs')
module.exports.bot = []
const loadplug = (botno) => {
const botplug = []
const bpl = fs.readdirSync('plugins')
for (const i in bpl) {
if (!bpl[i].endsWith('.js')) {
continue
}
try {
botplug.push(require(`./plugins/${bpl[i]}`))
} catch (e) { console.log(e) }
}
botplug.forEach((plug) => {
try {
if (plug.load) {
plug.load(module.exports.bot[botno])
}
} catch (e) { console.log(e) }
})
}
const createBot = function createBot (host, oldId) {
if (host.options.disabled) {
return
}
const bot = new EventEmitter()
bot._client = m.createClient({
host: host.host,
port: host.port ? host.port : 25565,
username: generateUser(host.options.legalName),
version: host.version ? host.version : settings.version_mc
})
if (typeof oldId !== 'undefined') {
for (const i in module.exports.bot[oldId].interval) {
clearInterval(module.exports.bot[oldId].interval[i])
}
delete module.exports.bot[oldId]
bot.id = oldId
module.exports.bot[oldId] = bot
} else {
bot.id = module.exports.bot.length
module.exports.bot.push(bot)
}
bot.host = host
bot.interval = {}
bot.info = (msg) => {
console.log(`[${bot.id}] [info] ${msg}`)
}
bot.displayChat = (type, msg) => {
console.log(`[${bot.id}] [${type}] ${msg}`)
}
loadplug(bot.id)
bot._client.on('error', (err) => {
console.log(err)
})
}
for (const i in settings.servers) {
createBot(settings.servers[i])
}
module.exports.createBot = createBot

8
launch.cmd Normal file
View file

@ -0,0 +1,8 @@
@echo off
:botlaunch
node index.js
if %errorlevel%==1 (
exit
)
timeout /nobreak /t 5 > nul
goto botlaunch

6
launch.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
while [ true ];
do node index.js;
if [ $? -eq 1 ]; then exit; fi
sleep 6;
done

830
package-lock.json generated Executable file
View file

@ -0,0 +1,830 @@
{
"name": "botv10",
"version": "10.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "botv10",
"version": "10.0.0",
"license": "UNLICENSED",
"dependencies": {
"minecraft-protocol": "^1.45.0",
"prismarine-chat": "^1.10.0"
}
},
"node_modules/@azure/msal-common": {
"version": "14.14.0",
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.14.0.tgz",
"integrity": "sha512-OxcOk9H1/1fktHh6//VCORgSNJc2dCQObTm6JNmL824Z6iZSO6eFo/Bttxe0hETn9B+cr7gDouTQtsRq3YPuSQ==",
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@azure/msal-node": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.12.0.tgz",
"integrity": "sha512-jmk5Im5KujRA2AcyCb0awA3buV8niSrwXZs+NBJWIvxOz76RvNlusGIqi43A0h45BPUy93Qb+CPdpJn82NFTIg==",
"license": "MIT",
"dependencies": {
"@azure/msal-common": "14.14.0",
"jsonwebtoken": "^9.0.0",
"uuid": "^8.3.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@types/node": {
"version": "22.2.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz",
"integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.13.0"
}
},
"node_modules/@types/readable-stream": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.15.tgz",
"integrity": "sha512-oAZ3kw+kJFkEqyh7xORZOku1YAKvsFTogRY8kVl4vHpEKiDkfnSA/My8haRE7fvmix5Zyy+1pwzOi7yycGLBJw==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
"safe-buffer": "~5.1.1"
}
},
"node_modules/@xboxreplay/errors": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@xboxreplay/errors/-/errors-0.1.0.tgz",
"integrity": "sha512-Tgz1d/OIPDWPeyOvuL5+aai5VCcqObhPnlI3skQuf80GVF3k1I0lPCnGC+8Cm5PV9aLBT5m8qPcJoIUQ2U4y9g==",
"license": "MIT"
},
"node_modules/@xboxreplay/xboxlive-auth": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/@xboxreplay/xboxlive-auth/-/xboxlive-auth-3.3.3.tgz",
"integrity": "sha512-j0AU8pW10LM8O68CTZ5QHnvOjSsnPICy0oQcP7zyM7eWkDQ/InkiQiirQKsPn1XRYDl4ccNu0WM582s3UKwcBg==",
"license": "MIT",
"dependencies": {
"@xboxreplay/errors": "^0.1.0",
"axios": "^0.21.1"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/aes-js": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
"integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==",
"license": "MIT"
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha512-6i37w/+EhlWlGUJff3T/Q8u1RGmP5wgbiwYnOnbOqvtrPxT63/sYFyP9RcpxtxGymtfA075IvmOnL7ycNOWl3w==",
"license": "MIT"
},
"node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/buffer-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
"integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
"license": "MIT",
"engines": {
"node": ">=0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"license": "BSD-3-Clause"
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
"node_modules/debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/discontinuous-range": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
"integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==",
"license": "MIT"
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/endian-toggle": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/endian-toggle/-/endian-toggle-0.0.0.tgz",
"integrity": "sha512-ShfqhXeHRE4TmggSlHXG8CMGIcsOsqDw/GcoPcosToE59Rm9e4aXaMhEQf2kPBsBRrKem1bbOAv5gOKnkliMFQ==",
"license": "MIT"
},
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"license": "MIT",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"license": "MIT"
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/jose": {
"version": "4.15.9",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
"integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"license": "MIT"
},
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
"license": "MIT",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^7.5.4"
},
"engines": {
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"license": "MIT"
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
"license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT"
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
"license": "MIT"
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
"license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"license": "MIT"
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
"license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"license": "MIT"
},
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT"
},
"node_modules/lodash.reduce": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
"integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==",
"license": "MIT"
},
"node_modules/macaddress": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.5.3.tgz",
"integrity": "sha512-vGBKTA+jwM4KgjGZ+S/8/Mkj9rWzePyGY6jManXPGhiWu63RYwW8dKPyk5koP+8qNVhPhHgFa1y/MJ4wrjsNrg==",
"license": "MIT"
},
"node_modules/minecraft-data": {
"version": "3.67.0",
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.67.0.tgz",
"integrity": "sha512-/hLeYXopx9o1UdViPPFenLJ3hT5S4qUEwLQM0MAHOIhqkAUGXdkl47O7ohG+f87DH3+cZksbbM61sTnSRsQpsA==",
"license": "MIT"
},
"node_modules/minecraft-folder-path": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minecraft-folder-path/-/minecraft-folder-path-1.2.0.tgz",
"integrity": "sha512-qaUSbKWoOsH9brn0JQuBhxNAzTDMwrOXorwuRxdJKKKDYvZhtml+6GVCUrY5HRiEsieBEjCUnhVpDuQiKsiFaw==",
"license": "MIT"
},
"node_modules/minecraft-protocol": {
"version": "1.47.0",
"resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.47.0.tgz",
"integrity": "sha512-IHL8faXLLIWv1O+2v2NgyKlooilu/OiSL9orI8Kqed/rZvVOrFPzs2PwMAYjpQX9gxLPhiSU19KqZ8CjfNuqhg==",
"license": "BSD-3-Clause",
"dependencies": {
"@types/readable-stream": "^4.0.0",
"aes-js": "^3.1.2",
"buffer-equal": "^1.0.0",
"debug": "^4.3.2",
"endian-toggle": "^0.0.0",
"lodash.get": "^4.1.2",
"lodash.merge": "^4.3.0",
"minecraft-data": "^3.55.0",
"minecraft-folder-path": "^1.2.0",
"node-fetch": "^2.6.1",
"node-rsa": "^0.4.2",
"prismarine-auth": "^2.2.0",
"prismarine-chat": "^1.10.0",
"prismarine-nbt": "^2.5.0",
"prismarine-realms": "^1.2.0",
"protodef": "^1.8.0",
"readable-stream": "^4.1.0",
"uuid-1345": "^1.0.1",
"yggdrasil": "^1.4.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/mojangson": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mojangson/-/mojangson-2.0.4.tgz",
"integrity": "sha512-HYmhgDjr1gzF7trGgvcC/huIg2L8FsVbi/KacRe6r1AswbboGVZDS47SOZlomPuMWvZLas8m9vuHHucdZMwTmQ==",
"license": "MIT",
"dependencies": {
"nearley": "^2.19.5"
}
},
"node_modules/moo": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
"license": "BSD-3-Clause"
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/nearley": {
"version": "2.20.1",
"resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
"integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
"license": "MIT",
"dependencies": {
"commander": "^2.19.0",
"moo": "^0.5.0",
"railroad-diagrams": "^1.0.0",
"randexp": "0.4.6"
},
"bin": {
"nearley-railroad": "bin/nearley-railroad.js",
"nearley-test": "bin/nearley-test.js",
"nearley-unparse": "bin/nearley-unparse.js",
"nearleyc": "bin/nearleyc.js"
},
"funding": {
"type": "individual",
"url": "https://nearley.js.org/#give-to-nearley"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/node-rsa": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-0.4.2.tgz",
"integrity": "sha512-Bvso6Zi9LY4otIZefYrscsUpo2mUpiAVIEmSZV2q41sP8tHZoert3Yu6zv4f/RXJqMNZQKCtnhDugIuCma23YA==",
"license": "MIT",
"dependencies": {
"asn1": "0.2.3"
}
},
"node_modules/prismarine-auth": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/prismarine-auth/-/prismarine-auth-2.5.0.tgz",
"integrity": "sha512-CRv/pL6d/T+4cdjWS223PXG+ygHbz40Kef04L59SLMT+axNdAQro23eZZhgiIIu6u7rlvJcZYlIY93gFNtKxXA==",
"license": "MIT",
"dependencies": {
"@azure/msal-node": "^2.0.2",
"@xboxreplay/xboxlive-auth": "^3.3.3",
"debug": "^4.3.3",
"jose": "^4.1.4",
"node-fetch": "^2.6.1",
"smart-buffer": "^4.1.0",
"uuid-1345": "^1.0.2"
}
},
"node_modules/prismarine-chat": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/prismarine-chat/-/prismarine-chat-1.10.1.tgz",
"integrity": "sha512-XukYcuueuhDxzEXG7r8BZyt6jOObrPPB4JESCgb+/XenB9nExoSHF8eTQWWj8faKPLqm1dRQaYwFJlNBlJZJUw==",
"license": "MIT",
"dependencies": {
"mojangson": "^2.0.1",
"prismarine-nbt": "^2.0.0",
"prismarine-registry": "^1.4.0"
}
},
"node_modules/prismarine-nbt": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-2.5.0.tgz",
"integrity": "sha512-F0/8UAa9SDDnAGrBYqZc4nG8h2zj5cE2eAJU5xlDR/IsQQ3moVxkOjE3h3nMv6SbvZrvAcgX7waA/nd9LLHYdA==",
"license": "MIT",
"dependencies": {
"protodef": "^1.9.0"
}
},
"node_modules/prismarine-realms": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/prismarine-realms/-/prismarine-realms-1.3.2.tgz",
"integrity": "sha512-5apl9Ru8veTj5q2OozRc4GZOuSIcs3yY4UEtALiLKHstBe8bRw8vNlaz4Zla3jsQ8yP/ul1b1IJINTRbocuA6g==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.3",
"node-fetch": "^2.6.1"
}
},
"node_modules/prismarine-registry": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/prismarine-registry/-/prismarine-registry-1.7.0.tgz",
"integrity": "sha512-yyva0FpWI078nNeMhx8ekVza5uUTYhEv+C+ADu3wUQXiG8qhXkvrf0uzsnhTgZL8BLdsi2axgCEiKw9qSKIuxQ==",
"license": "MIT",
"dependencies": {
"minecraft-data": "^3.0.0",
"prismarine-nbt": "^2.0.0"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/protodef": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/protodef/-/protodef-1.15.0.tgz",
"integrity": "sha512-bZ2Omw8dT+DACjJHLrBWZlqN4MlT9g9oSpJDdkUAJOStUzgJp+Zn42FJfPUdwutUxjaxA0PftN0PDlNa2XbneA==",
"license": "MIT",
"dependencies": {
"lodash.get": "^4.4.2",
"lodash.reduce": "^4.6.0",
"protodef-validator": "^1.3.0",
"readable-stream": "^3.0.3"
},
"engines": {
"node": ">=14"
}
},
"node_modules/protodef-validator": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/protodef-validator/-/protodef-validator-1.3.1.tgz",
"integrity": "sha512-lZ5FWKZYR9xOjpMw1+EfZRfCjzNRQWPq+Dk+jki47Sikl2EeWEPnTfnJERwnU/EwFq6us+0zqHHzSsmLeYX+Lg==",
"license": "MIT",
"dependencies": {
"ajv": "^6.5.4"
},
"bin": {
"protodef-validator": "cli.js"
}
},
"node_modules/protodef/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/railroad-diagrams": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
"integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==",
"license": "CC0-1.0"
},
"node_modules/randexp": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
"integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
"license": "MIT",
"dependencies": {
"discontinuous-range": "1.0.0",
"ret": "~0.1.10"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/readable-stream": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
"integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
"license": "MIT",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"license": "MIT",
"engines": {
"node": ">=0.12"
}
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"license": "MIT",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/string_decoder/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz",
"integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==",
"license": "MIT"
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/uuid-1345": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/uuid-1345/-/uuid-1345-1.0.2.tgz",
"integrity": "sha512-bA5zYZui+3nwAc0s3VdGQGBfbVsJLVX7Np7ch2aqcEWFi5lsAEcmO3+lx3djM1npgpZI8KY2FITZ2uYTnYUYyw==",
"license": "MIT",
"dependencies": {
"macaddress": "^0.5.1"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/yggdrasil": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/yggdrasil/-/yggdrasil-1.7.0.tgz",
"integrity": "sha512-QBIo5fiNd7688G3FqXXYGr36uyrYzczlNuzpWFy2zL3+R+3KT2lF+wFxm51synfA3l3z6IBiGOc1/EVXWCYY1Q==",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.6.1",
"uuid": "^8.2.0"
}
}
}
}

15
package.json Executable file
View file

@ -0,0 +1,15 @@
{
"dependencies": {
"minecraft-protocol": "^1.45.0",
"prismarine-chat": "^1.10.0"
},
"name": "botv10",
"version": "10.0.0-beta-2",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"description": ""
}

148
plugins/!chat.js Executable file
View file

@ -0,0 +1,148 @@
const settings = require('../settings.json')
const parsePlain = require('../util/chatparse_plain.js')
const parseConsole = require('../util/chatparse_console.js')
const parse1204 = require('../util/parseNBT.js')
const messageTypes = [
'',
'chat.type.emote',
'commands.message.display.incoming',
'commands.message.display.outgoing',
'',
'chat.type.announcement',
'chat.type.team.text',
'chat.type.team.sent'
]
module.exports = {
load: (b) => {
b._client.on('profileless_chat', (data) => {
if (data.type === 4) {
const json = parse1204(data.message)
const parsed = parsePlain(json)
const split = parsed.split(': ')
const chatName = split.splice(0, 1)[0]
const username = b.findRealName(chatName)
const uuid = b.findUUID(username)
b.emit('chat', { json, type: 'profileless', uuid, message: split.join(': '), username })
} else if (data.type === 6 || data.type === 7) {
b.emit('chat', {
json: {
translate: messageTypes[data.type],
color: (data.type === 2 || data.type === 3) ? 'gray' : 'reset',
with: [
parse1204(data.target),
parse1204(data.name),
data.message
]
},
type: 'profileless',
uuid: data.senderUuid,
message: parsePlain(data.message),
username: parsePlain(parse1204(data.name))
})
} else {
b.emit('chat', {
json: {
translate: messageTypes[data.type],
color: (data.type === 2 || data.type === 3) ? 'gray' : 'reset',
with: [
parse1204(data.name),
parse1204(data.message)
]
},
type: 'profileless',
uuid: '00000000-0000-0000-0000-000000000000',
message: parsePlain(parse1204(data.message)),
username: parsePlain(parse1204(data.name))
})
}
})
b._client.on('player_chat', (data) => {
if (data.type === 4) {
b.emit('chat', { json: parse1204(data.unsignedChatContent), type: 'player', uuid: data.senderUuid, message: data.plainMessage, username: parsePlain(parse1204(data.networkName)) })
} else if (data.type === 6 || data.type === 7) {
b.emit('chat', {
json: {
translate: messageTypes[data.type],
color: data.type === 2 ? 'gray' : 'reset',
with: [
parse1204(data.networkTargetName),
parse1204(data.networkName),
data.plainMessage
]
},
type: 'player',
uuid: data.senderUuid,
message: parsePlain(data.plainMessage),
username: parsePlain(parse1204(data.networkName))
})
} else {
b.emit('chat', {
json: {
translate: messageTypes[data.type],
color: (data.type === 2 || data.type === 3) ? 'gray' : 'reset',
with: [
parse1204(data.networkName),
data.plainMessage
]
},
type: 'player',
uuid: data.senderUuid,
message: parsePlain(data.plainMessage),
username: parsePlain(parse1204(data.networkName))
})
}
})
b._client.on('system_chat', (data) => {
const json = parse1204(data.content)
const parsed = parsePlain(json)
const split = parsed.split(': ')
const chatName = split.splice(0, 1)[0]
const username = b.findRealName(chatName)
const uuid = b.findUUID(username)
b.emit('chat', { json, type: 'system', uuid, message: split.join(': '), username })
})
b._client.on('chat', (data) => { // Legacy chat
const json = parse1204(data.message)
const parsed = parsePlain(json)
let chatName
let username
let message
let uuid
if (b.host.options.isVanilla && json.translate === 'chat.type.text') { // Servers without Extras chat
if (json.with && json.with.length >= 2) {
message = parsePlain(json.with[1])
username = parsePlain(json.with[0])
}
uuid = b.findUUID(username)
} else { // Servers with Extras chat, such as Kaboom
const split = parsed.split(': ')
message = split.join(': ')
uuid = b.findUUID(username)
chatName = split.splice(0, 1)[0]
username = b.findRealName(chatName)
}
b.emit('chat', { json, type: 'legacy', uuid: data.uuid ? data.uuid : uuid, message, username })
})
b.on('chat', (data) => {
const msgConsole = parseConsole(data.json)
const msgPlain = parsePlain(data.json)
if (settings.logJSONmessages) console.log(data.json)
if (msgPlain.endsWith('\n\n\n\n\nThe chat has been cleared')) return
if (msgPlain.startsWith('Command set: ')) return
b.emit('plainchat', msgPlain)
b.displayChat(data.type, `${msgConsole}\x1b[0m`)
const fullCommand = data.message
for (const i in b.prefix) {
if (fullCommand.startsWith(b.prefix[i])) {
const command = fullCommand.slice(b.prefix[i].length)
b.runCommand(data.username, data.uuid, command, b.prefix[i])
}
}
})
}
}

23
plugins/cloop.js Executable file
View file

@ -0,0 +1,23 @@
module.exports = {
load: (b) => {
b.cloops = []
b.addCloop = function (command, rate) {
b.cloops.push({
command,
rate,
interval: setInterval(() => { b.ccq.push(command) }, rate)
})
b.ccq.push(command)
}
b.removeCloop = function (index) {
clearInterval(b.cloops[index].interval)
b.cloops.splice(index, 1)
}
b.clearCloops = function () {
for (const i in b.cloops) {
clearInterval(b.cloops[i].interval)
}
b.cloops = []
}
}
}

64
plugins/command.js Executable file
View file

@ -0,0 +1,64 @@
const Command = require('../util/Command.js')
const hashcheck = require('../util/hashcheck.js')
const settings = require('../settings.json')
const { getMessage } = require('../util/lang.js')
const cmds = require('../util/commands.js')
const fs = require("fs")
if(!fs.readdirSync('.').includes('userPref')) fs.mkdirSync("userPref");
const loadSettings = function(uuid){
try {
return require(`../userPref/${uuid}.json`)
} catch (e) {
return {}
}
}
module.exports = {
load: (b) => {
b.prefix = settings.prefix
b.lastCmd = 0
b.runCommand = (name, uuid, text, prefix) => {
if (uuid === '00000000-0000-0000-0000-000000000000') return
if (Date.now() - b.lastCmd <= 1000) return
const userSettings = loadSettings(uuid);
b.lastCmd = Date.now()
const cmd = text.split(' ')
const lang = settings.defaultLang
const verify = hashcheck(cmd)
if (verify > 0) {
text = cmd.slice(0, cmd.length - 1).join(' ')
}
if (cmds[cmd[0].toLowerCase()]) {
const command = cmds[cmd[0].toLowerCase()]
if (command.level !== undefined && command.level > verify) {
b.tellraw(uuid, {
text: getMessage(lang, 'command.disallowed.perms')
})
b.tellraw(uuid, {
text: getMessage(lang, 'command.disallowed.perms.yourLevel', [verify + ''])
})
b.tellraw(uuid, {
text: getMessage(lang, 'command.disallowed.perms.cmdLevel', [command.level + ''])
})
return
}
try {
cmds[cmd[0].toLowerCase()].execute(new Command(uuid, name, 'nick N/A', text, prefix, b, verify, userSettings))
} catch (e) {
console.log(e)
b.tellraw(uuid, {
text: getMessage(lang, 'command.error'),
color: 'red',
hoverEvent: {
action: 'show_text',
value: {
text: e.stack
}
}
})
}
}
}
}
}

118
plugins/commandblock.js Executable file
View file

@ -0,0 +1,118 @@
const uuidToInt = require('../util/uuidtoint.js')
const cs = {
x: 4,
y: 6,
z: 4
}
module.exports = {
load: function (b) {
b.interval.commandFill = setInterval(() => { if (b.sc_tasks.cc) b.sc_tasks.cc.failed = 1 }, 150000)
b.ccq = []
b.blocknoX = 0
b.blocknoZ = 0
b.ccStarted = false
b.blocknoY = 0
b.pos = { x: 0, y: 0, z: 0 }
b.refillCoreCmd = `/fill ~ 55 ~ ~${cs.x - 1} ${54 + cs.y} ~${cs.z - 1} command_block{CustomName:'{"translate":"%s %s","with":[{"translate":"entity.minecraft.ender_dragon"},{"translate":"language.region"}],"color":"#FFAAEE"}'}`
b.advanceccq = function () {
if (b.ccq[0] && b.ccq[0].length !== 0) {
b._client.write('update_command_block', {
command: b.ccq[0],
location: {
x: b.commandPos.x + b.blocknoX,
y: b.commandPos.y + b.blocknoY,
z: b.commandPos.z + b.blocknoZ
},
mode: 2,
flags: 1
})
b._client.write('update_command_block', {
command: b.ccq[0],
location: {
x: b.commandPos.x + b.blocknoX,
y: b.commandPos.y + b.blocknoY,
z: b.commandPos.z + b.blocknoZ
},
mode: 2,
flags: 5
})
b.blocknoX++
if (b.blocknoX === cs.x) {
b.blocknoY++
b.blocknoX = 0
if (b.blocknoY === cs.y) {
b.blocknoZ++
b.blocknoY = 0
if (b.blocknoZ === cs.z) {
b.blocknoZ = 0
}
}
}
}
b.ccq.splice(0, 1)
}
b._client.on('login', () => {
b.add_sc_task('cc', () => {
b.chat(b.refillCoreCmd)
}, true)
b.add_sc_task('cc_size', () => {
b.chat('/gamerule commandModificationBlockLimit 32768')
})
})
b.on('ccstart', () => {
setTimeout(() => { b.interval.ccqi = setInterval(b.advanceccq, 3) }, 1000) // 1 Second and 3 Milliseconds
b.ccStarted = true
})
b.on('chat', (data) => {
if (data.json.translate === 'commands.fill.failed' || (data.json.extra && data.json.extra[0] && data.json.extra[0].translate === 'commands.fill.failed') ||
data.json.translate === 'commands.fill.success' || (data.json.extra && data.json.extra[0] && data.json.extra[0].translate === 'commands.fill.success')) {
if (!b.ccStarted) {
b.emit('ccstart')
}
b.sc_tasks.cc.failed = 0
b.sc_tasks.cc_size.failed = 0
} else if (data.json.translate === 'commands.fill.toobig' || (data.json.extra && data.json.extra[0] && data.json.extra[0].translate === 'commands.fill.toobig')) {
b.sc_tasks.cc_size.failed = 1
}
})
b._client.on('position', function (a) {
if (!b.ccStarted) {
b.original_pos = { x: a.x, y: a.y, z: a.z }
b.pos = { x: a.x, y: a.y, z: a.z }
} else {
b.pos = { x: a.x, y: a.y, z: a.z }
if (a.x !== b.original_pos.x || a.z !== b.original_pos.z) {
b.original_pos = { x: a.x, y: a.y, z: a.z }
b.sc_tasks.cc.failed = 1
}
}
b.commandPos = {
x: Math.floor(a.x),
z: Math.floor(a.z),
y: 55
}
b._client.write('teleport_confirm', { teleportId: a.teleportId })
})
b.tellraw = (uuid, message) => {
let finalname = ''
if (uuid === '@a') {
finalname = '@a'
} else if (uuid.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/)) {
finalname = `@a[nbt={UUID:[I;${uuidToInt(uuid)}]}]`
} else {
finalname = uuid
}
let tellrawCommand
if (b.host.options.isVanilla) {
tellrawCommand = 'tellraw'
} else {
tellrawCommand = 'minecraft:tellraw'
}
b.ccq.push(`/${tellrawCommand} ${finalname} ${JSON.stringify(message)}`)
}
}
}

52
plugins/console.js Normal file
View file

@ -0,0 +1,52 @@
const readln = require('readline')
const index = require('../index.js')
const ConsoleCommand = require('../util/ConsoleCommand.js')
const cmds = require('../util/commands.js')
const rl = readln.createInterface({
input: process.stdin,
output: process.stdout,
prompt: '\x1b[0m> '
})
rl.on('line', (l) => {
try {
if (cmds[l.split(' ')[0].toLowerCase()]) {
if (cmds[l.split(' ')[0].toLowerCase()].consoleIndex) {
const tmpcmd = l.split(' ')
const index2 = tmpcmd.splice(1, 1)[0]
if (index2 === '*') {
for (let i = 0; i < index.bot.length; i++) {
const cmd = new ConsoleCommand(tmpcmd.join(' '), i)
cmds[l.split(' ')[0].toLowerCase()].execute(cmd)
}
} else {
const cmd = new ConsoleCommand(tmpcmd.join(' '), +index2)
cmds[l.split(' ')[0].toLowerCase()].execute(cmd)
}
} else {
const cmd = new ConsoleCommand(l, -2)
cmds[l.split(' ')[0].toLowerCase()].execute(cmd)
}
}
} catch (e) {
console.log(e)
}
rl.prompt(false)
})
rl.prompt()
function consoleWrite (text) {
readln.cursorTo(process.stdout, 0)
readln.clearLine(process.stdout, 0)
process.stdout.write(text + '\n')
rl.prompt(true)
}
module.exports = {
load: (b) => {
b.info = (msg) => {
consoleWrite(`[${b.id}] [info] ${msg}`)
}
b.displayChat = (type, msg) => {
consoleWrite(`[${b.id}] [${type}] ${msg}`)
}
}
}

19
plugins/cq.js Executable file
View file

@ -0,0 +1,19 @@
module.exports = {
load: (b) => {
b._client.on('login', () => {
b.interval.chatQueue = setInterval(() => {
if (b.chatqueue.length !== 0) {
b._client.chat(b.chatqueue[0])
b.chatqueue.splice(0, 1)
}
}, 100)
})
b.chatqueue = []
b.chat = function chat (msg) {
if (msg.length === 0) return
msg.match(/.{1,255}/g).forEach(element => {
b.chatqueue.push(element)
})
}
}
}

52
plugins/player.js Normal file
View file

@ -0,0 +1,52 @@
const parse = require('../util/chatparse_plain')
const parseNBT = require('../util/parseNBT')
module.exports = {
load: (b) => {
b.players = {}
b._client.on('player_info', (data) => {
const buffer2 = {}
for (const i in data.data) {
let uuid
if (data.data[i].uuid) {
uuid = data.data[i].uuid
} else if (data.data[i].UUID) {
uuid = data.data[i].UUID
}
let displayName
if (data.data[i].displayName !== undefined) {
displayName = data.data[i].displayName
} else {
displayName = '{"text":"[[[[ No display name ]]]]"}'
}
if (data.data[i].player && data.data[i].player.name !== undefined) {
buffer2[uuid] = { realName: data.data[i].player.name, displayName: parse(parseNBT(displayName)) }
} else if (data.data[i].name !== undefined) {
buffer2[uuid] = { realName: data.data[i].name, displayName: parse(parseNBT(displayName)) }
} else if (data.data[i].displayName !== undefined) {
buffer2[uuid] = { displayName: displayName.plain }
}
}
for (const uuid in buffer2) {
if (!b.players[uuid]) b.players[uuid] = { displayName: '', realName: '' }
if (buffer2[uuid].displayName) b.players[uuid].displayName = buffer2[uuid].displayName
if (buffer2[uuid].realName) b.players[uuid].realName = buffer2[uuid].realName
}
})
b.findUUID = (name) => {
for (const i in b.players) {
if (b.players[i].realName === name) {
return i
}
}
return '00000000-0000-0000-0000-000000000000'
}
b.findRealName = (name) => {
for (const i in b.players) {
if (b.players[i].displayName === name) {
return b.players[i].realName
}
}
return '[[[[ no name ]]]]'
}
}
}

15
plugins/rejoin.js Executable file
View file

@ -0,0 +1,15 @@
const index = require('../index.js')
module.exports = {
load: (b) => {
b._client.on('end', () => {
b.info(`Bot ${b.id} disconnected`)
for (const i in b.interval) {
clearInterval(b.interval[i])
}
setTimeout(() => {
b.info(`Re-connecting bot ${b.id}`)
index.createBot(b.host, b.id)
}, 5000)
})
}
}

84
plugins/selfcare.js Executable file
View file

@ -0,0 +1,84 @@
class SCTask {
constructor (failTask, startFailed = false) {
/*
* failed: Whether to run this task
* failTask: Command to run when failed is true
*/
this.failed = startFailed
this.failTask = failTask
}
}
module.exports = {
load: (b) => {
b.sc_tasks = {}
b.selfcareRun = 0
b.interval.sc = setInterval(() => {
if(Date.now() - b.selfcareRun <= 600){
return
}
for (const i in b.sc_tasks) {
if (b.sc_tasks[i].failed) {
b.sc_tasks[i].failTask()
}
}
b.selfcareRun = Date.now()
}, 40)
b.add_sc_task = (name, failTask, startFailed) => {
b.sc_tasks[name] = new SCTask(failTask, startFailed)
}
// Self care tasks
// Operator
b.add_sc_task('op', () => {
b.chat('/op @s[type=player]')
})
b._client.on('login', (p) => {
b.entityId = p.entityId
})
b._client.on('entity_status', (p) => {
if (p.entityId === b.entityId && p.entityStatus === 24) {
b.sc_tasks.op.failed = 1
} else if (p.entityId === b.entityId && p.entityStatus === 28) {
b.sc_tasks.op.failed = 0
}
})
// CommandSpy
if (!b.host.options.isVanilla) {
b.add_sc_task('cspy', () => {
b.chat('/cspy on')
}, true)
b.on('plainchat', (msg) => {
if (msg === 'Successfully disabled CommandSpy') {
b.sc_tasks.cspy.failed = 1
} else if (msg === 'Successfully enabled CommandSpy') {
b.sc_tasks.cspy.failed = 0
}
})
}
// Gamemode
b.add_sc_task('gamemode', () => {
b.chat('/minecraft:gamemode creative')
})
b._client.on('game_state_change', (p) => {
if (p.reason === 3 && p.gameMode !== 1) {
b.sc_tasks.gamemode.failed = 1
} else if (p.reason === 3 && p.gameMode === 1) {
b.sc_tasks.gamemode.failed = 0
}
})
// Respawning after dying
b.add_sc_task('respawn', () => {
b._client.write('client_command', { actionId: 0 }) // Simulates respawning
b.sc_tasks.respawn.failed = 0
})
b.on('chat', (data) => {
if (data.json.translate === 'chat.disabled.options' || (data.json.extra && data.json.extra[0] && data.json.extra[0].translate === 'chat.disabled.options')) {
b.sc_tasks.respawn.failed = 1
}
})
}
}

5
plugins/testing.js Executable file
View file

@ -0,0 +1,5 @@
module.exports = {
load: (b) => {
}
}

6
secret_example.json Normal file
View file

@ -0,0 +1,6 @@
{
"keyTrusted": "Insert trusted level key here... (PLEASE CHANGE THIS, THIS KEY IS PUBLIC)",
"keyOwner": "Insert owner level key here... (PLEASE CHANGE THIS, THIS KEY IS PUBLIC)",
"onlineEmail": "email@example.com",
"onlinePass": "password"
}

23
settings_example.json Executable file
View file

@ -0,0 +1,23 @@
{
"secret":"/path/to/secrets/file/secret.json",
"version_mc": "1.20.4",
"defaultLang": "en-US",
"terminalMode": "blackTerminal_24bit",
"colors": {
"primary": "#FFCCEE",
"secondary": "#FF99DD"
},
"prefix":[
"bot:",
"\""
],
"servers":[
{
"host": "kaboom.pw",
"port": 25565,
"options":{
"name": "kaboom"
}
}
]
}

42
util/Command.js Normal file
View file

@ -0,0 +1,42 @@
// HOW TO WRITE CLASS JS
const settings = require('../settings.json')
class Command {
constructor (uuid, user, nick, cmd, prefix, bot, verify, prefs) {
this.send = (text, uuid) => { bot.tellraw(uuid || '@a', text) }
this.reply = text => bot.tellraw(uuid, text)
this.uuid = uuid
this.username = user
this.nickname = nick
this.command = cmd
this.prefix = prefix
this.bot = bot
this.type = 'minecraft'
this.index = bot.id
this.args = cmd.split(' ').slice(1)
this.verify = verify
this.host = bot.host.host
this.port = bot.host.port
// this.lang = lang
this.prefs = prefs
if(prefs.lang){
this.lang = prefs.lang
} else {
this.lang = settings.defaultLang
}
let _colors = {}
if(prefs.colorPrimary){
_colors.primary = prefs.colorPrimary
} else {
_colors.primary = settings.colors.primary
}
if(prefs.colorSecondary){
_colors.secondary = prefs.colorSecondary
} else {
_colors.secondary = settings.colors.secondary
}
this.colors = _colors
}
}
module.exports = Command

28
util/ConsoleCommand.js Normal file
View file

@ -0,0 +1,28 @@
// HOW TO WRITE CLASS JS
const index = require('../index.js')
const parse = require('../util/chatparse_console.js')
const settings = require('../settings.json')
class ConsoleCommand {
constructor (cmd, index2) {
this.send = () => {} // not needed for console
this.reply = text => process.stdout.write(parse(text) + '\n')
this.uuid = 'dde5a2a6-ebdd-7bbb-8eac-f75b10c10446' // hard-coded because uuid does not exist at console
this.username = 'Owner'
this.nickname = 'Console'
this.command = cmd
this.prefix = '' // prefix does not exist at console
this.bot = index2 >= 0
? index.bot[index2]
: {}
this.type = 'console'
this.index = index2
this.args = cmd.split(' ').slice(1)
this.verify = 3
this.host = ''
this.port = '3' // :3
this.lang = settings.defaultLang
this.colors = settings.colors
}
}
module.exports = ConsoleCommand

104
util/chatparse_console.js Normal file
View file

@ -0,0 +1,104 @@
const settings = require('../settings.json')
const lang = require('./mc_lang.js')
const _consoleColors = require('./consolecolors.json')
let consoleColors
let consoleColors24
if (_consoleColors[settings.terminalMode]) {
consoleColors = _consoleColors[settings.terminalMode].fourBit
consoleColors24 = _consoleColors[settings.terminalMode].twentyFourBit
} else {
consoleColors = _consoleColors.none.fourBit
consoleColors24 = _consoleColors.none.twentyFourBit
}
const hexColorParser = (color) => {
if (!consoleColors24.enabled || consoleColors24.bit !== 24) { // Hex color parsing to the 8 bit and 4 bit modes has not been implemented yet
return ''
}
let out = '\x1B[0;'
const redChannel = Number(`0x${color.slice(1, 3)}`)
const greenChannel = Number(`0x${color.slice(3, 5)}`)
const blueChannel = Number(`0x${color.slice(5, 7)}`)
if (!consoleColors24.lightMode && redChannel < 64 && greenChannel < 64 && blueChannel < 64) {
out += '48;2;220;220;220;'
} else if (consoleColors24.lightMode && ((redChannel > 192 && greenChannel > 192 && blueChannel > 192) || greenChannel > 160)) {
out += '48;2;0;0;0;'
}
return out + `38;2;${redChannel};${greenChannel};${blueChannel}m`
}
const processColor = (col, rcol) => {
let out
if (col === 'reset') {
out = rcol
} else if (col.startsWith('#')) {
out = hexColorParser(col)
} else {
out = consoleColors[col]
}
return out
}
const parse = function (_data, l = 0, resetColor = consoleColors.reset) {
if (l >= 4) {
return ''
}
let data
if (typeof _data === 'string') {
data = { text: _data, color: 'reset' }
} else if (typeof _data === 'number') {
data = { text: _data + '', color: 'reset' }
} else if (_data.constructor === Array) {
data = { extra: _data, color: 'reset' }
} else {
data = _data
}
if (data['']) {
data.text = data['']
if (!data.color) data.color = 'reset'
}
let out = ''
if (data.color) {
out += processColor(data.color, resetColor)
} else {
out += resetColor
}
if (data.text) {
let _text = data.text
if (typeof _text === 'number') {
_text = _text.toString()
}
out += _text.replaceAll('\x1b', '').replaceAll('\x0e', '') // Remove escape codes and [SO] from console format
}
if (data.translate) {
let trans = data.translate.replace(/%%/g, '\ue123').replaceAll('\x1b', '').replaceAll('\x0e', '') // Remove escape codes from console format
if (lang[trans] !== undefined) {
trans = lang[trans].replace(/%%/g, '\ue123')
}
for (const i in data.with) {
const j2 = parse(data.with[i], l + 1, data.color ? processColor(data.color, resetColor) : resetColor)
trans = trans.replace(/%s/, j2.replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
trans = trans.replaceAll(`%${+i + 1}$s`, j2.replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
}
out += trans.replace(/\ue123/g, '%').replace(/\ue124/g, '%s').replace(/\ue125/g, '$s')
}
if (data.extra) {
for (const i in data.extra) {
const parsed = parse(data.extra[i], l, data.color ? processColor(data.color, resetColor) : resetColor)
out += parsed
}
}
out += resetColor
return out
}
const parse2 = function (_data, l, resetColor) {
try {
return parse(_data)
} catch (e) {
console.error(e)
return `\x1B[0m\x1B[38;2;255;85;85mAn error occured while parsing a message. See console for more information.\nJSON that caused the error: ${JSON.stringify(_data)}`
}
}
module.exports = parse2

55
util/chatparse_plain.js Normal file
View file

@ -0,0 +1,55 @@
const lang = require('./mc_lang.js')
const parse = function (_data, l = 0) {
if (l >= 4) {
return ''
}
let data
if (typeof _data === 'string') {
data = { text: _data }
} else if (typeof _data === 'number') {
data = { text: _data + '' }
} else if (_data.constructor === Array) {
data = { extra: _data }
} else {
data = _data
}
let out = ''
if (data['']) {
data.text = data['']
}
if (data.text) {
let _text = data.text
if (typeof _text === 'number') {
_text = _text.toString()
}
out += _text
}
if (data.translate) {
let trans = data.translate.replace(/%%/g, '\ue123')
if (lang[trans] !== undefined) {
trans = lang[trans].replace(/%%/g, '\ue123')
}
for (const i in data.with) {
const j2 = parse(data.with[i], l + 1)
trans = trans.replace(/%s/, j2.replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
trans = trans.replaceAll(`%${+i + 1}$s`, j2.replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
}
out += trans.replace(/\ue123/g, '%').replace(/\ue124/g, '%s').replace(/\ue125/g, '$s')
}
if (data.extra) {
for (const i in data.extra) {
const parsed = parse(data.extra[i], l)
out += parsed
}
}
return out
}
const parse2 = function (_data, l) {
try {
return parse(_data)
} catch (e) {
console.error(e)
return `An error occured while parsing a message. See console for more information. JSON that caused the error: ${JSON.stringify(_data)}`
}
}
module.exports = parse2

28
util/commands.js Normal file
View file

@ -0,0 +1,28 @@
const fs = require('fs')
const cmds = Object.create(null)
const bpl = fs.readdirSync('./commands')
for (const i in bpl) {
if (!bpl[i].endsWith('.js')) {
continue
}
try {
const commandName = bpl[i].split('.js')[0]
cmds[commandName] = require(`../commands/${bpl[i]}`)
if (cmds[commandName].level === undefined) {
cmds[commandName].level = 0
}
if (cmds[commandName].aliases) {
for (const j in cmds[commandName].aliases) {
cmds[cmds[commandName].aliases[j]] = {
execute: cmds[commandName].execute,
alias: commandName,
usage: cmds[commandName].usage,
level: cmds[commandName].level,
hidden: true,
consoleIndex: cmds[commandName].consoleIndex
}
}
}
} catch (e) { console.log(e) }
}
module.exports = cmds

182
util/consolecolors.json Normal file
View file

@ -0,0 +1,182 @@
{
"blackTerminal_24bit":{
"fourBit":{
"dark_red": "\u001B[0;38;2;170;0;0m",
"red": "\u001B[0;38;2;255;85;85m",
"dark_green": "\u001B[0;38;2;0;170;0m",
"green": "\u001B[0;38;2;85;255;85m",
"gold": "\u001B[0;38;2;255;170;0m",
"yellow": "\u001B[0;38;2;255;255;85m",
"dark_blue": "\u001B[0;38;2;0;0;170m",
"blue": "\u001B[0;38;2;85;85;255m",
"dark_purple": "\u001B[0;38;2;170;0;170m",
"light_purple": "\u001B[0;38;2;255;85;255m",
"dark_aqua": "\u001B[0;38;2;0;170;170m",
"aqua": "\u001B[0;38;2;85;255;255m",
"black": "\u001B[0;48;2;220;220;220;38;2;0;0;0m",
"gray": "\u001B[0;38;2;170;170;170m",
"dark_gray": "\u001B[0;38;2;85;85;85m",
"white": "\u001B[0;38;2;255;255;255m",
"reset": "\u001B[0;38;2;255;255;255m"
},
"twentyFourBit":{
"enabled": true,
"bit": 24,
"lightMode": false
}
},
"whiteTerminal_24bit":{
"fourBit":{
"dark_red": "\u001B[0;38;2;170;0;0m",
"red": "\u001B[0;38;2;255;85;85m",
"dark_green": "\u001B[0;38;2;0;170;0m",
"green": "\u001B[0;48;2;20;20;20;38;2;85;255;85m",
"gold": "\u001B[0;38;2;255;170;0m",
"yellow": "\u001B[0;48;2;20;20;20;38;2;255;255;85m",
"dark_blue": "\u001B[0;38;2;0;0;170m",
"blue": "\u001B[0;38;2;85;85;255m",
"dark_purple": "\u001B[0;38;2;170;0;170m",
"light_purple": "\u001B[0;38;2;255;85;255m",
"dark_aqua": "\u001B[0;38;2;0;170;170m",
"aqua": "\u001B[0;48;2;20;20;20;38;2;85;255;255m",
"black": "\u001B[0;38;2;0;0;0m",
"gray": "\u001B[0;38;2;170;170;170m",
"dark_gray": "\u001B[0;38;2;85;85;85m",
"white": "\u001B[0;48;2;20;20;20;38;2;255;255;255m",
"reset": "\u001B[0;48;2;20;20;20;38;2;255;255;255m"
},
"twentyFourBit":{
"enabled": true,
"bit": 24,
"lightMode": true
}
},
"blackTerminal_8bit":{
"fourBit":{
"dark_red": "\u001B[0;38;5;1m",
"red": "\u001B[0;38;5;9m",
"dark_green": "\u001B[0;38;5;2m",
"green": "\u001B[0;38;5;10m",
"gold": "\u001B[0;38;5;3m",
"yellow": "\u001B[0;38;5;11m",
"dark_blue": "\u001B[0;38;5;4m",
"blue": "\u001B[0;38;5;12m",
"dark_purple": "\u001B[0;38;5;5m",
"light_purple": "\u001B[0;38;5;13m",
"dark_aqua": "\u001B[0;38;5;6m",
"aqua": "\u001B[0;38;5;14m",
"black": "\u001B[0;48;5;15;38;5;0m",
"gray": "\u001B[0;38;5;7m",
"dark_gray": "\u001B[0;38;5;8m",
"white": "\u001B[0;38;5;15m",
"reset": "\u001B[0;38;5;15m"
},
"twentyFourBit":{
"enabled": true,
"bit": 8,
"lightMode": false
}
},
"whiteTerminal_8bit":{
"fourBit":{
"dark_red": "\u001B[0;38;5;1m",
"red": "\u001B[0;38;5;9m",
"dark_green": "\u001B[0;38;5;2m",
"green": "\u001B[0;48;5;0;38;5;10m",
"gold": "\u001B[0;38;5;3m",
"yellow": "\u001B[0;48;5;0;38;5;11m",
"dark_blue": "\u001B[0;38;5;4m",
"blue": "\u001B[0;38;5;12m",
"dark_purple": "\u001B[0;38;5;5m",
"light_purple": "\u001B[0;38;5;13m",
"dark_aqua": "\u001B[0;38;5;6m",
"aqua": "\u001B[0;48;5;0;38;5;14m",
"black": "\u001B[0;38;5;0m",
"gray": "\u001B[0;38;5;7m",
"dark_gray": "\u001B[0;38;5;8m",
"white": "\u001B[0;48;5;0;38;5;15m",
"reset": "\u001B[0;48;5;0;38;5;15m"
},
"twentyFourBit":{
"enabled": true,
"bit": 8,
"lightMode": true
}
},
"blackTerminal_4bit":{
"fourBit":{
"dark_red": "\u001B[0;31m",
"red": "\u001B[0;1;31m",
"dark_green": "\u001B[0;32m",
"green": "\u001B[0;1;32m",
"gold": "\u001B[0;33m",
"yellow": "\u001B[0;1;33m",
"dark_blue": "\u001B[0;34m",
"blue": "\u001B[0;1;34m",
"dark_purple": "\u001B[0;35m",
"light_purple": "\u001B[0;1;35m",
"dark_aqua": "\u001B[0;36m",
"aqua": "\u001B[0;1;36m",
"black": "\u001B[0;1;47;30m",
"gray": "\u001B[0;37m",
"dark_gray": "\u001B[0;1;30m",
"white": "\u001B[0;1;37m",
"reset": "\u001B[0;1;37m"
},
"twentyFourBit":{
"enabled": true,
"bit": 4,
"lightMode": false
}
},
"whiteTerminal_4bit":{
"fourBit":{
"dark_red": "\u001B[0;31m",
"red": "\u001B[0;1;31m",
"dark_green": "\u001B[0;32m",
"green": "\u001B[0;40;1;32m",
"gold": "\u001B[0;33m",
"yellow": "\u001B[0;40;1;33m",
"dark_blue": "\u001B[0;34m",
"blue": "\u001B[0;1;34m",
"dark_purple": "\u001B[0;35m",
"light_purple": "\u001B[0;1;35m",
"dark_aqua": "\u001B[0;36m",
"aqua": "\u001B[0;40;1;36m",
"black": "\u001B[0;30m",
"gray": "\u001B[0;37m",
"dark_gray": "\u001B[0;1;30m",
"white": "\u001B[0;40;1;37m",
"reset": "\u001B[0;40;1;37m"
},
"twentyFourBit":{
"enabled": true,
"bit": 4,
"lightMode": true
}
},
"none":{
"fourBit":{
"dark_red": "",
"red": "",
"dark_green": "",
"green": "",
"gold": "",
"yellow": "",
"dark_blue": "",
"blue": "",
"dark_purple": "",
"light_purple": "",
"dark_aqua": "",
"aqua": "",
"black": "",
"gray": "",
"dark_gray": "",
"white": "",
"reset": ""
},
"twentyFourBit":{
"enabled": false
}
}
}

19
util/hashcheck.js Normal file
View file

@ -0,0 +1,19 @@
const crypto = require('crypto')
const settings = require('../settings.json')
const secret = require(settings.secret)
module.exports = function (cmd) {
const cmdWithoutHash = cmd.slice(0, cmd.length - 1).join(' ')
const _dateString = Date.now().toString()
const dateString = _dateString.slice(0, _dateString.length - 4)
const hashTrusted = `babyboom:${secret.keyTrusted}:${cmdWithoutHash}:${dateString}`
const hashOwner = `babyboom:${secret.keyOwner}:${cmdWithoutHash}:${dateString}`
const validhashT = crypto.createHash('sha256').update(hashTrusted).digest('hex')
const validhashO = crypto.createHash('sha256').update(hashOwner).digest('hex')
if (cmd[cmd.length - 1] === validhashT) {
return 1
}
if (cmd[cmd.length - 1] === validhashO) {
return 2
}
return 0
}

63
util/lang.js Normal file
View file

@ -0,0 +1,63 @@
const fs = require('fs')
const languages = {}
const loadplug = (botno) => {
const bpl = fs.readdirSync('util/lang')
for (const i in bpl) {
if (!bpl[i].endsWith('.json')) {
continue
}
try {
languages[bpl[i].split('.')[0]] = require(`./lang/${bpl[i]}`)
} catch (e) { console.log(e) }
}
}
loadplug()
const getMessage = function (l, msg, with2) {
let message = msg.replace(/%%/g, '\ue123')
if (languages[l] && languages[l][message] !== undefined) {
message = languages[l][message].replace(/%%/g, '\ue123')
} else if (languages['en-US'] && languages['en-US'][message] !== undefined) {
message = languages['en-US'][message].replace(/%%/g, '\ue123')
}
for (const i in with2) {
message = message.replace(/%s/, with2[i].replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
message = message.replaceAll(`%${+i + 1}$s`, with2[i].replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
}
return message.replace(/\ue123/g, '%').replace(/\ue124/g, '%s').replace(/\ue125/g, '$s')
}
module.exports = {
languages: Object.keys(languages),
getMessage,
formatTime: function (time, language) {
let finalString = ''
const seconds = Math.floor(time / 1000) % 60
const minutes = Math.floor(time / 60000) % 60
const hours = Math.floor(time / 3600000) % 24
const days = Math.floor(time / 86400000) % 7
const weeks = Math.floor(time / 604800000)
if (weeks !== 0) {
finalString += weeks
finalString += `${weeks === 1 ? getMessage(language, 'time.week') : getMessage(language, 'time.weekPlural')}`
}
if (days !== 0) {
finalString += days
finalString += `${days === 1 ? getMessage(language, 'time.day') : getMessage(language, 'time.dayPlural')}`
}
if (hours !== 0) {
finalString += hours
finalString += `${hours === 1 ? getMessage(language, 'time.hour') : getMessage(language, 'time.hourPlural')}`
}
if (minutes !== 0) {
finalString += minutes
finalString += `${minutes === 1 ? getMessage(language, 'time.minute') : getMessage(language, 'time.minutePlural')}`
}
if (seconds !== 0) {
finalString += seconds
finalString += `${seconds === 1 ? getMessage(language, 'time.second') : getMessage(language, 'time.secondPlural')}`
}
return finalString
}
}

98
util/lang/en-US.json Normal file
View file

@ -0,0 +1,98 @@
{
"language.name": "English",
"language.region": "United States",
"time.week": " week ",
"time.weekPlural": " weeks ",
"time.day": " day ",
"time.dayPlural": " days ",
"time.hour": " hour ",
"time.hourPlural": " hours ",
"time.minute": " minute ",
"time.minutePlural": " minutes ",
"time.second": " second ",
"time.secondPlural": " seconds ",
"command.about.usage": "",
"command.about.desc": "About the bot",
"command.cb.usage": " <command>",
"command.cb.desc": "Run a command in a command block",
"command.cloop.usage": " add <rate> <command>|| remove <index>|| list|| clear",
"command.cloop.desc": "Manage command loops",
"command.eval.usage": " <code>",
"command.eval.desc": "Run JavaScript code",
"command.help.usage": " [cmd]",
"command.help.desc": "Shows command help",
"command.logoff.usage": "",
"command.logoff.desc": "Disconnect and reconnect the bot from a server",
"command.netmsg.usage": " <message>",
"command.netmsg.desc": "Send a message to all servers the bot is connected to",
"command.refill.usage": "",
"command.refill.desc": "Refill core",
"command.say.usage": " <message>",
"command.say.desc": "Sends a message to chat",
"command.stop.usage": "",
"command.stop.desc": "Restart bot",
"command.template.usage": " <required> [optional]",
"command.template.desc": "Does nothing",
"command.tpr.desc": "Teleport to a random location",
"command.tpr.usage": "",
"command.verify.usage": " [args...]",
"command.verify.desc": "Check the hashing system",
"command.about.author": "%s - a Minecraft bot made by %s for Kaboom and clones",
"command.about.version": "Version %s",
"command.about.preRelease": "This is prerelease software - there may be errors, and features may be changed or removed at any time.",
"command.about.sourceCode": "Source code: %s",
"command.about.sourceCode.openInBrowser": "Click to open the source code link in your default browser",
"command.cloop.error.tooShort": "Command loops must have a rate above 20ms.",
"command.cloop.error.subcommand": "Unknown subcommand, please do %s",
"command.cloop.success.add": "Added command loop with command %s and rate %s",
"command.cloop.success.remove": "Removed command loop %s",
"command.cloop.success.clear": "Cleared all command loops",
"command.cloop.list": "%s: Command: %s Rate: %s",
"command.help.cmdList": "Commands:",
"command.help.commandInfo": "%s%s - %s",
"command.help.commandUsage": "Usage - %s%s",
"command.help.commandDesc": "Description - %s",
"command.help.commandPerms": "Required permissions - %s",
"command.help.permsNormal": "Normal",
"command.help.permsTrusted": "Trusted",
"command.help.permsOwner": "Owner",
"command.help.permsConsole": "Console",
"command.help.noCommand": "Command does not exist",
"command.help.alias": "Alias to %s",
"command.netmsg.disabled": "This command has been disabled on this server.",
"command.settings.get.colorPrimary": "Primary color",
"command.settings.get.colorSecondary": "Secondary color",
"command.settings.get.language": "Language",
"command.settings.setLanguage": "Run %s to set this as your language",
"command.settings.error.invalidKey": "Invalid key",
"command.settings.error.invalidLanguage": "Invalid language",
"command.settings.error.mustProvideValue": "You must provide a value",
"command.about.serverInfo.os.android": "Android %s",
"command.about.serverInfo.os.android.noVersion": "Android",
"command.about.serverInfo.os.freebsd": "FreeBSD %s",
"command.about.serverInfo.os.linux": "Linux %s",
"command.about.serverInfo.os.macos": "macOS",
"command.about.serverInfo.os.macos_old": "OS X",
"command.about.serverInfo.os": "Operating system",
"command.about.serverInfo.processor": "CPU",
"command.about.serverInfo.arch": "Architecture",
"command.about.serverInfo.osUsername": "Username",
"command.about.serverInfo.hostName": "Hostname",
"command.about.serverInfo.workingDir": "Working directory",
"command.about.serverInfo.runTime": "Bot uptime",
"command.about.serverInfo.upTime": "System uptime",
"command.about.serverInfo.nodeVersion": "Node.js version",
"command.about.serverInfo.osRelease": "Linux release",
"command.about.serverInfo.osRelease.missing": "/etc/os-release does not exist. Information may be limited.",
"command.about.serverInfo.os.android.version": "Android version",
"command.about.serverInfo.os.android.model": "Device model",
"command.about.serverInfo.botName": "Bot name",
"command.about.serverInfo.botVer": "Bot version",
"command.tpr.success": "Teleporting %s to %s, %s, %s",
"command.verify.success": "Successfully verified with permission level %s",
"command.error": "An error occured (check console for more info)",
"command.disallowed.perms": "You do not have permission to run this command. If you do have permission, please make sure you put the command hash at the end, or ran the command through your client's hashing system.",
"command.disallowed.perms.yourLevel": "Your permission level: %s",
"command.disallowed.perms.cmdLevel": "Command requires: %s",
"copyText": "Click to copy!"
}

6
util/mc_lang.js Normal file
View file

@ -0,0 +1,6 @@
const _lang = require('minecraft-data')('1.20.2').language
const lang = Object.create(null) // Without constructor function
for (const i in _lang) {
lang[i] = _lang[i]
}
module.exports = lang

11
util/parseNBT.js Normal file
View file

@ -0,0 +1,11 @@
const { processNbtMessage } = require('prismarine-chat')
const parse = function (data) {
if (typeof data.type === 'string') {
return JSON.parse(processNbtMessage(data))
} else if (typeof data === 'string') {
return JSON.parse(data)
} else {
return data
}
}
module.exports = parse

38
util/usergen.js Normal file
View file

@ -0,0 +1,38 @@
const rsg = function (count) {
let output = ''
for (let i = 0; i < count; i++) {
const type = Math.floor(Math.random() * 6)
switch (type) {
case 0:
output += ' '
break
case 1:
output += '§§'
break
case 2:
output += '§ '
break
case 3:
case 4:
case 5:{ // Make this case more likely
let rng = Math.floor(Math.random() * 16) + 1
if (rng === 7) rng = 17 // No bells
if (rng === 10) rng = 18 // No line feeds
if (rng === 11) rng = 19 // No vertical tabulations
if (rng === 12) rng = 20 // No form feed
if (rng === 13) rng = 21 // No carriage returns
if (rng === 14) rng = 22 // No shift out
if (rng === 15) rng = 23 // No shift in
output += `§${String.fromCharCode(rng)}`
}
}
}
return output
}
module.exports = function (legal) {
if (legal) {
return Math.floor(Math.random() * 1000000).toString()
} else {
return rsg(6 + Math.floor(Math.random() * 3))
}
}

5
util/uuidtoint.js Normal file
View file

@ -0,0 +1,5 @@
module.exports = function (uuid) {
const splitUUID = uuid.replace(/[^0-9a-f]/g, '').replace(/.{1,8}/g, a => { return `0x${a}` }).match(/.{1,10}/g)
const numUUID = [+splitUUID[0] << 0, +splitUUID[1] << 0, +splitUUID[2] << 0, +splitUUID[3] << 0]
return numUUID
}

20
util/version.js Normal file
View file

@ -0,0 +1,20 @@
const version = require('../version.json')
const cp = require('child_process')
let botVersion = version.botVersion
let gitCommit
let gitBranch
try {
gitCommit = cp.execSync('git rev-parse --short HEAD').toString('UTF-8').split('\n')[0]
gitBranch = cp.execSync('git rev-parse --abbrev-ref HEAD').toString('UTF-8').split('\n')[0]
} catch (e) {
gitCommit = false
gitBranch = false
}
if (gitCommit) {
botVersion += ` (${gitCommit} - ${gitBranch})`
}
module.exports = botVersion

7
version.json Normal file
View file

@ -0,0 +1,7 @@
{
"botName": "botvX Dev",
"botVersion": "10.0.0-beta.2",
"botAuthor": "a5a06d596f15c7db",
"isPreRelease": true,
"sourceURL": "https://code.chipmunk.land/7cc5c4f330d47060/botvX"
}