Compare commits
134 commits
mainline-2
...
main
Author | SHA1 | Date | |
---|---|---|---|
aed4d9691f | |||
2e036d5880 | |||
3ae93be9ce | |||
cb5628ec25 | |||
04b6ccba63 | |||
75e48f2103 | |||
a894dfd133 | |||
d79167b3f9 | |||
9e48e9b6ea | |||
f9e076fe91 | |||
e05e58f867 | |||
a3835de35c | |||
f2fd8bc486 | |||
57f44cc73d | |||
ebf052234e | |||
2b3e4789c6 | |||
1be6ea282e | |||
d1573a1305 | |||
cfb19faee6 | |||
d612c085f0 | |||
9e03210af4 | |||
a71121225c | |||
06cfc7347d | |||
b689f18627 | |||
a1c91568d3 | |||
223cd5a0aa | |||
86275ef8ed | |||
084eb15db8 | |||
307bbf15c2 | |||
02028f6a54 | |||
34075d8c86 | |||
dbba89fbe4 | |||
4c04d06673 | |||
9d50d224ae | |||
24ce5d13fe | |||
2ca476c0cc | |||
8e7dd2bb4b | |||
17e1576f68 | |||
d363bbc9f7 | |||
6245e8ef40 | |||
0516ee1797 | |||
97bf3d0d56 | |||
d98073b9da | |||
5aafb01b22 | |||
76bb172416 | |||
24236cf7a7 | |||
fffa39abe8 | |||
6cdec0db4d | |||
3a6867ee96 | |||
441418c8e7 | |||
cf75c34e7b | |||
c461e87ef1 | |||
a4ff4ca374 | |||
b1d6b159ab | |||
8ed9d06121 | |||
e46a76e9f6 | |||
7dea5a7355 | |||
f9ffb00468 | |||
774204582e | |||
97767b6aa5 | |||
57e84ef53a | |||
598723f7cc | |||
54fd31f890 | |||
e609a1b716 | |||
bfe1111e29 | |||
9847623b25 | |||
a67785b1d7 | |||
19e21b1594 | |||
a76971147e | |||
bfd8c76e15 | |||
b8a6883933 | |||
9c6eb5ee4e | |||
284ebf488e | |||
d6db8547a3 | |||
270c7442c6 | |||
cde624bbcf | |||
316fcd1f86 | |||
d23094ccfd | |||
523bd90179 | |||
43ed8beab8 | |||
69b8f32266 | |||
8d5e8a61a1 | |||
aaf56e4b92 | |||
26534a28d3 | |||
7d141f1cc5 | |||
ff722932bc | |||
21263ca4d2 | |||
9928432592 | |||
464f1ac009 | |||
c23d6bd3f1 | |||
f7d0a17afc | |||
e243eb02f7 | |||
946698b705 | |||
b02f53d0c6 | |||
ea31b52917 | |||
a93648958e | |||
|
189f2a1f60 | ||
413c77cf89 | |||
35ebfb4ef8 | |||
0c6605462f | |||
af05ff16e9 | |||
189c04d2d2 | |||
ae14106a0d | |||
f8ddba5fd7 | |||
8a7a97cfe9 | |||
da1a55616d | |||
945f3a8276 | |||
eb70a31db7 | |||
ce13b085ec | |||
c074b030aa | |||
b18f9a850a | |||
1f24c53603 | |||
6d6119bc07 | |||
9050dfbe7f | |||
ea54f228d4 | |||
d7101c1d4b | |||
cb39c0fb04 | |||
e8ed4dd501 | |||
3a86ef8e5d | |||
4bafb14418 | |||
2ca151b4b2 | |||
2881f1918a | |||
a7263576bc | |||
c8df297f66 | |||
951a3dad29 | |||
9aa49a28eb | |||
7d93eafd72 | |||
af0b2405b4 | |||
103a3790f7 | |||
0974696db2 | |||
b17409deea | |||
e5e27f38d4 | |||
035729a1db | |||
217804a5c6 |
57 changed files with 963 additions and 318 deletions
LICENSEREADME.md
commands
about.jscb.jscloop.jseval.jshelp.jslogoff.jsnetmsg.jsrefill.jsrestart.jssay.jssettings.jsstop.jstemplate.jstest.jsvalidate.js
index.jslang
package-lock.jsonpackage.jsonplugins
chat.js
secret_example.jsonsettings_example.jsonchatParsers
chat_cmm.jschat_cmm_mcp.jschat_extras_profileless.jschat_player.jschat_system.jschat_vanilla_legacy.js
chatlog.jscommand.jscommandblock.jsconsole.jscq.jsperms.jsplayer.jsselfcare.jsutil
Command.jsConsoleCommand.jschatlog.jschatparse_console.jschatparse_mc.jschatparse_mc_withHex.jschatparse_plain.jscommands.jsconsolecolors.jsongetProtocolVersion.jshashcheck.jslang.jsmc_lang.jsmemoryconvert.jsparseNBT.jsusergen.jsuuidtoint.jsversion.js
version.json
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 7cc5c4f330d47060
|
||||
Copyright (c) 2024-2025 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:
|
||||
|
||||
|
|
30
README.md
30
README.md
|
@ -1,28 +1,32 @@
|
|||
# botvX
|
||||
# owobot
|
||||
|
||||
## What is it?
|
||||
|
||||
botvX is a Minecraft bot originally designed for [Kaboom](https://kaboom.pw/) and its clones. It has many of the features that you would expect in a modern Kaboom bot:
|
||||
owobot is a Minecraft bot originally designed 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
|
||||
|
||||
It supports all Minecraft versions from 1.13 to 1.20.4 that are supported by node-minecraft-protocol.
|
||||
|
||||
If you are not sure if this code is safe to run, you can read through every line of code. You can also see the commit history by clicking on the (n) commits button, to make sure nobody has added any exploits or introduced vulnerabilities to the code.
|
||||
|
||||
If you find any exploits, security issues, etc in the code, please send me an issue or pull request and I will try to respond to it as soon as possible.
|
||||
|
||||
## 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>.
|
||||
2. Download the latest release, or alternatively, download the latest development version using `git clone https://code.chipmunk.land/7cc5c4f330d47060/owobot`.
|
||||
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.
|
||||
4. Run `npm install` 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 `settings_example.json` to `settings.json` and `secret_example.json` to `secret.json`, and adjust the settings to fit your needs. Change the example keys in secret.json as well.
|
||||
6. Run ./launch.sh (macOS, Linux, FreeBSD) or ./launch.cmd (Windows). This will start a bot launcher, which will restart the bot when the process closes. Alternatively, you can run `node index.js` 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 |
|
||||
| about | [serverlist \| servers \| server] | About the bot. May also show system information or a list of connected servers. |
|
||||
| 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)|
|
||||
|
@ -30,10 +34,12 @@ botvX is a Minecraft bot originally designed for [Kaboom](https://kaboom.pw/) an
|
|||
| 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 |
|
||||
| restart | | Restart bot, closes when launched directly |
|
||||
| say | \<message\> | Sends a message to chat |
|
||||
| serverinfo | | Get system/bot info, similar to Kaboom's <code>serverinfo</code> command |
|
||||
| stop | | Restart bot |
|
||||
| settings | get, set <key> <value> | Set your user preferences |
|
||||
| stop | | Close bot |
|
||||
| template | | Used in development, does nothing |
|
||||
| test | | Debug command for the chat parser |
|
||||
| tpr | | Teleport to a random location |
|
||||
| verify | | Check the hashing system |
|
||||
| validate | | Check the hashing system |
|
||||
|
||||
|
|
43
commands/about.js
Normal file → Executable file
43
commands/about.js
Normal file → Executable file
|
@ -1,6 +1,7 @@
|
|||
const os = require('os')
|
||||
const cp = require('child_process')
|
||||
const { getMessage, formatTime } = require('../util/lang.js')
|
||||
const memoryconvert = require('../util/memoryconvert.js')
|
||||
const fs = require('fs')
|
||||
const botVersion = require('../util/version.js')
|
||||
const version = require('../version.json')
|
||||
|
@ -28,6 +29,10 @@ const aboutBot = function (c) {
|
|||
})
|
||||
}
|
||||
c.reply({ text: '' })
|
||||
c.reply({
|
||||
text: getMessage(c.lang, 'command.about.license'),
|
||||
color: c.colors.secondary
|
||||
})
|
||||
c.reply({
|
||||
translate: getMessage(c.lang, 'command.about.sourceCode'),
|
||||
color: c.colors.secondary,
|
||||
|
@ -155,6 +160,21 @@ const aboutServer = function (c) {
|
|||
})
|
||||
}
|
||||
|
||||
// System memory (total)
|
||||
displayInfo('command.about.serverInfo.totalMem', () => {
|
||||
return memoryconvert(os.totalmem())
|
||||
})
|
||||
|
||||
// System memory (free)
|
||||
displayInfo('command.about.serverInfo.freeMem', () => {
|
||||
return memoryconvert(os.freemem())
|
||||
})
|
||||
|
||||
// System memory (used)
|
||||
displayInfo('command.about.serverInfo.usedMem', () => {
|
||||
return memoryconvert(os.totalmem() - os.freemem())
|
||||
})
|
||||
|
||||
// Username and UID
|
||||
displayInfo('command.about.serverInfo.osUsername', () => {
|
||||
return `${os.userInfo().username} (${os.userInfo().uid})`
|
||||
|
@ -201,10 +221,16 @@ const aboutServer = function (c) {
|
|||
}
|
||||
|
||||
const displayServerList = function (c) {
|
||||
index.bot.forEach((item, i) => {
|
||||
if (item.host.options && item.host.options.hidden && c.verify !== 3 && c.bot.id !== i) return
|
||||
index.bots.forEach((item, i) => {
|
||||
if (c.bot.id === i && c.bot.host.options.hideLocally) return
|
||||
if (item.host.options && item.host.options.hidden && c.verify !== 2 && c.bot.id !== i) return
|
||||
let message = 'command.about.serverListItem'
|
||||
if (c.bot.id === i) message = 'command.about.serverListItem.thisServer'
|
||||
let host = item.host.host
|
||||
const port = item.host.port
|
||||
if (item.host.options && item.host.options.displayAsIPv6) {
|
||||
host = `[${host}]`
|
||||
}
|
||||
c.reply({
|
||||
translate: getMessage(c.lang, message),
|
||||
color: c.colors.secondary,
|
||||
|
@ -214,11 +240,11 @@ const displayServerList = function (c) {
|
|||
color: c.colors.primary
|
||||
},
|
||||
{
|
||||
text: `${item.host.host}:${item.host.port}`,
|
||||
text: `${host}:${port}`,
|
||||
color: c.colors.primary,
|
||||
clickEvent: {
|
||||
action: 'copy_to_clipboard',
|
||||
value: `${item.host.host}:${item.host.port}`
|
||||
value: `${host}:${port}`
|
||||
},
|
||||
hoverEvent: {
|
||||
action: 'show_text',
|
||||
|
@ -239,10 +265,11 @@ const displayServerList = function (c) {
|
|||
|
||||
module.exports = {
|
||||
execute: function (c) {
|
||||
let subcmd = c.args[0]
|
||||
let subcmd
|
||||
if (c.args.length >= 1) subcmd = c.args[0].toLowerCase()
|
||||
if (subcmd === 'servers') subcmd = 'serverlist'
|
||||
if (c.cmdName === 'serverinfo') subcmd = 'server'
|
||||
if (c.cmdName === 'serverlist' || c.cmdName === 'servers') subcmd = 'serverlist'
|
||||
if (c.cmdName.toLowerCase() === 'serverinfo' || c.cmdName.toLowerCase() === 'specs') subcmd = 'server'
|
||||
if (c.cmdName.toLowerCase() === 'serverlist' || c.cmdName.toLowerCase() === 'servers') subcmd = 'serverlist'
|
||||
if (subcmd === 'server') {
|
||||
aboutServer(c)
|
||||
} else if (subcmd === 'serverlist') {
|
||||
|
@ -251,5 +278,5 @@ module.exports = {
|
|||
aboutBot(c)
|
||||
}
|
||||
},
|
||||
aliases: ['info', 'serverlist', 'servers', 'serverinfo']
|
||||
aliases: ['info', 'serverlist', 'servers', 'serverinfo', 'specs']
|
||||
}
|
||||
|
|
0
commands/cb.js
Normal file → Executable file
0
commands/cb.js
Normal file → Executable file
3
commands/cloop.js
Normal file → Executable file
3
commands/cloop.js
Normal file → Executable file
|
@ -1,7 +1,8 @@
|
|||
const { getMessage } = require('../util/lang.js')
|
||||
module.exports = {
|
||||
execute: (c) => {
|
||||
const subcmd = c.args.splice(0, 1)[0]
|
||||
let subcmd
|
||||
if (c.args.length >= 1) subcmd = c.args.splice(0, 1)[0].toLowerCase()
|
||||
switch (subcmd) {
|
||||
case 'add': {
|
||||
const rate = +(c.args.splice(0, 1)[0])
|
||||
|
|
40
commands/eval.js
Normal file → Executable file
40
commands/eval.js
Normal file → Executable file
|
@ -1,11 +1,41 @@
|
|||
const index = require('../index.js') // Not used in the code, but may be used by users of the command
|
||||
const { getMessage } = require('../util/lang.js')
|
||||
module.exports = {
|
||||
execute: (c) => {
|
||||
try {
|
||||
console.log(eval(c.args.join(' ')))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
const item = eval(c.args.join(' '))
|
||||
if (c.type === 'console') {
|
||||
console.log(item)
|
||||
} else {
|
||||
c.reply({
|
||||
translate: '%s: %s',
|
||||
color: c.colors.primary,
|
||||
with: [
|
||||
{
|
||||
text: getMessage(c.lang, 'command.eval.output'),
|
||||
color: c.colors.secondary
|
||||
},
|
||||
{
|
||||
text: item + '',
|
||||
color: c.colors.primary,
|
||||
clickEvent: {
|
||||
action: 'copy_to_clipboard',
|
||||
value: item + ''
|
||||
},
|
||||
hoverEvent: {
|
||||
action: 'show_text',
|
||||
contents: {
|
||||
text: getMessage(c.lang, 'copyText'),
|
||||
color: c.colors.secondary
|
||||
},
|
||||
value: { // Added twice for backwards compatibility
|
||||
text: getMessage(c.lang, 'copyText'),
|
||||
color: c.colors.secondary
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
},
|
||||
level: 3
|
||||
level: 2
|
||||
}
|
||||
|
|
120
commands/help.js
Normal file → Executable file
120
commands/help.js
Normal file → Executable file
|
@ -1,10 +1,11 @@
|
|||
const fs = require('fs')
|
||||
const settings = require('../settings.json')
|
||||
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
|
||||
const level1 = cmds[c1.with[0].text].level ? cmds[c1.with[0].text].level : 0
|
||||
const level2 = cmds[c2.with[0].text].level ? cmds[c2.with[0].text].level : 0
|
||||
return level1 - level2
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,7 @@ for (const plugin of bpl) {
|
|||
}
|
||||
try {
|
||||
const commandName = plugin.split('.js')[0]
|
||||
if (commandName === 'settings' && settings.disableUserSettings) continue
|
||||
if (commandName !== 'help') {
|
||||
cmds[commandName] = require(`./${plugin}`)
|
||||
if (cmds[commandName].level === undefined) {
|
||||
|
@ -26,47 +28,120 @@ for (const plugin of bpl) {
|
|||
|
||||
const printHelp = (c) => {
|
||||
const commandList = []
|
||||
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 permList = [permsN, permsT, permsO]
|
||||
const colorList = ['green', 'red', 'dark_red']
|
||||
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'
|
||||
if (colorList[cmds[i].level]) {
|
||||
cmdColor = colorList[cmds[i].level]
|
||||
} else {
|
||||
cmdColor = colorList[0]
|
||||
}
|
||||
let usage = getMessage(c.lang, `command.${i}.usage`).split('||')
|
||||
let desc = getMessage(c.lang, `command.${i}.desc`)
|
||||
if (cmds[i].usage) {
|
||||
usage = cmds[i].usage.split('||')
|
||||
}
|
||||
if (cmds[i].desc) {
|
||||
desc = cmds[i].desc
|
||||
}
|
||||
const hoverText = []
|
||||
for (const item of usage) {
|
||||
hoverText.push({
|
||||
translate: getMessage(c.lang, 'command.help.commandUsage.lf'),
|
||||
color: c.colors.secondary,
|
||||
with: [
|
||||
{
|
||||
text: i,
|
||||
color: c.colors.primary
|
||||
},
|
||||
{
|
||||
text: item,
|
||||
color: c.colors.primary
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
hoverText.push({
|
||||
translate: getMessage(c.lang, 'command.help.commandDesc.lf'),
|
||||
color: c.colors.secondary,
|
||||
with: [
|
||||
{
|
||||
text: desc,
|
||||
color: c.colors.primary
|
||||
}
|
||||
]
|
||||
})
|
||||
const rPerms = cmds[i].level ? cmds[i].level : 0
|
||||
hoverText.push({
|
||||
translate: getMessage(c.lang, 'command.help.commandPerms.lf'),
|
||||
color: c.colors.secondary,
|
||||
with: [
|
||||
{
|
||||
text: permList[rPerms],
|
||||
color: c.colors.primary
|
||||
}
|
||||
]
|
||||
})
|
||||
hoverText.push({
|
||||
translate: getMessage(c.lang, 'command.help.runCommand'),
|
||||
color: c.colors.secondary
|
||||
})
|
||||
commandList.push(
|
||||
{
|
||||
translate: '%s ',
|
||||
color: cmdColor,
|
||||
with: [
|
||||
i
|
||||
{
|
||||
text: i,
|
||||
hoverEvent: {
|
||||
action: 'show_text',
|
||||
value: hoverText,
|
||||
contents: hoverText
|
||||
},
|
||||
clickEvent: {
|
||||
action: 'suggest_command',
|
||||
value: `${c.prefix}${i}`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
const permListFormat = []
|
||||
permList.forEach((item, i) => {
|
||||
permListFormat.push({
|
||||
translate: i === permList.length - 1 ? '%s' : '%s ',
|
||||
color: colorList[i],
|
||||
with: [
|
||||
item
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
c.reply({
|
||||
translate: '%s %s',
|
||||
with: [
|
||||
getMessage(c.lang, 'command.help.cmdList'),
|
||||
{
|
||||
translate: '%s (%s):',
|
||||
with: [
|
||||
getMessage(c.lang, 'command.help.cmdList'),
|
||||
permListFormat
|
||||
]
|
||||
},
|
||||
commandList.sort(sortHelp)
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
const printCmdHelp = (c) => {
|
||||
const cmd = c.args[0]
|
||||
if (!cmds[cmd]) {
|
||||
let cmd
|
||||
if (c.args.length >= 1) cmd = c.args[0].toLowerCase()
|
||||
if (!cmds[cmd] || (cmds[cmd].hidden && c.type !== 'console')) {
|
||||
c.reply({ text: getMessage(c.lang, 'command.help.noCommand') })
|
||||
return
|
||||
}
|
||||
|
@ -118,14 +193,13 @@ const printCmdHelp = (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')
|
||||
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],
|
||||
text: [permsN, permsT, permsO][rPerms],
|
||||
color: c.colors.primary
|
||||
}
|
||||
]
|
||||
|
|
0
commands/logoff.js
Normal file → Executable file
0
commands/logoff.js
Normal file → Executable file
9
commands/netmsg.js
Normal file → Executable file
9
commands/netmsg.js
Normal file → Executable file
|
@ -1,4 +1,4 @@
|
|||
const { bot } = require('../index.js')
|
||||
const { bots } = require('../index.js')
|
||||
const { getMessage } = require('../util/lang.js')
|
||||
module.exports = {
|
||||
execute: (c) => {
|
||||
|
@ -7,6 +7,8 @@ module.exports = {
|
|||
if (c.bot.host.options && c.bot.host.options.hidden) {
|
||||
host = 'localhost' // Makes hidden servers appear as localhost
|
||||
port = '25565'
|
||||
} else if (c.bot.host.options && c.bot.host.options.displayAsIPv6) {
|
||||
host = `[${host}]`
|
||||
}
|
||||
const json = {
|
||||
translate: '[%s] %s: %s',
|
||||
|
@ -41,12 +43,13 @@ module.exports = {
|
|||
color: c.colors.primary
|
||||
},
|
||||
{
|
||||
text: c.args.join(' ')
|
||||
text: c.args.join(' ').slice(0, 512)
|
||||
}
|
||||
],
|
||||
color: 'white'
|
||||
}
|
||||
bot.forEach(item => {
|
||||
bots.forEach(item => {
|
||||
if (item.host.options && item.host.options.netmsgIncomingDisabled && c.type !== 'console') return
|
||||
item.tellraw('@a', json)
|
||||
})
|
||||
}
|
||||
|
|
0
commands/refill.js
Normal file → Executable file
0
commands/refill.js
Normal file → Executable file
0
commands/restart.js
Normal file → Executable file
0
commands/restart.js
Normal file → Executable file
38
commands/say.js
Normal file → Executable file
38
commands/say.js
Normal file → Executable file
|
@ -1,7 +1,41 @@
|
|||
const settings = require('../settings.json')
|
||||
const version = require('../version.json')
|
||||
module.exports = {
|
||||
execute: (c) => {
|
||||
if (c.args[0].startsWith('/') && c.verify < 1) return
|
||||
c.bot.chat(c.args.join(' '))
|
||||
if (c.verify < 1) {
|
||||
c.bot.tellraw('@a', {
|
||||
translate: '%s %s: %s',
|
||||
color: 'white',
|
||||
with: [
|
||||
{
|
||||
translate: '[%s]',
|
||||
color: 'white',
|
||||
with: [
|
||||
{
|
||||
translate: '%s: %s',
|
||||
color: settings.colors.secondary,
|
||||
with: [
|
||||
{
|
||||
text: 'Prefix'
|
||||
},
|
||||
{
|
||||
text: settings.prefix[0],
|
||||
color: settings.colors.primary
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: version.botName,
|
||||
color: settings.colors.primary
|
||||
},
|
||||
c.args.join(' ').slice(0, 512)
|
||||
]
|
||||
})
|
||||
return
|
||||
}
|
||||
c.bot.chat(c.args.join(' ').slice(0, 512))
|
||||
},
|
||||
consoleIndex: true,
|
||||
aliases: ['echo']
|
||||
|
|
11
commands/settings.js
Normal file → Executable file
11
commands/settings.js
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
const { languages, getMessage } = require('../util/lang.js')
|
||||
const fs = require('fs')
|
||||
const settings = require('../settings.json')
|
||||
module.exports = {
|
||||
execute: (c) => {
|
||||
if (c.type === 'console') {
|
||||
|
@ -9,7 +10,15 @@ module.exports = {
|
|||
})
|
||||
return
|
||||
}
|
||||
const subcmd = c.args.splice(0, 1)[0]
|
||||
if (settings.disableUserSettings) {
|
||||
c.reply({
|
||||
text: getMessage(c.lang, 'command.settings.disabled.global'),
|
||||
color: c.colors.secondary
|
||||
})
|
||||
return
|
||||
}
|
||||
let subcmd
|
||||
if (c.args.length >= 1) subcmd = c.args.splice(0, 1)[0].toLowerCase()
|
||||
switch (subcmd) {
|
||||
case 'set':{
|
||||
const allowedKeys = ['colorPrimary', 'colorSecondary', 'lang']
|
||||
|
|
0
commands/stop.js
Normal file → Executable file
0
commands/stop.js
Normal file → Executable file
0
commands/template.js
Normal file → Executable file
0
commands/template.js
Normal file → Executable file
1
commands/test.js
Normal file → Executable file
1
commands/test.js
Normal file → Executable file
|
@ -37,6 +37,7 @@ module.exports = {
|
|||
c.reply(reply('nickname', c.nickname))
|
||||
c.reply(reply('command', c.command))
|
||||
c.reply(reply('msgType', c.msgType))
|
||||
c.reply(reply('msgSubtype', c.msgSubtype))
|
||||
c.reply(reply('prefix', c.prefix))
|
||||
c.reply(reply('args', c.args.join(', ')))
|
||||
c.reply(reply('verify', c.verify.toString()))
|
||||
|
|
3
commands/validate.js
Normal file → Executable file
3
commands/validate.js
Normal file → Executable file
|
@ -4,13 +4,12 @@ module.exports = {
|
|||
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],
|
||||
text: [permsN, permsT, permsO][c.verify],
|
||||
color: c.colors.primary
|
||||
}
|
||||
]
|
||||
|
|
63
index.js
63
index.js
|
@ -8,14 +8,18 @@ if (!fs.readdirSync('.').includes('settings.json')) {
|
|||
if (!fs.readdirSync('.').includes('secret.json')) {
|
||||
console.log('Secrets file is missing, using defaults.')
|
||||
fs.copyFileSync('secret_example.json', 'secret.json')
|
||||
console.log('Please change the hashing keys in the secrets file.')
|
||||
console.log('Please change the hashing keys in the secrets file. It is also recommended to remove permissions of other users to read from this file, for example, by giving it 600 permissions if running on a Unix or Unix-like OS.')
|
||||
}
|
||||
|
||||
const m = require('minecraft-protocol')
|
||||
const generateUser = require('./util/usergen.js')
|
||||
const EventEmitter = require('node:events')
|
||||
const settings = require('./settings.json')
|
||||
module.exports.bot = []
|
||||
const secret = require('./secret.json')
|
||||
const version = require('./version.json')
|
||||
const protover = require('./util/getProtocolVersion.js')
|
||||
const mcd = require('minecraft-data')
|
||||
module.exports.bots = []
|
||||
|
||||
const botplug = []
|
||||
const bpl = fs.readdirSync('plugins')
|
||||
|
@ -32,44 +36,69 @@ const loadplug = (botno) => {
|
|||
botplug.forEach((plug) => {
|
||||
try {
|
||||
if (plug.load) {
|
||||
plug.load(module.exports.bot[botno])
|
||||
plug.load(module.exports.bots[botno])
|
||||
}
|
||||
} catch (e) { console.log(e) }
|
||||
})
|
||||
}
|
||||
|
||||
let bypassWarningShown = false
|
||||
|
||||
const createBot = function createBot (host, oldId) {
|
||||
if (host.options.disabled) {
|
||||
return
|
||||
}
|
||||
const bot = new EventEmitter()
|
||||
bot._client = m.createClient({
|
||||
const options = {
|
||||
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])
|
||||
}
|
||||
if (protover(options.version) < version.minimumMcVersion) {
|
||||
if (!settings.bypassVersionRequirement) {
|
||||
console.error(`[error] ${version.botName} does not support Minecraft versions below ${version.minimumMcVersion} (${mcd.postNettyVersionsByProtocolVersion.pc[version.minimumMcVersion][0].minecraftVersion})`)
|
||||
return
|
||||
} else {
|
||||
if (!bypassWarningShown) console.warn('[warning] You have disabled the version requirement, allowing the bot to join to servers with old Minecraft versions. These versions are unsupported and may break at any time. Any issues on such versions will not be fixed.')
|
||||
bypassWarningShown = true
|
||||
}
|
||||
delete module.exports.bot[oldId]
|
||||
bot.id = oldId
|
||||
module.exports.bot[oldId] = bot
|
||||
}
|
||||
if (host.options.online) {
|
||||
options.username = secret.onlineEmail
|
||||
options.password = secret.onlinePass
|
||||
options.auth = 'microsoft'
|
||||
} else {
|
||||
bot.id = module.exports.bot.length
|
||||
module.exports.bot.push(bot)
|
||||
options.username = generateUser(host.options.legalName)
|
||||
}
|
||||
const bot = new EventEmitter()
|
||||
bot._client = m.createClient(options)
|
||||
if (typeof oldId !== 'undefined') {
|
||||
for (const i in module.exports.bots[oldId].interval) {
|
||||
clearInterval(module.exports.bots[oldId].interval[i])
|
||||
}
|
||||
delete module.exports.bots[oldId]
|
||||
bot.id = oldId
|
||||
module.exports.bots[oldId] = bot
|
||||
} else {
|
||||
bot.id = module.exports.bots.length
|
||||
module.exports.bots.push(bot)
|
||||
}
|
||||
|
||||
bot.host = host
|
||||
if (bot.host.host.includes(':')) {
|
||||
bot.host.options.displayAsIPv6 = true
|
||||
}
|
||||
bot.interval = {}
|
||||
|
||||
bot.info = (msg) => {
|
||||
console.log(`[${bot.id}] [info] ${msg}`)
|
||||
}
|
||||
|
||||
bot.displayChat = (type, msg) => {
|
||||
console.log(`[${bot.id}] [${type}] ${msg}`)
|
||||
bot.displayChat = (type, subtype, msg) => {
|
||||
if (settings.displaySubtypesToConsole) {
|
||||
console.log(`[${bot.id}] [${type}] [${subtype}] ${msg}`)
|
||||
} else {
|
||||
console.log(`[${bot.id}] [${type}] ${msg}`)
|
||||
}
|
||||
}
|
||||
|
||||
loadplug(bot.id)
|
||||
|
|
26
lang/en-US.json
Normal file → Executable file
26
lang/en-US.json
Normal file → Executable file
|
@ -11,6 +11,7 @@
|
|||
"time.minutePlural": " minutes ",
|
||||
"time.second": " second ",
|
||||
"time.secondPlural": " seconds ",
|
||||
"chat.antiSpamTriggered": "Anti-spam has been triggered for this server.",
|
||||
"command.about.usage": "",
|
||||
"command.about.desc": "About the bot",
|
||||
"command.cb.usage": " <command>",
|
||||
|
@ -31,20 +32,23 @@
|
|||
"command.say.desc": "Sends a message to chat",
|
||||
"command.settings.usage": " get|| set <key> <value>",
|
||||
"command.settings.desc": "Set your user preferences",
|
||||
"command.restart.usage": "",
|
||||
"command.restart.desc": "Restart bot",
|
||||
"command.stop.usage": "",
|
||||
"command.stop.desc": "Restart bot",
|
||||
"command.stop.desc": "Stop bot",
|
||||
"command.template.usage": " <required> [optional]",
|
||||
"command.template.desc": "Does nothing",
|
||||
"command.test.usage": " [args...]",
|
||||
"command.test.desc": "Chat parsing debugger command",
|
||||
"command.tpr.usage": "",
|
||||
"command.tpr.desc": "Teleport to a random location",
|
||||
"command.verify.usage": " [args...]",
|
||||
"command.verify.desc": "Check the hashing system",
|
||||
"command.validate.usage": " [args...]",
|
||||
"command.validate.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 a development version - there may be errors, and features may be changed or removed at any time. Please report any errors to the bot's developer.",
|
||||
"command.about.sourceCode": "Source code: %s",
|
||||
"command.about.license": "This bot is free and open-source software and is available under the terms of the MIT license.",
|
||||
"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",
|
||||
|
@ -52,15 +56,19 @@
|
|||
"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.eval.output": "Output",
|
||||
"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.commandUsage.lf": "Usage - %s%s\n",
|
||||
"command.help.commandDesc.lf": "Description - %s\n",
|
||||
"command.help.commandPerms.lf": "Required permissions - %s\n",
|
||||
"command.help.runCommand": "Click to run command",
|
||||
"command.help.permsNormal": "Public",
|
||||
"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.",
|
||||
|
@ -79,6 +87,7 @@
|
|||
"command.test.nickname": "Nickname",
|
||||
"command.test.command": "Command",
|
||||
"command.test.msgType": "Message type",
|
||||
"command.test.msgSubtype": "Message subtype",
|
||||
"command.test.prefix": "Prefix",
|
||||
"command.test.args": "Arguments",
|
||||
"command.test.verify": "Permission level",
|
||||
|
@ -97,6 +106,9 @@
|
|||
"command.about.serverInfo.kernelVer": "Kernel version",
|
||||
"command.about.serverInfo.processor": "CPU",
|
||||
"command.about.serverInfo.arch": "Architecture",
|
||||
"command.about.serverInfo.totalMem": "Total memory",
|
||||
"command.about.serverInfo.freeMem": "Free memory",
|
||||
"command.about.serverInfo.usedMem": "Used memory",
|
||||
"command.about.serverInfo.osUsername": "Username",
|
||||
"command.about.serverInfo.hostName": "Hostname",
|
||||
"command.about.serverInfo.workingDir": "Working directory",
|
||||
|
@ -114,7 +126,7 @@
|
|||
"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": "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 the hashing system of your client or proxy.",
|
||||
"command.disallowed.perms.yourLevel": "Your permission level: %s",
|
||||
"command.disallowed.perms.cmdLevel": "Command requires: %s",
|
||||
"copyText": "Click to copy!"
|
||||
|
|
114
package-lock.json
generated
114
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "botv10",
|
||||
"version": "10.0.0",
|
||||
"name": "botv11",
|
||||
"version": "11.0.0-alpha.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "botv10",
|
||||
"version": "10.0.0",
|
||||
"name": "botv11",
|
||||
"version": "11.0.0-alpha.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minecraft-protocol": "^1.45.0",
|
||||
|
@ -14,21 +14,21 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@azure/msal-common": {
|
||||
"version": "14.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.14.1.tgz",
|
||||
"integrity": "sha512-2Q3tqNz/PZLfSr8BvcHZVpRRfSn4MjGSqjj9J+HlBsmbf1Uu4P0WeXnemjTJwwx9KrmplsrN3UkZ/LPOR720rw==",
|
||||
"version": "14.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.15.0.tgz",
|
||||
"integrity": "sha512-ImAQHxmpMneJ/4S8BRFhjt1MZ3bppmpRPYYNyzeQPeFN288YKbb8TmmISQEbtfkQ1BPASvYZU5doIZOPBAqENQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-node": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.13.0.tgz",
|
||||
"integrity": "sha512-DhP97ycs7qlCVzzzWGzJiwAFyFj5okno74E4FUZ61oCLfKh4IxA1kxirqzrWuYZWpBe9HVPL6GA4NvmlEOBN5Q==",
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.15.0.tgz",
|
||||
"integrity": "sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "14.14.1",
|
||||
"@azure/msal-common": "14.15.0",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"uuid": "^8.3.0"
|
||||
},
|
||||
|
@ -37,18 +37,18 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz",
|
||||
"integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==",
|
||||
"version": "22.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.4.tgz",
|
||||
"integrity": "sha512-SpNNxkftTJOPk0oN+y2bIqurEXHTA2AOZ3EJDDKeJ5VzkvvORSvmQXGQarcOzWV1ac7DCaPBEdMDxBsM+d8jWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
"undici-types": "~6.19.8"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "4.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.16.tgz",
|
||||
"integrity": "sha512-Fvp+8OcU8PyV90KTk5tR/rI8OjD3MP5NUow5rjOsZo+9zxf4p4soJtK9j4V6yeG30TH6rZxqRaP4JLa8lNNTNQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
|
@ -189,12 +189,12 @@
|
|||
"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==",
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
|
@ -257,9 +257,9 @@
|
|||
"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==",
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
@ -296,12 +296,6 @@
|
|||
],
|
||||
"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",
|
||||
|
@ -427,9 +421,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/minecraft-data": {
|
||||
"version": "3.68.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.68.0.tgz",
|
||||
"integrity": "sha512-pNBTi39a1zbFpN9itwi0YSL3hqAsSw38D7pE9C6m+aURmXljpBlNTO+TkpZxxDv4KqqtNBOhmkj4x46IDW6R+Q==",
|
||||
"version": "3.78.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.78.0.tgz",
|
||||
"integrity": "sha512-Ssks8QD31lsoxqa7LySTqeP9romsfAbfsSGiUHiGMeqfxRi/PtOxGLyKD1BXB8V/tXLztFcbQYqzIhprDkPguw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/minecraft-folder-path": {
|
||||
|
@ -439,9 +433,9 @@
|
|||
"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==",
|
||||
"version": "1.50.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.50.0.tgz",
|
||||
"integrity": "sha512-GiZy8g4YG0iZEKifX6ulCyhVnTDGZ1gH0ouUdxjo6xkKwp4KOf+ptbBgZ8G5+WHCumrI91+v/JYU07uCvKdi0w==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^4.0.0",
|
||||
|
@ -451,7 +445,7 @@
|
|||
"endian-toggle": "^0.0.0",
|
||||
"lodash.get": "^4.1.2",
|
||||
"lodash.merge": "^4.3.0",
|
||||
"minecraft-data": "^3.55.0",
|
||||
"minecraft-data": "^3.78.0",
|
||||
"minecraft-folder-path": "^1.2.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-rsa": "^0.4.2",
|
||||
|
@ -459,7 +453,7 @@
|
|||
"prismarine-chat": "^1.10.0",
|
||||
"prismarine-nbt": "^2.5.0",
|
||||
"prismarine-realms": "^1.2.0",
|
||||
"protodef": "^1.8.0",
|
||||
"protodef": "^1.17.0",
|
||||
"readable-stream": "^4.1.0",
|
||||
"uuid-1345": "^1.0.1",
|
||||
"yggdrasil": "^1.4.0"
|
||||
|
@ -484,9 +478,9 @@
|
|||
"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==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nearley": {
|
||||
|
@ -586,12 +580,12 @@
|
|||
}
|
||||
},
|
||||
"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==",
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-registry/-/prismarine-registry-1.10.0.tgz",
|
||||
"integrity": "sha512-6TYQiZHtsJ87HsB2E0yamCFp77ZyyLT16OmW5iXB5V30yCPflhHvR5TR2IqISmmiRc2093BkHfiIhsOZaMatmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minecraft-data": "^3.0.0",
|
||||
"minecraft-data": "^3.70.0",
|
||||
"prismarine-nbt": "^2.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -605,15 +599,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/protodef": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/protodef/-/protodef-1.15.0.tgz",
|
||||
"integrity": "sha512-bZ2Omw8dT+DACjJHLrBWZlqN4MlT9g9oSpJDdkUAJOStUzgJp+Zn42FJfPUdwutUxjaxA0PftN0PDlNa2XbneA==",
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/protodef/-/protodef-1.17.0.tgz",
|
||||
"integrity": "sha512-mnpNPV3xwu63u3NwZuXM1RCp979vjHxUGHzVrb6dxbvof5Fx+b8Rs0G0c3xtEuFDreGAMWS7VrlNkDUDBMsFWQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.reduce": "^4.6.0",
|
||||
"protodef-validator": "^1.3.0",
|
||||
"readable-stream": "^3.0.3"
|
||||
"readable-stream": "^4.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
|
@ -631,20 +625,6 @@
|
|||
"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",
|
||||
|
@ -776,12 +756,6 @@
|
|||
"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",
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
"minecraft-protocol": "^1.45.0",
|
||||
"prismarine-chat": "^1.10.0"
|
||||
},
|
||||
"name": "botv10",
|
||||
"version": "10.0.0",
|
||||
"name": "botv11",
|
||||
"version": "11.0.0-alpha.2",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
|
|
|
@ -2,6 +2,8 @@ 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 { getMessage } = require('../util/lang.js')
|
||||
const fs = require('fs')
|
||||
const convertChatStyleItem = (item) => {
|
||||
const output = {}
|
||||
for (const i in item) {
|
||||
|
@ -24,8 +26,29 @@ const convertChatTypeItem = (item) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Level 0: highly specific parsers for certain players
|
||||
// Level 1: server chat format parsers
|
||||
// Level 2: generic parsers
|
||||
const parsers = [[], [], []]
|
||||
const bpl = fs.readdirSync('plugins/chatParsers')
|
||||
for (const plugin of bpl) {
|
||||
if (!plugin.endsWith('.js')) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
const parser = require(`./chatParsers/${plugin}`)
|
||||
parsers[parser.priority].push(parser.parse)
|
||||
} catch (e) { console.log(e) }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
load: (b) => {
|
||||
b.messageCount = 0
|
||||
b.chatDisabledUntil = 0
|
||||
b.interval.antiSpam = setInterval(() => {
|
||||
b.messageCount = 0
|
||||
}, 4000)
|
||||
b.messageTypes = []
|
||||
b._client.on('registry_data', (data) => {
|
||||
if (data.codec.value['minecraft:chat_type']) {
|
||||
|
@ -37,7 +60,8 @@ module.exports = {
|
|||
}
|
||||
})
|
||||
b._client.on('profileless_chat', (data) => {
|
||||
const messageType = b.messageTypes[data.type]
|
||||
let messageType = b.messageTypes[data.type]
|
||||
if (messageType === undefined) messageType = { translation_key: '%s', parameters: ['content'] }
|
||||
const json = { translate: messageType.translation_key, with: [] }
|
||||
messageType.parameters.forEach((item, i) => {
|
||||
if (item === 'content') {
|
||||
|
@ -51,37 +75,24 @@ module.exports = {
|
|||
for (const i in messageType.style) {
|
||||
json[i] = messageType.style[i]
|
||||
}
|
||||
let username = ''
|
||||
let nickname = ''
|
||||
let uuid = '00000000-0000-0000-0000-000000000000'
|
||||
let message = ''
|
||||
if (messageType.translation_key === '%s') {
|
||||
const parsed = parsePlain(json)
|
||||
const split = parsed.split(': ')
|
||||
const chatName = split.splice(0, 1)[0]
|
||||
const chatNameSplit = chatName.split(' ')
|
||||
nickname = chatNameSplit[chatNameSplit.length - 1]
|
||||
username = b.findRealName(chatName)
|
||||
uuid = b.findUUID(username)
|
||||
message = split.join(': ')
|
||||
} else {
|
||||
message = parsePlain(parse1204(data.message))
|
||||
uuid = b.findUUID(parsePlain(parse1204(data.name)))
|
||||
nickname = b.findDisplayName(uuid)
|
||||
username = parsePlain(parse1204(data.name))
|
||||
}
|
||||
b.emit('chat', {
|
||||
const message = parsePlain(parse1204(data.message))
|
||||
const uuid = b.findUUID(parsePlain(parse1204(data.name)))
|
||||
const nickname = b.findDisplayName(uuid)
|
||||
const username = parsePlain(parse1204(data.name))
|
||||
b.emit('chat_unparsed', {
|
||||
json,
|
||||
type: 'profileless',
|
||||
uuid,
|
||||
message,
|
||||
nickname,
|
||||
username
|
||||
username,
|
||||
playerChatType: messageType
|
||||
})
|
||||
})
|
||||
|
||||
b._client.on('player_chat', (data) => {
|
||||
const messageType = b.messageTypes[data.type]
|
||||
let messageType = b.messageTypes[data.type]
|
||||
if (messageType === undefined) messageType = { translation_key: '%s', parameters: ['content'] }
|
||||
const json = { translate: messageType.translation_key, with: [] }
|
||||
messageType.parameters.forEach((item, i) => {
|
||||
if (item === 'content') {
|
||||
|
@ -99,85 +110,85 @@ module.exports = {
|
|||
for (const i in messageType.style) {
|
||||
json[i] = messageType.style[i]
|
||||
}
|
||||
b.emit('chat', {
|
||||
b.emit('chat_unparsed', {
|
||||
json,
|
||||
type: 'player',
|
||||
uuid: data.senderUuid,
|
||||
message: data.plainMessage,
|
||||
nickname: parsePlain(parse1204(data.networkName)),
|
||||
username: b.findRealNameFromUUID(data.senderUuid)
|
||||
username: b.findRealNameFromUUID(data.senderUuid),
|
||||
playerChatType: messageType
|
||||
})
|
||||
})
|
||||
|
||||
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 chatNameSplit = chatName.split(' ')
|
||||
const nickname = chatNameSplit[chatNameSplit.length - 1]
|
||||
const username = b.findRealName(chatName)
|
||||
const uuid = b.findUUID(username)
|
||||
b.emit('chat', {
|
||||
b.emit('chat_unparsed', {
|
||||
json,
|
||||
type: 'system',
|
||||
uuid,
|
||||
message: split.join(': '),
|
||||
nickname,
|
||||
username
|
||||
uuid: '00000000-0000-0000-0000-000000000000',
|
||||
message: '',
|
||||
nickname: '',
|
||||
username: '',
|
||||
playerChatType: {}
|
||||
})
|
||||
})
|
||||
|
||||
b._client.on('chat', (data) => { // Legacy chat for versions <1.19
|
||||
const json = parse1204(data.message)
|
||||
const parsed = parsePlain(json)
|
||||
let chatName
|
||||
let nickname
|
||||
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(': ')
|
||||
chatName = split.splice(0, 1)[0]
|
||||
const chatNameSplit = chatName.split(' ')
|
||||
nickname = chatNameSplit[chatNameSplit.length - 1]
|
||||
username = b.findRealName(chatName)
|
||||
uuid = b.findUUID(username)
|
||||
message = split.join(': ')
|
||||
}
|
||||
if (data.uuid) uuid = data.uuid
|
||||
b.emit('chat', {
|
||||
b.emit('chat_unparsed', {
|
||||
json,
|
||||
type: 'legacy',
|
||||
uuid,
|
||||
message,
|
||||
nickname,
|
||||
username
|
||||
username,
|
||||
playerChatType: {}
|
||||
})
|
||||
})
|
||||
|
||||
b.on('chat_unparsed', (data) => {
|
||||
for (const lvl of parsers) {
|
||||
for (const item of lvl) {
|
||||
const output = item(data, b)
|
||||
if (output.parsed) {
|
||||
b.emit('chat', output)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
b.emit('chat', {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype: 'fallback',
|
||||
uuid: '00000000-0000-0000-0000-000000000000',
|
||||
message: '',
|
||||
nickname: '',
|
||||
username: ''
|
||||
})
|
||||
})
|
||||
|
||||
b.on('chat', (data) => {
|
||||
b.messageCount++
|
||||
if (Date.now() < b.chatDisabledUntil) return
|
||||
if (b.messageCount >= 100) {
|
||||
b.info(getMessage(settings.defaultLang, 'chat.antiSpamTriggered'))
|
||||
b.chatDisabledUntil = Date.now() + 30000
|
||||
return
|
||||
}
|
||||
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, data.type)
|
||||
b.displayChat(data.type, `${msgConsole}\x1b[0m`)
|
||||
|
||||
const fullCommand = data.message
|
||||
for (const prefix of b.prefix) {
|
||||
if (fullCommand.startsWith(prefix)) {
|
||||
const command = fullCommand.slice(prefix.length)
|
||||
b.runCommand(data.username, data.nickname, data.uuid, command, data.type, prefix)
|
||||
}
|
||||
}
|
||||
b.emit('plainchat', msgPlain, data.type, data.subtype)
|
||||
b.displayChat(data.type, data.subtype, `${msgConsole}\x1b[0m`)
|
||||
})
|
||||
}
|
||||
}
|
47
plugins/chatParsers/chat_cmm.js
Executable file
47
plugins/chatParsers/chat_cmm.js
Executable file
|
@ -0,0 +1,47 @@
|
|||
const parsePlain = require('../../util/chatparse_plain.js')
|
||||
module.exports = {
|
||||
parse: (data, b) => {
|
||||
if (data.type === 'system' || data.type === 'legacy') {
|
||||
if (data.json.translate === '%s %s › %s' || data.json.translate === '[%s] %s › %s') {
|
||||
let subtype = 'chipmunkmod_'
|
||||
if (data.json.translate === '%s %s › %s') {
|
||||
subtype += 'name3'
|
||||
} else if (data.json.translate === '[%s] %s › %s') {
|
||||
subtype += 'chomens'
|
||||
}
|
||||
if (data.json.with && data.json.with[1] && data.json.with[2]) {
|
||||
const username = parsePlain(data.json.with[1])
|
||||
const uuid = b.findUUID(username)
|
||||
const nickname = b.findDisplayName(uuid)
|
||||
const message = parsePlain(data.json.with[2].extra)
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype,
|
||||
uuid,
|
||||
message,
|
||||
nickname,
|
||||
username
|
||||
}
|
||||
} else {
|
||||
subtype += '_invalid'
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype,
|
||||
uuid: '00000000-0000-0000-0000-000000000000',
|
||||
message: '',
|
||||
nickname: '',
|
||||
username: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
parsed: false
|
||||
}
|
||||
},
|
||||
priority: 0
|
||||
}
|
27
plugins/chatParsers/chat_cmm_mcp.js
Executable file
27
plugins/chatParsers/chat_cmm_mcp.js
Executable file
|
@ -0,0 +1,27 @@
|
|||
const parsePlain = require('../../util/chatparse_plain.js')
|
||||
module.exports = {
|
||||
parse: (data, b) => {
|
||||
if (data.type === 'system' || data.type === 'legacy') {
|
||||
if (data.json.extra && data.json.extra[4] && data.json.extra[3] && data.json.extra[5] && data.json.extra[4].text === ' » ') { // ChipmunkMod format - m_c_player
|
||||
const username = parsePlain(data.json.extra[3])
|
||||
const uuid = b.findUUID(username)
|
||||
const nickname = b.findDisplayName(uuid)
|
||||
const message = parsePlain(data.json.extra[5])
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype: 'chipmunkmod_mcp',
|
||||
uuid,
|
||||
message,
|
||||
nickname,
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
parsed: false
|
||||
}
|
||||
},
|
||||
priority: 0
|
||||
}
|
31
plugins/chatParsers/chat_extras_profileless.js
Executable file
31
plugins/chatParsers/chat_extras_profileless.js
Executable file
|
@ -0,0 +1,31 @@
|
|||
const parsePlain = require('../../util/chatparse_plain.js')
|
||||
module.exports = {
|
||||
parse: (data, b) => {
|
||||
if (data.type === 'profileless') {
|
||||
if (data.playerChatType.translation_key === '%s') {
|
||||
const parsed = parsePlain(data.json)
|
||||
const split = parsed.split(': ')
|
||||
const chatName = split.splice(0, 1)[0]
|
||||
const chatNameSplit = chatName.split(' ')
|
||||
const nickname = chatNameSplit[chatNameSplit.length - 1]
|
||||
const username = b.findRealName(chatName)
|
||||
const uuid = b.findUUID(username)
|
||||
const message = split.join(': ')
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype: 'extras_profileless',
|
||||
uuid,
|
||||
message,
|
||||
nickname,
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
parsed: false
|
||||
}
|
||||
},
|
||||
priority: 1
|
||||
}
|
20
plugins/chatParsers/chat_player.js
Executable file
20
plugins/chatParsers/chat_player.js
Executable file
|
@ -0,0 +1,20 @@
|
|||
module.exports = {
|
||||
parse: (data, b) => {
|
||||
if (data.type === 'player' || data.type === 'profileless') {
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype: 'generic_player',
|
||||
uuid: data.uuid,
|
||||
message: data.message,
|
||||
nickname: data.nickname,
|
||||
username: data.username
|
||||
}
|
||||
}
|
||||
return {
|
||||
parsed: false
|
||||
}
|
||||
},
|
||||
priority: 2
|
||||
}
|
40
plugins/chatParsers/chat_system.js
Executable file
40
plugins/chatParsers/chat_system.js
Executable file
|
@ -0,0 +1,40 @@
|
|||
const parsePlain = require('../../util/chatparse_plain.js')
|
||||
module.exports = {
|
||||
parse: (data, b) => {
|
||||
if (data.type === 'system' || data.type === 'legacy') {
|
||||
let subtype = 'generic_system'
|
||||
if (data.type === 'legacy' && data.uuid) subtype += '_withuuid'
|
||||
const parsed = parsePlain(data.json)
|
||||
const split = parsed.split(': ')
|
||||
const chatName = split.splice(0, 1)[0]
|
||||
const chatNameSplit = chatName.split(' ')
|
||||
|
||||
let uuid
|
||||
let username
|
||||
let nickname
|
||||
if (data.uuid) {
|
||||
uuid = data.uuid
|
||||
username = b.findRealNameFromUUID(uuid)
|
||||
nickname = b.findDisplayName(uuid)
|
||||
} else {
|
||||
nickname = chatNameSplit[chatNameSplit.length - 1]
|
||||
username = b.findRealName(chatName)
|
||||
uuid = b.findUUID(username)
|
||||
}
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype,
|
||||
uuid,
|
||||
message: split.join(': '),
|
||||
nickname,
|
||||
username
|
||||
}
|
||||
}
|
||||
return {
|
||||
parsed: false
|
||||
}
|
||||
},
|
||||
priority: 2
|
||||
}
|
33
plugins/chatParsers/chat_vanilla_legacy.js
Executable file
33
plugins/chatParsers/chat_vanilla_legacy.js
Executable file
|
@ -0,0 +1,33 @@
|
|||
const parsePlain = require('../../util/chatparse_plain.js')
|
||||
module.exports = {
|
||||
parse: (data, b) => {
|
||||
if (data.type === 'legacy') {
|
||||
let subtype = 'vanilla_legacy'
|
||||
if (data.type === 'legacy' && data.uuid) subtype += '_withuuid'
|
||||
if (data.json.translate === 'chat.type.text') { // Servers without Extras chat
|
||||
let message
|
||||
let username
|
||||
if (data.json.with && data.json.with.length >= 2) {
|
||||
message = parsePlain(data.json.with[1])
|
||||
username = parsePlain(data.json.with[0])
|
||||
}
|
||||
const uuid = b.findUUID(username)
|
||||
const nickname = b.findDisplayName(uuid)
|
||||
return {
|
||||
parsed: true,
|
||||
json: data.json,
|
||||
type: data.type,
|
||||
subtype,
|
||||
uuid,
|
||||
message,
|
||||
nickname,
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
parsed: false
|
||||
}
|
||||
},
|
||||
priority: 1
|
||||
}
|
|
@ -25,8 +25,8 @@ module.exports = {
|
|||
b.on('plainchat', (msg, type) => {
|
||||
if (!settings.disableLogging && !settings.disableChatLogging) chatlog(`chat_${b.host.host}_${b.host.port}`, `[${type}] ${msg}`)
|
||||
})
|
||||
b.on('command', (name, uuid, text) => {
|
||||
if (!settings.disableLogging && !settings.disableCommandLogging) chatlog(`cmd_${b.host.host}_${b.host.port}`, `${name} (${uuid}): ${text}`)
|
||||
b.on('command', c => {
|
||||
if (!settings.disableLogging && !settings.disableCommandLogging) chatlog(`cmd_${b.host.host}_${b.host.port}`, `[${c.msgType}] ${c.username} (${c.uuid}): ${c.command}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +1,48 @@
|
|||
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')
|
||||
if (!fs.readdirSync('.').includes('userPref') && !settings.disableUserSettings) fs.mkdirSync('userPref')
|
||||
|
||||
const loadSettings = function (uuid) {
|
||||
try {
|
||||
return require(`../userPref/${uuid}.json`)
|
||||
if (settings.disableUserSettings) {
|
||||
return {}
|
||||
} else {
|
||||
return require(`../userPref/${uuid}.json`)
|
||||
}
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
load: (b) => {
|
||||
b.prefix = settings.prefix
|
||||
b.lastCmd = 0
|
||||
b.runCommand = (name, nickname, uuid, text, msgType, prefix) => {
|
||||
b.on('chat', (data) => {
|
||||
const fullCommand = data.message
|
||||
for (const prefix of settings.prefix) {
|
||||
if (fullCommand.startsWith(prefix)) {
|
||||
const command = fullCommand.slice(prefix.length)
|
||||
b.runCommand(data.username, data.nickname, data.uuid, command, data.type, data.subtype, prefix)
|
||||
}
|
||||
}
|
||||
})
|
||||
b.runCommand = (name, nickname, uuid, text, msgType, msgSubtype, 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(' ')
|
||||
}
|
||||
b.emit('command', name, uuid, text, prefix)
|
||||
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
|
||||
}
|
||||
|
||||
const commandClass = new Command(uuid, name, nickname, text, msgType, msgSubtype, prefix, b, userSettings)
|
||||
b.emit('command', commandClass)
|
||||
if (commandClass.cancel === true) return
|
||||
|
||||
if (cmds[commandClass.cmdName.toLowerCase()]) {
|
||||
try {
|
||||
cmds[cmd[0].toLowerCase()].execute(new Command(uuid, name, nickname, text, msgType, prefix, b, verify, userSettings))
|
||||
cmds[commandClass.cmdName.toLowerCase()].execute(commandClass)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
b.tellraw(uuid, {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const uuidToInt = require('../util/uuidtoint.js')
|
||||
const plainParser = require('../util/chatparse_plain.js')
|
||||
const mcParser = require('../util/chatparse_mc.js')
|
||||
const cs = {
|
||||
x: 4,
|
||||
y: 6,
|
||||
|
@ -17,6 +19,7 @@ module.exports = {
|
|||
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.host.options.useChat) return
|
||||
if (b.ccq[0] && b.ccq[0].length !== 0) {
|
||||
b._client.write('update_command_block', {
|
||||
command: '/',
|
||||
|
@ -63,18 +66,20 @@ module.exports = {
|
|||
skinParts: 127, // Allow the second layer of the skin, when the bot is sudoed to do /skin
|
||||
mainHand: 1 // Right hand
|
||||
})
|
||||
b.add_sc_task('cc', () => {
|
||||
b.chat(b.refillCoreCmd)
|
||||
}, true)
|
||||
b.add_sc_task('cc_size', () => {
|
||||
b.chat('/gamerule commandModificationBlockLimit 32768')
|
||||
})
|
||||
if (!b.host.options.useChat) {
|
||||
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, 2) }, 1000)
|
||||
b.ccStarted = true
|
||||
})
|
||||
b.on('chat', (data) => {
|
||||
b.on('chat_unparsed', (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) {
|
||||
|
@ -107,20 +112,28 @@ module.exports = {
|
|||
|
||||
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)}]}]`
|
||||
if (b.host.options.useChat) {
|
||||
if (b.host.options.useAmpersandColorCodes) {
|
||||
b.chat(mcParser(message).replaceAll('§', '&'))
|
||||
} else {
|
||||
b.chat(plainParser(message))
|
||||
}
|
||||
} else {
|
||||
finalname = uuid
|
||||
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)}`)
|
||||
}
|
||||
let tellrawCommand
|
||||
if (b.host.options.isVanilla) {
|
||||
tellrawCommand = 'tellraw'
|
||||
} else {
|
||||
tellrawCommand = 'minecraft:tellraw'
|
||||
}
|
||||
b.ccq.push(`/${tellrawCommand} ${finalname} ${JSON.stringify(message)}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
plugins/console.js
Normal file → Executable file
11
plugins/console.js
Normal file → Executable file
|
@ -2,6 +2,7 @@ const readln = require('readline')
|
|||
const index = require('../index.js')
|
||||
const ConsoleCommand = require('../util/ConsoleCommand.js')
|
||||
const cmds = require('../util/commands.js')
|
||||
const settings = require('../settings.json')
|
||||
const rl = readln.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
|
@ -14,7 +15,7 @@ rl.on('line', (l) => {
|
|||
const tmpcmd = l.split(' ')
|
||||
const index2 = tmpcmd.splice(1, 1)[0]
|
||||
if (index2 === '*') {
|
||||
for (let i = 0; i < index.bot.length; i++) {
|
||||
for (let i = 0; i < index.bots.length; i++) {
|
||||
const cmd = new ConsoleCommand(tmpcmd.join(' '), i)
|
||||
cmds[l.split(' ')[0].toLowerCase()].execute(cmd)
|
||||
}
|
||||
|
@ -45,8 +46,12 @@ module.exports = {
|
|||
b.info = (msg) => {
|
||||
consoleWrite(`[${b.id}] [info] ${msg}`)
|
||||
}
|
||||
b.displayChat = (type, msg) => {
|
||||
consoleWrite(`[${b.id}] [${type}] ${msg}`)
|
||||
b.displayChat = (type, subtype, msg) => {
|
||||
if (settings.displaySubtypesToConsole) {
|
||||
consoleWrite(`[${b.id}] [${type}] [${subtype}] ${msg}`)
|
||||
} else {
|
||||
consoleWrite(`[${b.id}] [${type}] ${msg}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ module.exports = {
|
|||
}
|
||||
}, 100)
|
||||
})
|
||||
b.matcherRegex = /.{1,255}/g
|
||||
b.chatqueue = []
|
||||
b.chat = function chat (msg) {
|
||||
if (msg.length === 0) return
|
||||
msg.match(/.{1,255}/g).forEach(element => {
|
||||
msg.match(b.matcherRegex).forEach(element => {
|
||||
b.chatqueue.push(element)
|
||||
})
|
||||
}
|
||||
|
|
31
plugins/perms.js
Executable file
31
plugins/perms.js
Executable file
|
@ -0,0 +1,31 @@
|
|||
const cmds = require('../util/commands.js')
|
||||
const { getMessage } = require('../util/lang.js')
|
||||
const hashcheck = require('../util/hashcheck.js')
|
||||
|
||||
module.exports = {
|
||||
load: (b) => {
|
||||
b.on('command', c => {
|
||||
const cmd = c.command.split(' ')
|
||||
const command = cmds[c.cmdName.toLowerCase()]
|
||||
const verify = hashcheck(cmd, c.uuid)
|
||||
const permsN = getMessage(c.lang, 'command.help.permsNormal')
|
||||
const permsT = getMessage(c.lang, 'command.help.permsTrusted')
|
||||
const permsO = getMessage(c.lang, 'command.help.permsOwner')
|
||||
if (command && command.level !== undefined && command.level > verify) {
|
||||
b.tellraw(c.uuid, {
|
||||
text: getMessage(c.lang, 'command.disallowed.perms')
|
||||
})
|
||||
b.tellraw(c.uuid, {
|
||||
text: getMessage(c.lang, 'command.disallowed.perms.yourLevel', [[permsN, permsT, permsO][verify]])
|
||||
})
|
||||
b.tellraw(c.uuid, {
|
||||
text: getMessage(c.lang, 'command.disallowed.perms.cmdLevel', [[permsN, permsT, permsO][command.level]])
|
||||
})
|
||||
c.cancel = true
|
||||
} else if (verify > 0) {
|
||||
c.rewriteCommand(cmd.slice(0, cmd.length - 1).join(' '))
|
||||
c.verify = verify
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
25
plugins/player.js
Normal file → Executable file
25
plugins/player.js
Normal file → Executable file
|
@ -28,8 +28,17 @@ module.exports = {
|
|||
}
|
||||
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
|
||||
let displayName = ''
|
||||
let realName = ''
|
||||
if (buffer2[uuid].displayName) {
|
||||
displayName = buffer2[uuid].displayName
|
||||
b.players[uuid].displayName = buffer2[uuid].displayName
|
||||
}
|
||||
if (buffer2[uuid].realName) {
|
||||
realName = buffer2[uuid].realName
|
||||
b.players[uuid].realName = buffer2[uuid].realName
|
||||
}
|
||||
b.emit('playerdata', uuid, displayName, realName)
|
||||
}
|
||||
})
|
||||
b.findUUID = (name) => {
|
||||
|
@ -48,16 +57,16 @@ module.exports = {
|
|||
}
|
||||
return '[[[[ no name ]]]]'
|
||||
}
|
||||
b.findRealNameFromUUID = (name) => {
|
||||
if (b.players[name]) {
|
||||
return b.players[name].realName
|
||||
b.findRealNameFromUUID = (uuid) => {
|
||||
if (b.players[uuid]) {
|
||||
return b.players[uuid].realName
|
||||
} else {
|
||||
return '[[[[ no name ]]]]'
|
||||
}
|
||||
}
|
||||
b.findDisplayName = (name) => {
|
||||
if (b.players[name]) {
|
||||
const displayName = b.players[name].displayName.split(' ')
|
||||
b.findDisplayName = (uuid) => {
|
||||
if (b.players[uuid]) {
|
||||
const displayName = b.players[uuid].displayName.split(' ')
|
||||
return displayName[displayName.length - 1]
|
||||
} else {
|
||||
return '[[[[ No display name ]]]]'
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
const parsePlain = require('../util/chatparse_plain.js')
|
||||
const parseMc = require('../util/chatparse_mc_withHex.js')
|
||||
const settings = require('../settings.json')
|
||||
const version = require('../version.json')
|
||||
class SCTask {
|
||||
constructor (failTask, startFailed = false) {
|
||||
/*
|
||||
|
@ -12,17 +16,19 @@ 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._client.on('login', () => {
|
||||
b.interval.sc = setInterval(() => {
|
||||
if (Date.now() - b.selfcareRun <= 600) {
|
||||
return
|
||||
}
|
||||
}
|
||||
b.selfcareRun = Date.now()
|
||||
}, 40)
|
||||
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)
|
||||
}
|
||||
|
@ -58,7 +64,7 @@ module.exports = {
|
|||
})
|
||||
}
|
||||
|
||||
// Gamemode
|
||||
// Gamemode / end portal bug
|
||||
b.add_sc_task('gamemode', () => {
|
||||
b.chat('/minecraft:gamemode creative')
|
||||
})
|
||||
|
@ -67,6 +73,8 @@ module.exports = {
|
|||
b.sc_tasks.gamemode.failed = 1
|
||||
} else if (p.reason === 3 && p.gameMode === 1) {
|
||||
b.sc_tasks.gamemode.failed = 0
|
||||
} else if (p.reason === 4) {
|
||||
b.sc_tasks.respawn.failed = 1
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -75,11 +83,53 @@ module.exports = {
|
|||
b._client.write('client_command', { actionId: 0 }) // Simulates respawning
|
||||
b.sc_tasks.respawn.failed = 0
|
||||
})
|
||||
b.on('chat', (data) => {
|
||||
|
||||
b.on('chat_unparsed', (data) => {
|
||||
if (data.json.translate === 'chat.disabled.options' || (data.json.extra && data.json.extra[0] && data.json.extra[0].translate === 'chat.disabled.options') ||
|
||||
data.json.translate === 'Chat disabled in client options' || (data.json.extra && data.json.extra[0] && data.json.extra[0].translate === 'Chat disabled in client options')) {
|
||||
b.sc_tasks.respawn.failed = 1
|
||||
}
|
||||
})
|
||||
|
||||
// Prefix tablist ads
|
||||
if (!b.host.options.isVanilla) {
|
||||
b.adPrefix = {
|
||||
translate: '[%s] %s', // Since the bot aims to have an invisible name, the ad prefix should contain information about the bot.
|
||||
color: 'white',
|
||||
with: [
|
||||
{
|
||||
translate: '%s: %s',
|
||||
color: settings.colors.secondary,
|
||||
with: [
|
||||
{
|
||||
text: 'Prefix'
|
||||
},
|
||||
{
|
||||
text: settings.prefix[0],
|
||||
color: settings.colors.primary
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: version.botName,
|
||||
color: settings.colors.primary
|
||||
}
|
||||
]
|
||||
}
|
||||
b.add_sc_task('playerlist_ads', () => {
|
||||
b.chat(`/prefix ${parseMc(b.adPrefix).replaceAll('§', '&')}`)
|
||||
})
|
||||
b.on('playerdata', (uuid, displayName) => {
|
||||
if (uuid === b._client.uuid && !displayName.startsWith(parsePlain(b.adPrefix))) {
|
||||
b.sc_tasks.playerlist_ads.failed = 1
|
||||
}
|
||||
})
|
||||
b.on('plainchat', (msg) => {
|
||||
if (msg === `You now have the tag: ${parseMc(b.adPrefix).replaceAll('§', '&')}` ||
|
||||
msg === 'Something went wrong while saving the prefix. Please check console.') { // Fix the prefix issue
|
||||
b.sc_tasks.playerlist_ads.failed = 0
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
0
secret_example.json
Normal file → Executable file
0
secret_example.json
Normal file → Executable file
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"secret":"/path/to/secrets/file/secret.json",
|
||||
"version_mc": "1.20.4",
|
||||
"defaultLang": "en-US",
|
||||
"terminalMode": "blackTerminal_24bit",
|
||||
|
|
12
util/Command.js
Normal file → Executable file
12
util/Command.js
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
|||
const settings = require('../settings.json')
|
||||
class Command {
|
||||
constructor (uuid, user, nick, cmd, msgType, prefix, bot, verify, prefs) {
|
||||
constructor (uuid, user, nick, cmd, msgType, msgSubtype, prefix, bot, prefs) {
|
||||
this.send = (text, uuid) => { bot.tellraw(uuid || '@a', text) }
|
||||
this.reply = text => bot.tellraw(uuid, text)
|
||||
this.uuid = uuid
|
||||
|
@ -8,16 +8,18 @@ class Command {
|
|||
this.nickname = nick
|
||||
this.command = cmd
|
||||
this.msgType = msgType
|
||||
this.msgSubtype = msgSubtype
|
||||
this.prefix = prefix
|
||||
this.bot = bot
|
||||
this.type = 'minecraft'
|
||||
this.args = cmd.split(' ').slice(1)
|
||||
this.cmdName = cmd.split(' ')[0]
|
||||
this.verify = verify
|
||||
this.verify = 0
|
||||
this.host = bot.host.host
|
||||
this.port = bot.host.port
|
||||
this.serverName = bot.host.options.name
|
||||
this.prefs = prefs
|
||||
this.cancel = false
|
||||
if (prefs.lang) {
|
||||
this.lang = prefs.lang
|
||||
} else {
|
||||
|
@ -36,6 +38,12 @@ class Command {
|
|||
_colors.secondary = settings.colors.secondary
|
||||
}
|
||||
this.colors = _colors
|
||||
|
||||
this.rewriteCommand = newCmd => {
|
||||
this.command = newCmd
|
||||
this.args = newCmd.split(' ').slice(1)
|
||||
this.cmdName = newCmd.split(' ')[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
9
util/ConsoleCommand.js
Normal file → Executable file
9
util/ConsoleCommand.js
Normal file → Executable file
|
@ -1,6 +1,7 @@
|
|||
const index = require('../index.js')
|
||||
const parse = require('../util/chatparse_console.js')
|
||||
const settings = require('../settings.json')
|
||||
const version = require('../version.json')
|
||||
class ConsoleCommand {
|
||||
constructor (cmd, index2) {
|
||||
this.send = () => {}
|
||||
|
@ -10,17 +11,19 @@ class ConsoleCommand {
|
|||
this.nickname = 'Owner'
|
||||
this.command = cmd
|
||||
this.msgType = '_bot_console'
|
||||
this.msgSubtype = '_bot_console'
|
||||
this.prefix = ''
|
||||
this.bot = index2 >= 0
|
||||
? index.bot[index2]
|
||||
? index.bots[index2]
|
||||
: {}
|
||||
this.type = 'console'
|
||||
this.args = cmd.split(' ').slice(1)
|
||||
this.cmdName = cmd.split(' ')[0]
|
||||
this.verify = 3
|
||||
this.verify = 2
|
||||
this.host = ''
|
||||
this.port = '3'
|
||||
this.serverName = 'botvX Console'
|
||||
this.serverName = `${version.botName} Console`
|
||||
this.cancel = false
|
||||
this.lang = settings.defaultLang
|
||||
this.colors = settings.colors
|
||||
}
|
||||
|
|
0
util/chatlog.js
Normal file → Executable file
0
util/chatlog.js
Normal file → Executable file
0
util/chatparse_console.js
Normal file → Executable file
0
util/chatparse_console.js
Normal file → Executable file
0
util/chatparse_mc.js
Normal file → Executable file
0
util/chatparse_mc.js
Normal file → Executable file
98
util/chatparse_mc_withHex.js
Executable file
98
util/chatparse_mc_withHex.js
Executable file
|
@ -0,0 +1,98 @@
|
|||
const lang = require('./mc_lang.js')
|
||||
|
||||
const consoleColors = {
|
||||
dark_red: '§4',
|
||||
red: '§c',
|
||||
dark_green: '§2',
|
||||
green: '§a',
|
||||
gold: '§6',
|
||||
yellow: '§e',
|
||||
dark_blue: '§1',
|
||||
blue: '§9',
|
||||
dark_purple: '§5',
|
||||
light_purple: '§d',
|
||||
dark_aqua: '§3',
|
||||
aqua: '§b',
|
||||
black: '§0',
|
||||
gray: '§7',
|
||||
dark_gray: '§8',
|
||||
white: '§f',
|
||||
reset: '§r§f'
|
||||
}
|
||||
|
||||
const processColor = (col, rcol) => {
|
||||
let out
|
||||
if (col === 'reset') {
|
||||
out = rcol
|
||||
} else if (col.startsWith('#')) {
|
||||
out = `§${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', '')
|
||||
}
|
||||
if (data.translate) {
|
||||
let trans = data.translate.replaceAll('%%', '\ud900\ud801').replaceAll('\x1b', '').replaceAll('\x0e', '')
|
||||
if (lang[trans] !== undefined) {
|
||||
trans = lang[trans].replace(/%%/g, '\ue123')
|
||||
}
|
||||
if (data.with) {
|
||||
data.with.forEach((item, i) => {
|
||||
const j2 = parse(item, l + 1, data.color ? processColor(data.color, resetColor) : resetColor)
|
||||
trans = trans.replace(/%s/, j2.replaceAll('%s', '\ud900\ud804').replaceAll('$s', '\ud900\ud805'))
|
||||
trans = trans.replaceAll(`%${+i + 1}$s`, j2.replaceAll('%s', '\ud900\ud804').replaceAll('$s', '\ud900\ud805'))
|
||||
})
|
||||
}
|
||||
out += trans.replaceAll('\ud900\ud801', '%').replaceAll('\ud900\ud804', '%s').replaceAll('\ud900\ud805', '$s')
|
||||
}
|
||||
if (data.extra) {
|
||||
for (const item of data.extra) {
|
||||
const parsed = parse(item, 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
|
10
util/chatparse_plain.js
Normal file → Executable file
10
util/chatparse_plain.js
Normal file → Executable file
|
@ -29,10 +29,12 @@ const parse = function (_data, l = 0) {
|
|||
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.replaceAll('%s', '\ud900\ud804').replaceAll('$s', '\ud900\ud805'))
|
||||
trans = trans.replaceAll(`%${+i + 1}$s`, j2.replaceAll('%s', '\ud900\ud804').replaceAll('$s', '\ud900\ud805'))
|
||||
if (data.with) {
|
||||
data.with.forEach((item, i) => {
|
||||
const j2 = parse(item, l + 1)
|
||||
trans = trans.replace(/%s/, j2.replaceAll('%s', '\ud900\ud804').replaceAll('$s', '\ud900\ud805'))
|
||||
trans = trans.replaceAll(`%${+i + 1}$s`, j2.replaceAll('%s', '\ud900\ud804').replaceAll('$s', '\ud900\ud805'))
|
||||
})
|
||||
}
|
||||
out += trans.replaceAll('\ud900\ud801', '%').replaceAll('\ud900\ud804', '%s').replaceAll('\ud900\ud805', '$s')
|
||||
}
|
||||
|
|
2
util/commands.js
Normal file → Executable file
2
util/commands.js
Normal file → Executable file
|
@ -1,4 +1,5 @@
|
|||
const fs = require('fs')
|
||||
const settings = require('../settings.json')
|
||||
const cmds = Object.create(null)
|
||||
const bpl = fs.readdirSync('./commands')
|
||||
for (const plugin of bpl) {
|
||||
|
@ -7,6 +8,7 @@ for (const plugin of bpl) {
|
|||
}
|
||||
try {
|
||||
const commandName = plugin.split('.js')[0]
|
||||
if (commandName === 'settings' && settings.disableUserSettings) continue
|
||||
cmds[commandName] = require(`../commands/${plugin}`)
|
||||
if (cmds[commandName].level === undefined) {
|
||||
cmds[commandName].level = 0
|
||||
|
|
0
util/consolecolors.json
Normal file → Executable file
0
util/consolecolors.json
Normal file → Executable file
4
util/getProtocolVersion.js
Executable file
4
util/getProtocolVersion.js
Executable file
|
@ -0,0 +1,4 @@
|
|||
const mcd = require('minecraft-data')
|
||||
module.exports = function (ver) {
|
||||
return mcd.versionsByMinecraftVersion.pc[ver].version
|
||||
}
|
6
util/hashcheck.js
Normal file → Executable file
6
util/hashcheck.js
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
|||
const crypto = require('crypto')
|
||||
const secret = require('../secret.json')
|
||||
module.exports = function (cmd) {
|
||||
module.exports = function (cmd, uuid) {
|
||||
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 hashTrusted = `babyboom:${secret.keyTrusted}:${uuid}:${cmdWithoutHash}:${dateString}`
|
||||
const hashOwner = `babyboom:${secret.keyOwner}:${uuid}:${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) {
|
||||
|
|
6
util/lang.js
Normal file → Executable file
6
util/lang.js
Normal file → Executable file
|
@ -1,5 +1,7 @@
|
|||
const fs = require('fs')
|
||||
const languages = {}
|
||||
const settings = require('../settings.json')
|
||||
const fallbackLocale = settings.fallbackLocale ? settings.fallbackLocale : 'en-US'
|
||||
|
||||
const loadplug = (botno) => {
|
||||
const bpl = fs.readdirSync('lang')
|
||||
|
@ -18,8 +20,8 @@ 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')
|
||||
} else if (languages[fallbackLocale] && languages['en-US'][message] !== undefined) {
|
||||
message = languages[fallbackLocale][message].replace(/%%/g, '\ue123')
|
||||
}
|
||||
if (with2) {
|
||||
with2.forEach((withItem, i) => {
|
||||
|
|
0
util/mc_lang.js
Normal file → Executable file
0
util/mc_lang.js
Normal file → Executable file
15
util/memoryconvert.js
Executable file
15
util/memoryconvert.js
Executable file
|
@ -0,0 +1,15 @@
|
|||
module.exports = function (bytes) {
|
||||
if (bytes >= 1125899906842624) { // Petabytes
|
||||
return `${Math.round(bytes / 1125899906842624 * 100) / 100} PB`
|
||||
} else if (bytes >= 1099511627776) { // Terabytes
|
||||
return `${Math.round(bytes / 1099511627776 * 100) / 100} TB`
|
||||
} else if (bytes >= 1073741824) { // Gigabytes
|
||||
return `${Math.round(bytes / 1073741824 * 100) / 100} GB`
|
||||
} else if (bytes >= 1048576) { // Megabytes
|
||||
return `${Math.round(bytes / 1048576 * 100) / 100} MB`
|
||||
} else if (bytes >= 1024) { // Kilobytes
|
||||
return `${Math.round(bytes / 1024 * 100) / 100} KB`
|
||||
} else { // Bytes
|
||||
return `${bytes} B`
|
||||
}
|
||||
}
|
0
util/parseNBT.js
Normal file → Executable file
0
util/parseNBT.js
Normal file → Executable file
11
util/usergen.js
Normal file → Executable file
11
util/usergen.js
Normal file → Executable file
|
@ -2,20 +2,17 @@ const crypto = require('crypto')
|
|||
const rsg = function (count) {
|
||||
let output = ''
|
||||
for (let i = 0; i < count; i++) {
|
||||
const type = Math.floor(Math.random() * 6)
|
||||
const type = Math.floor(Math.random() * 5)
|
||||
switch (type) {
|
||||
case 0:
|
||||
output += ' '
|
||||
break
|
||||
case 1:
|
||||
output += '§§'
|
||||
break
|
||||
case 2:
|
||||
case 1:
|
||||
output += '§ '
|
||||
break
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:{ // Make this case more likely
|
||||
case 4:{ // 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
|
||||
|
|
0
util/uuidtoint.js
Normal file → Executable file
0
util/uuidtoint.js
Normal file → Executable file
0
util/version.js
Normal file → Executable file
0
util/version.js
Normal file → Executable file
11
version.json
Normal file → Executable file
11
version.json
Normal file → Executable file
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"botName": "botvX Dev",
|
||||
"botVersion": "10.1.0-alpha.1",
|
||||
"botAuthor": "a5a06d596f15c7db",
|
||||
"botName": "UBot Dev",
|
||||
"botVersion": "11.0.0-alpha.2",
|
||||
"botAuthor": "uwu1104090889",
|
||||
"isPreRelease": true,
|
||||
"sourceURL": "https://code.chipmunk.land/7cc5c4f330d47060/botvX"
|
||||
}
|
||||
"sourceURL": "https://code.chipmunk.land/7cc5c4f330d47060/owobot",
|
||||
"minimumMcVersion": 393
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue