v6.0.0-alpha
This commit is contained in:
commit
2d49c8003f
47 changed files with 3894 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
config.yml
|
||||
.git
|
||||
src/modules/exploits.js
|
80
Changelog.md
Normal file
80
Changelog.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
beta 0.1 - 0.2 0.5 release 2022 (first release)
|
||||
ParkerBot/DEMONBOT/Woomybot/Boyfriend
|
||||
ehh nothing much just the release of the betas
|
||||
--------------------------------------
|
||||
beta 1.0 release 1/25/23 codename: in console test.
|
||||
original commands:!cloop bcraw,!cloop sudo,!troll,!say,!op (broke),!deop (broke), !gms (broke),!freeze,!icu <--- these commands no longer can be used in game but in console for beta 1.0
|
||||
commands added: fake kick,ban,kick,crashserver,stop,gmc,greetin,test(broken idk),bypass,entity spam(broken idk),gms(broke),stop,tntspam (broke idk),prefix (not tested yet),annoy (broke results in a complete server crash keeping ayunboom down for 3 to 5 hours),freeze(i dont even know what this do since i cant do !freeze),crashserver,troll(more destructive),trol(more destructive),icu(broke idk),say,sudo,cloop
|
||||
-------------------------------------
|
||||
1.0 release 1/26/23 1:47am codename:
|
||||
FNFBoyfriendBot.
|
||||
commands added: BOOM,deop,troll and trol(added extra code to both commands),kaboom,serverdeop,
|
||||
commands fixed:tp,gms,annoy(attemps to crash the server but not as bad as it was)
|
||||
commands untested:prefix
|
||||
command Broke:icu,freeze,tntspam,entityspam,tntspam?
|
||||
changed name to &b &lFNFBoyfriendBot may change later idk
|
||||
-------------------------------------
|
||||
1.0 revision 1 release 1/26/23 2:00pm
|
||||
codename revision 1.
|
||||
reworked the kaboom command and fixed the description commands but thats about it. also reworked the greeting command
|
||||
--------------------------------------
|
||||
1.1 release 1/28/23 1:51
|
||||
nothing much just added extra stuff to the troll, trol and that is about it
|
||||
-------------------------------------
|
||||
1.2 release 1/30/32 no codename
|
||||
for ppl me making me really mad -.- got released early
|
||||
--------------------------------------
|
||||
|
||||
|
||||
2.0 2/07/23 8:01pm codename: Major
|
||||
added DREAMSTANALERT,technoblade,GODSWORD,KFC,MYLEG,OHHAIL,altcrash,MyHead
|
||||
Reworked tntspam,entityspam,soundbreaker
|
||||
added Spim to the whitelist of the bot
|
||||
released too early than it was planned gonna be released due do the code almost leaked it had to be released early
|
||||
--------------------------------------
|
||||
|
||||
|
||||
2.1 release 2/11/23 5:30pm
|
||||
added: refillcore(had early prototypes of this was original), vanish,deop,cloopdeop,mute,cloopmute
|
||||
reworked: op (supposed to already op the bot but didnt work until this release) and reworked gmc (same problem with op)
|
||||
(had early prototypes of vanish,refillcore,gmc,and op but these were original gonna be automatic but after alot of attempts i said screw it and added 2 commands refillcore, and vanish reworked gmc and op and got them working finally) removed Spim because come to find out he couldnt be trusted
|
||||
--------------------------------------
|
||||
2.2 release 2/20/23 4:21pm central time
|
||||
bug fixes
|
||||
added ckill(added back after trial and error),serversuicidal
|
||||
changed username of the bot from hex code to FNFBoyfriendBot because hex code for the username was confusing as it changes everytime
|
||||
---------------------------------------
|
||||
3.0 Beta codename: blue-balled corruption
|
||||
was canceled due to ayunboom being rewriten and renamed to creayun barely usable on there because commands blocks are disabled which i created a bot for that server that has no command blocks https://replit.com/@Parker2991/FNFBoyfriendbotcreayun-bot-final-build#index.js just finished the final build of that bot due to chip announcing that he may make a kaboom clone yk what 1.5.2 and 1.8 support but anyway onto what is in the 3.0 beta well the beta for right now
|
||||
commands added:discord,version,online,list,iownyou,endmysuffering,wafflehouse,whopper,bcraw,destroycore
|
||||
Notes:the original say command was reworked into talking in chat without bcraw and command blocks which the bcraw chatting code is still in the bot but was reworked into the bcraw commmand. maybe some commands removed? i dont know yet edit there is 2 commands removed
|
||||
commands removed:tpe and serverdeop???
|
||||
reworked commands :say command for right now
|
||||
relay chat mabe will be added as a seperate repl i dont know yet possible would need a whole code rewrite for relay chat
|
||||
-----------------------------------------
|
||||
3.0 full release CodeName:Sky Remanifested
|
||||
the full release of 3.0 the rewrite has been pushed back to 4.0 due to 3.0 already pass its release date and the code i had on hand was done but the rewrite wasnt done
|
||||
Added: SelfCare
|
||||
Made during development:Relay chat prototypes for several servers
|
||||
---------------------
|
||||
3.0.5 release
|
||||
Bug fixes
|
||||
-----------
|
||||
3.0.9
|
||||
commands added:Help(finally added after about a year),consolelog(added cuz yes),cloopconsolelog(added cuz yes)
|
||||
-------------------
|
||||
4.0 beta Codename:FNFBoyfriendBot Ultimate
|
||||
all of the command removed and or rewriten from version 3.0.9
|
||||
Commands added or rewriten:ban,buyrealminecraft,cloop,discord,echo,errortest,freeze,help,icu,info,kick,bots,skids,romncitrash,say,selfdestruct,serversuicidal,sudo,test,trol,troll
|
||||
(note that this is different and is not CommandModules)Modules Added:discord,chat,chat_command_handler,command_manager,position,registry,reconnect,command_core
|
||||
CustomChats added:kaboom(for normal chat)
|
||||
(note that this is different and is not Modules)CommandModules Added:command_error,Command_source
|
||||
a beta release for rn
|
||||
-----------------------------
|
||||
4.0 Alpha Codename:FNFBoyfriendBot Ulitmate
|
||||
Commands added: calculator,ckill,evaljs,urban,crash,cloopcrash,core,list,ping,netmsg,skin,tpr
|
||||
Commands Removed:Buyrealminecraft
|
||||
(note that this is different and is not CommandModules)Modules Added:op selfcare,gmc selfcare,vanish selfcare,cspy selfcare,console
|
||||
(note that this is different and is not Modules)CustomChats Added:u2O3a(for custom chat)
|
||||
added util with between(for urban) eval_colors(for evaljs)
|
||||
----------------------------------
|
0
README.md
Normal file
0
README.md
Normal file
1960
package-lock.json
generated
Normal file
1960
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
13
package.json
Normal file
13
package.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"discord.js": "^14.11.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jvm": "^0.5.3",
|
||||
"man-db": "^1.0.3",
|
||||
"minecraft-data": "^3.36.1",
|
||||
"minecraft-protocol": "^1.47.0",
|
||||
"prismarine-auth": "^2.2.0",
|
||||
"prismarine-chat": "^1.10.1",
|
||||
"prismarine-registry": "^1.7.0"
|
||||
}
|
||||
}
|
74
src/bot.js
Normal file
74
src/bot.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
const mc = require('minecraft-protocol')
|
||||
const { EventEmitter } = require('events')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
require("events").EventEmitter.defaultMaxListeners = Infinity;
|
||||
function createBot(options = {}) {
|
||||
const bot = new EventEmitter()
|
||||
bot.options = {
|
||||
// Set some default values in options
|
||||
host: options.host ??= 'localhost',
|
||||
username: options.username ??= 'Player',
|
||||
hideErrors: options.hideErrors ??= true, // HACK: Hide errors by default as a lazy fix to console being spammed with them
|
||||
};
|
||||
bot.options = options
|
||||
|
||||
// Create our client object, put it on the bot, and register some events
|
||||
bot.on('init_client', client => {
|
||||
client.on('packet', (data, meta) => {
|
||||
bot.emit('packet', data, meta)
|
||||
bot.emit('packet.' + meta.name, data)
|
||||
})
|
||||
|
||||
client.on('login', () => {
|
||||
bot.uuid = client.uuid
|
||||
bot.username = client.username
|
||||
})
|
||||
client.on('disconnect', (data) => {
|
||||
bot.emit("disconnect", data.reason)
|
||||
})
|
||||
client.on('end', reason => {
|
||||
bot.emit('end', reason);
|
||||
})
|
||||
|
||||
client.on('error', error => {
|
||||
// bot.emit('error', error)
|
||||
console.log(error.toString())
|
||||
})
|
||||
|
||||
client.on("keep_alive", ({ keepAliveId }) => {
|
||||
bot.emit("keep_alive", { keepAliveId })
|
||||
})
|
||||
|
||||
client.on('kick_disconnect', (data) => {
|
||||
bot.emit("kick_disconnect", data.reason)
|
||||
})
|
||||
|
||||
process.on("uncaughtException", (e) => {
|
||||
console?.warn(e.stack)
|
||||
});
|
||||
})
|
||||
|
||||
const client = options.client ?? mc.createClient(options)
|
||||
bot._client = client
|
||||
bot.emit('init_client', client)
|
||||
|
||||
bot.bots = options.bots ?? [bot]
|
||||
|
||||
// Modules
|
||||
/*
|
||||
bot.loadModule = module => module(bot, options)
|
||||
|
||||
for (const filename of fs.readdirSync(path.join(__dirname, 'modules'))) {
|
||||
try {
|
||||
const module = require(path.join(__dirname, 'modules', filename))
|
||||
bot.loadModule(module)
|
||||
} catch (error) {
|
||||
console.error('Failed to load module', filename, ':', error)
|
||||
}
|
||||
}
|
||||
*/
|
||||
return bot
|
||||
}
|
||||
|
||||
module.exports = createBot
|
199
src/commands/bots.js
Normal file
199
src/commands/bots.js
Normal file
|
@ -0,0 +1,199 @@
|
|||
// TODO: Maybe add more authors
|
||||
const bots = [
|
||||
{
|
||||
name: { text: 'HBot', color: 'aqua', bold:true },
|
||||
authors: ['hhhzzzsss'],
|
||||
exclaimer:'HBOT HARRYBUTT LMAOOOOOOOOOOOOOOOOO',
|
||||
foundation: 'java/mcprotocollib',
|
||||
prefixes: ['#']
|
||||
},
|
||||
{
|
||||
name: [{ text: 'Evil', color: 'dark_red' }, {text:'Bot', color:'dark_purple'}],
|
||||
authors: ['FusseligerDev'],
|
||||
exclaimer:'',
|
||||
foundation: 'Java/Custom',
|
||||
prefixes: ['!']
|
||||
},
|
||||
{
|
||||
name: { text: 'SBot Java', color: 'white', bold:true }, // TODO: Gradient
|
||||
authors: ['evkc'],
|
||||
foundation: 'Java/MCProtocolLib',
|
||||
prefixes: [':']
|
||||
},
|
||||
{
|
||||
name: { text: 'SBot Rust', color: 'white', bold:true }, // TODO: Gradient
|
||||
authors: ['evkc'],
|
||||
foundation: 'Rust',
|
||||
prefixes: ['re:']
|
||||
},
|
||||
{
|
||||
name: { text: 'Z-Boy-Bot', color: 'dark_purple' }, // TODO: Gradient
|
||||
exclaimer: 'Most likely skidded along with kbot that the dev used',
|
||||
authors: ['Romnci'],
|
||||
foundation: 'NodeJS/mineflayer or Java/mcprotocollib idfk',
|
||||
prefixes: ['Z]']
|
||||
},
|
||||
{
|
||||
name: { text: 'ABot', color: 'gold', bold:true }, // TODO: Gradient
|
||||
exclaimer: '',
|
||||
authors: ['yfd'],
|
||||
foundation: 'NodeJS/Node-Minecraft-Protocol',
|
||||
prefixes: ['<']
|
||||
},
|
||||
{
|
||||
name: { text: 'FardBot', color: 'dark_purple' },
|
||||
authors: ['_yfd'],
|
||||
exclaimer: 'bot is dead lol',
|
||||
foundation: 'NodeJS/Mineflayer',
|
||||
prefixes: ['<']
|
||||
},
|
||||
|
||||
{
|
||||
name: { text: 'ChipmunkBot', color: 'green' },
|
||||
authors: ['_ChipMC_'],
|
||||
exclaimer: 'chips? also shoutout to chip and chayapak for helping in the rewrite',
|
||||
|
||||
foundation: 'Java/MCProtocolLib',
|
||||
prefixes: ["'", "/'"]
|
||||
},
|
||||
{
|
||||
name: { text: 'ChipmunkBot Old', color: 'green' },
|
||||
authors: ['_ChipMC_'],
|
||||
foundation: 'NodeJS/Node-Minecraft-Protocol',
|
||||
|
||||
},
|
||||
{
|
||||
name: { text: 'TestBot', color: 'aqua' },
|
||||
authors: ['Blackilykat'],
|
||||
foundation: 'Java/MCProtocolLib',
|
||||
prefixes: ["-"]
|
||||
},
|
||||
{
|
||||
name: { text: 'UBot', color: 'grey' },
|
||||
authors: ['HexWoman'],
|
||||
exclaimer: 'UwU OwO',
|
||||
|
||||
foundation: 'NodeJS/node-minecraft-protocol',
|
||||
prefixes: ['"']
|
||||
},
|
||||
{
|
||||
name: { text: 'ChomeNS Bot Java', color: 'yellow'},
|
||||
authors: ['chayapak'],
|
||||
exclaimer: 'wow its my bot !! ! 4374621q43567%^&#%67868-- chayapak',
|
||||
foundation: 'Java/MCProtocolLib',
|
||||
prefixes: ['*', 'cbot ', '/cbot ']
|
||||
},
|
||||
{
|
||||
name: { text: 'ChomeNS Bot NodeJS', color: 'yellow'},
|
||||
authors: ['chayapak'],
|
||||
|
||||
foundation: 'NodeJS/Node-Minecraft-Protocol',
|
||||
prefixes: ['*', 'cbot', '/cbot']
|
||||
},
|
||||
{
|
||||
name: { text: 'RecycleBot', color: 'dark_green'},
|
||||
foundation: ['MorganAnkan'],
|
||||
exclaimer: 'nice bot',
|
||||
language: 'NodeJS/node-minecraft-protocol',
|
||||
prefixes: ['=']
|
||||
},
|
||||
{
|
||||
name: { text: 'ManBot', color: 'dark_green' , },
|
||||
exclaimer: '(more like men bot :skull:) OH HAAAAAAAAAAAAAAIIILL LOGINTIMEDOUT',
|
||||
authors: ['Man/LogintimedOut'],
|
||||
foundation: 'NodeJS/mineflayer',
|
||||
prefixes: ['(Note:I dont remember!!)']
|
||||
},
|
||||
{
|
||||
name: [{ text: 'Useless', color: 'red', bold:false}, { text: 'Bot', color: 'gray', bold:false}],
|
||||
exclaimer: 'it isnt useless its a good bot................',
|
||||
authors: ['IuCC'],
|
||||
foundation: 'NodeJS/node-minecraft-protocol',
|
||||
prefixes: ['[']
|
||||
},
|
||||
{
|
||||
name: [{ text: 'Blurry', color: 'dark_purple'}, { text: 'Bot', color: 'red' }],
|
||||
exclaimer: '',
|
||||
authors: ['SirLennox'],
|
||||
foundation: 'Java/custom',
|
||||
prefixes: [',']
|
||||
},
|
||||
{
|
||||
name: [{ text: 'KittyCorp', color: 'yellow' }, { text: 'Bot', color: 'yellow' }],
|
||||
exclaimer: '3 words ginlang is gay',
|
||||
authors: ['ginlang , G6_, ArrayBuffer, and i guess more??'],
|
||||
foundation: 'NodeJS/node-minecraft-protocol',
|
||||
prefixes: ['^']
|
||||
},
|
||||
|
||||
{
|
||||
name: [{ text:'FNF', color: 'dark_purple', bold: true}, {text:'Boyfriend', color: 'aqua', bold:true}, {text:'Bot', color:'dark_red', bold:true}, {text:'X', color:'black', bold:true}],
|
||||
authors: [{ text:'Parker2991', color: 'dark_red'}, {text:' _ChipMC_', color: 'dark_green', bold:true}, {text:' chayapak', color:'yellow', bold:true}],
|
||||
exclaimer: '4.0 (this Bot) also the Ultimate version of the FNFBoyfriendBot Builds',
|
||||
foundation: 'NodeJS/node-minecraft-protocol',
|
||||
prefixes: ['~']
|
||||
},
|
||||
{
|
||||
name: [{ text:'FNF', color: 'dark_purple', bold: true}, {text:'Boyfriend', color: 'aqua', bold:true}, {text:'Bot', color:'dark_red', bold:true}, {text:' Legacy', color:'green', bold:true}],
|
||||
authors: [{text:'Parker2991', color:'dark_red' }, {text:' _ChipMC_', color:'dark_green', bold:true }],
|
||||
exclaimer:'1037 LINES OF CODE WTFARD!??! also this version is in console commands only' ,
|
||||
foundation: 'NodeJS/mineflayer',
|
||||
prefixes: []
|
||||
}
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
name: 'bots',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
"knownbots"
|
||||
],
|
||||
description: 'A list of known bots',
|
||||
usages: [
|
||||
'<bot>',
|
||||
],
|
||||
execute (context) {
|
||||
const query = context.arguments.join(' ').toLowerCase()
|
||||
const source = context.source;
|
||||
const bot = context.bot;
|
||||
if (query.length === 0) {
|
||||
const list = []
|
||||
|
||||
for (const info of bots) {
|
||||
if (list.length !== 0) list.push({ text: ', ', color: 'gray' })
|
||||
list.push(info.name)
|
||||
}
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, ['Known bots (', bots.length, ') - ', ...list], false)
|
||||
return
|
||||
}
|
||||
|
||||
for (const info of bots) {
|
||||
const plainName = String(context.bot.getMessageAsPrismarine(info.name)).toLowerCase()
|
||||
if (plainName.includes(query)) this.sendBotInfo(info, context.bot)
|
||||
}
|
||||
},
|
||||
|
||||
sendBotInfo (info, bot) {
|
||||
const component = ['']
|
||||
component.push('Name: ', info.name)
|
||||
if (info.exclaimer) component.push('\n', 'Exclaimer: ', info.exclaimer)
|
||||
if (info.authors && info.authors.length !== 0) {
|
||||
component.push('\n', 'Authors: ')
|
||||
for (const author of info.authors) {
|
||||
component.push(author, { text: ', ', color: 'gray' })
|
||||
}
|
||||
component.pop()
|
||||
}
|
||||
if (info.foundation) component.push('\n', 'Foundation: ', info.foundation)
|
||||
if (info.prefixes && info.prefixes.length !== 0) {
|
||||
component.push('\n', 'Prefixes: ')
|
||||
for (const prefix of info.prefixes) {
|
||||
component.push(prefix, { text: ', ', color: 'gray' })
|
||||
}
|
||||
component.pop()
|
||||
}
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, [component])
|
||||
}
|
||||
}//it doing it just for the ones i added lol
|
||||
// prob a replit moment, it probably thinks there are regexes in the strings
|
77
src/commands/cloop.js
Normal file
77
src/commands/cloop.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
module.exports = {
|
||||
name: 'cloop',
|
||||
trustLevel: 1,
|
||||
aliases: [
|
||||
"commandloop"
|
||||
],
|
||||
description: 'run cloops',
|
||||
execute (context) {
|
||||
const args = context.arguments
|
||||
const bot = context.bot
|
||||
const source = context.source
|
||||
if (!args && !args[0] && !args[1] && !args[2] && !args[3]) return
|
||||
switch (args[1]) {
|
||||
case 'add':
|
||||
if (parseInt(args[2]) === NaN) bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: 'Invalid interval', color: 'red' })
|
||||
const interval = parseInt(args[2])
|
||||
const command = args.slice(3).join(' ');
|
||||
bot.cloop.add(command, interval)
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, {
|
||||
translate: 'Added \'%s\' with interval %s to the cloops',
|
||||
with: [ command, interval ]
|
||||
})
|
||||
break
|
||||
case 'remove':
|
||||
if (parseInt(args[2]) === NaN) bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: 'Invalid index', color: 'red' })
|
||||
|
||||
const index = parseInt(args[2])
|
||||
|
||||
bot.cloop.remove(index)
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, {
|
||||
translate: 'Removed cloop %s',
|
||||
with: [ index ]
|
||||
})
|
||||
break
|
||||
case 'clear':
|
||||
bot.cloop.clear()
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: 'Cleared all cloops' })
|
||||
break
|
||||
case 'list':
|
||||
const component = []
|
||||
|
||||
const listComponent = []
|
||||
let i = 0
|
||||
for (const cloop of bot.cloop.list) {
|
||||
listComponent.push({
|
||||
translate: '%s \u203a %s (%s)',
|
||||
with: [
|
||||
i,
|
||||
cloop.command,
|
||||
cloop.interval
|
||||
]
|
||||
})
|
||||
listComponent.push('\n')
|
||||
|
||||
i++
|
||||
}
|
||||
|
||||
listComponent.pop()
|
||||
|
||||
component.push({
|
||||
translate: 'Cloops (%s):',
|
||||
with: [ bot.cloop.list.length ]
|
||||
})
|
||||
component.push('\n')
|
||||
component.push(listComponent)
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, component)
|
||||
break
|
||||
default:
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: 'Invalid action', color: 'red' })
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
33
src/commands/console.js
Normal file
33
src/commands/console.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
module.exports = {
|
||||
name: 'console',
|
||||
trustLevel: 3,
|
||||
aliases: [
|
||||
|
||||
],
|
||||
execute (context) {
|
||||
const bot = context.bot
|
||||
const args = context.arguments;
|
||||
const source = context.source;
|
||||
if (!args && !args[0] && !args[1] && !args[2] && !args[3]) return;
|
||||
switch (args[0]) {
|
||||
case "consoleserver":
|
||||
case "csvr":
|
||||
const servers = bot.bots.map(eachBot => eachBot.options.host);
|
||||
for (const eachBot of bot.bots) {
|
||||
if (args.slice(1).join(' ').toLowerCase() === 'all') {
|
||||
eachBot.console.consoleServer = 'all'
|
||||
bot.console.log("Set the console server to all");
|
||||
continue
|
||||
}
|
||||
const server = servers.find(server => server.toLowerCase().includes(args[1]))
|
||||
if (!server) {
|
||||
bot.console.log("Invalid server");
|
||||
return
|
||||
}
|
||||
bot.console.log(`Set the console server to ` + server);
|
||||
eachBot.console.consoleServer = server;
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
21
src/commands/core.js
Normal file
21
src/commands/core.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
|
||||
module.exports = {
|
||||
name: 'core',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
"cb",
|
||||
"corerun",
|
||||
"commandcorerun",
|
||||
],
|
||||
description: 'run commands in core!',
|
||||
execute (context) {
|
||||
const bot = context.bot
|
||||
const message = context.arguments.join(' ')
|
||||
if (message.startsWith('/')) {
|
||||
bot.core.run(message.substring(1))
|
||||
return
|
||||
}
|
||||
bot.core.run(message)
|
||||
}
|
||||
}
|
9
src/commands/discord.js
Normal file
9
src/commands/discord.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
|
||||
module.exports = {
|
||||
name: 'discord',
|
||||
trustLevel: 0,
|
||||
execute (context) {
|
||||
bot.tellraw(context.bot.discord.invite, false)
|
||||
}
|
||||
}
|
19
src/commands/echo.js
Normal file
19
src/commands/echo.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
module.exports = {
|
||||
name: 'echo',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
"say",
|
||||
"botsay",
|
||||
],
|
||||
description: 'Make me say something',
|
||||
execute (context) {
|
||||
const bot = context.bot
|
||||
const message = context.arguments.join(' ')
|
||||
|
||||
if (message.startsWith('/')) {
|
||||
bot.chat.command(message.substring(1))
|
||||
return
|
||||
}
|
||||
bot.chat.message(message)
|
||||
}
|
||||
}
|
10
src/commands/errortest.js
Normal file
10
src/commands/errortest.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
|
||||
module.exports = {
|
||||
name: 'errortest',
|
||||
trustLevel: 0,
|
||||
execute (context) {
|
||||
const message = context.arguments.join(' ')
|
||||
throw new Error(message)
|
||||
}
|
||||
}
|
93
src/commands/help.js
Normal file
93
src/commands/help.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
/*
|
||||
pub_lickColor: "#2b7589"
|
||||
t_rustedColor: "#219696"
|
||||
own_herColor: "#2081c3"
|
||||
*/
|
||||
module.exports = {
|
||||
name: 'help',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
"heko",
|
||||
"?",
|
||||
"cmds",
|
||||
],
|
||||
description: 'a list of the bots commands',
|
||||
execute (context) {
|
||||
const commandList = [];
|
||||
const bot = context.bot;
|
||||
const source = context.source;
|
||||
const args = context.arguments;
|
||||
const selector = '@a';
|
||||
console.log(source)
|
||||
const category = {
|
||||
translate: '(%s%s%s%s%s) \u203a ',
|
||||
bold: false,
|
||||
color: 'gray',
|
||||
with: [
|
||||
{ color: "blue", text: 'Public'},
|
||||
{ color: "gray", text: ' | '},
|
||||
{ color: "dark_aqua", text: 'Trusted'},
|
||||
{ color: 'gray', text: ' | '},
|
||||
{ color: "dark_blue", text: 'Owner'},
|
||||
]
|
||||
}
|
||||
let public = [];
|
||||
let trusted = [];
|
||||
let owner = [];
|
||||
for (const command of bot.commandManager.commandlist) {
|
||||
console.log(command.name)
|
||||
if (args[0] === command.name) {
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, [
|
||||
{
|
||||
text: `CommandName \u203a ${command.name}\n`,
|
||||
color: 'gray',
|
||||
},
|
||||
{
|
||||
text: `Aliases \u203a ${command.aliases}\n`,
|
||||
color: 'gray',
|
||||
},
|
||||
{
|
||||
text: `Description \u203a ${command.description}`,
|
||||
color: 'gray',
|
||||
}
|
||||
]);
|
||||
return
|
||||
}
|
||||
if (command.trustLevel === 0) {
|
||||
public.push([
|
||||
{
|
||||
text: command.name + ' ',
|
||||
color: "blue",
|
||||
}
|
||||
])
|
||||
} else if (command.trustLevel === 1) {
|
||||
trusted.push([
|
||||
{
|
||||
text: command.name + ' ',
|
||||
color: "dark_aqua"
|
||||
}
|
||||
])
|
||||
} else if (command.trustLevel === 2) {
|
||||
owner.push([
|
||||
{
|
||||
text: command.name + ' ',
|
||||
color: "dark_blue"
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
const length = bot.commandManager.commandlist.filter(c => c.trustLevel != 3).length
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, [
|
||||
{ text: 'Commands (', color: 'gray' },
|
||||
{ text: JSON.stringify(length), color: 'gold' },
|
||||
{ text: ') ', color: 'gray' },
|
||||
category,
|
||||
public,
|
||||
trusted,
|
||||
owner
|
||||
])
|
||||
// bot.tellraw([ public, trusted, owner ])
|
||||
}
|
||||
}
|
||||
|
35
src/commands/info.js
Normal file
35
src/commands/info.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
module.exports = {
|
||||
name: 'info',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
"information",
|
||||
],
|
||||
description: 'check the bots info',
|
||||
execute (context) {
|
||||
const bot = context.bot;
|
||||
const args = context.arguments;
|
||||
const config = context.config;
|
||||
const discordClient = context.discordClient;
|
||||
const source = context.source;
|
||||
switch (args[0]) {
|
||||
case 'version':
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, `§9Friday §9Night §9Funkin §3Boyfriend §1Bot§8§r-v6.0.0-alpha-700-§bSk§4y §bRedux\n11/22/22 - ${new Date().toLocaleDateString("en-US", { timeZone: "America/CHICAGO" })}`);
|
||||
break // &9 &3 &1
|
||||
case 'login':
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, [
|
||||
{
|
||||
text: `Minecraft username \u203a ${bot.options.username}\n`,
|
||||
color: 'gray',
|
||||
},
|
||||
{
|
||||
text: `Discord username \u203a ${discordClient.user.tag}`,
|
||||
color: 'gray',
|
||||
}
|
||||
]);
|
||||
break;
|
||||
case 'discord':
|
||||
bot.tellraw('@a', config.discord.invite)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
51
src/commands/list.js
Normal file
51
src/commands/list.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
const { EmbedBuilder } = require('discord.js')
|
||||
const { request } = require('undici');
|
||||
module.exports = {
|
||||
name: 'list',
|
||||
description:['check the player list'],
|
||||
trustLevel: 0,
|
||||
aliases:['playerlist', 'plist', 'pl'],
|
||||
usage:[""],
|
||||
async execute (context) {
|
||||
const bot = context.bot
|
||||
const args = context.arguments
|
||||
const players = bot.players
|
||||
const source = context.source
|
||||
const component = []
|
||||
const url = await request(`https://eu.mc-api.net/v3/server/ping/${bot.options.host}`)
|
||||
const server = await url.body.json()
|
||||
for (const player of players) {
|
||||
component.push({
|
||||
translate: `%s \u203a %s [%s %s %s %s %s]`,
|
||||
with: [
|
||||
player.displayName ?? player.profile.name,
|
||||
player.uuid,
|
||||
{ text: `Ping:`, color: 'dark_green' },
|
||||
{ text: `${player.latency}`, color: 'gold' },
|
||||
{ text: '/', color: 'gray' },
|
||||
{ text: `Gamemode:`, color: 'dark_purple' },
|
||||
{ text: `${player.gamemode}`, color: 'gold' },
|
||||
]
|
||||
})
|
||||
component.push('\n')
|
||||
}
|
||||
component.pop()
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, [
|
||||
{ text: `Players: `, color:'gray' },
|
||||
{ text: '(' , color: 'gray' },
|
||||
{ text: `${JSON.stringify(bot.players.length)}`, color: 'gold' },
|
||||
{ text: ` / `, color: 'gray' },
|
||||
{ text: `${server.players.max}`, color: 'gold' },
|
||||
{ text: ')\n', color: 'gray' },
|
||||
component
|
||||
])
|
||||
// bot.tellraw(component)
|
||||
},
|
||||
discordExecute(context) {
|
||||
const bot = context.bot
|
||||
const players = bot.players
|
||||
}
|
||||
}
|
||||
//what is wi
|
||||
// IDK
|
61
src/commands/mcserver.js
Normal file
61
src/commands/mcserver.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
const { request } = require('undici');
|
||||
const CommandError = require('../util/command_error.js');
|
||||
module.exports = {
|
||||
name: 'mcserver',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
// "say",
|
||||
// "botsay",
|
||||
],
|
||||
description: 'look up minecraft server info',
|
||||
async execute (context) {
|
||||
const bot = context.bot;
|
||||
const discordClient = context.discordClient;
|
||||
const args = context.arguments;
|
||||
const source = context.source;
|
||||
try {
|
||||
const url = await request(`https://eu.mc-api.net/v3/server/ping/${args[0]}`)
|
||||
server = await url.body.json()
|
||||
console.log(server)
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, [
|
||||
{
|
||||
text: `Ip \u203a ${args[0]}\n`,
|
||||
color: 'gray'
|
||||
},
|
||||
{
|
||||
text: `Players \u203a ${server.players.online}/${server.players.max}\n`,
|
||||
color: 'gray'
|
||||
},
|
||||
{
|
||||
text: `Version \u203a ${server.version.name}\n`,
|
||||
color: 'gray',
|
||||
},
|
||||
{
|
||||
text: "Motd \u203a\n",
|
||||
color: 'gray',
|
||||
},
|
||||
server.description,
|
||||
])// error: 'Ping Failed',
|
||||
} catch (error) {
|
||||
if (error.toString() === "TypeError: Cannot read properties of undefined (reading 'online')") {
|
||||
bot.tellraw({ text: 'unable to ping server make sure the ip is correct', color: 'dark_red' })
|
||||
} else {
|
||||
bot.tellraw(error.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
try {
|
||||
const server = await request(`https://eu.mc-api.net/v3/server/ping/${interaction.options.getString('ip')}`);
|
||||
json = await server.body.json()
|
||||
console.log((json))
|
||||
const Embed = new EmbedBuilder()
|
||||
.setColor(`${config.colors.commands.embed}`)
|
||||
.setTitle(`${this.data.name} Command`)
|
||||
setDescription(
|
||||
`IP \u203a ${interaction.options.getString('ip')}\nPlayer Count \u203a ${json.players.online}/${json.players.max}\nOnline \u203a ${json.online}\n
|
||||
Version \u203a ${json.version.name}\nMotd \u203a ${JSON.stringify(json.description)}`)
|
||||
.setThumbnail(`${json.favicon}`)
|
||||
|
||||
*/
|
25
src/commands/netmsg.js
Normal file
25
src/commands/netmsg.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const CommandError = require('../util/command_error.js')
|
||||
module.exports = {
|
||||
name: 'netmsg',
|
||||
trustLevel: 0,
|
||||
aliases: [
|
||||
|
||||
],
|
||||
description: 'netmsg to other servers',
|
||||
execute (context) {
|
||||
const message = context.arguments.join(' ')
|
||||
const bot = context.bot;
|
||||
const source = context.source
|
||||
//throw new CommandError('ohio')
|
||||
const component = {
|
||||
translate: '[%s] %s \u203a %s',
|
||||
with: [
|
||||
bot.options.host + ':' + bot.options.port,
|
||||
source.player.displayName ?? source.player.profile.name,
|
||||
message
|
||||
]
|
||||
}
|
||||
|
||||
for (const eachBot of bot.bots) eachBot.tellraw("@a", component)
|
||||
}
|
||||
}
|
8
src/commands/ownervalidationtest.js
Normal file
8
src/commands/ownervalidationtest.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
name: 'ovtest',
|
||||
trustLevel: 2,
|
||||
execute (context) {
|
||||
const bot = context.bot
|
||||
bot.chat.message('mrrrroww >:3')
|
||||
}
|
||||
}
|
21
src/commands/ping.js
Normal file
21
src/commands/ping.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
module.exports = {
|
||||
name: 'ping',
|
||||
trustLevel: 0,
|
||||
execute (context) {
|
||||
const source = context.source;
|
||||
const bot = context.bots;
|
||||
if (context.arguments.length !== 0) {
|
||||
const argumentList = []
|
||||
|
||||
for (const argument of context.arguments) {
|
||||
if (argumentList.length !== 0) argumentList.push(' ')
|
||||
argumentList.push(argument)
|
||||
}
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: 'Ping Arguments: ', extra: argumentList }, false)
|
||||
return
|
||||
}
|
||||
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, 'Pong!', false)
|
||||
}
|
||||
}
|
14
src/commands/reconnect.js
Normal file
14
src/commands/reconnect.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
name: 'reconnect',
|
||||
trustLevel: 1,
|
||||
aliases: [
|
||||
"end",
|
||||
"recon",
|
||||
],
|
||||
description: 'reconnect the bot',
|
||||
execute (context) {
|
||||
const bot = context.bot
|
||||
const message = context.arguments.join(' ')
|
||||
bot._client.end()
|
||||
}
|
||||
}
|
21
src/commands/test.js
Normal file
21
src/commands/test.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
|
||||
module.exports = {
|
||||
name: 'test',
|
||||
trustLevel: 0,
|
||||
execute (context) {
|
||||
if (context.arguments.length !== 0) {
|
||||
const argumentList = []
|
||||
|
||||
for (const argument of context.arguments) {
|
||||
if (argumentList.length !== 0) argumentList.push(' ')
|
||||
argumentList.push(argument)
|
||||
}
|
||||
|
||||
bot.tellraw({ text: 'Hello, world! Arguments: ', extra: argumentList }, false)
|
||||
return
|
||||
}
|
||||
|
||||
bot.tellraw('Hello, world!', false)
|
||||
}
|
||||
}
|
78
src/commands/urban.js
Normal file
78
src/commands/urban.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
const CommandError = require('../util/command_error')
|
||||
const { EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, SlashCommandBuilder } = require('discord.js');
|
||||
const { request } = require('undici');
|
||||
module.exports = {
|
||||
name: 'urban',
|
||||
description:['urban dictionary'],
|
||||
aliases:['urbandictionary'],
|
||||
trustLevel: 0,
|
||||
usage:[
|
||||
"all <definition>",
|
||||
"single <definition>",
|
||||
],
|
||||
async execute (context) {
|
||||
const source = context.source
|
||||
const args = context.arguments
|
||||
const bot = context.bot
|
||||
const prefix = [
|
||||
{ text: '[', color: 'dark_gray' },
|
||||
{ text: 'Urban', color: '#B72A00' },
|
||||
{ text: '] ', color: 'dark_gray'}
|
||||
]
|
||||
let component = [];
|
||||
let term = `${args.join(' ')}`
|
||||
const query = new URLSearchParams({ term });
|
||||
const dictResult = await request(`https://api.urbandictionary.com/v0/define?${query}`);
|
||||
const { list } = await dictResult.body.json();
|
||||
if (!list.length) {
|
||||
bot.sendError('No results found');
|
||||
}
|
||||
for (const definitions of list) {
|
||||
component.push(prefix, [
|
||||
{
|
||||
text: `${definitions.definition.replaceAll('\r','').replaceAll('[', '\xa71\xa7n\xa7o').replaceAll(']','\xa7r\xa77')}\n`,
|
||||
color: 'gray',
|
||||
underlined: false,
|
||||
italic: false,
|
||||
translate:"",
|
||||
hoverEvent: {
|
||||
action:"show_text",
|
||||
value: [
|
||||
{
|
||||
text: `Example \u203a \n ${definitions.example.replaceAll('\r', '').replaceAll('[', '\xa71\xa7n\xa7o').replaceAll(']','\xa7r\xa77')}`,
|
||||
color: 'dark_blue'
|
||||
},
|
||||
{
|
||||
text: `Word \u203a ${definitions.word.replaceAll('\r', '').replaceAll('[', '\xa71\xa7n\xa7o').replaceAll(']','\xa7r\xa77')}\n`,
|
||||
color: 'dark_blue',
|
||||
},
|
||||
{
|
||||
text: `Author \u203a ${definitions.author.replaceAll('\r', '').replaceAll('[', '\xa71\xa7n\xa7o').replaceAll(']','\xa7r\xa77')}\n`,
|
||||
color: 'dark_blue'
|
||||
},
|
||||
{
|
||||
text: `written on \u203a ${definitions.written_on.replaceAll('\r', '').replaceAll('[', '\xa71\xa7n\xa7o').replaceAll(']','\xa7r\xa77')}\n`,
|
||||
color: 'dark_blue'
|
||||
},
|
||||
{
|
||||
text: `Rating \u203a Thumbs-Up ${definitions.thumbs_up} / Thumbs-Down ${definitions.thumbs_down}`,
|
||||
color: 'gray'
|
||||
}
|
||||
]
|
||||
},
|
||||
clickEvent: {
|
||||
action: 'open_url',
|
||||
value: `${definitions.permalink}`
|
||||
}
|
||||
},
|
||||
])
|
||||
}
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, component)
|
||||
},
|
||||
async discordExecute (context) {
|
||||
const bot = context.bot;
|
||||
const args = context.arguments;
|
||||
const component = [];
|
||||
}
|
||||
}
|
||||
|
18
src/commands/validate.js
Normal file
18
src/commands/validate.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
module.exports = {
|
||||
name: 'validate',
|
||||
trustLevel: 1,
|
||||
aliases: [
|
||||
"val"
|
||||
],
|
||||
description: 'validate through the bot',
|
||||
execute (context) {
|
||||
const bot = context.bot;
|
||||
const args = context.arguments;
|
||||
const source = context.source;
|
||||
if (args[0] === bot.trusted) {
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: "Valid Trusted hash", color: "dark_green" });
|
||||
} if (args[0] === bot.owner) {
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: "Valid Owner hash", color: "dark_green" });
|
||||
}
|
||||
}
|
||||
}
|
18
src/data/default_config.yml
Normal file
18
src/data/default_config.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
prefixes:
|
||||
- "!"
|
||||
|
||||
discord:
|
||||
token: "discord bot token here"
|
||||
prefix: "!"
|
||||
invite: "discord server invite here"
|
||||
|
||||
keys:
|
||||
trusted: "trusted key here"
|
||||
owner: "owner key here"
|
||||
|
||||
bots:
|
||||
- host: "localhost"
|
||||
username: "FNFBoyfriendBot"
|
||||
version: "1.20.2"
|
||||
reconnectDelay: 6000
|
||||
channelId: "channel id here"
|
28
src/index.js
Normal file
28
src/index.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
const createBot = require('./bot.js');
|
||||
const readline = require('readline');
|
||||
const loadModules = require('./util/loadModules');
|
||||
const js_yaml = require('js-yaml');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { Client, GatewayIntentBits } = require('discord.js');
|
||||
const { MessageContent, GuildMessages, Guilds } = GatewayIntentBits;
|
||||
const discordClient = new Client({ intents: [Guilds, GuildMessages, MessageContent] });
|
||||
console.log('Starting FNFBoyfriendBot');
|
||||
try {
|
||||
config = js_yaml.load(fs.readFileSync(path.join(__dirname, '../', 'config.yml')))
|
||||
} catch (e) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
})
|
||||
const bots = [];
|
||||
for (const options of config.bots) {
|
||||
const bot = createBot(options);
|
||||
bots.push(bot);
|
||||
bot.bots = bots;
|
||||
discordClient.login(config.discord.token);
|
||||
loadModules(bot, options, config, discordClient);
|
||||
bot.console.useReadlineInterface(rl);
|
||||
}
|
6
src/modules/boot.js
Normal file
6
src/modules/boot.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
function boot (bot, options, discordClient, config) {
|
||||
bot.on("packet.login", (data) => {
|
||||
bot.chat.message('&9FNF&3Boyfriend&1Bot &fcreated by &4Parker&02991');
|
||||
}) // &9 &3 &1
|
||||
}
|
||||
module.exports = boot;
|
144
src/modules/chat.js
Normal file
144
src/modules/chat.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
const loadPrismarineChat = require('prismarine-chat')
|
||||
const KaboomChatParser = require('../util/ChatParsers/Kaboom')
|
||||
const ChipmunkModChatParser = require('../util/ChatParsers/ChipmunkMod')
|
||||
|
||||
function tryParse (json) {
|
||||
try {
|
||||
return JSON.parse(json)
|
||||
} catch (error) {
|
||||
return { text: '' }
|
||||
}
|
||||
}
|
||||
//what was changed??
|
||||
function chat (bot, options, config) {
|
||||
let ChatMessage
|
||||
bot.on('registry_ready', registry => {
|
||||
ChatMessage = loadPrismarineChat(registry)
|
||||
})
|
||||
|
||||
bot.chatParsers = [KaboomChatParser, ChipmunkModChatParser]
|
||||
|
||||
bot.on('packet.profileless_chat', packet => {
|
||||
const message = tryParse(packet.message)
|
||||
const sender = tryParse(packet.name)
|
||||
|
||||
bot.emit('profileless_chat', {
|
||||
message,
|
||||
type: packet.type,
|
||||
sender
|
||||
})
|
||||
|
||||
bot.emit('message', message)
|
||||
|
||||
tryParsingMessage(message, { senderName: sender, players: bot.players, getMessageAsPrismarine: bot.getMessageAsPrismarine })
|
||||
})
|
||||
|
||||
bot.on('packet.player_chat', packet => {
|
||||
const unsigned = tryParse(packet.unsignedChatContent)
|
||||
|
||||
bot.emit('player_chat', { plain: packet.plainMessage, unsigned, senderUuid: packet.senderUuid })
|
||||
|
||||
bot.emit('message', unsigned)
|
||||
|
||||
tryParsingMessage(unsigned, { senderUuid: packet.senderUuid, players: bot.players, getMessageAsPrismarine: bot.getMessageAsPrismarine })
|
||||
})
|
||||
|
||||
bot.on('packet.system_chat', packet => {
|
||||
const message = tryParse(packet.content)
|
||||
|
||||
if (message.translate === 'advMode.setCommand.success') return // Ignores command set message
|
||||
|
||||
bot.emit('system_chat', { message, actionbar: packet.isActionBar })
|
||||
|
||||
if (packet.isActionBar) {
|
||||
return
|
||||
}
|
||||
|
||||
bot.emit('message', message)
|
||||
|
||||
tryParsingMessage(message, { players: bot.players, getMessageAsPrismarine: bot.getMessageAsPrismarine })
|
||||
})
|
||||
|
||||
function tryParsingMessage (message, data) {
|
||||
let parsed
|
||||
for (const parser of bot.chatParsers) {
|
||||
parsed = parser(message, data)
|
||||
if (parsed) break
|
||||
}
|
||||
|
||||
if (!parsed) return
|
||||
bot.emit('parsed_message', parsed)
|
||||
}
|
||||
|
||||
bot.getMessageAsPrismarine = message => {
|
||||
try {
|
||||
if (ChatMessage !== undefined) {
|
||||
return new ChatMessage(message)
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return undefined
|
||||
}
|
||||
/*
|
||||
bot.chat = message => {
|
||||
const acc = 0
|
||||
const bitset = Buffer.allocUnsafe(3)
|
||||
bitset[0] = acc & 0xFF
|
||||
bitset[1] = (acc >> 8) & 0xFF
|
||||
bitset[2] = (acc >> 16) & 0xFF
|
||||
bot._client.write('chat_message', {
|
||||
message,
|
||||
timestamp: BigInt(Date.now()),
|
||||
salt: 0n,
|
||||
offset: 0,
|
||||
acknowledged: bitset
|
||||
})
|
||||
}
|
||||
*/
|
||||
bot.chat = {
|
||||
message: message => {
|
||||
const acc = 0;
|
||||
const bitset = Buffer.allocUnsafe(3);
|
||||
bitset[0] = acc & 0xFF;
|
||||
bitset[1] = (acc >> 8) & 0xFF;
|
||||
bitset[2] = (acc >> 16) & 0xFF;
|
||||
bot._client.write('chat_message', {
|
||||
message: message?.substring(0, 256),
|
||||
timestamp: BigInt(Date.now()),
|
||||
salt: 0n,
|
||||
offset: 0,
|
||||
acknowledged: bitset
|
||||
})
|
||||
},
|
||||
command: command => {
|
||||
bot._client.write('chat_command', {
|
||||
command: command?.substring(0, 256),
|
||||
timestamp: BigInt(Date.now()),
|
||||
salt: 0n,
|
||||
argumentSignatures: [],
|
||||
signedPreview: false,
|
||||
messageCount: 0,
|
||||
acknowledged: Buffer.alloc(3),
|
||||
previousMessages: []
|
||||
})
|
||||
}
|
||||
}
|
||||
// console.log(bot.chat.sendMessage)
|
||||
/*
|
||||
bot.command = command => {
|
||||
bot._client.write('chat_command', {
|
||||
command,
|
||||
timestamp: BigInt(Date.now()),
|
||||
salt: 0n,
|
||||
argumentSignatures: [],
|
||||
signedPreview: false,
|
||||
messageCount: 0,
|
||||
acknowledged: Buffer.alloc(3),
|
||||
previousMessages: []
|
||||
})
|
||||
}
|
||||
*/
|
||||
// bot.tellraw = (message, selector = '@a') => bot.core.run('minecraft:tellraw @a ' + JSON.stringify(message)) // ? Should this be here?
|
||||
}
|
||||
|
||||
module.exports = chat;
|
74
src/modules/command_core.js
Normal file
74
src/modules/command_core.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
function core (bot, options, config) {
|
||||
bot.core = {
|
||||
area: {
|
||||
start: options.core?.area.start ?? { x: 0, y: 0, z: 0 },
|
||||
end: options.core?.area.end ?? { x: 15, y: 0, z: 15 }
|
||||
},
|
||||
position: null,
|
||||
currentBlockRelative: { x: 0, y: 0, z: 0 },
|
||||
|
||||
refill () {
|
||||
const pos = bot.core.position
|
||||
const { start, end } = bot.core.area
|
||||
|
||||
if (!pos) return
|
||||
|
||||
bot.chat.command(`minecraft:fill ${pos.x + start.x} ${pos.y + start.y} ${pos.z + start.z} ${pos.x + end.x} ${pos.y + end.y} ${pos.z + end.z} repeating_command_block`)
|
||||
},
|
||||
|
||||
move (pos = bot.position) {
|
||||
bot.core.position = {
|
||||
x: Math.floor(pos.x / 16) * 16,
|
||||
y: 0,
|
||||
z: Math.floor(pos.z / 16) * 16
|
||||
}
|
||||
bot.core.refill()
|
||||
},
|
||||
|
||||
currentBlock () {
|
||||
const relativePosition = bot.core.currentBlockRelative
|
||||
const corePosition = bot.core.position
|
||||
if (!corePosition) return null
|
||||
return { x: relativePosition.x + corePosition.x, y: relativePosition.y + corePosition.y, z: relativePosition.z + corePosition.z }
|
||||
},
|
||||
|
||||
incrementCurrentBlock () {
|
||||
const relativePosition = bot.core.currentBlockRelative
|
||||
const { start, end } = bot.core.area
|
||||
|
||||
relativePosition.x++
|
||||
|
||||
if (relativePosition.x > end.x) {
|
||||
relativePosition.x = start.x
|
||||
relativePosition.z++
|
||||
}
|
||||
|
||||
if (relativePosition.z > end.z) {
|
||||
relativePosition.z = start.z
|
||||
relativePosition.y++
|
||||
}
|
||||
|
||||
if (relativePosition.y > end.y) {
|
||||
relativePosition.x = start.x
|
||||
relativePosition.y = start.y
|
||||
relativePosition.z = start.z
|
||||
}
|
||||
},
|
||||
|
||||
run (command) {
|
||||
const location = bot.core.currentBlock()
|
||||
if (!location) return
|
||||
|
||||
bot._client.write('update_command_block', { command: command.substring(0, 32767), location, mode: 1, flags: 0b100 })
|
||||
|
||||
bot.core.incrementCurrentBlock()
|
||||
}
|
||||
}
|
||||
|
||||
bot.on('move', () => {
|
||||
bot.core.move(bot.position)
|
||||
setTimeout(() => bot.core.run('say Hello, world!'), 1000)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = core;
|
17
src/modules/command_loop.js
Normal file
17
src/modules/command_loop.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
function command_loop (bot, options, config) {
|
||||
bot.cloop = {
|
||||
list: [],
|
||||
add (command, interval) {
|
||||
this.list.push({ timer: setInterval(() => bot.core.run(command), interval), command, interval })
|
||||
},
|
||||
|
||||
remove (index) {
|
||||
clearInterval(this.list[index].timer)
|
||||
},
|
||||
clear () {
|
||||
for (const cloop of this.list) clearInterval(cloop.timer)
|
||||
this.list = []
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = command_loop;
|
96
src/modules/command_manager.js
Normal file
96
src/modules/command_manager.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const CommandError = require('../util/command_error.js');
|
||||
const CommandSource = require('../util/command_source');
|
||||
function command_manager (bot, options, config, discordClient) {
|
||||
bot.commandManager = {
|
||||
commands: {},
|
||||
commandlist: [],
|
||||
execute (source, commandName, args) {
|
||||
const command = this.getCommand(commandName.toLowerCase())
|
||||
|
||||
try {
|
||||
if (!command || !command.execute) throw new CommandError({ translate: 'Unknown command: %s', with: [commandName] })
|
||||
if (command.trustLevel === 1 && bot.trusted) {
|
||||
const hash = args[0]
|
||||
if (args.length === 0 && bot.trusted && bot.owner && !source.sources.console) throw new CommandError({ text: "Please provide an trusted or owner hash" })
|
||||
if (args[0] !== bot.trusted && args[0] !== bot.owner && !source.sources.console) throw new CommandError({ translate: 'Invalid trusted or owner hash', color: 'dark_red' })
|
||||
}
|
||||
if (command.trustLevel === 2 && bot.owner) {
|
||||
if (args.length === 0 && bot.owner) throw new CommandError({ text: "Please provide an owner hash" })
|
||||
if (args[0] !== bot.owner) throw new CommandError({ translate: 'Invalid owner hash', color: 'dark_red' })
|
||||
} else if (command.trustLevel === 3 && !source.sources.console) {
|
||||
throw new CommandError('This command can only be ran via console');
|
||||
}
|
||||
if (!command.discordExecute && command && source.sources.discord) {
|
||||
throw new CommandError(`${command.name} command is not supported in discord!`)
|
||||
} else if (command.discordExecute && command && source.sources.discord) {
|
||||
return command.discordExecute({ bot, source, arguments: args, config, discordClient })
|
||||
} else if (command.execute && command && !source.sources.discord) {
|
||||
return command.execute({ bot, source, arguments: args, config, discordClient})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
if (error instanceof CommandError) bot.tellraw("@a", { text: error.message, color: "dark_red" }) //bot.tellraw({ text: `${}`, color: "dark_red" })
|
||||
else bot.tellraw("@a", { translate: 'command.failed', color: "dark_red", hoverEvent: { action: 'show_text', contents: `${error.stack}` } })
|
||||
}
|
||||
},
|
||||
executeString (source, command) {
|
||||
const [commandName, ...args] = command.split(' ')
|
||||
return this.execute(source, commandName, args)
|
||||
},
|
||||
|
||||
discordExecute(source, command) {
|
||||
const [commandName, ...args] = command.split(" ");
|
||||
if (source?.sources?.discord && !source.sources.console) {
|
||||
return this.discordExecute(source, commandName, args)
|
||||
}
|
||||
},
|
||||
register (command) {
|
||||
this.commands[command.name] = command
|
||||
if (command.aliases) {
|
||||
command.aliases.map((a) => (this.commands[a] = command));
|
||||
}
|
||||
},
|
||||
|
||||
getCommand (name) {
|
||||
return this.commands[name]
|
||||
},
|
||||
|
||||
getCommands () {
|
||||
return Object.values(this.commands)
|
||||
}
|
||||
}
|
||||
|
||||
commandlist = [];
|
||||
for (const filename of fs.readdirSync(path.join(__dirname, '../commands'))) {
|
||||
try {
|
||||
const command = require(path.join(__dirname, '../commands', filename))
|
||||
bot.commandManager.register(command)
|
||||
bot.commandManager.commandlist.push(command)
|
||||
} catch (error) {
|
||||
console.error('Failed to load command', filename, ':', error)
|
||||
}
|
||||
}
|
||||
let ratelimit = 0;
|
||||
bot.on("parsed_message", (data) => {
|
||||
if (data.type !== "minecraft:chat") return;
|
||||
const prefixes = config.prefixes;
|
||||
prefixes.map((prefix) => {
|
||||
const plainMessage = bot.getMessageAsPrismarine(data.contents)?.toString();
|
||||
if (!plainMessage.startsWith(prefix)) return
|
||||
const command = plainMessage.substring(prefix.length)
|
||||
const source = new CommandSource(data.sender, { discord: false, console: false }, true)
|
||||
ratelimit++
|
||||
setTimeout(() => {
|
||||
ratelimit--
|
||||
}, 1000)
|
||||
if (ratelimit > 2) {
|
||||
bot.tellraw(`@a[name="${source?.player?.profile?.name}"]`, { text: 'You are using commands too fast!', color: 'dark_red'})
|
||||
} else {
|
||||
bot.commandManager.executeString(source, command)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
module.exports = command_manager;
|
50
src/modules/console.js
Normal file
50
src/modules/console.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
const CommandSource = require('../util/command_source')
|
||||
function CommandConsole (bot, options, config) {
|
||||
bot.console = {
|
||||
readline: null,
|
||||
|
||||
consoleServer: 'all',
|
||||
|
||||
useReadlineInterface (rl) {
|
||||
this.readline = rl
|
||||
|
||||
rl.on('line', line => {
|
||||
if (bot.options.host !== this.consoleServer && this.consoleServer !== 'all') return
|
||||
// bot.commandManager.executeString(bot.console.source, line)
|
||||
if (line.startsWith('c.')) {
|
||||
return bot.commandManager.executeString(bot.console.source, line.substring(2))
|
||||
} if (line.startsWith("")) {
|
||||
return bot.commandManager.executeString(bot.console.source, `echo ${line.substring(0)}`)
|
||||
}
|
||||
})
|
||||
|
||||
rl.on('close', () => {
|
||||
this.readline = null
|
||||
})
|
||||
|
||||
const originalConsole = console
|
||||
this.log = (...args) => {
|
||||
rl.output.write('\x1b[2K\r')
|
||||
originalConsole.log(args.toString())
|
||||
rl._refreshLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
bot.console.logs = function log (message) {
|
||||
console.log(`[${new Date().toLocaleString("en-US", { timeZone:"America/CHICAGO" })}] [${options.host}:${options.port}] ${message}`)
|
||||
}
|
||||
bot.console.source = new CommandSource(null, { console: true, discord: false });
|
||||
bot.console.source.sendFeedback = message => {
|
||||
const ansi = bot.getMessageAsPrismarine(message)?.toAnsi()
|
||||
bot.console.logs(ansi)
|
||||
// cosnole.log(ansi)
|
||||
}
|
||||
|
||||
bot.on('message', message => {
|
||||
const ansi = bot.getMessageAsPrismarine(message)?.toAnsi()
|
||||
const string = bot.getMessageAsPrismarine(message)?.toString()
|
||||
bot.console.logs(`${ansi}`)
|
||||
// this.log('sus')
|
||||
})
|
||||
}
|
||||
module.exports = CommandConsole;
|
182
src/modules/discord.js
Normal file
182
src/modules/discord.js
Normal file
|
@ -0,0 +1,182 @@
|
|||
// TODO: Maybe move client creation elsepwhere
|
||||
const { Client, GatewayIntentBits, interaction } = require('discord.js')
|
||||
const { MessageContent, GuildMessages, Guilds } = GatewayIntentBits
|
||||
const fixansi = require('../util/ansi');
|
||||
const CommandSource = require('../util/command_source')
|
||||
|
||||
const client = new Client({ intents: [Guilds, GuildMessages, MessageContent] })
|
||||
const util = require('util')
|
||||
|
||||
function discord(bot, options, config, discordClient) {
|
||||
// client.login(config.discord.token)
|
||||
if (!options?.channelId) {
|
||||
bot.discord = {
|
||||
invite: config.discord?.invite
|
||||
}
|
||||
return
|
||||
}
|
||||
bot.discord = {
|
||||
client: discordClient,
|
||||
channel: undefined,
|
||||
invite: config.discord.invite || undefined,
|
||||
prefix: config.discord.prefix,
|
||||
// presence: bot.discord.presence,
|
||||
token: config.discord.token,
|
||||
}
|
||||
discordClient.on('ready', (context) => {
|
||||
bot.discord.channel = discordClient.channels.cache.get(options.channelId)
|
||||
/* client.user.setPresence({
|
||||
activities: [{
|
||||
name: `${bot.discord.presence.name}`,
|
||||
type: bot.discord.presence.type
|
||||
}],
|
||||
status: `${bot.discord.presence.status}`
|
||||
});*/
|
||||
})
|
||||
|
||||
let discordQueue = []
|
||||
setInterval(() => {
|
||||
if (discordQueue.length === 0) return
|
||||
try {
|
||||
bot?.discord?.channel?.send(`\`\`\`ansi\n${discordQueue.join('\n').substring(0, 1984)}\n\`\`\``)
|
||||
} catch (error) {
|
||||
bot.console.error(error.stack)
|
||||
|
||||
}
|
||||
discordQueue = []
|
||||
}, 2000)
|
||||
|
||||
function sendDiscordMessage(message) {
|
||||
discordQueue.push(message)
|
||||
}
|
||||
|
||||
function sendComponent(message) {
|
||||
const ansi = bot.getMessageAsPrismarine(message)?.toAnsi().replaceAll('```\u001b[9```' + '```\u001b[3```').replaceAll('https://discord','https:\rdiscord')?.replaceAll('discord.gg', 'discord.\rgg');
|
||||
try {
|
||||
sendDiscordMessage(fixansi(ansi.replaceAll('`', '`\u200b')))
|
||||
} catch (e) {
|
||||
bot.console.error(`Error sending a message to Discord:\n${e.message}`)
|
||||
sendDiscordMessage(e.message)
|
||||
}
|
||||
}
|
||||
bot.on('message', message => {
|
||||
sendComponent(message)
|
||||
})
|
||||
|
||||
function messageCreate(message, source) {
|
||||
bot.discord.Message = message
|
||||
if (message.author.id === bot.discord.client.user.id) return
|
||||
|
||||
if (message.channel.id !== bot.discord.channel.id) return
|
||||
|
||||
if (message.content.startsWith(config.discord.prefix)) { // TODO: Don't hardcode this
|
||||
const source = new CommandSource({
|
||||
profile: {
|
||||
name: message?.member?.displayName
|
||||
}
|
||||
}, {
|
||||
discord: true,
|
||||
console: false
|
||||
}, false, message)
|
||||
|
||||
bot.sendFeedback = message => {
|
||||
sendComponent(message)
|
||||
}
|
||||
|
||||
bot.commandManager.executeString(source, message.content.substring(config.discord.prefix.length))
|
||||
return
|
||||
}
|
||||
const tag = {
|
||||
translate: '[%s] %s \u203a %s',
|
||||
with: [{
|
||||
translate: '%s%s%s %s',
|
||||
bold: false,
|
||||
with: [{
|
||||
text: 'FNF',
|
||||
bold: false,
|
||||
color: 'blue'
|
||||
},
|
||||
{
|
||||
text: 'Boyfriend',
|
||||
bold: false,
|
||||
color: 'dark_aqua'
|
||||
},
|
||||
{
|
||||
text: 'Bot',
|
||||
bold: false,
|
||||
color: 'dark_blue'
|
||||
},
|
||||
{
|
||||
text: 'Discord',
|
||||
bold: false,
|
||||
color: 'dark_blue'
|
||||
}
|
||||
],
|
||||
clickEvent: bot.discord.invite ? {
|
||||
action: 'open_url',
|
||||
value: bot.discord.invite
|
||||
} : undefined,
|
||||
hoverEvent: {
|
||||
action: 'show_text',
|
||||
contents: 'Click to join the discord'
|
||||
}
|
||||
},
|
||||
{
|
||||
text: message?.member?.displayName
|
||||
},
|
||||
message.content
|
||||
]
|
||||
}
|
||||
if (message.attachments.size > 0) {
|
||||
message.attachments.forEach(Attachment => {
|
||||
bot.tellraw('@a', [tag, {
|
||||
text: ' ' ? ' [Attachment] ' : ' [Attachment] ',
|
||||
hoverEvent: {
|
||||
action: 'show_text',
|
||||
contents: 'Click here to view attachment'
|
||||
},
|
||||
clickEvent: {
|
||||
action: 'open_url',
|
||||
value: `${Attachment.url}`
|
||||
}
|
||||
}])
|
||||
})
|
||||
} else {
|
||||
bot.tellraw('@a', tag);
|
||||
}
|
||||
}
|
||||
discordClient.on('messageCreate', messageCreate)
|
||||
|
||||
process.on("uncaughtException", (e) => {
|
||||
// sendDiscordMessage("uncaught " + e.stack);
|
||||
});
|
||||
|
||||
/*
|
||||
function fixansi(message) {
|
||||
const ansilist = {
|
||||
"\x1B\[93m": "\x1B[33m", // Yellow
|
||||
"\x1B\[96m": "\x1B[36m", // Blue
|
||||
"\x1B\[94m": "\x1B[34m", // Discord Blue
|
||||
"\x1B\[90m": "\x1B[30m", // Gray
|
||||
"\x1B\[91m": "\x1B[31m", // Light Red
|
||||
"\x1B\[95m": "\x1B\[35m", // Pink
|
||||
"\x1B\[92m": "\x1B\[32m", // Green
|
||||
"\x1B\[0m": "\x1B\[0m\x1B\[37m", // White
|
||||
"\x1B\[97m": "\x1B\[0m\x1B\[37m", // White
|
||||
};
|
||||
let i = message;
|
||||
|
||||
for (const ansi in ansilist) {
|
||||
if (ansilist.hasOwnProperty(ansi)) {
|
||||
i = i.replace(new RegExp(escapeRegExpChars(ansi), 'g'), ansilist[ansi]);
|
||||
|
||||
function escapeRegExpChars(text) {
|
||||
return text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}*/
|
||||
}
|
||||
module.exports = discord;
|
81
src/modules/player_list.js
Normal file
81
src/modules/player_list.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
function player_list (bot, options, config) {
|
||||
bot.players = []
|
||||
|
||||
bot.on('packet.player_info', packet => {
|
||||
const actions = []
|
||||
|
||||
if (packet.action & 0b000001) actions.push(addPlayer)
|
||||
if (packet.action & 0b000010) actions.push(initializeChat)
|
||||
if (packet.action & 0b000100) actions.push(updateGamemode)
|
||||
if (packet.action & 0b001000) actions.push(updateListed)
|
||||
if (packet.action & 0b010000) actions.push(updateLatency)
|
||||
if (packet.action & 0b100000) actions.push(updateDisplayName)
|
||||
|
||||
for (const entry of packet.data) {
|
||||
for (const action of actions) {
|
||||
action(entry)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
bot.on('packet.player_remove', ({ players }) => {
|
||||
// TODO: Add player removal (with validation)
|
||||
for (const player of players) {
|
||||
bot.players = bot.players.filter(entry => entry.uuid !== player)
|
||||
}
|
||||
})
|
||||
|
||||
function addPlayer (entry) {
|
||||
bot.players = bot.players.filter(_entry => _entry.uuid !== entry.uuid)
|
||||
bot.players.push({
|
||||
uuid: entry.uuid,
|
||||
profile: { name: entry.player.name, properties: entry.player.properties },
|
||||
|
||||
chatSession: undefined,
|
||||
gamemode: undefined,
|
||||
listed: undefined,
|
||||
latency: undefined,
|
||||
displayName: undefined
|
||||
})
|
||||
}
|
||||
|
||||
function initializeChat (entry) {
|
||||
// TODO: Handle chat sessions
|
||||
}
|
||||
|
||||
function updateGamemode (entry) {
|
||||
const target = bot.players.find(_entry => _entry.uuid === entry.uuid)
|
||||
if (!target) return
|
||||
|
||||
target.gamemode = entry.gamemode
|
||||
}
|
||||
|
||||
function updateListed (entry) {
|
||||
const target = bot.players.find(_entry => _entry.uuid === entry.uuid)
|
||||
if (!target) return
|
||||
|
||||
target.listed = entry.listed
|
||||
}
|
||||
|
||||
function updateLatency (entry) {
|
||||
const target = bot.players.find(_entry => _entry.uuid === entry.uuid)
|
||||
if (!target) return
|
||||
|
||||
target.latency = entry.latency
|
||||
}
|
||||
|
||||
function updateDisplayName (entry) {
|
||||
const target = bot.players.find(_entry => _entry.uuid === entry.uuid)
|
||||
if (!target) return
|
||||
|
||||
try {
|
||||
target.displayName = JSON.parse(entry.displayName)
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
bot.on('end', () => (bot.players = []))
|
||||
}
|
||||
|
||||
module.exports = player_list;
|
19
src/modules/position.js
Normal file
19
src/modules/position.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
function position (bot, options, config) {
|
||||
bot.position = null
|
||||
|
||||
bot.on('packet.position', packet => {
|
||||
bot.position = {
|
||||
x: packet.flags & 1 ? (this.x + packet.x) : packet.x,
|
||||
y: packet.flags & 2 ? (this.y + packet.y) : packet.y,
|
||||
z: packet.flags & 4 ? (this.z + packet.z) : packet.z
|
||||
}
|
||||
|
||||
bot._client.write('teleport_confirm', { teleportId: packet.teleportId })
|
||||
|
||||
bot.emit('move')
|
||||
})
|
||||
|
||||
bot.on('end', () => { bot.position = null })
|
||||
}
|
||||
|
||||
module.exports = position
|
14
src/modules/reconnect.js
Normal file
14
src/modules/reconnect.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
const mc = require('minecraft-protocol')
|
||||
|
||||
function reconnect (bot, options) {
|
||||
bot.reconnectDelay = options.reconnectDelay ?? 5000
|
||||
|
||||
bot.on('end', () => {
|
||||
if (bot.reconnectDelay < 0) return
|
||||
|
||||
bot._client = mc.createClient(options)
|
||||
bot.emit('init_client', bot._client)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = reconnect;
|
10
src/modules/registry.js
Normal file
10
src/modules/registry.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const createRegistry = require('prismarine-registry')
|
||||
|
||||
function registry (bot) {
|
||||
bot.on('packet.login', packet => {
|
||||
bot.registry = createRegistry(bot._client.version)
|
||||
bot.emit('registry_ready', bot.registry)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = registry;
|
53
src/modules/selfcare.js
Normal file
53
src/modules/selfcare.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
function selfcare (bot, options, config) {
|
||||
let entityId;
|
||||
let permissionLevel = 2;
|
||||
let gameMode;
|
||||
let commandSpy = false;
|
||||
let vanished = false;
|
||||
let prefix = false;
|
||||
// You now have the tag: &8[&bPrefix&8: &3~&8]
|
||||
// You no longer have a tag
|
||||
bot.on('message', (message) => {
|
||||
const stringMessage = bot.getMessageAsPrismarine(message).toString();
|
||||
if (stringMessage.startsWith("Successfully enabled CommandSpy")) commandSpy = true;
|
||||
else if (stringMessage?.startsWith("Successfully disabled CommandSpy")) commandSpy = false;
|
||||
else if (stringMessage === `Vanish for ${bot.options.username}: enabled`) vanished = true;
|
||||
else if (stringMessage === `Vanish for ${bot.options.username}: disabled`) vanished = false;
|
||||
else if (stringMessage === `You now have the tag: &8[&bPrefix&8: &3${config.prefixes[0]}&8]` || stringMessage === "Something went wrong while saving the prefix. Please check console.") prefix = true;
|
||||
else if (stringMessage?.startsWith("You now have the tag: ") || stringMessage === "You no longer have a tag") prefix = false
|
||||
})
|
||||
// else if (stringmessage?.startsWith("You now have the tag: ") || JSON?.stringify(message) === '{"text":"You no longer have a tag"}') prefix = false
|
||||
bot.on('packet.entity_status', packet => {
|
||||
if (packet.entityId !== entityId || packet.entityStatus < 24 || packet.entityStatus > 28) return
|
||||
permissionLevel = packet.entityStatus - 24
|
||||
})
|
||||
bot.on('packet.game_state_change', packet => {
|
||||
if (packet.reason !== 3) return // Reason 3 = Change Game Mode
|
||||
// if (packet.reason !== 4) return // Reason 4 = end credits
|
||||
gameMode = packet.gameMode;
|
||||
});
|
||||
bot.on("packet.game_state.change", packet => {
|
||||
|
||||
})
|
||||
let timer;
|
||||
bot.on('packet.login', (packet) => {
|
||||
entityId = packet.entityId;
|
||||
gameMode = packet.gameMode;
|
||||
timer = setInterval(() => {
|
||||
if (permissionLevel < 2) bot.chat.command('op @s[type=player]');
|
||||
else if (gameMode !== 1) bot.chat.command('gamemode creative @s[type=player]');
|
||||
else if (!commandSpy) bot.chat.command('commandspy on');
|
||||
else if (!vanished) bot.core.run(`vanish ${bot.options.username} on`);
|
||||
else if (!prefix) bot.chat.command(`prefix &8[&bPrefix&8: &3${config.prefixes[0]}&8]`);
|
||||
else if (gameMode !== 4) bot._client.write("client_command", { actionId: 0 });
|
||||
}, 1000);
|
||||
});
|
||||
bot.on('end', () => {
|
||||
if (timer) clearInterval(timer)
|
||||
prefix = false;
|
||||
commandSpy = false;
|
||||
vanished = false;
|
||||
prefix = false;
|
||||
});
|
||||
}
|
||||
module.exports = selfcare;
|
6
src/modules/tellraw.js
Normal file
6
src/modules/tellraw.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
function tellraw (bot, options, config) {
|
||||
bot.tellraw = (selector, message) => {
|
||||
bot.core.run(`minecraft:tellraw ${selector} ` + JSON.stringify(message))
|
||||
}
|
||||
}
|
||||
module.exports = tellraw;
|
10
src/modules/validation.js
Normal file
10
src/modules/validation.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const crypto = require("crypto");
|
||||
function validation (bot, options, config) {
|
||||
bot.trusted = "";
|
||||
let trusted;
|
||||
let hashRegenInterval = setInterval(() => {
|
||||
bot.trusted = crypto.createHash('sha256').update(Math.floor(Date.now() / 5000) + config.keys.trusted).digest('hex').substring(0, 16)
|
||||
bot.owner = crypto.createHash('sha256').update(Math.floor(Date.now() / 5000) + config.keys.owner).digest('hex').substring(0, 16)
|
||||
}, 2000)
|
||||
}
|
||||
module.exports = validation;
|
35
src/util/ChatParsers/ChipmunkMod.js
Normal file
35
src/util/ChatParsers/ChipmunkMod.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
function chipmunkmod (message, data, context, bot) {
|
||||
try {
|
||||
if (message === null || typeof message !== 'object') return
|
||||
|
||||
if (message.with?.length < 3 || (message.translate !== '[%s] %s › %s' && message.translate !== '%s %s › %s')) return
|
||||
|
||||
const senderComponent = message.with[1]
|
||||
// wtf spam again -
|
||||
//console.log(senderComponent)//wtf...
|
||||
|
||||
|
||||
const contents = message.with[2]
|
||||
// spam lol - console.log(contents)
|
||||
let sender
|
||||
|
||||
const hoverEvent = senderComponent.hoverEvent
|
||||
//console.log(JSON.stringify(hoverEvent))
|
||||
if (hoverEvent?.action === 'show_entity') {
|
||||
const id = hoverEvent.contents.id
|
||||
//
|
||||
sender = data.players.find(player => player.uuid === id)
|
||||
} else {
|
||||
const stringUsername = data.getMessageAsPrismarine(senderComponent).toString() // TypeError: data.getMessageAsPrismarine is not a function
|
||||
|
||||
sender = data.players.find(player => player.profile.name) //=== stringusername)
|
||||
}
|
||||
|
||||
if (!sender) return null
|
||||
|
||||
return { sender, contents, type: 'minecraft:chat', senderComponent }
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
module.exports = chipmunkmod
|
41
src/util/ChatParsers/Kaboom.js
Normal file
41
src/util/ChatParsers/Kaboom.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
const util = require('util')
|
||||
|
||||
function parseMessage (message, data) {
|
||||
if (message === null || typeof message !== 'object') return
|
||||
|
||||
if (message.text !== '' || !Array.isArray(message.extra) || message.extra.length < 3) return
|
||||
|
||||
const children = message.extra
|
||||
|
||||
const prefix = children[0]
|
||||
let displayName = data.senderName ?? { text: '' }
|
||||
let contents = { text: '' }
|
||||
|
||||
if (isSeparatorAt(children, 1)) { // Missing/blank display name
|
||||
if (children.length > 3) contents = children[3]
|
||||
} else if (isSeparatorAt(children, 2)) {
|
||||
displayName = children[1]
|
||||
if (children.length > 4) contents = children[4]
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const playerListDisplayName = { extra: [prefix, displayName], text: '' }
|
||||
let sender
|
||||
if (data.uuid) {
|
||||
sender = data.players.find(player => player.uuid === data.senderUuid)
|
||||
} else {
|
||||
const playerListDisplayName = { extra: [prefix, displayName], text: '' }
|
||||
sender = data.players.find(player => util.isDeepStrictEqual(player.displayName, playerListDisplayName))
|
||||
}
|
||||
|
||||
if (!sender) return undefined
|
||||
|
||||
return { sender, contents, type: 'minecraft:chat', displayName }
|
||||
}
|
||||
|
||||
function isSeparatorAt (children, start) {
|
||||
return (children[start]?.text === ':' || children[start]?.text === '\xa7f:') && children[start + 1]?.text === ' '
|
||||
}
|
||||
|
||||
module.exports = parseMessage
|
26
src/util/ansi.js
Normal file
26
src/util/ansi.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
function ansi (message) {
|
||||
const ansilist = {
|
||||
"\x1B\[93m": "\x1B[33m", // Yellow
|
||||
"\x1B\[96m": "\x1B[36m", // Blue
|
||||
"\x1B\[94m": "\x1B[34m", // Discord Blue
|
||||
"\x1B\[90m": "\x1B[30m", // Gray
|
||||
"\x1B\[91m": "\x1B[31m", // Light Red
|
||||
"\x1B\[95m": "\x1B\[35m", // Pink
|
||||
"\x1B\[92m": "\x1B\[32m", // Green
|
||||
"\x1B\[0m": "\x1B\[0m\x1B\[37m", // White
|
||||
"\x1B\[97m": "\x1B\[0m\x1B\[37m", // White
|
||||
};
|
||||
let i = message;
|
||||
|
||||
for (const ansi in ansilist) {
|
||||
if (ansilist.hasOwnProperty(ansi)) {
|
||||
i = i.replace(new RegExp(escapeRegExpChars(ansi), 'g'), ansilist[ansi]);
|
||||
|
||||
function escapeRegExpChars(text) {
|
||||
return text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
module.exports = ansi;
|
16
src/util/command_error.js
Normal file
16
src/util/command_error.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// TODO: Improve how messages are stringified
|
||||
const ChatMessage = require('prismarine-chat')('1.20.1')
|
||||
const stringify = message => new ChatMessage(message).toString()
|
||||
|
||||
class CommandError extends Error {
|
||||
constructor (message, filename, lineError) {
|
||||
super(stringify(message), filename, lineError)
|
||||
this.name = 'CommandError'
|
||||
this._message = message
|
||||
}
|
||||
|
||||
get message () {
|
||||
return stringify(this._message)
|
||||
}
|
||||
}
|
||||
module.exports = CommandError
|
14
src/util/command_source.js
Normal file
14
src/util/command_source.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
class CommandSource {
|
||||
constructor (player, sources) {
|
||||
this.player = player;
|
||||
this.sources = sources;
|
||||
}
|
||||
/* sendFeedback () {}
|
||||
|
||||
sendError (message) {
|
||||
this.sendFeedback([{ text: '', color: 'dark_red' }, message], false)
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
module.exports = CommandSource
|
20
src/util/loadModules.js
Normal file
20
src/util/loadModules.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const readline = require("readline");
|
||||
/*const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
})*/
|
||||
function loadModules (bot, options, config, discordClient) {
|
||||
bot.loadModule = module => module(bot, options, config, discordClient)
|
||||
|
||||
for (const filename of fs.readdirSync(path.join(__dirname, '../', 'modules'))) {
|
||||
try {
|
||||
const module = require(path.join(__dirname, '../', 'modules', filename))
|
||||
bot.loadModule(module)
|
||||
} catch (error) {
|
||||
console.error('Failed to load module', filename, ':', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = loadModules;
|
10
src/util/usernameGen.js
Normal file
10
src/util/usernameGen.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
function usernameGen () {
|
||||
const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
||||
let username = '';
|
||||
for (let i = 0; i < 10; i++ ) {
|
||||
const randomIndex = Math.floor(Math.random() * characters.length);
|
||||
username += characters[randomIndex];
|
||||
}
|
||||
return username;
|
||||
}
|
||||
module.exports = usernameGen;
|
Loading…
Reference in a new issue