Compare commits

...

31 commits

Author SHA1 Message Date
ac9ce2d957 Update README.md 2024-09-20 00:06:33 -04:00
8ddee3cf3a
Backport README update to 10.0 branch 2024-09-20 00:04:32 -04:00
5a7a6548d7
Bump version 2024-09-13 03:50:03 -04:00
7ce5949d86
Bugfix 2024-09-13 03:49:00 -04:00
171b6a2f9a
Bump version 2024-09-12 00:19:03 -04:00
a85269ecce
Lint 2024-09-12 00:18:41 -04:00
28ebfc7b62
How did I not see this 2024-09-08 22:39:08 -04:00
f1994b7f7f
Improvements to about command 2024-09-08 22:24:36 -04:00
0b0fad42ef
Fix "info serveR 2024-09-08 22:24:02 -04:00
bf111d2648
Case sensitivity fixes 2024-09-08 22:23:22 -04:00
32852ff120
Update branding
If it causes problems, botvX
2024-09-08 22:06:35 -04:00
83d2cf4a65
Add m_c_player format 2024-09-08 22:06:29 -04:00
4cf86f31c1
Add chipmunk mod format 2024-09-08 22:06:25 -04:00
9658c63dcd
Change author 2024-08-30 21:46:25 -04:00
u0_a342
0f28a43a03 Update packages 2024-08-28 23:20:25 -04:00
81b6612233 Readme fix 2024-08-28 23:09:16 -04:00
08b6a1df01
README improvements 2024-08-28 20:16:14 -04:00
40c45b6935
Add provisional branding which is subject to change 2024-08-28 20:14:52 -04:00
a608d852dd
Lint 2024-08-25 22:31:09 -04:00
49485b1040
Allow bot owners to disable user settings 2024-08-25 22:27:39 -04:00
0147badad3
Remove settings location from example settings 2024-08-25 22:26:51 -04:00
cb4aa5a818
Hide hidden commands within specific command help 2024-08-25 22:26:33 -04:00
f6b2365ccd
Fix end portal bug with packets 2024-08-25 22:26:10 -04:00
314cfc9f85
Lint 2024-08-25 22:26:03 -04:00
831ed85c00
Add anti-spam system 2024-08-25 22:25:08 -04:00
2e19b33053
Add disable of incoming netmsg 2024-08-25 22:23:15 -04:00
e4dffbaad9
Make the name field in options useful (netmsg) 2024-08-25 07:12:23 -04:00
00a2a4f48f
Remove "Dev" label 2024-08-25 07:11:23 -04:00
5b4b7e8958
Disable parsing attempts for 4/8 bits 2024-08-25 07:10:49 -04:00
a473d15d4e
This is not a pre-release branch 2024-08-23 10:56:42 -04:00
60b2ba83e3
Serverinfo bugfix 2024-08-23 10:54:43 -04:00
21 changed files with 238 additions and 145 deletions

View file

@ -1,28 +1,30 @@
# 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
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 added any exploits 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 whenever I see it.
## 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 +32,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 |

View file

@ -112,7 +112,7 @@ const aboutServer = function (c) {
text: thisItem,
color: c.colors.primary,
clickEvent: {
action: "copy_to_clipboard",
action: 'copy_to_clipboard',
value: thisItem
},
hoverEvent: {
@ -201,10 +201,10 @@ const aboutServer = function (c) {
}
const displayServerList = function (c) {
index.bot.forEach((item, i)=>{
index.bot.forEach((item, i) => {
if (item.host.options && item.host.options.hidden && c.verify !== 3 && c.bot.id !== i) return
let message = 'command.about.serverListItem';
if(c.bot.id == i) message = 'command.about.serverListItem.thisServer'
let message = 'command.about.serverListItem'
if (c.bot.id === i) message = 'command.about.serverListItem.thisServer'
c.reply({
translate: getMessage(c.lang, message),
color: c.colors.secondary,
@ -217,7 +217,7 @@ const displayServerList = function (c) {
text: `${item.host.host}:${item.host.port}`,
color: c.colors.primary,
clickEvent: {
action: "copy_to_clipboard",
action: 'copy_to_clipboard',
value: `${item.host.host}:${item.host.port}`
},
hoverEvent: {
@ -239,10 +239,11 @@ const displayServerList = function (c) {
module.exports = {
execute: function (c) {
let subcmd = c.args[0]
if(subcmd === "servers") subcmd = "serverlist"
if(c.cmdName === "serverinfo") subcmd = "server"
if(c.cmdName === "serverlist" || c.cmdName === "servers") subcmd = "serverlist"
let subcmd
if (c.args.length >= 1) subcmd = c.args[0].toLowerCase()
if (subcmd === '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 +252,5 @@ module.exports = {
aboutBot(c)
}
},
aliases: ['info', 'serverlist', 'servers', 'serverinfo']
aliases: ['info', 'serverlist', 'servers', 'serverinfo', 'specs']
}

View 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])
@ -44,7 +45,7 @@ module.exports = {
break
}
case 'list':
c.bot.cloops.forEach((item, i)=>{
c.bot.cloops.forEach((item, i) => {
c.reply({
translate: getMessage(c.lang, 'command.cloop.list'),
color: c.colors.secondary,

View file

@ -65,8 +65,9 @@ const printHelp = (c) => {
}
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
}

View file

@ -2,29 +2,39 @@ const { bot } = require('../index.js')
const { getMessage } = require('../util/lang.js')
module.exports = {
execute: (c) => {
if (c.bot.host && c.bot.host.options.hidden) {
c.reply({
text: getMessage(c.lang, 'command.netmsg.disabled'),
color: c.colors.secondary
})
return
let host = c.host
let port = c.port
if (c.bot.host.options && c.bot.host.options.hidden) {
host = 'localhost' // Makes hidden servers appear as localhost
port = '25565'
}
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
text: c.serverName,
hoverEvent: {
action: 'show_text',
value: {
translate: '%s: %s:%s',
with: [
{
text: getMessage(c.lang, 'command.netmsg.serverAddress'),
color: c.colors.primary
},
{
text: host,
color: c.colors.primary
},
{
text: port + '',
color: c.colors.primary
}
],
color: c.colors.secondary
}
],
color: c.colors.secondary
},
color: c.colors.primary
},
{
text: c.username,
@ -37,7 +47,7 @@ module.exports = {
color: 'white'
}
bot.forEach(item => {
if (item.host.options.hidden) return
if (item.host.options && item.host.options.netmsgIncomingDisabled && c.type !== 'console') return
item.tellraw('@a', json)
})
}

View file

@ -1,15 +1,24 @@
const { languages, getMessage } = require('../util/lang.js')
const fs = require('fs')
const settings = require('../settings.json')
module.exports = {
execute: (c) => {
if(c.type == "console"){
if (c.type === 'console') {
c.reply({
text: getMessage(c.lang, 'command.settings.disabled.console'),
color: c.colors.secondary
})
return
}
const subcmd = c.args.splice(0, 1)[0]
if (settings.userSettingsDisabled) {
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']

View file

@ -14,7 +14,7 @@ module.exports = {
text: item,
color: c.colors.primary,
clickEvent: {
action: "copy_to_clipboard",
action: 'copy_to_clipboard',
value: item
},
hoverEvent: {

View file

@ -1,14 +1,14 @@
const fs = require('fs')
if (!fs.readdirSync('.').includes('settings.json')) {
console.log("Settings file is missing, using defaults.")
fs.copyFileSync("settings_example.json", "settings.json")
console.log('Settings file is missing, using defaults.')
fs.copyFileSync('settings_example.json', '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('Secrets file is missing, using defaults.')
fs.copyFileSync('secret_example.json', 'secret.json')
console.log('Please change the hashing keys in the secrets file.')
}
const m = require('minecraft-protocol')

View 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,16 +32,18 @@
"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.",
@ -64,6 +67,7 @@
"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.netmsg.serverAddress": "Server Address",
"command.settings.disabled.console": "This command cannot be run from the console.",
"command.settings.get.colorPrimary": "Primary color",
"command.settings.get.colorSecondary": "Secondary color",

6
package-lock.json generated
View file

@ -37,9 +37,9 @@
}
},
"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.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz",
"integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"

View file

@ -2,15 +2,16 @@ 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 convertChatStyleItem = (item) => {
let output={};
for(const i in item){
const output = {}
for (const i in item) {
output[i] = item[i].value
}
return output;
return output
}
const convertChatTypeItem = (item) => {
if(item.style){
if (item.style) {
return {
translation_key: item.translation_key.value,
parameters: item.parameters.value.value,
@ -26,11 +27,16 @@ const convertChatTypeItem = (item) => {
}
module.exports = {
load: (b) => {
b.messageTypes = [];
b._client.on("registry_data",(data)=>{
if(data.codec.value['minecraft:chat_type']){
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']) {
b.messageTypes = data.codec.value['minecraft:chat_type']
const nbtItems = data.codec.value['minecraft:chat_type'].value.value.value.value;
const nbtItems = data.codec.value['minecraft:chat_type'].value.value.value.value
nbtItems.forEach((item, i) => {
b.messageTypes[i] = convertChatTypeItem(item.element.value.chat.value)
})
@ -38,24 +44,24 @@ module.exports = {
})
b._client.on('profileless_chat', (data) => {
const messageType = b.messageTypes[data.type]
let json = {translate: messageType.translation_key, with: []}
messageType.parameters.forEach((item, i)=>{
if(item == "content"){
const json = { translate: messageType.translation_key, with: [] }
messageType.parameters.forEach((item, i) => {
if (item === 'content') {
json.with[i] = parse1204(data.message)
} else if(item == "sender"){
} else if (item === 'sender') {
json.with[i] = parse1204(data.name)
} else if(item == "target"){
} else if (item === 'target') {
json.with[i] = parse1204(data.target)
}
})
for(const i in messageType.style){
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") {
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]
@ -63,7 +69,7 @@ module.exports = {
nickname = chatNameSplit[chatNameSplit.length - 1]
username = b.findRealName(chatName)
uuid = b.findUUID(username)
message = split.join(": ")
message = split.join(': ')
} else {
message = parsePlain(parse1204(data.message))
uuid = b.findUUID(parsePlain(parse1204(data.name)))
@ -71,7 +77,7 @@ module.exports = {
username = parsePlain(parse1204(data.name))
}
b.emit('chat', {
json: json,
json,
type: 'profileless',
uuid,
message,
@ -82,25 +88,25 @@ module.exports = {
b._client.on('player_chat', (data) => {
const messageType = b.messageTypes[data.type]
let json = {translate: messageType.translation_key, with: []}
messageType.parameters.forEach((item, i)=>{
if(item == "content"){
if(messageType.translation_key === "%s"){
const json = { translate: messageType.translation_key, with: [] }
messageType.parameters.forEach((item, i) => {
if (item === 'content') {
if (messageType.translation_key === '%s') {
json.with[i] = parse1204(data.unsignedChatContent)
} else {
json.with[i] = data.plainMessage
}
} else if(item == "sender"){
} else if (item === 'sender') {
json.with[i] = parse1204(data.networkName)
} else if(item == "target"){
} else if (item === 'target') {
json.with[i] = parse1204(data.networkTargetName)
}
})
for(const i in messageType.style){
for (const i in messageType.style) {
json[i] = messageType.style[i]
}
b.emit('chat', {
json: json,
json,
type: 'player',
uuid: data.senderUuid,
message: data.plainMessage,
@ -111,21 +117,60 @@ module.exports = {
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', {
json,
type: 'system',
uuid,
message: split.join(': '),
nickname,
username
})
if (json.translate === '%s %s %s') { // ChipmunkMod format
if (json.with && json.with[1] && json.with[2]) {
const username = parsePlain(json.with[1])
const uuid = b.findUUID(username)
const nickname = b.findDisplayName(uuid)
const message = parsePlain(json.with[2].extra)
b.emit('chat', {
json,
type: 'system',
uuid,
message,
nickname,
username
})
} else {
b.emit('chat', {
json,
type: 'system',
uuid: '00000000-0000-0000-0000-000000000000',
message: '',
nickname: '',
username: ''
})
}
} else if (json.extra && json.extra[4] && json.extra[3] && json.extra[5] && json.extra[4].text === ' » ') { // ChipmunkMod format - m_c_player
const username = parsePlain(json.extra[3])
const uuid = b.findUUID(username)
const nickname = b.findDisplayName(uuid)
const message = parsePlain(json.extra[5])
b.emit('chat', {
json,
type: 'system',
uuid,
message,
nickname,
username
})
} else { // Generic system chat format
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', {
json,
type: 'system',
uuid,
message: split.join(': '),
nickname,
username
})
}
})
b._client.on('chat', (data) => { // Legacy chat for versions <1.19
@ -136,7 +181,19 @@ module.exports = {
let username
let message
let uuid
if (b.host.options.isVanilla && json.translate === 'chat.type.text') { // Servers without Extras chat
if (json.translate === '%s %s %s') { // ChipmunkMod format
if (json.with && json.with[1] && json.with[2]) {
username = parsePlain(json.with[1])
uuid = b.findUUID(username)
nickname = b.findDisplayName(uuid)
message = parsePlain(json.with[2].extra)
}
} else if (json.extra && json.extra[4] && json.extra[3] && json.extra[5] && json.extra[4].text === ' » ') { // ChipmunkMod format - m_c_player
username = parsePlain(json.extra[3])
uuid = b.findUUID(username)
nickname = b.findDisplayName(uuid)
message = parsePlain(json.extra[5])
} else 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])
@ -163,6 +220,13 @@ module.exports = {
})
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)
@ -170,14 +234,6 @@ module.exports = {
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)
}
}
})
}
}

View file

@ -5,11 +5,15 @@ 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.userSettingsDisabled) fs.mkdirSync('userPref')
const loadSettings = function (uuid) {
try {
return require(`../userPref/${uuid}.json`)
if (settings.userSettingsDisabled) {
return {}
} else {
return require(`../userPref/${uuid}.json`)
}
} catch (e) {
return {}
}
@ -18,6 +22,15 @@ module.exports = {
load: (b) => {
b.prefix = settings.prefix
b.lastCmd = 0
b.on('chat', (data) => {
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.runCommand = (name, nickname, uuid, text, msgType, prefix) => {
if (uuid === '00000000-0000-0000-0000-000000000000') return
if (Date.now() - b.lastCmd <= 1000) return

View file

@ -58,7 +58,7 @@ module.exports = {
})
}
// Gamemode
// Gamemode / end portal bug
b.add_sc_task('gamemode', () => {
b.chat('/minecraft:gamemode creative')
})
@ -67,6 +67,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
}
})

View file

@ -1,5 +1,4 @@
{
"secret":"/path/to/secrets/file/secret.json",
"version_mc": "1.20.4",
"defaultLang": "en-US",
"terminalMode": "blackTerminal_24bit",

View file

@ -16,6 +16,7 @@ class Command {
this.verify = verify
this.host = bot.host.host
this.port = bot.host.port
this.serverName = bot.host.options.name
this.prefs = prefs
if (prefs.lang) {
this.lang = prefs.lang

View file

@ -1,13 +1,14 @@
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 = () => {}
this.reply = text => process.stdout.write(parse(text) + '\n')
this.uuid = 'dde5a2a6-ebdd-7bbb-8eac-f75b10c10446'
this.username = 'Owner'
this.nickname = 'Console'
this.nickname = 'Owner'
this.command = cmd
this.msgType = '_bot_console'
this.prefix = ''
@ -20,6 +21,7 @@ class ConsoleCommand {
this.verify = 3
this.host = ''
this.port = '3'
this.serverName = `${version.botName} Console`
this.lang = settings.defaultLang
this.colors = settings.colors
}

View file

@ -13,9 +13,7 @@ if (_consoleColors[settings.terminalMode]) {
}
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 ''
}
if (!consoleColors24.enabled) return ''
let out = '\x1B[0;'
const redChannel = Number(`0x${color.slice(1, 3)}`)
const greenChannel = Number(`0x${color.slice(3, 5)}`)
@ -77,7 +75,7 @@ const parse = function (_data, l = 0, resetColor = consoleColors.reset) {
if (lang[trans] !== undefined) {
trans = lang[trans].replace(/%%/g, '\ue123')
}
if(data.with){
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'))

View file

@ -72,9 +72,7 @@
"reset": "\u001B[0;38;5;15m"
},
"twentyFourBit":{
"enabled": true,
"bit": 8,
"lightMode": false
"enabled": false
}
},
"whiteTerminal_8bit":{
@ -98,9 +96,7 @@
"reset": "\u001B[0;48;5;0;38;5;15m"
},
"twentyFourBit":{
"enabled": true,
"bit": 8,
"lightMode": true
"enabled": false
}
},
"blackTerminal_4bit":{
@ -124,9 +120,7 @@
"reset": "\u001B[0;1;37m"
},
"twentyFourBit":{
"enabled": true,
"bit": 4,
"lightMode": false
"enabled": false
}
},
"whiteTerminal_4bit":{
@ -150,9 +144,7 @@
"reset": "\u001B[0;40;1;37m"
},
"twentyFourBit":{
"enabled": true,
"bit": 4,
"lightMode": true
"enabled": false
}
},
"none":{

View file

@ -21,11 +21,11 @@ const getMessage = function (l, msg, with2) {
} else if (languages['en-US'] && languages['en-US'][message] !== undefined) {
message = languages['en-US'][message].replace(/%%/g, '\ue123')
}
if (with2){
for (const withItem of with2) {
if (with2) {
with2.forEach((withItem, i) => {
message = message.replace(/%s/, withItem.replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
message = message.replaceAll(`%${+i + 1}$s`, withItem.replace(/%s/g, '\ue124').replace(/\$s/g, '\ue125'))
}
})
}
return message.replace(/\ue123/g, '%').replace(/\ue124/g, '%s').replace(/\ue125/g, '$s')
}

View file

@ -32,12 +32,12 @@ const rsg = function (count) {
}
const rsgLegal = function (count) {
let output = ''
if(Math.random()>0.5){
output += "uwu_"
if (Math.random() > 0.5) {
output += 'uwu_'
} else {
output += "owo_"
output += 'owo_'
}
output += crypto.randomBytes(count).toString("hex")
output += crypto.randomBytes(count).toString('hex')
return output
}
module.exports = function (legal) {

View file

@ -1,7 +1,7 @@
{
"botName": "botvX Dev",
"botVersion": "10.0.0",
"botAuthor": "a5a06d596f15c7db",
"isPreRelease": true,
"sourceURL": "https://code.chipmunk.land/7cc5c4f330d47060/botvX"
}
"botName": "owobot",
"botVersion": "10.0.3",
"botAuthor": "SundanceNanshan",
"isPreRelease": false,
"sourceURL": "https://code.chipmunk.land/7cc5c4f330d47060/owobot"
}