Compare commits

...

No commits in common. "main" and "v5.0.5" have entirely different histories.
main ... v5.0.5

280 changed files with 15936 additions and 7660 deletions

75
.bot.js.2274242318~ Normal file
View file

@ -0,0 +1,75 @@
const mc = require('minecraft-protocol')
const { EventEmitter } = require('node:events')
const fs = require('fs')
const path = require('path')
const util = require('node:util')
function createBot(options = {}) {
const bot = new EventEmitter()
const rs = require('randomstring')
// Set some default values in options
let r = Math.floor(Math.random() * 255) + 1;
options.host ??= 'localhost'
options.username ??= 'Player' + Math.floor(Math.random() * 1000)
options.hideErrors ??= false // 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', async function (data) {
bot.uuid = client.uuid
bot.username = client.username
bot.entityId = data.entityId
bot.host = bot.options.host
bot.port = bot.options.port
bot.buildstring = process.env['buildstring']
bot.fbs = process.env['FoundationBuildString']
})
client.on('end', reason => { bot.emit('end', reason)
try {
if (reason.text) {
if
}
}
})if
client.on('error', error => bot.emit('error', error), )
})
const buildstring = process.env['buildstring']
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('\x1b[0m\x1b[91m[ERROR]: \x1b[0m\x1b[90mFailed to load module', filename, ':', error)
}
}
return bot
}
// ABot username function mabe mabe
module.exports = createBot

147
.bot.js.3332916295~ Normal file
View file

@ -0,0 +1,147 @@
const mc = require("minecraft-protocol");
const { EventEmitter } = require("node:events");
const fs = require("fs");
const path = require("path");
const util = require("node:util");
console.log(`Starting ${process.env["buildstring"]} .......`);
console.log(`Foundation: ${process.env["FoundationBuildString"]}`);
console.log("this may take a few moments....");
require("events").EventEmitter.defaultMaxListeners = 30;
function createBot(options = {}) {
const bot = new EventEmitter();
const rs = require("randomstring");
// Set some default values in options
let r = Math.floor(Math.random() * 255) + 1;
options.host ??= "localhost";
options.username ??= "FNFBoyfriendBot";
options.hideErrors ??= false; // HACK: Hide errors by default as a lazy fix to console being spammed with them
options.console ??= true;
options.input ??= true;
options.commands.MainPrefix ??= "~";
options.commands.SecondaryPrefix ??= "%";
options.commands.TertiaryPrefix ??= "&";
options.selfcare.unmuted ??= true;
options.selfcare.vanished ??= true;
options.selfcare.prefix ??= true;
options.selfcare.skin ??= true;
options.selfcare.cspy ??= true;
options.selfcare.op ??= true;
options.selfcare.gmc ??= true;
options.selfcare.interval ??= 500;
options.selfcare.username ??= true;
options.selfcare.nickname ??= true;
options.selfcare.god ??= true;
options.selfcare.tptoggle ??= true;
options.discord.commandPrefix ??= "~";
options.reconnectDelay ??= 1000;
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", async function (data) {
bot.uuid = client.uuid;
bot.username = client.username;
bot.entityId = data.entityId;
bot.host = bot.options.host;
bot.port = bot.options.port;
bot.buildstring = process.env["buildstring"];
bot.fbs = process.env["FoundationBuildString"];
bot.version = bot.options.version;
console.log(`Username: ${bot.options.username}`);
console.log(`Host: ${bot.options.host}:${bot.options.port}`);
console.log(`Minecraft java version: ${bot.options.version}`);
/* console.log(`Username: ${bot.username}`)
console.log(`Host: ${bot.host}:${bot.port}`)
console.log(`Minecraft java version: ${bot.version}`)*/
});
//reason, fullReason
client.on("end", (reason) => {
bot.emit("end", reason);
console.log(reason);
});
client.on("disconnect", (reason) => {
bot.emit("disconnect", reason);
console.log(reason);
});
client.on("kick_disconnect", (reason) => {
bot.emit("kick_disconnect", reason);
console.log(reason);
});
client.on("keep_alive", ({ keepAliveId }) => {
bot.emit("keep_alive", { keepAliveId });
// console.log(keepAliveId)
});
client.on("error", (error) => bot.emit("error", error));
//client.end(reason, fullReason)
});
/*
bot._client.on('kick_disconnect', (data) => {
const parsed = JSON.parse(data.reason)
bot.end(parsed, 'kick_disconnect')
})
*/
const buildstring = process.env["buildstring"];
const client = options.client ?? mc.createClient(options);
bot._client = client;
bot.emit("init_client", client);
bot.bots = options.bots ?? [bot];
//bot.setMaxListeners(Infinity)
//bot._client.setMaxListeners(Infinity)
// 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);
//console.log(filename.length);
} catch (error) {
console.error(
"\x1b[0m\x1b[91m[ERROR]: \x1b[0m\x1b[90mFailed to load module",
filename,
":",
error,
);
}
}
return bot;
} //path.join(__dirname, 'modules', filename)
//path.join(amonger + 'FridayNightFunkinBoyfriendBot') !== path.join(amonger)
//fs.stat
const amonger = "../";
if (fs.existsSync("../FridayNightFunkinBoyfriendBot") == false) {
process.exit(1);
}
//path.join('') != fs. existsSync('~/FridayNightFunkinBoyfriendBot/index.js')
// ABot username function mabe mabe
module.exports = createBot;

10
.gitignore vendored
View file

@ -1,10 +0,0 @@
node_modules
config.yml
.git
src/modules/exploits.js
logs/*
src/data/filter.json
data/filter.json
prototyping-crap
src/data/trustedPlayers.js
data/trustedPlayers.js

74
.index.js.3066437094~ Normal file
View file

@ -0,0 +1,74 @@
const util = require('util')
const createBot = require('./bot.js')
//const chomensjs = require('./ChomensJS')
// TODO: Load a default config
const fs = require('fs/promises')
const fileExist = require('./util/file-exists')
const path = require('path')
function load () {
//const config = require('./config.js')
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
require('dotenv').config()
const bots = []
for (const options of config.bots) {
const bot = createBot(options)
bots.push(bot)
bot.bots = bots
bot.options.username
bot.console.useReadlineInterface(rl)
// bot.on('error', (error), util.inspect(error))
try{
bot.on('error', console.error)
}catch(error){
console.log(error.stack)
}
}
}
async function checkConfig () {
if (!await fileExist(path.join(__dirname, 'config.js'))) {
console.error('Config not found! Creating a new Config from ')
await fs.copyFile(path.join(__dirname, 'default.js'), path.join(__dirname, 'config.js'))
} if (await fileExist(path.join(__dirname, 'config.js'))){
console.log('Config found! loading config please wait,......')
}
config = require('./config.js')
load()
}
checkConfig()
const modules = "./modules";
const util = "./util";
const CommandModules = "./CommandModules";
const commands = "./commands";
const chat = "./chat";
fs.readdir(util, (err, files) => {
console.log("Successfully loaded: " + files.length + " util files");
});
fs.readdir(modules, (err, files) => {
console.log("Successfully loaded: " + files.length + " module files");
});
fs.readdir(commands, (err, files) => {
console.log("Successfully loaded: " + files.length + " command files");
});
fs.readdir(CommandModules, (err, files) => {
console.log("Successfully loaded: " + files.length + " CommandModule files");
});
fs.readdir(chat, (err, files) => {
console.log("Successfully loaded: " + files.length + " chat files");
});
process.on('uncaughtException', (e) => {
console.log('uncaught ' + e.stack)
})

128
ChomensJS/bot.js Normal file
View file

@ -0,0 +1,128 @@
const mc = require('minecraft-protocol')
const { EventEmitter } = require('node:events')
const { loadPlugins } = require('./util/loadPlugins')
const util = require('node:util')
const randomstring = require('randomstring')
/**
* makes the bot
* @param {object} server the server object used in the config
* @param {object} config the config file
* @param {Function} getBots get bots function in index.js
* @param {Function} setNewBot ig real
* @param {Class} dcclient discord client
* @param {object} rl readline.
* @return {object} the bot object
*/
async function createBot (server, config, getBots, setNewBot, dcclient, rl) {
const bot = new EventEmitter()
bot.options = {
username: server.username ?? randomstring.generate(8),
host: server.host ?? 'localhost',
port: server.port ?? 25565,
version: config.version,
kaboom: server.kaboom ?? true,
logging: server.logging ?? true,
useChat: server.useChat ?? false,
checkTimeoutInterval: config.timeoutInterval,
hideErrors: true
}
// among us fix for bot.options.host and bot.options.port
bot.server = {
host: server.host,
port: server.port
}
bot.visibility = false
bot.getBots = getBots
bot.end = (reason = 'end', event) => {
bot.emit('end', reason, event)
bot.removeAllListeners()
bot._client.end()
bot._client.removeAllListeners()
}
bot._client = mc.createClient(bot.options)
bot.setMaxListeners(Infinity)
bot._client.setMaxListeners(Infinity)
bot.version = bot._client.version
bot.write = (name, data) => bot._client.write(name, data)
setNewBot(bot.server.host, bot)
const channel = dcclient.channels.cache.get(config.discord.servers[`${bot.server.host}:${bot.server.port}`])
channel.send(
`Connecting to: \`${bot.server.host}:${bot.server.port}\``
)
bot._client.on('login', (data) => bot.emit('login', data))
bot.on('login', async function (data) {
bot.entityId = data.entityId
bot.uuid = bot._client.uuid
bot.username = bot._client.username
channel.send(
`Successfully logged in to: \`${bot.server.host}:${bot.server.port}\``
)
})
await loadPlugins(bot, dcclient, config, rl)
bot._client.on('end', (reason) => {
bot.end(reason, 'end')
})
bot.on('end', (reason, event) => {
bot.console.info(
`Disconnected from ${bot.server.host} (${event} event): ${util.inspect(reason)}`
)
channel.send(`Disconnected: \`${util.inspect(reason)}\``)
let timeout = config.reconnectTimeout
try {
if (reason.text) {
if (reason.text ===
'Wait 5 seconds before connecting, thanks! :)' ||
reason.text ===
'You are logging in too fast, try again later.'
) timeout = 1000 * 7
}
} catch (e) {
bot.console.error(e)
}
setTimeout(() => {
bot.end()
createBot(server, config, getBots, setNewBot, dcclient, rl)
}, timeout)
})
bot._client.on('keep_alive', ({ keepAliveId }) => {
bot.write('keep_alive', { keepAliveId })
})
bot._client.on('kick_disconnect', (data) => {
const parsed = JSON.parse(data.reason)
bot.end(parsed, 'kick_disconnect')
})
bot._client.on('disconnect', (data) => {
const parsed = JSON.parse(data.reason)
bot.end(parsed, 'disconnect')
})
bot._client.on('error', (data) => {
bot.end(data, 'error')
})
return bot
};
module.exports = { createBot }

View file

@ -0,0 +1,19 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'botuser',
alias: [],
description: 'Shows the bot\'s username and UUID',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.tellraw(selector, [{ text: 'The bot\'s username is: ', color: 'white' }, { text: bot.username, color: 'gold', clickEvent: { action: 'copy_to_clipboard', value: bot.username }, hoverEvent: { action: 'show_text', contents: [{ text: 'Click here to copy the username to your clipboard', color: 'green' }] } }, { text: ' and the UUID is: ' }, { text: bot.uuid, color: 'aqua', clickEvent: { action: 'copy_to_clipboard', value: bot.uuid }, hoverEvent: { action: 'show_text', contents: [{ text: 'Click here to copy the UUID to your clipboard', color: 'green' }] } }])
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Bot\'s User')
.setDescription(`The bot's username is: \`${bot.username}\` and the UUID is: \`${bot.uuid}\``)
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,63 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'botvisibility',
alias: ['botvis', 'togglevis', 'togglevisibility'],
description: 'Changes the bot\'s visibility',
usage: [
'<hash> <true|false>',
'<hash> <on|off>',
'<hash>'
],
trusted: 1,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[1] === 'true' || args[1] === 'on') {
bot.visibility = true
bot.chat('/essentials:vanish disable')
bot.tellraw(selector, [{ text: 'The bot\'s visibility is now ', color: 'white' }, { text: 'visible', color: 'green' }])
} else if (args[1] === 'false' || args[1] === 'off') {
bot.visibility = false
bot.chat('/essentials:vanish enable')
bot.tellraw(selector, [{ text: 'The bot\'s visibility is now ', color: 'white' }, { text: 'invisible', color: 'gold' }])
} else if (!args[1]) {
bot.visibility = !bot.visibility
const greenOrGold = bot.visibility ? 'green' : 'gold'
const visibleOrInvisible = bot.visibility ? 'visible' : 'invisible'
const enableOrDisable = bot.visibility ? 'disable' : 'enable'
bot.chat(`/essentials:vanish ${enableOrDisable}`)
bot.tellraw(selector, [{ text: 'The bot\'s visibility is now ', color: 'white' }, { text: visibleOrInvisible, color: greenOrGold }])
} else {
throw new SyntaxError('Invalid argument')
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
if (args[0] === 'true' || args[0] === 'on') {
bot.visibility = true
bot.chat('/essentials:vanish disable')
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Bot\'s Visibility')
.setDescription('The bot\'s visibility is now visible')
channeldc.send({ embeds: [Embed] })
} else if (args[0] === 'false' || args[0] === 'off') {
bot.visibility = false
bot.chat('/essentials:vanish enable')
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Bot\'s Visibility')
.setDescription('The bot\'s visibility is now invisible')
channeldc.send({ embeds: [Embed] })
} else if (!args[0]) {
bot.visibility = !bot.visibility
const visibleOrInvisible = bot.visibility ? 'visible' : 'invisible'
const enableOrDisable = bot.visibility ? 'disable' : 'enable'
bot.chat(`/essentials:vanish ${enableOrDisable}`)
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Bot\'s Visibility')
.setDescription(`The bot's visibility is now ${visibleOrInvisible}`)
channeldc.send({ embeds: [Embed] })
} else {
throw new SyntaxError('Invalid argument')
}
}
}

View file

@ -0,0 +1,19 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'bruhify',
alias: [],
description: 'RecycleBot bruhify but actionbar',
usage: '<message>',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.bruhifyText = args.join(' ')
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
bot.bruhifyText = args.join(' ')
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Bruhify')
.setDescription(`Bruhify set to: ${bot.bruhifyText}`)
channeldc.send({ embeds: [Embed] })
}
}

13
ChomensJS/commands/cb.js Normal file
View file

@ -0,0 +1,13 @@
module.exports = {
name: 'cb',
alias: ['cmd', 'commandblock', 'run'],
description: 'Executes a command in the command core',
usage: '<command>',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.core.run(args.join(' '))
},
discordExecute (bot, username, sender, prefix, args, channeldc) {
bot.core.run(args.join(' '))
}
}

View file

@ -0,0 +1,22 @@
module.exports = {
name: 'clearchat',
alias: ['cc'],
description: 'Clears the chat',
usage: '[player]',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[0]) {
bot.tellraw(args.join(' '), [{ text: '\n'.repeat(100), color: 'white' }, { text: `Your chat has been cleared by ${username}.`, color: 'dark_green' }])
} else {
bot.tellraw('@a', [{ text: '\n'.repeat(100), color: 'white' }, { text: 'The chat has been cleared.', color: 'dark_green' }])
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message) {
if (args[0]) {
bot.tellraw(args.join(' '), [{ text: '\n'.repeat(100), color: 'white' }, { text: `Your chat has been cleared by ${username} (on Discord).`, color: 'dark_green' }])
} else {
bot.tellraw('@a', [{ text: '\n'.repeat(100), color: 'white' }, { text: 'The chat has been cleared.', color: 'dark_green' }])
}
}
}

View file

@ -0,0 +1,19 @@
module.exports = {
name: 'clearchatqueue',
description: 'Clears the bot\'s chat queue',
alias: ['ccq'],
usage: '',
trusted: 0,
execute (bot) {
if (bot._chatQueue[0]) {
bot.chatQueue = []
bot._chatQueue = []
}
},
discordExecute (bot) {
if (bot._chatQueue[0]) {
bot.chatQueue = []
bot._chatQueue = []
}
}
}

102
ChomensJS/commands/cloop.js Normal file
View file

@ -0,0 +1,102 @@
const { EmbedBuilder } = require('discord.js')
function list (bot, discord, channeldc, selector, config) {
const message = []
if (discord) {
for (const [index, { command, interval, list }] of Object.entries(bot.cloop.list)) {
if (!list) continue
message.push(index)
message.push(' > ')
message.push(`\`${command}\``)
message.push(' - ')
message.push(interval)
message.push('\n')
}
message.pop()
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Cloops')
.setDescription(message.join(''))
channeldc.send({ embeds: [Embed] })
} else {
message.push({ text: 'Cloops:', color: 'green' })
message.push('\n')
for (const [index, { command, interval, list }] of Object.entries(bot.cloop.list)) {
if (!list) continue
message.push({ text: index, color: 'aqua' })
message.push({ text: ' > ', color: 'gold' })
message.push({ text: command, color: 'green' })
message.push({ text: ' - ', color: 'gold' })
message.push({ text: interval, color: 'green' })
message.push('\n')
}
message.pop()
bot.tellraw(selector, message)
}
}
module.exports = {
name: 'cloop',
alias: [],
description: 'Loop commands',
usage: [
'<hash> add <interval> <command>',
'<hash> remove <index>',
'<hash> removeall|clear',
'<hash> list'
],
trusted: 1,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[1] === 'add' && args[3]) {
if (!Number(args[2]) && Number(args[2]) !== 0) throw new SyntaxError('Invalid interval')
bot.cloop.add(args.slice(3).join(' '), args[2])
bot.tellraw(selector, [{ text: 'Added command ', color: 'white' }, { text: args.slice(3).join(' '), color: 'aqua' }, { text: ' with interval ', color: 'white' }, { text: args[2], color: 'green' }, { text: ' to the cloops', color: 'white' }])
} else if (args[1] === 'list') {
list(bot, false, null, selector)
} else if (args[1] === 'remove') {
bot.cloop.remove(args[2])
bot.tellraw(selector, [{ text: 'Removed cloop ' }, { text: args[2], color: 'aqua' }])
} else if (args[1] === 'removeall' || args[1] === 'clear') {
bot.cloop.clear()
bot.tellraw(selector, [{ text: 'Removed all looped commands', color: 'white' }])
} else {
throw new SyntaxError('Invalid argument')
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
if (args[0] === 'add' && args[2]) {
if (!Number(args[1]) && Number(args[1]) !== 0) throw new SyntaxError('Invalid interval')
bot.cloop.add(args.slice(2).join(' '), args[1])
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Cloop')
.setDescription(`Added cloop \`${args.slice(2).join(' ')}\` with interval ${args[1]} to the cloops`)
channeldc.send({ embeds: [Embed] })
} else if (args[0] === 'list') {
list(bot, true, channeldc, '@a', config)
} else if (args[0] === 'remove') {
bot.cloop.remove(args[1])
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Cloop')
.setDescription(`Removed cloop \`${args[1]}\``)
channeldc.send({ embeds: [Embed] })
} else if (args[0] === 'removeall' || args[0] === 'clear') {
bot.cloop.clear()
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Cloop')
.setDescription('Removed all looped commands')
channeldc.send({ embeds: [Embed] })
} else {
throw new Error('Invalid argument')
}
}
}

View file

@ -0,0 +1,43 @@
const cowsay = require('cowsay2')
const cows = require('cowsay2/cows')
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'cowsay',
alias: [],
description: 'Moo',
usage: [
'cow <message>',
'list (not supported on Discord)'
],
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[0] === 'list') {
const listed = Object.keys(cows)
let primary = true
const message = []
for (const value of listed) {
message.push({
text: value + ' ',
color: (!((primary = !primary)) ? 'gold' : 'yellow'),
clickEvent: {
action: 'suggest_command',
value: `${prefix}cowsay ${value} `
}
})
}
bot.tellraw(selector, message)
} else {
bot.tellraw(selector, { text: cowsay.say(args.slice(1).join(' '), { cow: cows[args[0]] }) })
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Cowsay')
.setDescription(`\`\`\`\n${cowsay.say(args.slice(1).join(' '), { cow: cows[args[0]] })}\n\`\`\``)
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,18 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'creator',
alias: [],
description: 'Shows the bot\'s creator',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.tellraw(selector, [{ text: 'ChomeNS Bot ', color: 'yellow' }, { text: 'was created by ', color: 'white' }, { text: 'chayapak', color: 'gold' }, { text: ' (', color: 'dark_gray' }, { text: 'Cloned ', color: 'blue' }, { text: 'by ', color: 'white' }, { text: 'Parker', color: 'dark_red' }, { text: '2991', color: 'black' }, { text: ')', color: 'dark_gray' }])
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Creator')
.setDescription('ChomeNS Bot was created by chayapak (§9Cloned by §4Parker§02991)')
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,23 @@
module.exports = {
name: 'discord',
alias: [],
description: 'Shows the discord invite',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.tellraw(selector, [
{
text: 'The Discord invite is ',
color: 'white'
},
{
text: 'https://discord.gg/xdgCkUyaA4',
color: 'blue',
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/xdgCkUyaA4'
}
}
])
}
}

View file

@ -0,0 +1,41 @@
const { resize } = require('../util/image')
const axios = require('axios')
const sharp = require('sharp')
module.exports = {
name: 'draw',
description: 'Draws an image',
alias: [],
trusted: 0,
usage: '<image url (JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF)>',
execute: async function (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
let image
try {
const url = args.join(' ')
image = await axios.get('https://http-proxy.nongsonchome.repl.co', {
params: {
uri: url
},
responseType: 'arraybuffer'
})
const loaded = sharp(image.data)
const metadata = await loaded
.metadata()
const { width, height } = resize(metadata.width, metadata.height)
const { data, info } = await loaded
.resize({ fit: 'fill', kernel: 'nearest', width, height })
.raw()
.toBuffer({ resolveWithObject: true })
bot.draw(data, info)
} catch (_err) {
const e = _err.toString() === 'Error: Input buffer contains unsupported image format' ? image.data.toString() : _err
bot.tellraw(selector, { text: e, color: 'red' })
}
}
}

View file

@ -0,0 +1,13 @@
module.exports = {
name: 'echo',
alias: [],
description: 'Says a message',
usage: '<message>',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.chat(args.join(' '))
},
discordExecute (bot, username, sender, prefix, args, channeldc) {
bot.chat(args.join(' '))
}
}

13
ChomensJS/commands/end.js Normal file
View file

@ -0,0 +1,13 @@
module.exports = {
name: 'end',
alias: [],
description: 'Ends the bot\'s client',
usage: '<hash>',
trusted: 1,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.end('end command')
},
discordExecute (bot, username, sender, prefix, args, channeldc, message) {
bot.end('end command')
}
}

View file

@ -0,0 +1,60 @@
const { EmbedBuilder } = require('discord.js')
const { VM } = require('vm2')
const axios = require('axios')
const util = require('util')
const { stylize } = require('../util/colors/minecraft')
module.exports = {
name: 'eval',
alias: [],
description: 'Safe eval 100% secure!!!',
trusted: 1,
usage: [
'run <code>',
'reset'
],
async execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[0] === 'run') {
try {
bot.tellraw(selector, { text: util.inspect(bot.vm.run(args.slice(1).join(' ')), { stylize }).substring(0, 32000) })
} catch (err) {
bot.tellraw(selector, { text: util.inspect(err).replaceAll('runner', 'Parker2991'), color: 'red' })
}
}
if (args[0] === 'reset') {
bot.vm = new VM(bot.vmOptions)
}
if (args[0] === 'server') {
const res = await axios.post(config.eval.serverUrl, new URLSearchParams({
html: false,
showErrorMsg: false,
colors: 'minecraft',
code: args.slice(1).join(' ')
}).toString())
bot.tellraw(selector, { text: res.data })
}
},
async discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
if (args[0] === 'run') {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Output')
.setDescription(`\`\`\`${util.inspect(bot.vm.run(args.slice(1).join(' '))).substring(0, 1950)}\`\`\``)
channeldc.send({ embeds: [Embed] })
} else if (args[0] === 'reset') {
bot.vm = new VM(bot.vmOptions)
} else if (args[0] === 'server') {
const res = await axios.post(config.eval.serverUrl, new URLSearchParams({
html: false,
showErrorMsg: false,
code: args.slice(1).join(' ')
}).toString())
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Output')
.setDescription(`\`\`\`${res.data}\`\`\``)
channeldc.send({ embeds: [Embed] })
} else {
throw new SyntaxError('Invalid argument')
}
}
}

152
ChomensJS/commands/help.js Normal file
View file

@ -0,0 +1,152 @@
//samething here
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'help',
alias: ['heko', 'cmds', 'commands'],
description: 'Shows the help',
usage: '[command]',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[0]) {
for (const command of bot.command_handler.commands) {
function run () {
let alias = command.name
if (command.alias.toString() !== '') {
alias = command.alias.join(', ')
}
const usage = []
if (typeof command.usage === 'string') {
usage.push({ text: `${prefix}${command.name} `, color: 'gold' })
usage.push({ text: command.usage, color: 'aqua' })
} else {
for (const value of command.usage) {
usage.push({ text: `${prefix}${command.name} `, color: 'gold' })
usage.push({ text: value, color: 'aqua' })
usage.push('\n')
}
usage.pop()
}
const component = []
component.push({ text: prefix + command.name, color: 'gold' })
component.push({ text: ` (${alias})`, color: 'white' })
component.push({ text: ' - ', color: 'gray' })
component.push({ text: command.description, color: 'gray' })
component.push('\n')
component.push({ text: 'Trust level: ', color: 'green' })
component.push({ text: command.trusted, color: 'yellow' })
component.push('\n')
component.push({ text: 'Supported on Discord: ', color: 'green' })
component.push({ text: command.discordExecute ? 'true' : 'false', color: 'gold' })
component.push('\n')
component.push(usage)
bot.tellraw(selector, component)
}
if (command.name === args[0]) run()
for (const alias of command.alias) {
if (alias === args[0]) run()
}
};
} else {
const generalCommands = []
const trustedCommands = []
const ownerCommands = []
function component (command, color) {
return {
text: command.name + ' ',
color,
hoverEvent: {
action: 'show_text',
contents: [{
text: 'Click here to see the information for this command',
color: 'green'
}]
},
clickEvent: {
action: 'run_command',
value: `${prefix}help ${command.name}`
}
}
};
for (const command of bot.command_handler.commands) {
if (command.trusted !== 0 || command.proxy) continue
generalCommands.push(component(command, 'green'))
}
for (const command of bot.command_handler.commands) {
if (command.trusted !== 1 || command.proxy) continue
trustedCommands.push(component(command, 'red'))
}
for (const command of bot.command_handler.commands) {
if (command.trusted !== 2 || command.proxy) continue
ownerCommands.push(component(command, 'dark_red'))
}
const pre = [{ text: 'Commands ', color: 'gray' }, { text: '(', color: 'dark_gray' }, { text: 'Length: ', color: 'gray' }, { text: bot.command_handler.commands.length, color: 'green' }, { text: ') ', color: 'dark_gray' }, { text: '(', color: 'dark_gray' }, { text: 'Public ', color: 'green' }, { text: 'Trusted ', color: 'red' }, { text: 'Owner', color: 'dark_red' }, { text: ') - ', color: 'dark_gray' }]
bot.tellraw(selector, [pre, generalCommands, trustedCommands, ownerCommands])
}
},
discordExecute: async function (bot, username, sender, prefix, args, channeldc, message, config) {
if (args[0]) {
for (const command of bot.command_handler.commands) {
function run () {
let alias = command.name
if (command.alias.toString() !== '') {
alias = command.alias.join(', ')
}
const usage = []
if (typeof command.usage === 'string') {
usage.push(`${prefix}${command.name} ${command.usage}`)
} else {
for (const value of command.usage) {
usage.push(`${prefix}${command.name} ${value}`)
usage.push('\n')
}
usage.pop()
}
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle(`${prefix + command.name} (${alias}) - ${command.description}`)
.setDescription(`Trust level: ${command.trusted}
Supported: ${command.discordExecute ? 'true' : 'false'}
${usage}`
)
channeldc.send({ embeds: [Embed] })
}
if (command.name === args[0]) run()
for (const alias of command.alias) {
if (alias === args[0]) run()
}
};
} else {
let supportedCommands = ''
let unsupportedCommands = ''
for (const command of bot.command_handler.commands) {
if (!command.discordExecute) continue
supportedCommands += command.name + ' '
}
for (const command of bot.command_handler.commands) {
if (command.discordExecute || command.proxy) continue
unsupportedCommands += command.name + ' '
}
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle(`Commands (Length: ${bot.command_handler.commands.length})`)
.setDescription('**Supported Commands**\n' + supportedCommands + '\n**Unsupported Commands**\n' + unsupportedCommands)
channeldc.send({ embeds: [Embed] })
}
}
}

View file

@ -0,0 +1,76 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'list',
alias: [],
description: 'List players',
usage: '',
trusted: 0,
execute: async function (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
try {
const component = []
component.push({ text: 'Players ', color: 'green' })
component.push({ text: '(', color: 'dark_gray' })
component.push({ text: bot.players.list.length, color: 'gray' })
component.push({ text: ')', color: 'dark_gray' })
component.push('\n')
for (const property of bot.players.list) {
// if (property.match.startsWith('@')) continue;
component.push({
text: property.name,
color: 'yellow',
clickEvent: {
action: 'copy_to_clipboard',
value: property.name
},
hoverEvent: {
action: 'show_text',
contents: [{
text: 'Click here to copy the username to your clipboard',
color: 'green'
}]
}
})
component.push({
text: ' ',
color: 'dark_gray'
})
component.push({
text: property.UUID,
color: 'aqua',
clickEvent: {
action: 'copy_to_clipboard',
value: property.UUID
},
hoverEvent: {
action: 'show_text',
contents: [{
text: 'Click here to copy the UUID to your clipboard',
color: 'green'
}]
}
})
component.push('\n')
}
component.pop()
bot.tellraw(selector, component)
} catch (e) {
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
try {
let players = ''
for (const property of bot.players.list) {
// if (property.match.startsWith('@')) continue;
players += `\`${property.name}\` \`${property.UUID}\`` + '\n'
}
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle(`Players (${bot.players.list.length})`)
.setDescription(players.substring(0, 4096))
channeldc.send({ embeds: [Embed] })
} catch (e) {
}
}
}

369
ChomensJS/commands/music.js Normal file
View file

@ -0,0 +1,369 @@
/* eslint-disable no-case-declarations */
const fs = require('fs/promises')
const { EmbedBuilder } = require('discord.js')
const path = require('path')
const getFilenameFromUrl = require('../util/getFilenameFromUrl')
const fileExists = require('../util/file-exists')
const fileList = require('../util/file-list')
const axios = require('axios')
const os = require('os')
let SONGS_PATH
if (os.hostname() === 'chomens-kubuntu') {
SONGS_PATH = path.join(__dirname, '..', '..', 'nginx-html', 'midis')
} else {
SONGS_PATH = path.join(__dirname, '..', 'midis')
}
let song
async function play (bot, values, discord, channeldc, selector, config) {
try {
const filepath = values.join(' ')
const seperator = path.sep // for hosting bot on windows
let absolutePath
if (filepath.includes(seperator) && filepath !== '') {
const pathSplitted = filepath.split(seperator)
const songs = await fileList(
path.join(
SONGS_PATH,
pathSplitted[0]
)
)
// this part took a bunch of time to figure out, but still chomens moment!1!
const lowerCaseFile = pathSplitted.pop().toLowerCase()
const file = songs.filter((song) => song.toLowerCase().includes(lowerCaseFile))[0]
absolutePath = await resolve(path.join(pathSplitted.join(seperator), file))
} else {
const songs = await fileList(SONGS_PATH)
const file = songs.filter((song) => song.toLowerCase().includes(filepath.toLowerCase()))[0]
absolutePath = await resolve(file)
}
song = await bot.music.load(await fs.readFile(absolutePath), path.basename(absolutePath))
if (discord) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Music')
.setDescription(`Added ${song.name} to the song queue`)
channeldc.send({ embeds: [Embed] })
} else {
bot.tellraw(selector, [{ text: 'Added ', color: 'white' }, { text: song.name, color: 'gold' }, { text: ' to the song queue', color: 'white' }])
}
bot.music.queue.push(song)
bot.music.play(song)
} catch (e) {
bot.console.error(e.stack)
if (discord) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription('```SyntaxError: Invalid file```')
channeldc.send({ embeds: [Embed] })
} else {
bot.tellraw(selector, { text: 'SyntaxError: Invalid file', color: 'red' })
}
}
}
async function playUrl (bot, values, discord, channeldc, selector, config) {
let response
try {
const url = values.join(' ')
response = await axios.get('https://http-proxy.nongsonchome.repl.co', {
params: {
uri: url
},
responseType: 'arraybuffer'
})
song = await bot.music.load(response.data, getFilenameFromUrl(url))
if (discord) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Music')
.setDescription(`Added ${song.name} to the song queue`)
channeldc.send({ embeds: [Embed] })
} else {
bot.tellraw(selector, [{ text: 'Added ', color: 'white' }, { text: song.name, color: 'gold' }, { text: ' to the song queue', color: 'white' }])
}
bot.music.queue.push(song)
bot.music.play(song)
} catch (_err) {
const e = _err.toString().includes('Bad MIDI file. Expected \'MHdr\', got: ') ? response.data.toString() : _err
if (discord) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription(`\`\`\`${e}\`\`\``)
channeldc.send({ embeds: [Embed] })
} else {
bot.tellraw(selector, { text: e, color: 'red' })
}
}
}
async function resolve (filepath) {
if (!path.isAbsolute(filepath) && await fileExists(SONGS_PATH)) {
return path.join(SONGS_PATH, filepath)
}
return filepath
}
async function list (bot, discord, channeldc, prefix, selector, args, config) {
try {
let absolutePath
if (args[1]) absolutePath = await resolve(path.join(SONGS_PATH, args.slice(1).join(' ')))
else absolutePath = await resolve(SONGS_PATH)
if (!absolutePath.includes('midis')) throw new Error('bro trying to hack my server?!/1?!')
const listed = await fileList(absolutePath)
if (discord) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Songs')
.setDescription(listed.join(', '))
channeldc.send({ embeds: [Embed] })
return
}
let primary = true
const message = []
for (const value of listed) {
const isFile = (await fs.lstat(path.join(absolutePath, value))).isFile()
message.push({
text: value + ' ',
color: (!((primary = !primary)) ? 'gold' : 'yellow'),
clickEvent: {
action: 'suggest_command',
value: `${prefix}music ${isFile ? 'play' : 'list'} ${path.join(args.slice(1).join(' '), value)}`
},
hoverEvent: {
action: 'show_text',
contents: [
{ text: 'Name: ', color: 'white' },
{ text: value, color: 'gold' },
'\n',
{ text: 'Click here to suggest the command!', color: 'green' }
]
}
})
};
bot.tellraw(selector, message)
} catch (e) {
if (discord) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription(`\`\`\`${e.toString()}\`\`\``)
channeldc.send({ embeds: [Embed] })
} else {
bot.tellraw(selector, { text: e.toString(), color: 'red' })
}
}
};
module.exports = {
name: 'music',
description: 'Plays music',
alias: [],
trusted: 0,
usage: [
'play <song|url>',
'stop',
'loop <all|current|off>',
'list [directory]',
'skip',
'nowplaying',
'queue'
],
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
switch (args[0]) {
case 'play':
case 'playurl': // deprecated
if (args.slice(1).join(' ').startsWith('http')) {
playUrl(bot, args.slice(1), false, null, selector, config)
} else {
play(bot, args.slice(1), false, null, selector, config)
}
break
case 'stop':
bot.tellraw(selector, { text: 'Cleared the song queue' })
bot.music.stop()
break
case 'skip':
try {
bot.tellraw(selector, [{ text: 'Skipping ' }, { text: bot.music.song.name, color: 'gold' }])
bot.music.skip()
} catch (e) {
throw new Error('No music is currently playing!')
}
break
case 'loop':
switch (args[1]) {
case 'off':
bot.music.loop = 0
bot.tellraw(selector, [
{
text: 'Looping is now '
},
{
text: 'disabled',
color: 'red'
}
])
break
case 'current':
bot.music.loop = 1
bot.tellraw(selector, [
{
text: 'Now Looping '
},
{
text: song.name,
color: 'gold'
}
])
break
case 'all':
bot.music.loop = 2
bot.tellraw(selector, {
text: 'Now looping every song'
})
break
default:
throw new SyntaxError('Invalid argument')
}
break
case 'list':
list(bot, false, null, prefix, selector, args, config)
break
case 'nowplaying':
bot.tellraw(selector, [
{
text: 'Now playing '
},
{
text: bot.music.song.name,
color: 'gold'
}
])
break
case 'queue':
const queueWithName = []
for (const song of bot.music.queue) queueWithName.push(song.name)
bot.tellraw(selector, [
{
text: 'Queue: ',
color: 'green'
},
{
text: queueWithName.join(', '),
color: 'aqua'
}
])
break
default:
throw new SyntaxError('Invalid argument')
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
let Embed
switch (args[0]) {
case 'play':
play(bot, args.slice(1), true, channeldc, config)
break
case 'playurl':
playUrl(bot, args.slice(1), true, channeldc, config)
break
case 'stop':
try {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Stop')
.setDescription('Cleared the song queue')
channeldc.send({ embeds: [Embed] })
} catch (e) {
return
}
bot.music.stop()
break
case 'skip':
try {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Skip')
.setDescription(`Skipping ${bot.music.song.name}`)
channeldc.send({ embeds: [Embed] })
bot.music.skip()
} catch (e) {
throw new Error('No music is currently playing!')
}
break
case 'loop':
switch (args[1]) {
case 'off':
bot.music.loop = 0
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Loop')
.setDescription('Looping is now disabled')
channeldc.send({ embeds: [Embed] })
break
case 'current':
bot.music.loop = 1
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Loop')
.setDescription(`Now looping ${song.name}`)
channeldc.send({ embeds: [Embed] })
break
case 'all':
bot.music.loop = 2
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Loop')
.setDescription('Now looping every song')
channeldc.send({ embeds: [Embed] })
break
}
break
case 'list':
list(bot, true, channeldc, prefix, '@a', args, config)
break
case 'nowplaying':
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Now playing')
.setDescription(`Now playing ${bot.music.song.name}`)
channeldc.send({ embeds: [Embed] })
break
case 'queue':
const queueWithName = []
for (const song of bot.music.queue) queueWithName.push(song.name)
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Queue')
.setDescription(queueWithName.join(', '))
channeldc.send({ embeds: [Embed] })
break
default:
throw new SyntaxError('Invalid argument')
}
}
}

View file

@ -0,0 +1,50 @@
module.exports = {
name: 'netmsg',
alias: ['networkmessage', 'irc'],
description: 'Broadcasts a message to all of the servers that the bot is connected',
usage: '<message>',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
const message = args.join(' ')
if (message.toLowerCase().includes('netmsg')) return // lazy fix
const component = [
{
text: '[',
color: 'dark_gray'
},
{
text: bot.server.host === 'kitsune.icu' ? 'kit' : bot.server.host,
color: 'gray'
},
bot.server.host === 'kitsune.icu'
? {
text: 'sune.icu',
color: 'gray'
}
: '',
{
text: '] ',
color: 'dark_gray'
},
{
text: username,
color: 'gray'
},
{
text: ' \u203a ',
color: 'dark_gray'
},
{
text: message,
color: 'gray'
}
]
const bots = bot.getBots()
for (const bot of bots) {
bot.tellraw(selector, component)
}
}
}

View file

@ -0,0 +1,13 @@
module.exports = {
name: 'refillcore',
alias: ['rc'],
description: 'Resets the bot\'s command core',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.core.fillCore()
},
discordExecute (bot) {
bot.core.fillCore()
}
}

13
ChomensJS/commands/rtp.js Normal file
View file

@ -0,0 +1,13 @@
const { between } = require('../util/between')
module.exports = {
name: 'rtp',
alias: [],
description: 'Randomly teleports the player',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
const pos = `${between(1000, 10000)} 100 ${between(1000, 10000)}`
bot.tellraw(selector, [{ text: 'Teleporting ', color: 'white' }, { text: username, color: 'aqua' }, { text: ' to ', color: 'white' }, { text: pos, color: 'green' }, { text: '...', color: 'white' }])
bot.core.run(`essentials:teleport ${sender} ${pos}`)
}
}

View file

@ -0,0 +1,33 @@
/* eslint-disable no-eval */
const util = require('util')
const { stylize } = require('../util/colors/minecraft')
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'servereval',
alias: [],
description: 'Basically eval command but without vm2',
trusted: 2,
usage: '<ownerhash> <code>',
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
try {
bot.tellraw(selector, { text: util.inspect(eval(args.slice(1).join(' ')), { stylize }).substring(0, 32700) })
} catch (err) {
bot.tellraw(selector, { text: util.inspect(err).replaceAll('runner', 'home'), color: 'red' })
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
try {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Output')
.setDescription(util.inspect(eval(args.join(' '))))
channeldc.send({ embeds: [Embed] })
} catch (err) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription(`\`\`\`${util.inspect(err).replaceAll('runner', 'home')}\`\`\``)
channeldc.send({ embeds: [Embed] })
}
}
}

View file

@ -0,0 +1,66 @@
const os = require('os')
const path = require('path')
const fs = require('fs/promises')
const { EmbedBuilder } = require('discord.js')
// should i move this to util?
async function getCpuModelName () {
const cpuInfo = await fs.readFile('/proc/cpuinfo')
const lines = cpuInfo.toString().split('\n')
// among us way of doing it
const modelName = lines.find((line) => line.startsWith('model name')).split('\t: ')
return modelName[1]
}
module.exports = {
name: 'serverinfo',
alias: [],
description: 'Shows the info about the server that is hosting the bot',
trusted: 0,
usage: '',
execute: async function (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
const component = []
component.push({ text: 'Hostname: ', color: 'gold' })
component.push({ text: os.hostname(), color: 'aqua' })
component.push('\n')
component.push({ text: 'Working directory: ', color: 'gold' })
component.push({ text: path.join(__dirname, '..') /* if without .. it will includes the commands directory */, color: 'aqua' })
component.push('\n')
component.push({ text: 'OS architecture: ', color: 'gold' })
component.push({ text: os.arch(), color: 'aqua' })
component.push('\n')
component.push({ text: 'OS platform: ', color: 'gold' })
component.push({ text: os.platform(), color: 'aqua' })
component.push('\n')
component.push({ text: 'OS name: ', color: 'gold' })
component.push({ text: os.version(), color: 'aqua' })
component.push('\n')
component.push({ text: 'CPU cores: ', color: 'gold' })
component.push({ text: os.cpus().length, color: 'aqua' })
component.push('\n')
component.push({ text: 'CPU model: ', color: 'gold' })
component.push({ text: await getCpuModelName(), color: 'aqua' })
component.push('\n')
component.push({ text: 'Total memory usage: ', color: 'gold' })
component.push({ text: `${Math.floor(os.totalmem() / 1024 / 1024)} MB`, color: 'aqua' })
component.push('\n')
component.push({ text: 'Available memory usage: ', color: 'gold' })
component.push({ text: `${Math.floor(os.freemem() / 1024 / 1024)} MB`, color: 'aqua' })
bot.tellraw(selector, component)
},
discordExecute: async function (bot, username, sender, prefix, args, channeldc, message, config) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Server Info')
.setDescription(`Hostname: \`${os.hostname()}\`
Working directory: \`${path.join(__dirname, '..')}\`
OS architecture: \`${os.arch()}\`
OS platform: \`${os.platform()}\`
OS name: \`${os.version()}\`
CPU cores: \`${os.cpus().length}\`
CPU model: \`${await getCpuModelName()}\`
Total memory usage: \`${Math.floor(os.totalmem() / 1024 / 1024)} MB\`
Available memory usage: \`${Math.floor(os.freemem() / 1024 / 1024)} MB\``)
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,35 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'test',
alias: [],
description: 'Tests if the bot is working',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
bot.tellraw(selector, [
{
text: `Username: ${username},`,
color: 'green'
},
{
text: ` Sender UUID: ${sender},`,
color: 'green'
},
{
text: ` Prefix: ${prefix},`,
color: 'green'
},
{
text: ` Args: ${args.join(', ').toString()}`,
color: 'green'
}
])
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Hello!')
.setDescription('This is the first ever command to be discordified!' + '\n' + `More info: Username: ${username}, Prefix: ${prefix}, Args: ${args.join(' ')}`)
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,37 @@
const { EmbedBuilder } = require('discord.js')
const moment = require('moment-timezone')
module.exports = {
name: 'time',
alias: [],
description: 'Shows the time',
usage: '<timezone>',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
const timezone = args.join(' ')
if (!moment.tz.names().map((zone) => zone.toLowerCase()).includes(timezone.toLowerCase())) {
throw new SyntaxError('Invalid timezone')
}
const momented = moment().tz(timezone).format('dddd, MMMM Do, YYYY, hh:mm:ss A')
const component = [{ text: 'The current date and time for the timezone ', color: 'white' }, { text: timezone, color: 'aqua' }, { text: ' is: ', color: 'white' }, { text: momented, color: 'green' }]
bot.tellraw(selector, component)
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
const timezone = args.join(' ')
if (!moment.tz.names().map((zone) => zone.toLowerCase()).includes(timezone.toLowerCase())) {
throw new SyntaxError('Invalid timezone')
}
const momented = moment().tz(timezone).format('dddd, MMMM Do, YYYY, hh:mm:ss A')
const description = `The current date and time for the timezone ${timezone} is: ${momented}`
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Time')
.setDescription(description)
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,63 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'tpsbar',
alias: ['tps'],
description: 'Shows the server\'s TPS using Minecraft bossbar',
usage: '<on|off>',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
switch (args[0]) {
case 'on':
bot.tps.on()
bot.tellraw(selector, [
{
text: 'TPSBar is now ',
color: 'white'
},
{
text: 'enabled',
color: 'green'
}
])
break
case 'off':
bot.tps.off()
bot.tellraw(selector, [
{
text: 'TPSBar is now ',
color: 'white'
},
{
text: 'disabled',
color: 'red'
}
])
break
default:
throw new SyntaxError('Invalid argument')
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
let Embed
switch (args[0]) {
case 'on':
bot.tps.on()
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('TPSBar')
.setDescription('TPSBar is now enabled')
channeldc.send({ embeds: [Embed] })
break
case 'off':
bot.tps.off()
Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('TPSBar')
.setDescription('TPSBar is now disabled')
channeldc.send({ embeds: [Embed] })
break
default:
throw new SyntaxError('Invalid argument')
}
}
}

View file

@ -0,0 +1,33 @@
const { EmbedBuilder } = require('discord.js')
const { translate } = require('@vitalets/google-translate-api')
module.exports = {
name: 'translate',
alias: [],
description: 'Translate a message using Google Translate',
usage: '<language 1> <language 2> <message>',
trusted: 0,
execute: async function (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
try {
const res = await translate(args.slice(2).join(' '), { from: args[0], to: args[1] })
bot.tellraw(selector, [{ text: 'Result: ', color: 'gold' }, { text: res.text, color: 'green' }])
} catch (e) {
bot.tellraw(selector, { text: String(e), color: 'red' })
}
},
discordExecute: async function (bot, username, sender, prefix, args, channeldc, message, config) {
try {
const res = await translate(args.slice(2).join(' '), { from: args[0], to: args[1] })
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Result')
.setDescription(res.text)
channeldc.send({ embeds: [Embed] })
} catch (e) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription(`\`\`\`${e}\`\`\``)
channeldc.send({ embeds: [Embed] })
}
}
}

View file

@ -0,0 +1,23 @@
const { EmbedBuilder } = require('discord.js')
const moment = require('moment-timezone')
module.exports = {
name: 'uptime',
alias: [],
description: 'Shows the bot\'s uptime',
usage: '',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
const duration = moment.duration(Math.floor(performance.now()))
const time = `${duration.days()} days, ${duration.hours()} hours, ${duration.minutes()} minutes, ${duration.seconds()} seconds` // moment please add duration.format()
bot.tellraw(selector, [{ text: 'The bot\'s uptime is ', color: 'white' }, { text: time, color: 'green' }])
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
const duration = moment.duration(Math.floor(performance.now()))
const time = `${duration.days()} days, ${duration.hours()} hours, ${duration.minutes()} minutes, ${duration.seconds()} seconds` // moment please add duration.format()
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Bot\'s Uptime')
.setDescription(`The bot's uptime is ${time}`)
channeldc.send({ embeds: [Embed] })
}
}

View file

@ -0,0 +1,19 @@
const urban = require('urban-dictionary')
module.exports = {
name: 'urban',
alias: [],
description: 'Working Urban Dictionary',
usage: '<word>',
trusted: 0,
async execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
try {
const definitions = await urban.define(args.join(' '))
for (const definition of definitions) {
bot.tellraw(selector, [{ text: '[', color: 'dark_red' }, { text: 'Urban', color: 'red' }, { text: '] ', color: 'dark_red' }, { text: definition.word, color: 'white' }, { text: ' - ', color: 'white' }, { text: definition.definition, color: 'white' }])
}//
} catch (e) {
bot.tellraw(selector, { text: e.toString(), color: 'red' })
}
}
}

View file

@ -0,0 +1,84 @@
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'uuid',
alias: [],
description: 'Gets the UUID of a player. If no player specified it will show your UUID instead',
usage: '[player (required on Discord)]',
trusted: 0,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[0]) {
const playername = args.join(' ')
const player = bot.players.list.find((user) => user.name === playername)
if (!player) throw new SyntaxError('Invalid username')
const playerUUID = player.UUID
bot.tellraw(selector,
[
{
text: `${playername}'s UUID: `,
color: 'green'
},
{
text: playerUUID,
color: 'aqua',
clickEvent: {
action: 'copy_to_clipboard',
value: playerUUID
},
hoverEvent: {
action: 'show_text',
contents: [
{
text: 'Click here to copy the UUID to your clipboard',
color: 'green'
}
]
}
}
])
} else {
bot.tellraw(selector,
[
{
text: 'Your UUID: ',
color: 'green'
},
{
text: sender,
color: 'aqua',
clickEvent: {
action: 'copy_to_clipboard',
value: sender
},
hoverEvent: {
action: 'show_text',
contents: [
{
text: 'Click here to copy the uuid to your clipboard',
color: 'green'
}
]
}
}
])
}
},
discordExecute (bot, username, sender, prefix, args, channeldc, message, config) {
if (args[0]) {
const playername = args.join(' ')
const player = bot.players.list.find((user) => user.name === playername)
if (!player) throw new SyntaxError('Invalid username')
const playerUUID = player.UUID
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('UUID')
.setDescription(`${playername}'s UUID: ${playerUUID}`)
channeldc.send({ embeds: [Embed] })
} else {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription('No player name specified')
channeldc.send({ embeds: [Embed] })
}
}
}

View file

@ -0,0 +1,14 @@
module.exports = {
name: 'validate',
description: 'Validates a hash',
alias: ['checkhash'],
usage: '<hash|ownerHash>',
trusted: 1,
execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
if (args[0] === hash) {
bot.tellraw(selector, { text: 'Valid hash', color: 'green' })
} else if (args[0] === ownerhash) {
bot.tellraw(selector, { text: 'Valid OwnerHash', color: 'green' })
}
}
}

View file

@ -0,0 +1,36 @@
const wiki = require('wikipedia')
const util = require('util')
const { EmbedBuilder } = require('discord.js')
module.exports = {
name: 'wikipedia',
alias: ['wiki'],
description: 'Working Wikipedia!',
usage: '<page>',
trusted: 0,
execute: async function (bot, username, sender, prefix, args, config, hash, ownerhash, selector) {
try {
const page = await wiki.page(args.join(' '))
const summary = await page.summary()
bot.tellraw(selector, { text: summary.extract, color: 'green' })
} catch (e) {
bot.tellraw(selector, { text: e.toString(), color: 'red' })
}
},
discordExecute: async function (bot, username, sender, prefix, args, channeldc, message, config) {
try {
const page = await wiki.page(args.join(' '))
const summary = await page.summary()
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.normal)
.setTitle('Output')
.setDescription(summary.extract)
channeldc.send({ embeds: [Embed] })
} catch (e) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription(`\`\`\`${util.inspect(e)}\`\`\``)
channeldc.send({ embeds: [Embed] })
}
}
}

77
ChomensJS/default.js Normal file
View file

@ -0,0 +1,77 @@
module.exports = {
version: '1.19.2',
prefixes: [
'default*',
'defaultcbot ',
'/defaultcbot '
],
commandsDir: '../commands', // this will be used by the commands.js in the plugins folder so it needs ../
keys: {
normalKey: 'normal hash key here',
ownerHashKey: 'OwnerHash™ key here'
},
proxy: {
enabled: true,
version: '1.19.2'
},
console: true,
chat: {
messageLength: 100
},
core: {
layers: 3,
refillInterval: 1000 * 60,
customName: [
{
text: 'ChomeNS ',
color: 'yellow'
},
{
text: 'Core',
color: 'green'
},
{
text: '\u2122',
color: 'gold'
}
]
},
self_care: {
prefix: true,
op: true,
cspy: true,
vanish: true,
nickname: true,
socialspy: true,
gamemode: true,
mute: true,
endCredits: true
},
eval: {
serverUrl: 'http://localhost:4445/'
},
reconnectTimeout: 1000 * 2,
timeoutInterval: 1000 * 40,
self_care_check_interval: 2000,
discord: {
prefix: 'default!',
servers: {
'localhost:25565': '696969696969696969'
},
embedsColors: {
normal: '#FFFF00',
error: '#FF0000'
}
},
servers: [
// logging means log to console
{
host: 'localhost',
port: 25565,
username: 'ChomeNS_Bot',
kaboom: false,
logging: true,
useChat: false
}
]
}

48
ChomensJS/index.js Normal file
View file

@ -0,0 +1,48 @@
const fs = require('fs/promises')
const fileExist = require('./util/file-exists')
const path = require('path')
const { createBot } = require('./bot')
let config
function load () {
// these stuff takes time to load so i move it here
const readline = require('node:readline')
const { stdin: input, stdout: output } = require('node:process')
const rl = readline.createInterface({ input, output })
const { Client, GatewayIntentBits } = require('discord.js')
const { MessageContent, GuildMessages, Guilds } = GatewayIntentBits
const dcclient = new Client({ intents: [Guilds, GuildMessages, MessageContent] })
let bots = []
dcclient.on('ready', () => {
for (const server of config.servers) {
const getBots = () => bots
const setNewBot = (server, bot) => {
bots = bots.filter((eachBot) => eachBot.server.host !== server)
bots.push(bot)
}
createBot(server, config, getBots, setNewBot, dcclient, rl)
}
})
require('dotenv').config()
dcclient.login(process.env.discordtoken)
}
// TODO: improve this thing
async function checkConfig () {
if (!await fileExist(path.join(__dirname, 'config.js'))) {
console.error('Config file doesn\'t exist, so the default one was created')
await fs.copyFile(path.join(__dirname, 'default.js'), path.join(__dirname, 'config.js'))
}
config = require('./config')
load()
}
checkConfig()
process.on('uncaughtException', (e) => {
console.log('uncaught ' + e.stack)
})

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,26 @@
const convert = require('color-convert')
module.exports = {
inject: function (bot) {
bot.bruhifyText = ''
let startHue = 0
const timer = setInterval(() => {
if (bot.bruhifyText === '') return
let hue = startHue
const displayName = bot.bruhifyText
const increment = (360 / Math.max(displayName.length, 20))
const component = []
for (const character of displayName) {
const color = convert.hsv.hex(hue, 100, 100)
component.push({ text: character, color: `#${color}` })
hue = (hue + increment) % 360
}
bot.core.run(`minecraft:title @a actionbar ${JSON.stringify(component)}`)
startHue = (startHue + increment) % 360
}, 100)
bot.on('end', () => {
clearInterval(timer)
})
}
}

76
ChomensJS/plugins/chat.js Normal file
View file

@ -0,0 +1,76 @@
const { containsIllegalCharacters } = require('../util/containsIllegalCharacters')
const { chatPacketListener, parsePlayerMessages } = require('../util/chat')
const minecraftVersionToNumber = require('../util/minecraftVersionToNumber')
function inject (bot, dcclient, config) {
bot.chatQueue = []
bot._chatQueue = []
const _chatQueueInterval = setInterval(() => {
if (bot.chatQueue.length !== 0) {
if (containsIllegalCharacters(bot.chatQueue[0])) {
bot.chatQueue.shift()
return
};
for (const subMessage of bot.chatQueue[0].split('\n')) {
if (!subMessage) return
let smallMsg
for (let i = 0; i < subMessage.length; i += config.chat.messageLength) {
smallMsg = subMessage.substring(i, i + config.chat.messageLength)
bot._chatQueue.push(smallMsg)
}
}
bot.chatQueue.shift()
}
}, 0)
const chatQueueInterval = setInterval(function () {
if (bot._chatQueue.length !== 0) {
if (bot._chatQueue[0].startsWith('/') && minecraftVersionToNumber(bot.version) >= 1.19) {
// totallynotskidded™ from mineflayer
const command = bot._chatQueue[0].slice(1)
const timestamp = BigInt(Date.now())
bot._client.write('chat_command', {
command,
timestamp,
salt: 0n,
argumentSignatures: [],
signedPreview: false,
messageCount: 0,
acknowledged: Buffer.alloc(3),
previousMessages: []
})
} else {
bot._client.chat(bot._chatQueue[0])
}
bot._chatQueue.shift()
}
}, 450)
bot.chat = (message) => {
bot.chatQueue.push(String(message))
}
bot.on('end', () => {
clearInterval(chatQueueInterval)
clearInterval(_chatQueueInterval)
})
function listener (packet) {
chatPacketListener(
packet,
bot,
minecraftVersionToNumber(bot.version) >= 1.19
)
}
// TODO: support playerChat (formattedMessage doesn't exist on kaboom so prefixes like [OP] doesn't appear)
// bot._client.on('playerChat', listener)
bot._client.on('systemChat', listener)
bot._client.on('chat', listener)
bot.on('message', (message, parsedMessage) => parsePlayerMessages(message, parsedMessage, bot))
}
module.exports = { inject }

View file

@ -0,0 +1,25 @@
function inject (bot) {
bot.cloop = {
list: [],
add (command, interval, list = true) {
const id = setInterval(() => bot.core.run(command), interval)
const thingsToPush /* ig not the best variable name */ = { id, interval, command, list }
bot.cloop.list.push(thingsToPush)
return thingsToPush
},
remove (item) {
clearInterval(bot.cloop.list[item].id)
bot.cloop.list.splice(item, 1)
},
clear () {
for (const interval of bot.cloop.list) clearInterval(interval.id)
bot.cloop.list = []
}
}
}
module.exports = { inject }

View file

@ -0,0 +1,123 @@
const path = require('path')
const { EmbedBuilder } = require('discord.js')
function inject (bot, dcclient, config) {
const loadFiles = require('../util/load_files')
const channeldc = dcclient.channels.cache.get(config.discord.servers[`${bot.server.host}:${bot.server.port}`])
bot.command_handler = {}
bot.command_handler.commands = {}
bot.command_handler.reload = async function () {
bot.command_handler.commands = await loadFiles(path.join(__dirname, config.commandsDir))
}
bot.command_handler.reload()
bot.command_handler.main = function (prefix, username, message, sender, channeldc, hash, ownerhash, selector) {
bot.command_handler.reload()
let raw
let command
const discord = !!message.content
discord
? raw = message.content.substring(prefix.length)
: raw = message.substring(prefix.length)
const [commandName, ...args] = raw.split(' ')
command = bot.command_handler.commands.find((command) => command.name === commandName.toLowerCase())
try {
const alias = bot.command_handler.commands.find((command) => command.alias.includes(commandName.toLowerCase()))
if (alias) command = alias
if (prefix === '3*' && message.endsWith('3*') && message !== '3*') return
if (!command) throw new Error(`Unknown command: "${commandName}"`)
if (command.trusted > 0) {
const discordRoles = message.member?.roles?.cache // do i need the "?"s ?
// TODO: Don't hardcode the roles
// trusted and host
// discord
if (
discord &&
command.trusted === 1 &&
!discordRoles.some((role) => role.name === 'Trusted' || role.name === 'chomens' || role.name === 'FNFBoyfriendBot Owner')
) throw new Error('You\'re not in the trusted role!')
// in game
if (
!discord &&
command.trusted === 1 &&
args[0] !== hash &&
args[0] !== ownerhash
) throw new Error('Invalid hash')
// FNFBoyfriendBot Owner
// || role.name === 'Host'
if (
discord &&
command.trusted === 2 &&
!discordRoles.some((role) => role.name === 'chomens' || role.name === 'FNFBoyfriendBot Owner')
) throw new Error('You\'re not in the host role!')
// in game
if (
!discord &&
command.trusted === 2 &&
args[0] !== ownerhash
) throw new Error('Invalid OwnerHash')
}
if (prefix === config.discord.prefix) {
if (!command.discordExecute) throw new Error('This command is not yet supported on Discord!')
command.discordExecute(bot, username, sender, prefix, args, channeldc, message, config)
} else {
command.execute(bot, username, sender, prefix, args, config, hash, ownerhash, selector)
}
} catch (e) {
if (prefix === config.discord.prefix) {
const Embed = new EmbedBuilder()
.setColor(config.discord.embedsColors.error)
.setTitle('Error')
.setDescription(`\`\`\`${e}\`\`\``)
channeldc.send({ embeds: [Embed] })
} else {
bot.tellraw(selector, { text: String(e), color: 'red' })
}
}
}
bot.command_handler.run = function (username, message, sender, channeldc, hash, ownerhash, selector = '@a') {
for (const prefix of config.prefixes) {
if (!message.startsWith(prefix)) continue
bot.command_handler.main(prefix, username, message, sender, channeldc, hash, ownerhash, selector)
}
}
bot.on('chat', async (_username, _message) => {
const username = _username?.replace(/§.?/g, '')
const sender = bot.players.list.find((val) => val.name === username)?.UUID
const message = _message?.replace(/* /§r/g */ /§.?/g, '')/* .replace(/§/g, '') */
bot.command_handler.run(username, message, sender, channeldc, bot.hash, bot.ownerHash)
})
bot.on('cspy', async function (_username, _message) {
const username = _username.replace(/§.?/g, '')
const message = _message.replace(/§.?/g, '')
const sender = bot.players.list.find((val) => val.name === username)?.UUID
bot.command_handler.run(username, message, sender, channeldc, bot.hash, bot.ownerHash, username)
})
function handleDiscordMessages (message) {
try {
// ignores the message that comes from the bot itself
if (message.author.id === dcclient.user.id) return
// only receive messages in SPECIFIC channel
if (message.channel.id !== channeldc.id) return
if (!message.content.startsWith(config.discord.prefix)) return
bot.command_handler.main(config.discord.prefix, message.member.displayName, message, 'no sender for discord', channeldc)
} catch (e) {
bot.console.error(e.stack)
};
}
bot.on('end', () => {
dcclient.off('messageCreate', handleDiscordMessages)
})
dcclient.on('messageCreate', handleDiscordMessages)
};
module.exports = { inject }

View file

@ -0,0 +1,107 @@
const moment = require('moment-timezone')
function inject (bot, _dcclient, config, rl) {
// readline > fix on log
function log (...args) {
rl.output.write('\x1b[2K\r')
console.log(args.toString())
rl._refreshLine()
};
const chatMessage = require('prismarine-chat')(bot.version)
function prefix (prefix, _message) {
const message = `[${moment().format('DD/MM/YY HH:mm:ss')} ${prefix}§r] [${bot.server.host}] `
const component = chatMessage.MessageBuilder.fromString(message).toJSON()
return chatMessage.fromNotch(component).toAnsi() + _message
}
const originalConsole = console
this.log = (...args) => {
rl.output.write('\x1b[2K\r')
originalConsole.log(args.toString())
rl._refreshLine()
}
bot.console = {}
bot.console.host = 'all'
bot.console.log = function (message) {
log(prefix('&6LOG', message))
}
bot.console.info = function (message) {
log(prefix('&aINFO', message))
}
bot.console.error = function (error) {
log(prefix('&cERROR', typeof error === 'string' ? error : error.stack))
}
// previous message is op feature to have in console :)
let previousMessage = ''
bot.on('message', (message) => {
if (!bot.options.logging) return
if (previousMessage === message.toString()) return
previousMessage = message.toString()
bot.console.log(message.toAnsi())
})
if (!config.console) return
function handleLine (line) {
try {
if (line.toLowerCase() === '' ||
line.toLowerCase().startsWith(' ')) return
if (line.startsWith('.csvr ')) {
const host = line.substring(6)
for (const eachBot of bot.getBots()) eachBot.console.host = host
bot.console.info(`Host set to: ${host}`)
return
}
if (bot.server.host !== bot.console.host && bot.console.host !== 'all') return
if (line === '.kill') process.exit()
if (line.startsWith('.')) {
return bot.command_handler.run(
bot.username,
config.prefixes[0] + line.substring(1),
bot.uuid,
null,
'h',
'o'
)
}
bot.tellraw('@a', [
{
text: '[',
color: 'dark_gray'
},
{
text: `${bot.username} Console`,
color: 'gray'
},
{
text: '] ',
color: 'dark_gray'
},
{
text: 'chayapak ',
color: 'green'
},
{
text: '\u203a ',
color: 'dark_gray'
},
chatMessage.MessageBuilder.fromString('&7' + line)
])
} catch (e) {
bot.console.error(e)
}
}
rl.on('line', handleLine)
bot.on('end', () => {
rl.off('line', handleLine)
})
}
module.exports = { inject }

115
ChomensJS/plugins/core.js Normal file
View file

@ -0,0 +1,115 @@
const nbt = require('prismarine-nbt');
const Vec3 = require('vec3');
const relativePosition = new Vec3(0, 0, 0);
function inject(bot, dcclient, config) {
const mcData = require('minecraft-data')(bot.version);
const impulseMode = !bot.options.kaboom;
const core = {
// Initialize the height to 0
height: 0,
run(command) {
try {
// Check if height has reached the maximum configured height
if (core.height >= config.core.layers) {
// Reset the height to 0 and the relativePosition to (0, 0, 0)
core.height = 0;
relativePosition.x = 0;
relativePosition.y = 0;
relativePosition.z = 0;
}
const location = {
x: core.start.x + relativePosition.x,
y: core.start.y + core.height, // Use the core height
z: core.start.z + relativePosition.z
};
if (impulseMode) bot.write('update_command_block', { location, command: '', mode: 0, flags: 0 });
bot.write('update_command_block', {
location,
command: String(command).substring(0, 32767),
mode: impulseMode ? 2 : 1,
flags: 0b101
});
// Increment the relativePosition.x and update the height accordingly
relativePosition.x++;
if (relativePosition.x >= 16) {
relativePosition.x = 0;
relativePosition.z++;
if (relativePosition.z >= 16) {
relativePosition.z = 0;
core.height++; // Increment the height
}
}
} catch (e) {
bot.console.error(e);
}
},
fillCore() {
core.start = new Vec3(
Math.floor(bot.position.x / 16) * 16,
0 /* bot.position.y */,
Math.floor(bot.position.z / 16) * 16
).floor();
core.end = core.start.clone().translate(16, config.core.layers, 16).subtract(new Vec3(1, 1, 1));
placeCore();
}
};
bot.core = core;
function placeCore() {
try {
const fillCommand = `minecraft:fill ${core.start.x} ${core.start.y} ${core.start.z} ${core.end.x} ${core.end.y} ${core.end.z} repeating_command_block{CustomName:'${JSON.stringify(config.core.customName)}'}`;
const location = { x: Math.floor(bot.position.x), y: Math.floor(bot.position.y) - 1, z: Math.floor(bot.position.z) };
bot.write('set_creative_slot', {
slot: 36,
item: {
present: true,
itemId: impulseMode ? mcData.itemsByName.command_block.id : mcData.itemsByName.repeating_command_block.id,
itemCount: 64,
nbtData: nbt.comp({
BlockEntityTag: nbt.comp({
Command: nbt.string(fillCommand),
auto: nbt.byte(1),
TrackOutput: nbt.byte(0)
})
})
}
});
bot.write('block_dig', {
status: 0,
location,
face: 1
});
bot.write('block_place', {
location,
direction: 1,
hand: 0,
cursorX: 0.5,
cursorY: 0.5,
cursorZ: 0.5,
insideBlock: false
});
} catch (e) {
bot.console.error(e);
}
}
bot.on('position', bot.core.fillCore);
const interval = setInterval(bot.core.fillCore, config.core.refillInterval);
bot.on('end', () => {
clearInterval(interval);
});
}
module.exports = { inject };

View file

@ -0,0 +1,178 @@
const { escapeMarkdown } = require('../util/escapeMarkdown')
async function inject (bot, dcclient, config) {
const chatMessage = require('prismarine-chat')(bot.version)
const channel = dcclient.channels.cache.get(config.discord.servers[`${bot.server.host}:${bot.server.port}`])
let queue = ''
const queueInterval = setInterval(() => {
if (queue === '') return
channel.send({
content: '```ansi\n' + queue.substring(0, 1986) + '\n```',
allowedMentions: {
parse: []
}
})
queue = ''
}, 1000)
bot.on('message', (message) => {
const cleanMessage = escapeMarkdown(message.toAnsi(), true)
const discordMsg = cleanMessage
.replaceAll('@', '@\u200b')
.replaceAll('http', 'http\u200b')
.replaceAll('\u001b[9', '\u001b[3')
if (message.toMotd().startsWith('§8[§eChomeNS §9Discord§8] §c')) return
queue += '\n' + discordMsg
})
// handle discord messages!!!
async function handleDiscordMessages (message) {
// Ignore messages from the bot itself
if (message.author.id === dcclient.user.id) return
// Only handle messages in specified channel
if (message.channel.id !== channel.id) return
if (message.content.startsWith(config.discord.prefix)) return
try {
const attachmentsComponent = []
if (message.attachments) {
for (const __attachment of message.attachments) {
const _attachment = [...__attachment]
const attachment = _attachment[1] // BEST WAY REAL!?/1?!
attachmentsComponent.push({
text: message.content === '' ? '[Attachment]' : ' [Attachment]', // may not be the best fix
color: 'green',
clickEvent: {
action: 'open_url',
value: attachment.proxyURL
}
})
}
}
const component = [
{ text: '[', color: 'dark_gray', bold:false, },
{
text: 'FNF',
color: 'dark_purple',
bold:false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: 'Boyfriend',
color: 'aqua',
bold:false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: 'Bot',
color: 'dark_red',
bold: false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: ' Discord',
color: 'blue',
bold: false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: ']',
color: 'dark_gray',
bold: false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: '[',
color: 'dark_gray',
bold: false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: 'ChomeNS js ',
color: 'yellow',
bold:false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{
text: 'Bot',
color: 'yellow',
bold:false,
clickEvent: {
action: 'open_url',
value: 'https://discord.gg/GCKtG4erux'
}
},
{ text: '] ', color: 'dark_gray', bold:false, },
{
text: message.member.displayName,
color: 'red',
clickEvent: {
action: 'copy_to_clipboard',
value: `${message.author.username}#${message.author.discriminator}`
},
hoverEvent: {
action: 'show_text',
value: [
{
text: message.author.username,
color: 'white'
},
{
text: '#',
color: 'dark_gray'
},
{
text: message.author.discriminator,
color: 'gray'
},
'\n',
{
text: 'Click here to copy the tag to your clipboard',
color: 'green'
}
]
}
},
{ text: ' ', color: 'dark_gray' },
chatMessage.MessageBuilder.fromString('&7' + message.content),
attachmentsComponent.length === 0 ? '' : attachmentsComponent
]
bot.tellraw('@a', component)
} catch (e) {
}
}
bot.on('end', () => {
clearInterval(queueInterval)
dcclient.off('messageCreate', handleDiscordMessages)
})
dcclient.on('messageCreate', handleDiscordMessages)
};
module.exports = { inject }

53
ChomensJS/plugins/draw.js Normal file
View file

@ -0,0 +1,53 @@
const convert = require('color-convert')
// eslint-disable-next-line require-jsdoc
function inject (bot) {
/**
* draw which is totallynotskidded from ybot
* @param {buffer} data data buffer
* @param {*} info idk bout this
* @param {object} prefix prefix in the output compoenent
*/
function draw (data, info, prefix = {}) {
const pixels = []
// Data Buffer -> RGB Array
for (let i = 0; i < data.length; i += info.channels) {
pixels.push([
data[i + 0],
data[i + 1],
data[i + 2]
])
}
const rows = []
// RGB Array -> Rows Array
for (let i = 0; i < pixels.length; i += info.width) {
const row = pixels.slice(i, i + info.width)
rows.push(row)
}
const messages = []
for (const row of rows) {
const message = [{ ...prefix, text: '' }]
for (const rgb of row) {
message.push({
text: '⎮',
color: `#${convert.rgb.hex(rgb)}`
})
}
messages.push(message)
}
for (const message of messages) bot.tellraw('@a', message)
}
bot.draw = draw
}
module.exports = { inject }

18
ChomensJS/plugins/hash.js Normal file
View file

@ -0,0 +1,18 @@
const crypto = require('crypto')
module.exports = {
inject: function (bot, dcclient, config) {
bot.hash = ''
const interval = setInterval(() => {
const normalKey = process.env['chomensjs_key']
const ownerHashKey = process.env['chomensjs_owner_key']
bot.hash = crypto.createHash('sha256').update(Math.floor(Date.now() / 10000) + normalKey).digest('hex').substring(0, 16)
bot.ownerHash = crypto.createHash('sha256').update(Math.floor(Date.now() / 10000) + ownerHashKey).digest('hex').substring(0, 16)
}, 2000)
bot.on('end', () => {
clearInterval(interval)
})
}
}

190
ChomensJS/plugins/music.js Normal file
View file

@ -0,0 +1,190 @@
const path = require('path')
const { Midi } = require('@tonejs/midi')
const { convertMidi } = require('../util/midi_converter')
const convertNBS = require('../util/nbs_converter')
const parseTXTSong = require('../util/txt_song_parser')
const soundNames = {
harp: 'minecraft:block.note_block.harp',
basedrum: 'minecraft:block.note_block.basedrum',
snare: 'minecraft:block.note_block.snare',
hat: 'minecraft:block.note_block.hat',
bass: 'minecraft:block.note_block.bass',
flute: 'minecraft:block.note_block.flute',
bell: 'minecraft:block.note_block.bell',
guitar: 'minecraft:block.note_block.guitar',
chime: 'minecraft:block.note_block.chime',
xylophone: 'minecraft:block.note_block.xylophone',
iron_xylophone: 'minecraft:block.note_block.iron_xylophone',
cow_bell: 'minecraft:block.note_block.cow_bell',
didgeridoo: 'minecraft:block.note_block.didgeridoo',
bit: 'minecraft:block.note_block.bit',
banjo: 'minecraft:block.note_block.banjo',
pling: 'minecraft:block.note_block.pling'
}
function inject (bot) {
bot.music = function () {}
bot.music.song = null
bot.music.loop = 0
bot.music.queue = []
let time = 0
let startTime = 0
let noteIndex = 0
bot.music.skip = function () {
if (bot.music.loop === 2) {
bot.music.queue.push(bot.music.queue.shift())
bot.music.play(bot.music.queue[0])
} else {
bot.music.queue.shift()
}
resetTime()
}
const bossbarName = 'chomens_bot:music' // maybe make this in the config?
const selector = '@a[tag=!nomusic,tag=!chomens_bot_nomusic]'
const interval = setInterval(async () => {
if (!bot.music.queue.length) return
bot.music.song = bot.music.queue[0]
time = Date.now() - startTime
/*
// bot.core.run('minecraft:title @a[tag=!nomusic] actionbar ' + JSON.stringify(toComponent()))
// is spamming commands in core as a self care a good idea?
// btw this is totallynotskidded™ from my song bot except the bossbarName (above)
bot.core.run(`minecraft:bossbar add ${bossbarName} ""`) // is setting the name to "" as a placeholder a good idea?
bot.core.run(`minecraft:bossbar set ${bossbarName} players ${selector}`)
bot.core.run(`minecraft:bossbar set ${bossbarName} name ${JSON.stringify(toComponent())}`)
bot.core.run(`minecraft:bossbar set ${bossbarName} color yellow`) // should i use purple lol
bot.core.run(`minecraft:bossbar set ${bossbarName} visible true`)
bot.core.run(`minecraft:bossbar set ${bossbarName} value ${Math.floor(time)}`)
bot.core.run(`minecraft:bossbar set ${bossbarName} max ${bot.music.song.length}`)
*/
bot.core.run(`title @a actionbar ${JSON.stringify(toComponent())}`)
while (bot.music.song?.notes[noteIndex]?.time <= time) {
const note = bot.music.song.notes[noteIndex]
const floatingPitch = 2 ** ((note.pitch - 12) / 12.0)
bot.core.run(`minecraft:execute as ${selector} at @s run playsound ${soundNames[note.instrument]} record @s ~ ~ ~ ${note.volume} ${floatingPitch}`)
noteIndex++
if (noteIndex >= bot.music.song.notes.length) {
bot.tellraw('@a', [
{
text: 'Finished playing '
},
{
text: bot.music.song.name,
color: 'gold'
}
])
if (bot.music.loop === 1) {
resetTime()
return
}
if (bot.music.loop === 2) {
resetTime()
bot.music.queue.push(bot.music.queue.shift())
bot.music.play(bot.music.queue[0])
return
}
bot.music.queue.shift()
bot.music.song = null // useless?
if (!bot.music.queue[0]) {
bot.music.stop()
return
}
if (bot.music.queue[0].notes.length > 0) {
if (bot.music.queue.length !== 1) resetTime()
bot.music.play(bot.music.queue[0])
return
}
}
}
}, 50)
bot.on('end', () => {
clearInterval(interval)
})
bot.music.load = async function (buffer, fallbackName = '[unknown]') {
let song
switch (path.extname(fallbackName)) {
case '.nbs':
song = convertNBS(buffer)
if (song.name === '') song.name = fallbackName
break
case '.txt':
song = parseTXTSong(buffer.toString())
song.name = fallbackName
break
default:
// TODO: use worker_threads so the entire bot doesn't freeze (for example parsing we are number 1 black midi)
// eslint-disable-next-line no-case-declarations
const midi = new Midi(buffer)
song = convertMidi(midi)
if (song.name === '') song.name = fallbackName
break
}
return song
}
bot.music.play = function (song) {
if (bot.music.queue.length === 1) resetTime()
}
bot.music.stop = function () {
bot.music.song = null
bot.music.loop = 0
bot.music.queue = []
resetTime()
}
function resetTime () {
time = 0
startTime = Date.now()
noteIndex = 0
bot.core.run(`minecraft:bossbar remove ${bossbarName}`) // maybe not a good place to put it here but idk
}
function formatTime (time) {
const seconds = Math.floor(time / 1000)
return `${Math.floor(seconds / 60)}:${(seconds % 60).toString().padStart(2, '0')}`
}
function toComponent () {
const component = [
// { text: '[', color: 'dark_gray' },
// { text: 'ChomeNS Bot', color: 'yellow' },
// { text: '] ', color: 'dark_gray' },
// { text: 'Now Playing', color: 'gold' },
// { text: ' | ', color: 'dark_gray' },
{ text: bot.music.song.name, color: 'green' },
{ text: ' | ', color: 'dark_gray' },
{ text: formatTime(time), color: 'gray' },
{ text: ' / ', color: 'dark_gray' },
{ text: formatTime(bot.music.song.length), color: 'gray' },
{ text: ' | ', color: 'dark_gray' },
{ text: noteIndex, color: 'gray' },
{ text: ' / ', color: 'dark_gray' },
{ text: bot.music.song.notes.length, color: 'gray' }
]
if (bot.music.loop === 1) {
component.push({ text: ' | ', color: 'dark_gray' })
component.push({ text: 'Looping Current', color: 'green' })
}
if (bot.music.loop === 2) {
component.push({ text: ' | ', color: 'dark_gray' })
component.push({ text: 'Looping All', color: 'green' })
}
return component
}
}
module.exports = { inject }

View file

@ -0,0 +1,136 @@
const { EventEmitter } = require('events')
class PlayerList {
list = []
addPlayer (player) {
this.removePlayer(player)
this.list.push(player)
}
hasPlayer (player) {
return this.getPlayer(player) !== undefined
}
getPlayer (player) {
let identifier
switch (typeof player) {
case 'object':
identifier = player.UUID
break
case 'string':
identifier = player
break
default:
throw new Error(`Get player called with ${player}`)
}
return this.list.find((player) => [player.UUID, player.name].some((item) => item === identifier))
}
getPlayers () {
return Array.from(this.list)
}
removePlayer (player) {
this.list = this.list.filter(({ UUID }) => UUID !== player.UUID)
}
}
function inject (bot, dcclient, config) {
bot.players = new PlayerList()
const tabCompletePlayerList = {
list: [],
interval: setInterval(async () => {
bot.write('tab_complete', {
text: '/scoreboard players add '
})
const [packet] = await EventEmitter.once(bot._client, 'tab_complete')
return packet.matches
.filter((match) => !match.tooltip)
.map(({ match }) => match)
}, 1000 * 3)
}//???
bot._client.on('player_info', async (packet) => {
for (const player of packet.data) {
switch (packet.action) {
case 0:
addPlayer(player, packet)
break
case 1:
updateGamemode(player, packet)
break
case 2:
updatePing(player, packet)
break
case 3:
updateDisplayName(player, packet)
break
case 4:
removePlayer(player, packet)
break
}
}
})
function addPlayer (player, packet) {
if (bot.players.getPlayer(player)) bot.emit('player_unvanished', player, packet)
else bot.emit('player_added', player, packet)
bot.players.addPlayer(player)
}
function updateGamemode (player, packet) {
const fullPlayer = bot.players.getPlayer(player)
bot.emit('onPlayerGamemodeUpdate', player, packet)
if (fullPlayer === undefined) return
fullPlayer.gamemode = player.gamemode
}
function updatePing (player, packet) {
const fullPlayer = bot.players.getPlayer(player)
bot.emit('player_ping_updated', player, packet)
if (fullPlayer === undefined) return
fullPlayer.ping = player.ping
}
function updateDisplayName (player, packet) {
const fullPlayer = bot.players.getPlayer(player)
bot.emit('player_display_name_updated', player, packet)
if (fullPlayer === undefined) return
fullPlayer.displayName = player.displayName
}
function removePlayer (player, packet) {
const fullPlayer = bot.players.getPlayer(player)
const players = tabCompletePlayerList.list
if (fullPlayer && players.some((name) => name === fullPlayer.name)) {
bot.emit('player_vanished', player)
} else {
bot.emit('player_removed', player, packet)
bot.players.removePlayer(player)
}
}
bot.on('end', () => {
clearInterval(tabCompletePlayerList.interval)
})
}
module.exports = { inject }

View file

@ -0,0 +1,11 @@
function inject (bot) {
bot.position = { x: 0, y: 0, z: 0 }
bot._client.on('position', (position) => {
bot.position = position
bot.write('teleport_confirm', { teleportId: position.teleportId })
bot.emit('position', position)
})
}
module.exports = { inject }

129
ChomensJS/plugins/proxy.js Normal file
View file

@ -0,0 +1,129 @@
const util = require('util')
const mc = require('minecraft-protocol')
const { loadPlugins } = require('../util/loadPlugins')
const minecraftVersionToNumber = require('../util/minecraftVersionToNumber')
function inject (bot, dcclient, config) {
if (!config.proxy.enabled) return
let index
config.servers.forEach((server, _index) => {
if (bot.server.host !== server.host) return
index = _index
})
bot.proxy = {}
const version = config.proxy.version
const srv = mc.createServer({
'online-mode': false,
port: 25566 + index,
keepAlive: false,
version
})
srv.on('login', (client) => {
bot.console.info(`[Proxy] ${client.username} connected to proxy`)
let clientEnded = false
// eslint-disable-next-line no-unused-vars
let targetEnded = false
const target = mc.createClient({
username: client.username,
host: bot.server.host,
port: bot.server.port,
version
})
const clientPacketBlacklist = []
const targetPacketBlacklist = []
// should this be here or in the chat plugin?
target.sendMessage = function (message) {
if (message.startsWith('/') && minecraftVersionToNumber(target.version) >= 1.19) {
// totallynotskidded™ from mineflayer
const command = message.slice(1)
const timestamp = BigInt(Date.now())
target.write('chat_command', {
command,
timestamp,
salt: 0n,
argumentSignatures: [],
signedPreview: false,
messageCount: 0,
acknowledged: Buffer.alloc(3),
// 1.19.2 Chat Command packet also includes an array of last seen messages
previousMessages: []
})
} else {
target.chat(message)
}
}
target.on('login', (packet) => {
bot.console.info(`[Proxy] ${client.username} target logged in`)
target.entityId = packet.entityId
loadPlugins(bot, null, config, null, target, client, true, clientPacketBlacklist, targetPacketBlacklist)
})
target.on('packet', (data, meta) => {
if (!clientEnded &&
meta.state === mc.states.PLAY &&
client.state === mc.states.PLAY &&
!targetPacketBlacklist.includes(meta.name)
) client.write(meta.name, data)
})
target.on('error', () => {})
target.on('end', targetEndListener)
target.on('kick_disconnect', ({ reason }) => targetEndListener(JSON.parse(reason)))
target.on('disconnect', ({ reason }) => targetEndListener(JSON.parse(reason)))
function targetEndListener (reason) {
target.end()
client.end(`Target disconnected with reason: ${util.inspect(reason)}`)
targetEnded = true
}
client.on('end', () => {
clientEnded = true
target.end()
target.removeAllListeners()
client.removeAllListeners()
bot.console.info(`[Proxy] ${client.username} ended`)
})
client.on('error', () => {
clientEnded = true
target.removeAllListeners()
client.removeAllListeners()
bot.console.info(`[Proxy] ${client.username} got error`)
})
client.on('packet', (data, meta) => {
if (clientPacketBlacklist.includes(meta.name)) return
target.write(meta.name, data)
})
bot.proxy[client.username] = {
target,
client
}
function botEndListener (reason) {
delete bot.proxy[client.username]
client.end(`Bot disconnected with reason: ${util.inspect(reason)}`)
bot.off('end', botEndListener)
}
bot.on('end', botEndListener)
})
bot.on('end', () => {
srv.close()
srv.removeAllListeners()
})
};
module.exports = { inject }

View file

@ -0,0 +1,16 @@
const { chatPacketListener, parsePlayerMessages } = require('../../util/chat')
const minecraftVersionToNumber = require('../../util/minecraftVersionToNumber')
function inject (bot, client, target) {
function listener (packet) {
chatPacketListener(packet, target, minecraftVersionToNumber(target.version) >= 1.10)
}
target.on('systemChat', listener)
target.on('chat', listener)
target.on('message', (message, packet) => {
parsePlayerMessages(message, packet, target)
})
};
module.exports = { inject }

View file

@ -0,0 +1,58 @@
const minecraftVersionToNumber = require('../../util/minecraftVersionToNumber')
function inject (bot, client, target, config, clientPacketBlacklist) {
const { MessageBuilder } = require('prismarine-chat')(bot.version)
clientPacketBlacklist.push('chat')
clientPacketBlacklist.push('chat_message')
client.on(minecraftVersionToNumber(target.version) >= 1.19 ? 'chat_message' : 'chat', (data) => {
// not the best place to put command handler thing here but ok
if (data.message?.startsWith('.')) {
return bot.command_handler.run(
client.username,
config.prefixes[0] + data.message.substring(1),
client.uuid,
null,
'h', // real hash hardcode
'o',
client.username,
true,
client,
target
)
}
if (!data.message?.startsWith('/')) {
const codeParsedMessage = data.message.replace(/%[^%]+%/g, (code) => {
try {
// eslint-disable-next-line no-eval
return eval(code.substring(1).slice(0, -1))
} catch (e) {
return code
}
})
bot.tellraw('@a', {
color: 'dark_gray',
translate: '[%s] [%s] %s \u203a %s',
with: [
{
text: 'Chat',
color: 'gray'
},
{
text: 'Proxy',
color: 'gray'
},
{
selector: client.username,
color: 'green'
},
MessageBuilder.fromString('&7' + codeParsedMessage)
]
})
} else {
target.sendMessage(data)
}
})
};
module.exports = { inject }

View file

@ -0,0 +1,48 @@
function inject (bot, client, target, config) {
let cspy = false
let op = true
// let gameMode = 1
target.on('message', (data) => {
if (data.toString() === 'Successfully enabled CommandSpy' || data.toString() === ' Enabled your command spy.' || data.toString() === ' Your command spy is already enabled.') cspy = true
if (data.toString() === 'Successfully disabled CommandSpy' || data.toString() === ' Disabled your command spy.') cspy = false
})
target.on('entity_status', (data) => {
if (data.entityId !== target.entityId) return
switch (data.entityStatus) {
case 24:
op = false
break
case 28:
op = true
break
}
})
// target.on('game_state_change', (data) => {
// if (data.reason !== 3) return
//
// gameMode = data.gameMode
// })
//
// target.on('login', (data) => {
// gameMode = data.gameMode
// })
const interval = setInterval(() => {
if (bot.options.kaboom) {
if (!op && config.self_care.op) target.sendMessage('/minecraft:op @s[type=player]')
if (!cspy && config.self_care.cspy) target.sendMessage('/commandspy:commandspy on')
}
// if (gameMode !== 1 && config.self_care.gamemode) target.sendMessage('/minecraft:gamemode creative @s[type=player]')
}, config.self_care_check_interval)
bot.on('end', () => {
clearInterval(interval)
})
};
module.exports = { inject }

View file

@ -0,0 +1,90 @@
function inject (bot, dcclient, config) {
let vanish = false
let nickname = true
let socialspy = false
let cspy = false
let prefix = false
let op = false
let gameMode = 1
let muted = false
bot.on('message', (data) => {
if (data.toString() === 'You are now completely invisible to normal users, and hidden from in-game commands.') vanish = true
if (!bot.visibility && data.toString() === `Vanish for ${bot.username}: disabled`) vanish = false
if (data.toString() === 'You no longer have a nickname.') nickname = true
if (data.toString().startsWith('Your nickname is now ')) nickname = false
if (data.toString() === `SocialSpy for ${bot.username}: enabled`) socialspy = true
if (data.toString() === `SocialSpy for ${bot.username}: disabled`) socialspy = false
if (data.toString().startsWith('You have been muted')) muted = true
if (data.toString() === 'You have been unmuted.') muted = false
if (data.toString() === 'Successfully enabled CommandSpy' || data.toString() === ' Enabled your command spy.' || data.toString() === ' Your command spy is already enabled.') cspy = true
if (data.toString() === 'Successfully disabled CommandSpy' || data.toString() === ' Disabled your command spy.') cspy = false
if (data.toString() === 'You now have the tag: [ChomeNS Bot]' || // for 1.19.2 (or 1.19?) and older clones
data.toString() === 'You now have the tag: &8[&eChomeNS Bot&8]'
) {
prefix = true
return
}
if (data.toString().startsWith('You no longer have a tag')) prefix = false
if (data.toString().startsWith('You now have the tag: ')) prefix = false
})
bot._client.on('entity_status', (data) => {
if (data.entityId !== bot.entityId) return
switch (data.entityStatus) {
case 24:
op = false
bot.emit('deop')
break
case 28:
op = true
bot.emit('op')
break
}
bot.emit('entity_status', data)
})
bot._client.on('game_state_change', (data) => {
if (data.reason === 4 && config.self_care.endCredits) bot.write('client_command', { payload: 0 })
if (data.reason !== 3) return
gameMode = data.gameMode
})
bot._client.on('login', (data) => {
gameMode = data.gameMode
})
const interval = setInterval(() => {
if (bot.options.kaboom) {
if (!prefix && config.self_care.prefix) bot.chat('/extras:prefix &8[&eChomeNS Bot&8]')
if (!op && config.self_care.op) bot.chat('/minecraft:op @s[type=player]')
if (!cspy && config.self_care.cspy) bot.chat('/commandspy:commandspy on')
}
if (!vanish && config.self_care.vanish) bot.chat('/essentials:vanish enable')
//if (!socialspy && config.self_care.socialspy) bot.chat('/essentials:socialspy enable')
if (!nickname && config.self_care.nickname) bot.chat('/essentials:nickname off')
if (gameMode !== 1 && config.self_care.gamemode) bot.chat('/minecraft:gamemode creative @s[type=player]')
if (muted && config.self_care.mute) bot.chat('/essentials:mute ' + bot.uuid)
}, config.self_care_check_interval)
bot.on('end', () => {
clearInterval(interval)
})
};
module.exports = { inject }

View file

@ -0,0 +1,12 @@
function inject (bot, dcclient, config) {
const ChatMessage = require('prismarine-chat')(bot.version)
bot.tellraw = function (selector, message) {
if (bot.options.useChat && selector === '@a') {
bot.chat(ChatMessage.fromNotch(message).toMotd().replaceAll('\xa7', '&'))
return
}
bot.core.run(`minecraft:tellraw ${selector} ${JSON.stringify(message)}`)
}
};
module.exports = { inject }

75
ChomensJS/plugins/tps.js Normal file
View file

@ -0,0 +1,75 @@
const clamp = require('../util/clamp')
function inject (bot, dcclient, config) {
const bossbarName = 'chomens_bot:tps'
let enabled = false
bot.tps = {
on () {
enabled = true
},
off () {
enabled = false
bot.core.run(`minecraft:bossbar remove ${bossbarName}`)
}
}
const tickRates = []
let nextIndex = 0
let timeLastTimeUpdate = -1
let timeGameJoined
const interval = setInterval(() => {
if (!enabled) return
const component = {
translate: 'TPS - %s',
color: 'gray',
bold: false,
with: [
{ text: getTickRate(), color: 'green' }
]
}
bot.core.run(`minecraft:bossbar add ${bossbarName} ""`)
bot.core.run(`minecraft:bossbar set ${bossbarName} players @a`)
bot.core.run(`minecraft:bossbar set ${bossbarName} color yellow`)
bot.core.run(`minecraft:bossbar set ${bossbarName} visible true`)
bot.core.run(`minecraft:bossbar set ${bossbarName} style progress`)
bot.core.run(`minecraft:bossbar set ${bossbarName} name ${JSON.stringify(component)}`)
bot.core.run(`minecraft:bossbar set ${bossbarName} max 20`)
bot.core.run(`minecraft:bossbar set ${bossbarName} value ${Math.floor(getTickRate())}`)
}, 50)
function getTickRate () {
if (Date.now() - timeGameJoined < 4000) return 'Calculating...'
let numTicks = 0
let sumTickRates = 0.0
for (const tickRate of tickRates) {
if (tickRate > 0) {
sumTickRates += tickRate
numTicks++
}
}
const value = (sumTickRates / numTicks).toFixed(2)
if (value > 20) return 20
else return value
}
bot.on('login', () => {
nextIndex = 0
timeGameJoined = timeLastTimeUpdate = Date.now()
})
bot._client.on('update_time', () => {
const now = Date.now()
const timeElapsed = (now - timeLastTimeUpdate) / 1000.0
tickRates[nextIndex] = clamp(20.0 / timeElapsed, 0.0, 20.0)
nextIndex = (nextIndex + 1) % tickRates.length
timeLastTimeUpdate = now
})
bot.on('end', () => clearInterval(interval))
}
module.exports = { inject }

46
ChomensJS/plugins/vm.js Normal file
View file

@ -0,0 +1,46 @@
const mc = require('minecraft-protocol')
const crypto = require('crypto')
const colorConvert = require('color-convert')
const uuid = require('uuid-by-string')
const moment = require('moment-timezone')
const cowsay = require('cowsay2')
const cows = require('cowsay2/cows')
const { VM } = require('vm2')
const randomstring = require('randomstring')
const mineflayer = require('mineflayer')
const Vec3 = require('vec3')
function inject (bot) {
const chatMessage = require('prismarine-chat')(bot.version)
const mcData = require('minecraft-data')(bot.version)
bot.vmOptions = {
timeout: 2000,
sandbox: {
run (cmd) {
bot.core.run(cmd)
},
mc,
mineflayer,
chat: bot.chat,
moment,
randomstring,
uuid,
chatMessage,
crypto,
colorConvert,
bruhifyText (message) {
if (
typeof message !== 'string'
) throw new SyntaxError('message must be a string')
bot.bruhifyText = message.substring(0, 1000)
},
cowsay,
cows,
mcData,
Vec3
}
}
bot.vm = new VM(bot.vmOptions)
};
module.exports = { inject }

View file

@ -0,0 +1 @@
{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file .cache/replit/modules/nodejs-18:v9-20230908-bb1b9fd","time":"2023-09-17T03:59:55Z"}

13
ChomensJS/util/between.js Normal file
View file

@ -0,0 +1,13 @@
module.exports = {
/**
* this code is from somewhere i can't remember...
* @param {Number} min
* @param {Number} max
* @return {Number}
*/
between: function (min, max) {
return Math.floor(
Math.random() * (max - min) + min
)
}
}

146
ChomensJS/util/chat.js Normal file
View file

@ -0,0 +1,146 @@
/**
* for the chat packet listener (in util cuz proxy + bot)
* @param {object} packet chat packet
* @param {object} bot bot
* @param {boolean} mc119 minecraft 1.19 or newer
*/
function chatPacketListener (packet, bot, mc119) {
// try catch prevents json parse error (happens with a custom server that sends an invalid json component for example)
try {
const ChatMessage = require('prismarine-chat')(bot.version)
const parsedMessage = JSON.parse(mc119 ? packet.formattedMessage : packet.message)
// down here it prevents command set message
// for ayunboom cuz its 1.17.1
// VVVVVVVVVVVVVVVVVVVVVVVVVVVV
if (parsedMessage.extra) {
if (parsedMessage.extra[0].text === 'Command set: ') return
}
// for 1.18 or newer(?)
// VVVVVVVVVVVVVVVVVVVVV
if (parsedMessage.translate === 'advMode.setCommand.success') return
const message = ChatMessage.fromNotch(mc119 ? packet.formattedMessage : packet.message)
bot.emit('message', message, parsedMessage)
} catch (e) {
bot.console.error(e)
}
}
/**
* new parse player messages, more accurate message real!11!!
* @param {object} _message prismarine-chat ChatMessage - unused in code but used in legacy parsing
* @param {object} parsedMessage parsed message in a js object
* @param {object} bot bot
*/
function parsePlayerMessages (_message, parsedMessage, bot) {
const ChatMessage = require('prismarine-chat')(bot.version)
const vanillaKeys = [
'chat.type.text',
'chat.type.announcement',
'chat.type.emote'
]
// parse Extras™ chat messages
if (
parsedMessage.translate === '%s' &&
parsedMessage.with?.length === 1 &&
parsedMessage.with[0]?.text === '' &&
parsedMessage.with[0]?.extra?.length === 5
) {
const trueMessageComponent = parsedMessage.with[0].extra
const username = ChatMessage.fromNotch(trueMessageComponent[1]).toMotd()
const message = ChatMessage.fromNotch(trueMessageComponent[4]).toMotd()
bot.emit('chat', username, message)
return
}
// parse CommandSpy™ messages
if (
(
parsedMessage.color === 'yellow' ||
parsedMessage.color === 'aqua'
) &&
parsedMessage.extra?.length === 2
) {
const username = parsedMessage.text
const command = parsedMessage.extra[1].text
bot.emit('cspy', username, command)
return
}
// parse Minecraft Vanilla™ messages
if (
vanillaKeys.includes(parsedMessage.translate) &&
parsedMessage.with.length >= 2
) {
const username = ChatMessage.fromNotch(parsedMessage.with[0]).toMotd()
const message = ChatMessage.fromNotch(parsedMessage.with[1]).toMotd()
bot.emit('chat', username, message)
return
}
parsePlayerMessagesLegacy(_message, parsedMessage, bot)
}
/**
* LEGACY - parse player messages (for prismarine-chat)
* @param {object} message prismarine-chat ChatMessage
* @param {object} _parsedMessage parsed message in a js object
* @param {object} bot bot
*/
function parsePlayerMessagesLegacy (message, _parsedMessage, bot) {
try {
// here is all the player message parsing thing
const raw = message.toMotd() // lags the bot as you already know
// if (raw.match(/.* .*: .*/g)) {
// const username = raw.replace(/.*?\[.*?\] /g, '').replace(/:.*/g, '').replace(/§#....../gm, '')
// const message = raw.split(': ').slice(1).join(' ').replace(/§#....../gm, '')
// bot.emit('chat', username, message)
// } else
if (raw.match(/.* .*\u203a .*/g)) {
const username = raw.replace(/.*?\[.*?\] /g, '').replace(/\u203a.*/g, '').replace(/§#....../gm, '').split(' ')[0]
const message = raw.split('\u203a ').slice(1).join(' ').substring(2)
bot.emit('chat', username, message)
} else if (raw.match(/.* .*\u00BB .*/g)) {
const username = raw.replace(/.*?\[.*?\] /g, '').replace(/\u00BB.*/g, '').replace(/§#....../gm, '').split(' ')[0]
const message = raw.split('\u00BB ').slice(1).join(' ')
bot.emit('chat', username, message)
}
// } else if (raw.match(/.* .*> .*/g)) {
// const username = raw.replace(/.*?\[.*?\] /g, '').replace(/>.*/g, '').replace(/§#....../gm, '').split(' ')[0]
// const message = raw.split('> ').slice(1).join(' ').substring(2)
// bot.emit('chat', username, message)
// } else if (raw.match(/<.*> .*/g)) {
// const username = raw.substring(1).split('>')[0]
// const message = raw.split('> ').slice(1).join(' ')
//
// bot.emit('chat', username, message)
// } else if (raw.match(/§.*§b: §b\/.*/g)) {
// const username = raw.split('§b: §b')[0]
// const command = raw.split('§b: §b')[1]
// bot.emit('cspy', username, command)
// } else if (raw.match(/§.*§e: §e\/.*/g)) {
// const username = raw.split('§e: §e')[0]
// const command = raw.split('§e: §e')[1]
// bot.emit('cspy', username, command)
// } else if (raw.match(/§.*§b: \/.*/g)) {
// const username = raw.split('§b: ')[0]
// const command = raw.split('§b: ')[1]
// bot.emit('cspy', username, command)
// } else if (raw.match(/§.*§e: \/.*/g)) {
// const username = raw.split('§e: ')[0]
// const command = raw.split('§e: ')[1]
// bot.emit('cspy', username, command)
// }
} catch (e) {}
};
module.exports = { chatPacketListener, parsePlayerMessages }

6
ChomensJS/util/clamp.js Normal file
View file

@ -0,0 +1,6 @@
function clamp (value, min, max) {
if (value < min) return min
return Math.min(value, max)
}
module.exports = clamp

View file

@ -0,0 +1,23 @@
const styles = {
bigint: '\xa76',
boolean: '\xa76',
date: '\xa75',
module: '\xa7n',
name: undefined,
null: '\xa7l',
number: '\xa76',
regexp: '\xa74',
special: '\xa73',
string: '\xa72',
symbol: '\xa72',
undefined: '\xa78'
}
function stylize (str, styleType) {
const style = styles[styleType]
if (style !== undefined) return `${style}${str}\xa7r`
return str
}
module.exports = { stylize, styles }

View file

@ -0,0 +1,18 @@
/**
* character allowed in mc chat
* @param {String} character the character
* @return {boolean} allowed
*/
function isAllowedCharacter (character) {
return character !== '\xa7' && character !== '\x7f'
}
/**
* mc chat check if contains illegal chars.
* @param {String} string the string
* @return {boolean} if contains then true else false
*/
function containsIllegalCharacters (string) {
for (let i = 0; i < string.length; i++) if (!isAllowedCharacter(string[i])) return true
}
module.exports = { containsIllegalCharacters, isAllowedCharacter }

View file

@ -0,0 +1,22 @@
/**
* escape markdown so on discord it will be \_ChipMC\_ instead of _ChipMC_
* @param {String} text
* @param {Boolean} zwsp
* @return {String}
*/
function escapeMarkdown (text, zwsp) {
let unescaped
let escaped
try {
unescaped = text.replace(/\\(\*|@|_|`|~|\\)/g, '$1')
escaped = unescaped.replace(/(\*|@|_|`|~|\\)/g, zwsp
? '\u200b\u200b$1'
: '\\$1'
)
} catch (e) {
return unescaped
}
return escaped
}
module.exports = { escapeMarkdown }

View file

@ -0,0 +1,19 @@
const fs = require('fs/promises')
/**
* check if file exists
* @param {String} filepath the file path
* @return {boolean} if file exists true else false
*/
async function fileExists (filepath) {
try {
await fs.access(filepath)
return true
} catch (error) {
if (error.code !== 'ENOENT') throw error
return false
}
}
module.exports = fileExists

View file

@ -0,0 +1,18 @@
const fs = require('fs/promises')
/**
* just list the files
* @param {String} filepath file path
* @return {Array} component.
*/
async function list (filepath = '.') {
const files = await fs.readdir(filepath)
const component = []
for (const filename of files) {
component.push(filename)
}
return component
}
module.exports = list

View file

@ -0,0 +1,14 @@
const path = require('path')
/**
* get filename from url
* @param {string} urlStr the url
* @return {string} filename
* @example
* getFilenameFromUrl('https://sus.red/amogus.mid?verysus=true') // returns 'amogus.mid'
*/
function getFilenameFromUrl (urlStr) {
const url = new URL(urlStr)
return path.basename(url.pathname)
}
module.exports = getFilenameFromUrl

27
ChomensJS/util/image.js Normal file
View file

@ -0,0 +1,27 @@
/**
* resize image.
* @param {number} width width
* @param {number} height height
* @return {object} width and height
*/
function resize (width, height) {
const aspectRatio = width / height
let optimalWidth = Math.round(aspectRatio * 20 * (27 / 3))
let optimalHeight = 20
if (optimalWidth > 320) {
const reduction = optimalWidth / 320
optimalWidth = 320
optimalHeight *= reduction
}
return {
width: Math.floor(optimalWidth),
height: Math.floor(optimalHeight)
}
}
module.exports = { resize }

View file

@ -0,0 +1,33 @@
const fs = require('fs/promises')
const util = require('util')
const path = require('path')
/**
* load plugins
* @param {object} bot the bot object
* @param {object} dcclient discord client
* @param {object} config the config
* @param {object} rl readline
* @param {object} target proxy target
* @param {object} client proxy client
* @param {boolean} proxy is proxy
* @param {array} clientPacketBlacklist the client packet blacklist
* @param {array} targetPacketBlacklist target packet blacklist
*/
async function loadPlugins (bot, dcclient, config, rl, target, client, proxy, clientPacketBlacklist, targetPacketBlacklist) {
const dir = path.join(__dirname, '..', 'plugins', proxy ? 'proxy' : '')
const plugins = await fs.readdir(dir)
plugins.forEach((plugin) => {
if (!plugin.endsWith('.js')) return
try {
const plug = require(path.join(dir, plugin))
if (!proxy) plug.inject(bot, dcclient, config, rl)
else plug.inject(bot, client, target, config, clientPacketBlacklist, targetPacketBlacklist)
} catch (e) {
console.log(`Plugin ${plugin} is having exception loading the plugin:`)
console.log(util.inspect(e))
}
})
};
module.exports = { loadPlugins }

View file

@ -0,0 +1,25 @@
const fs = require('fs/promises')
const path = require('path')
/**
* loads js files
* @param {string} directory the directory that contains the js files
* @return {Array} an array of require()ed js files
*/
async function loadPlugins (directory) {
const plugins = []
for (const filename of await fs.readdir(directory)) {
if (!filename.endsWith('.js')) continue
const filepath = path.join(directory, filename)
const plugin = require(filepath)
plugins.push(plugin)
}
return plugins
}
module.exports = loadPlugins

View file

@ -0,0 +1,39 @@
const instrumentMap = require('./instrument_map.js')
const percussionMap = require('./percussion_map.js')
function convertNote (track, note) {
let instrument = null
const instrumentList = instrumentMap[track.instrument.number]
if (instrumentList != null) {
for (const candidateInstrument of instrumentList) {
if (note.midi >= candidateInstrument.offset && note.midi <= candidateInstrument.offset + 24) {
instrument = candidateInstrument
break
}
}
}
if (instrument == null) return null
const pitch = note.midi - instrument.offset
const time = Math.floor(note.time * 1000)
return { time, instrument: instrument.name, pitch, volume: note.velocity }
}
function convertPercussionNote (track, note) {
if (note.midi < percussionMap.length) {
const mapEntry = percussionMap[note.midi]
if (mapEntry == null) return
const { pitch, instrument } = mapEntry
const time = Math.floor(note.time * 1000)
return { time, instrument: instrument.name, pitch, volume: note.velocity }
}
return null
}
module.exports = { convertNote, convertPercussionNote }

View file

@ -0,0 +1,153 @@
const instruments = require('./instruments.json')
module.exports = [
// Piano (harp bass bell)
[instruments.harp, instruments.bass, instruments.bell], // Acoustic Grand Piano
[instruments.harp, instruments.bass, instruments.bell], // Bright Acoustic Piano
[instruments.bit, instruments.didgeridoo, instruments.bell], // Electric Grand Piano
[instruments.harp, instruments.bass, instruments.bell], // Honky-tonk Piano
[instruments.bit, instruments.didgeridoo, instruments.bell], // Electric Piano 1
[instruments.bit, instruments.didgeridoo, instruments.bell], // Electric Piano 2
[instruments.harp, instruments.bass, instruments.bell], // Harpsichord
[instruments.harp, instruments.bass, instruments.bell], // Clavinet
// Chromatic Percussion (iron_xylophone xylophone bass)
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Celesta
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Glockenspiel
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Music Box
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Vibraphone
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Marimba
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Xylophone
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Tubular Bells
[instruments.iron_xylophone, instruments.bass, instruments.xylophone], // Dulcimer
// Organ (bit didgeridoo bell)
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Drawbar Organ
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Percussive Organ
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Rock Organ
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Church Organ
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Reed Organ
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Accordian
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Harmonica
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Tango Accordian
// Guitar (bit didgeridoo bell)
[instruments.guitar, instruments.harp, instruments.bass, instruments.bell], // Acoustic Guitar (nylon)
[instruments.guitar, instruments.harp, instruments.bass, instruments.bell], // Acoustic Guitar (steel)
[instruments.guitar, instruments.harp, instruments.bass, instruments.bell], // Electric Guitar (jazz)
[instruments.guitar, instruments.harp, instruments.bass, instruments.bell], // Electric Guitar (clean)
[instruments.guitar, instruments.harp, instruments.bass, instruments.bell], // Electric Guitar (muted)
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Overdriven Guitar
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Distortion Guitar
[instruments.guitar, instruments.harp, instruments.bass, instruments.bell], // Guitar Harmonics
// Bass
[instruments.bass, instruments.harp, instruments.bell], // Acoustic Bass
[instruments.bass, instruments.harp, instruments.bell], // Electric Bass (finger)
[instruments.bass, instruments.harp, instruments.bell], // Electric Bass (pick)
[instruments.bass, instruments.harp, instruments.bell], // Fretless Bass
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Slap Bass 1
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Slap Bass 2
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Synth Bass 1
[instruments.didgeridoo, instruments.bit, instruments.xylophone], // Synth Bass 2
// Strings
[instruments.flute, instruments.guitar, instruments.bass, instruments.bell], // Violin
[instruments.flute, instruments.guitar, instruments.bass, instruments.bell], // Viola
[instruments.flute, instruments.guitar, instruments.bass, instruments.bell], // Cello
[instruments.flute, instruments.guitar, instruments.bass, instruments.bell], // Contrabass
[instruments.bit, instruments.didgeridoo, instruments.bell], // Tremolo Strings
[instruments.harp, instruments.bass, instruments.bell], // Pizzicato Strings
[instruments.harp, instruments.bass, instruments.chime], // Orchestral Harp
[instruments.harp, instruments.bass, instruments.bell], // Timpani
// Ensenble
[instruments.harp, instruments.bass, instruments.bell], // String Ensemble 1
[instruments.harp, instruments.bass, instruments.bell], // String Ensemble 2
[instruments.harp, instruments.bass, instruments.bell], // Synth Strings 1
[instruments.harp, instruments.bass, instruments.bell], // Synth Strings 2
[instruments.harp, instruments.bass, instruments.bell], // Choir Aahs
[instruments.harp, instruments.bass, instruments.bell], // Voice Oohs
[instruments.harp, instruments.bass, instruments.bell], // Synth Choir
[instruments.harp, instruments.bass, instruments.bell], // Orchestra Hit
// Brass
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.bit, instruments.didgeridoo, instruments.bell],
// Reed
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
// Pipe
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
[instruments.flute, instruments.didgeridoo, instruments.iron_xylophone, instruments.bell],
// Synth Lead
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
// Synth Pad
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
// Synth Effects
null,
null,
[instruments.bit, instruments.didgeridoo, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
[instruments.harp, instruments.bass, instruments.bell],
// Ethnic
[instruments.banjo, instruments.bass, instruments.bell],
[instruments.banjo, instruments.bass, instruments.bell],
[instruments.banjo, instruments.bass, instruments.bell],
[instruments.banjo, instruments.bass, instruments.bell],
[instruments.banjo, instruments.bass, instruments.bell],
[instruments.harp, instruments.didgeridoo, instruments.bell],
[instruments.harp, instruments.didgeridoo, instruments.bell],
[instruments.harp, instruments.didgeridoo, instruments.bell],
// Percussive
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone],
[instruments.iron_xylophone, instruments.bass, instruments.xylophone]
]

View file

@ -0,0 +1,82 @@
{
"harp": {
"id": 0,
"name": "harp",
"offset": 54
},
"basedrum": {
"id": 1,
"name": "basedrum",
"offset": 0
},
"snare": {
"id": 2,
"name": "snare",
"offset": 0
},
"hat": {
"id": 3,
"name": "hat",
"offset": 0
},
"bass": {
"id": 4,
"name": "bass",
"offset": 30
},
"flute": {
"id": 5,
"name": "flute",
"offset": 66
},
"bell": {
"id": 6,
"name": "bell",
"offset": 78
},
"guitar": {
"id": 7,
"name": "guitar",
"offset": 42
},
"chime": {
"id": 8,
"name": "chime",
"offset": 78
},
"xylophone": {
"id": 9,
"name": "xylophone",
"offset": 78
},
"iron_xylophone": {
"id": 10,
"name": "iron_xylophone",
"offset": 54
},
"cow_bell": {
"id": 11,
"name": "cow_bell",
"offset": 66
},
"didgeridoo": {
"id": 12,
"name": "didgeridoo",
"offset": 30
},
"bit": {
"id": 13,
"name": "bit",
"offset": 54
},
"banjo": {
"id": 14,
"name": "banjo",
"offset": 54
},
"pling": {
"id": 15,
"name": "pling",
"offset": 54
}
}

View file

@ -0,0 +1,37 @@
const { Midi } = require('@tonejs/midi')
const { convertNote, convertPercussionNote } = require('./convert_note.js')
function convertMidi (midi) {
if (!(midi instanceof Midi)) throw new TypeError('midi must be an instance of require(\'@tonejs/midi\').Midi')
let noteList = []
for (const track of midi.tracks) {
for (const note of track.notes) {
const mcNote = (track.instrument.percussion ? convertPercussionNote : convertNote)(track, note)
if (mcNote != null) {
noteList.push(mcNote)
}
}
}
noteList = noteList.sort((a, b) => a.time - b.time)
// It might be better to move some of this code to the converting loop (for performance reasons)
let maxVolume = 0.001
for (const note of noteList) {
if (note.volume > maxVolume) maxVolume = note.volume
}
for (const note of noteList) {
note.volume /= maxVolume
}
let songLength = 0
for (const note of noteList) {
if (note.time > songLength) songLength = note.time
}
return { name: midi.header.name, notes: noteList, loop: false, loopPosition: 0, length: songLength }
}
module.exports = { convertMidi, convertNote, convertPercussionNote }

View file

@ -0,0 +1,3 @@
{
"main": "main.js"
}

View file

@ -0,0 +1,58 @@
const instruments = require('./instruments.json')
module.exports = [
...new Array(35).fill(null), // offset
{ pitch: 10, instrument: instruments.basedrum },
{ pitch: 6, instrument: instruments.basedrum },
{ pitch: 6, instrument: instruments.hat },
{ pitch: 8, instrument: instruments.snare },
{ pitch: 6, instrument: instruments.hat },
{ pitch: 4, instrument: instruments.snare },
{ pitch: 6, instrument: instruments.basedrum },
{ pitch: 22, instrument: instruments.snare },
{ pitch: 13, instrument: instruments.basedrum },
{ pitch: 22, instrument: instruments.snare },
{ pitch: 15, instrument: instruments.basedrum },
{ pitch: 18, instrument: instruments.snare },
{ pitch: 20, instrument: instruments.basedrum },
{ pitch: 23, instrument: instruments.basedrum },
{ pitch: 17, instrument: instruments.snare },
{ pitch: 23, instrument: instruments.basedrum },
{ pitch: 24, instrument: instruments.snare },
{ pitch: 8, instrument: instruments.snare },
{ pitch: 13, instrument: instruments.snare },
{ pitch: 18, instrument: instruments.hat },
{ pitch: 18, instrument: instruments.snare },
{ pitch: 1, instrument: instruments.hat },
{ pitch: 13, instrument: instruments.snare },
{ pitch: 2, instrument: instruments.hat },
{ pitch: 13, instrument: instruments.snare },
{ pitch: 9, instrument: instruments.hat },
{ pitch: 2, instrument: instruments.hat },
{ pitch: 8, instrument: instruments.hat },
{ pitch: 22, instrument: instruments.basedrum },
{ pitch: 15, instrument: instruments.basedrum },
{ pitch: 13, instrument: instruments.snare },
{ pitch: 8, instrument: instruments.snare },
{ pitch: 8, instrument: instruments.hat },
{ pitch: 3, instrument: instruments.hat },
{ pitch: 20, instrument: instruments.hat },
{ pitch: 23, instrument: instruments.hat },
{ pitch: 24, instrument: instruments.hat },
{ pitch: 24, instrument: instruments.hat },
{ pitch: 17, instrument: instruments.hat },
{ pitch: 11, instrument: instruments.hat },
{ pitch: 18, instrument: instruments.hat },
{ pitch: 9, instrument: instruments.hat },
{ pitch: 5, instrument: instruments.hat },
{ pitch: 22, instrument: instruments.hat },
{ pitch: 19, instrument: instruments.snare },
{ pitch: 17, instrument: instruments.hat },
{ pitch: 22, instrument: instruments.hat },
{ pitch: 22, instrument: instruments.snare },
{ pitch: 24, instrument: instruments.chime },
{ pitch: 24, instrument: instruments.chime },
{ pitch: 21, instrument: instruments.hat },
{ pitch: 14, instrument: instruments.basedrum },
{ pitch: 7, instrument: instruments.basedrum }
]

View file

@ -0,0 +1,13 @@
/**
* converts minecraft version to number (for example '1.19.2' will be 1.19)
* @param {String} version
* @return {Number} decimal number of the version you specified
*/
function minecraftVersionToNumber (version) {
const versionArray = version.split('.')
if (versionArray.length === 2) return Number(version)
versionArray.pop()
return Number(versionArray.join('.'))
}
module.exports = minecraftVersionToNumber

View file

@ -0,0 +1,65 @@
const nbs = require('./nbs_file')
const instrumentNames = [
'harp',
'bass',
'basedrum',
'snare',
'hat',
'guitar',
'flute',
'bell',
'chime',
'xylophone',
'iron_xylophone',
'cow_bell',
'didgeridoo',
'bit',
'banjo',
'pling'
]
function convertNBS (buf) {
const parsed = nbs.parse(buf)
const song = {
name: parsed.songName,
notes: [],
loop: false,
loopPosition: 0,
length: 0
}
if (parsed.loop > 0) {
song.loop = true
song.loopPosition = parsed.loopStartTick
}
for (const note of parsed.nbsNotes) {
let instrument = note.instrument
if (note.instrument < instrumentNames.length) {
instrument = instrumentNames[note.instrument]
} else continue
let key = note.key
while (key < 33) key += 12;
while (key > 57) key -= 12;
const layerVolume = 100
// will add layer volume later
const time = tickToMs(note.tick, parsed.tempo)
song.length = Math.max(song.length, time)
song.notes.push({
instrument,
pitch: key - 33,
volume: note.velocity * layerVolume / 10000,
time
})
}
return song
}
function tickToMs (tick = 1, tempo) {
return Math.floor(1000 * tick * 100 / tempo)
}
module.exports = convertNBS

157
ChomensJS/util/nbs_file.js Normal file
View file

@ -0,0 +1,157 @@
function parse (buffer) {
let i = 0
let songLength = 0
let format = 0
let vanillaInstrumentCount = 0
songLength = readShort()
if (songLength === 0) {
format = readByte()
}
if (format >= 1) {
vanillaInstrumentCount = readByte()
}
if (format >= 3) {
songLength = readShort()
}
const layerCount = readShort()
const songName = readString()
const songAuthor = readString()
const songOriginalAuthor = readString()
const songDescription = readString()
const tempo = readShort()
const autoSaving = readByte()
const autoSavingDuration = readByte()
const timeSignature = readByte()
const minutesSpent = readInt()
const leftClicks = readInt()
const rightClicks = readInt()
const blocksAdded = readInt()
const blocksRemoved = readInt()
const origFileName = readString()
let loop = 0
let maxLoopCount = 0
let loopStartTick = 0
if (format >= 4) {
loop = readByte()
maxLoopCount = readByte()
loopStartTick = readShort()
}
const nbsNotes = []
let tick = -1
while (true) {
const tickJumps = readShort()
if (tickJumps === 0) break
tick += tickJumps
let layer = -1
while (true) {
const layerJumps = readShort()
if (layerJumps === 0) break
layer += layerJumps
const note = nbsNote()
note.tick = tick
note.layer = layer
note.instrument = readByte()
note.key = readByte()
if (format >= 4) {
note.velocity = readByte()
note.panning = readByte()
note.pitch = readShort()
}
nbsNotes.push(note)
}
}
const nbsLayers = []
if (i <= buffer.length) {
for (let j = 0; j < layerCount; j++) {
const layer = nbsLayer()
layer.name = readString()
if (format >= 4) {
layer.lock = readByte()
}
layer.volume = readByte()
if (format >= 2) {
layer.stereo = readByte()
}
nbsLayers.push(layer)
}
}
return {
songLength,
format,
vanillaInstrumentCount,
layerCount,
songName,
songAuthor,
songOriginalAuthor,
songDescription,
tempo,
autoSaving,
autoSavingDuration,
timeSignature,
minutesSpent,
leftClicks,
rightClicks,
blocksAdded,
blocksRemoved,
origFileName,
loop,
maxLoopCount,
loopStartTick,
nbsNotes,
nbsLayers
}
function readByte () {
return buffer.readInt8(i++)
}
function readShort () {
const short = buffer.readInt16LE(i)
i += 2
return short
}
function readInt () {
const int = buffer.readInt32LE(i)
i += 4
return int
}
function readString () {
let length = readInt()
let string = ''
for (; length > 0; length--) string += String.fromCharCode(readByte())
return string
}
}
function nbsNote () {
return {
tick: null,
layer: null,
instrument: null,
key: null,
velocity: 100,
panning: 100,
pitch: 0
}
}
function nbsLayer () {
return {
name: null,
lock: 0,
volume: null,
stereo: 100
}
}
module.exports = { parse, nbsNote, nbsLayer }

View file

@ -0,0 +1,15 @@
const { instrumentsArray } = require('minecraft-data')('1.15.2') // chip hardcoding moment
function parseTXTSong (data) {
let length = 0
const notes = String(data).split(/\r\n|\r|\n/).map(line => {
const [tick, pitch, instrument] = line.split(':').map(Number)
if (tick === undefined || pitch === undefined || instrument === undefined) return undefined
const time = tick * 50
length = Math.max(length, time)
return { time, pitch, instrument: instrumentsArray[instrument].name, volume: 1 }
}).filter(note => note !== undefined)
return { name: '', notes, loop: false, loopPosition: 0, length }
}
module.exports = parseTXTSong

View file

@ -1,14 +1,13 @@
// TODO: Improve how messages are stringified // TODO: Improve how messages are stringified
const ChatMessage = require('prismarine-chat')('1.20.2') const ChatMessage = require('prismarine-chat')('1.20.2')
const stringify = message => new ChatMessage(message)?.toString() const stringify = message => new ChatMessage(message).toString()
class CommandError extends Error { class CommandError extends Error {
constructor (message, filename, lineError, useChat) { constructor (message, filename, lineError) {
super(stringify(message), filename, lineError, useChat) super(stringify(message), filename, lineError)
this.name = 'CommandError' this.name = 'CommandError'
this._message = message this._message = message
return this._useChat = useChat
// this._useChat = useChat
} }
get message () { get message () {

View file

@ -0,0 +1,26 @@
class CommandSource {
constructor (player, sources, hash, owner, discordMessageEvent = null, consoleOnly, name, profile, bot, prefix = "~") {
this.player = player//kaboom on crack!
// idk fr // mabe
// /shrug
//am i good to restart it?
this.sources = sources
this.profile = bot
this.hash = hash
this.owner = owner
this.consoleOnly = consoleOnly
this.discordMessageEvent = discordMessageEvent
this.prefix = prefix
}
sendFeedback () {}
sendError (message) {
this.sendFeedback([{ text: '', color: 'red' }, message], false)
}
}
module.exports = CommandSource

122
bot.js Normal file
View file

@ -0,0 +1,122 @@
const mc = require("minecraft-protocol");
const { EventEmitter } = require("node:events");
const fs = require("fs");
const path = require("path");
const util = require("node:util");
console.log(`Starting ${process.env["buildstring"]} .......`);
console.log(`Foundation: ${process.env["FoundationBuildString"]}`);
console.log("this may take a few moments....");
require("events").EventEmitter.defaultMaxListeners = 31;
function createBot(options = {}) {
const bot = new EventEmitter();
const rs = require("randomstring");
// Set some default values in options
let r = Math.floor(Math.random() * 255) + 1;
options.host ??= "localhost";
options.username ??= "FNFBoyfriendBot";
options.hideErrors ??= false; // HACK: Hide errors by default as a lazy fix to console being spammed with them
options.Console.enabled ??= true;
options.Console.filelogging ??= false;
/*
options.commands.MainPrefix ??= "~";
options.commands.SecondaryPrefix ??= "%";
options.commands.TertiaryPrefix ??= "&";
options.selfcare.unmuted ??= true;
*/
options.selfcare.vanished ??= true;
options.selfcare.prefix ??= true;
options.selfcare.skin ??= true;
options.selfcare.cspy ??= true;
options.selfcare.op ??= true;
options.selfcare.gmc ??= true;
options.selfcare.interval ??= 500;
options.selfcare.username ??= true;
options.selfcare.nickname ??= true;
options.selfcare.god ??= true;
options.selfcare.tptoggle ??= true;
options.discord.commandPrefix ??= "~";
options.reconnectDelay ??= 1000;
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", async function (data) {
bot.uuid = client.uuid;
bot.username = client.username;
bot.port = bot.options.port;
bot.version = bot.options.version;
console.log(`Username: ${bot.options.username}`);
console.log(`Host: ${bot.options.host}:${bot.options.port}`);
console.log(`Minecraft java version: ${bot.options.version}`);
if(!bot.options.Core.enabled){
bot.console.info(`Coreless mode active for ${bot.options.host}:${bot.options.port} !`)
}
bot.chat('&5&lFNF&#00FFFF&lBoyfriend&4&lBot &f- &4Parker&02991')
//startupmsg:true,
const timer = setInterval(() => {
bot.chat(`Join the FNFBoyfriendBot discord ${bot.options.discord.invite}`)
}, 280000)
client.on("end", (reason) => {
bot.emit("end", reason);
console.log(reason);
bot.cloop.clear()
bot.memusage.off()
clearInterval(timer)
});
});
client.on("disconnect", (reason) => {
bot.emit("disconnect", reason);
console.log(reason);
});
client.on("kick_disconnect", (reason) => {
bot.emit("kick_disconnect", reason);
console.log(reason);
});
client.on("keep_alive", ({ keepAliveId }) => {
bot.emit("keep_alive", { keepAliveId });
});
client.on("error", (error) => bot.emit("error", error));
});
const client = options.client ?? mc.createClient(options);
bot._client = client;
bot.emit("init_client", client);
bot.bots = options.bots ?? [bot];
return bot;
}
const amonger = "../";
if (fs.existsSync("../FridayNightFunkinBoyfriendBot") == false) { // this isn't full proof. if the replit name is the same as this value, it will count as not a amonger | I have an idea, my idea is like check if the name of the system / info is whatever so if it's win32 but it should be whatever ubuntu or something it doesn't run | I might put it in minecraft-protocol files :skull:
process.exit(1);//but that would be overwritten when minecraft-protocol is being updated or smh
}
module.exports = createBot;

45
botsrun.js Normal file
View file

@ -0,0 +1,45 @@
const CommandError = require('../CommandModules/command_error')
module.exports = {
name: 'botsrun',
description:[''],
aliases:[],
trustLevel: 2,
execute (context) {
const bot = context.bot
// const client = context.client
const args = context.arguments
const source = context.source
const message = context.arguments.join(' ')
//const source = context.source
// if (args.length === 0){
//source.sendFeedback({translate:"Too few Arguments!", color:"red"})
const amogus = args.slice(1).join(' ');
if (!args && !args[0] && !args[1] && !args[2]) return
try{
switch (args[1]) {
case 'source':
for (const eachBot of bot.bots) {
eachBot.commandManager.executeString(source, `${args.slice(2).join(' ')} `)
}
break
case 'consolesource':
for (const eachBot of bot.bots) {
eachBot.commandManager.executeString(bot.console.source, `${args.slice(2).join(' ')} `)
}
break
default:
context.source.sendError([ { text: 'Invalid action', color: 'dark_red', bold:false }])
source.sendFeedback({text:'Args are source and consolesource', color:'green'})
}
}catch(error){
source.sendFeedback(error.stack)
}
// context.source.sendFeedback({ text: util.inspect(eval(script), { stylize }).substring(0, 32700) })
}//
}

33
bruhifytellraw.js Normal file
View file

@ -0,0 +1,33 @@
const convert = require('color-convert')
function inject (bot) {
bot.bruhifyTextTellraw = ''
let startHue = 0
const timer = setInterval(() => {
if (bot.bruhifyTextTellraw === '') return
let hue = startHue
const displayName = bot.bruhifyTextTellraw
const increment = (360 / Math.max(displayName.length, 20))
const component = []
for (const character of displayName) {
const color = convert.hsv.hex(hue, 100, 100)
component.push({
text: character,
color: `#${color}`,
})
// hoverEvent: { action:"show_text", value: '§aMan i like frogs - _ChipMC_'},
hue = (hue + increment) % 360
}
bot.core.run(`tellraw @a ${JSON.stringify(component)}`) // instead of doing just "tellraw" do "minecraft:tellraw"
startHue = (startHue + increment) % 360
}, 50)
bot.on('end', () => {
clearInterval(timer)
})
}
module.exports = inject

33
bruhifytitle.js Normal file
View file

@ -0,0 +1,33 @@
const convert = require('color-convert')
function inject (bot) {
bot.bruhifyTextTitle = ''
let startHue = 0
const timer = setInterval(() => {
if (bot.bruhifyTextTitle === '') return
let hue = startHue
const displayName = bot.bruhifyTextTitle
const increment = (360 / Math.max(displayName.length, 20))
const component = []
for (const character of displayName) {
const color = convert.hsv.hex(hue, 100, 100)
component.push({
text: character,
color: `#${color}`,
})
// hoverEvent: { action:"show_text", value: '§aMan i like frogs - _ChipMC_'},
hue = (hue + increment) % 360
}
bot.core.run(`title @a title ${JSON.stringify(component)}`) // instead of doing just "tellraw" do "minecraft:tellraw"
startHue = (startHue + increment) % 360
}, 100)
bot.on('end', () => {
clearInterval(timer)
})
}
module.exports = inject

74
calculator.js Normal file
View file

@ -0,0 +1,74 @@
const CommandError = require('../CommandModules/command_error')
module.exports = {
name: 'calculator',
description:['calculate maths'],
trustLevel: 0,
aliases:['calc'],
execute (context) {
const bot = context.bot
const args = context.arguments
const cmd = {//test.js
translate: '[%s] ',
bold: false,
color: 'white',
with: [
{ color: 'blue', text: 'Calculator Cmd'},
]
}
const operation = args[0]
const operator1 = parseFloat(args[1])
const operator2 = parseFloat(args[2])
//
switch (operation) {
case 'add':
context.source.sendFeedback({
translate: '[%s] %s is %s',
with: [
{color: 'blue', text:'Calculator Cmd'},
`${operator1} + ${operator2}`,
operator1 + operator2
]
});
break
case 'subtract':
context.source.sendFeedback({
translate: `[%s] %s is %s`,
with: [
{ color: 'blue', text: 'Calculator Cmd'},
`${operator1} - ${operator2}`,
operator1 - operator2
]
});
break
case 'multiply':
context.source.sendFeedback({
translate: '[%s] %s is %s',
with: [
{ color: 'blue', text: 'Calculator Cmd'},
`${operator1} x ${operator2}`,
operator1 * operator2
]
});
break
case 'divide':
context.source.sendFeedback({
translate: '[%s] %s is %s',
with: [
{ color: 'blue', text: 'Calculator Cmd'},
`${operator1} / ${operator2}`,
operator1 / operator2
]
});
break
default:
context.source.sendError([cmd, { text: 'Invalid action', color: 'dark_red' }])
}
}
}

34
chat/chatTypeEmote.js Normal file
View file

@ -0,0 +1,34 @@
function parseMessage (message, data, context) {
try{
if (message === null || typeof message !== 'object') return
if (message.with?.length < 2 || (message.translate !== 'chat.type.emote' && message.translate !== '%s %s')) return
const senderComponent = message.with[0]
// wtf spam again - console.log(senderComponent)//wtf...
//console.log(senderComponent)
const contents = message.with[1]
// spam lol - console.log(contents)
//console.log(contents)
let sender
const hoverEvent = senderComponent.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 undefined
return { sender, contents, type: 'minecraft:chat', senderComponent }
}catch(e){
console.log(e.stack)
}
}
module.exports = parseMessage

34
chat/chatTypeText.js Normal file
View file

@ -0,0 +1,34 @@
function parseMessage (message, data, context) {
try {
if (message === null || typeof message !== 'object') return
if (message.with?.length < 2 || (message.translate !== 'chat.type.text' && message.translate !== '%s %s')) return
const senderComponent = message.with[0]
// wtf spam again - console.log(senderComponent)//wtf...
//console.log(senderComponent)
const contents = message.with[1]
// spam lol - console.log(contents)
//console.log(contents)
let sender
const hoverEvent = senderComponent.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 undefined
return { sender, contents, type: 'minecraft:chat', senderComponent }
}catch(e){
console.log(e.stack)
}
}
module.exports = parseMessage

35
chat/chipmunkmod.js Normal file
View file

@ -0,0 +1,35 @@
function parseMessage (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 = parseMessage

View file

@ -0,0 +1,27 @@
function parseMessage (message, data) {
if (message === null || typeof message !== 'object') return
if (message.with?.length < 4 || (message.translate !== '[%s%s] %s %s', message.color !== '#55FFFF' && message.translate !== '%s%s %s %s', message.color !== '#55FFFF')) return
const senderComponent = message.with[1]
const contents = message.with[3]
let sender
const hoverEvent = senderComponent.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 undefined
return { sender, contents, type: 'minecraft:chat', senderComponent }
}
module.exports = parseMessage

33
chat/creayun.js Normal file
View file

@ -0,0 +1,33 @@
function parseMessage (messageobj, data) { // this function is not getting called
const ChatMessage = require('prismarine-chat')('1.20.1')
const stringify = message => new ChatMessage(message).toString()
const message = stringify(messageobj);
var pattern = /^(.*?) (\S*?) » (.*?)$/;
// var pattern = /^(.*?) (\S*?) \u203a (.*?)$/;
//console.log('[debug] parsing a message');
const match = message.match(pattern);
if(pattern.test(message)) {
// console.log('[debug]', match);
return { sender: match[2], contents: match[3], type: 'minecraft:chat'}; //
} else {
//console.log('[debug] pattern does not match');
}//i just realized that the bot uses tellraw
//ima try to fix that
}//it picks players up as undefined in creayun
//and i tried using the kaboom chat parser but edited and that didnt work
// [] username »
module.exports = parseMessage//:troll:
// •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
// function(function(function(function(function(function(function(function(function(function(function(function(function(function(function(function)))))))))))))))
// i guess so because it connects you
// i think?
//🐔💨💩😎🐒🥶😁😂⏰❌🐒🛏
//very real
// theres so much things that get logged :sob:
//gotta love when it refuses to connect
// someones trying to be fake me in kaboom
//the bot is being waaay to sus
// i will crash him when i get on // sus // very
//k
// getting the fake parker out of kaboom
// pcrashed

View file

@ -1,6 +1,6 @@
const util = require('util') const util = require('util')
function kaboom (message, data) { function parseMessage (message, data) {
if (message === null || typeof message !== 'object') return if (message === null || typeof message !== 'object') return
if (message.text !== '' || !Array.isArray(message.extra) || message.extra.length < 3) return if (message.text !== '' || !Array.isArray(message.extra) || message.extra.length < 3) return
@ -38,4 +38,4 @@ function isSeparatorAt (children, start) {
return (children[start]?.text === ':' || children[start]?.text === '\xa7f:') && children[start + 1]?.text === ' ' return (children[start]?.text === ':' || children[start]?.text === '\xa7f:') && children[start + 1]?.text === ' '
} }
module.exports = kaboom module.exports = parseMessage

309
commands/bots.js Normal file
View file

@ -0,0 +1,309 @@
// TODO: Maybe add more authors
const bots = [
{
name: { text: "HBot", color: "aqua", bold: false },
authors: ["hhhzzzsss"],
exclaimer: "HBOT HARRYBUTT LMAOOOOOOOOOOOOOOOOO",
foundation: "java/mcprotocollib",
prefixes: ["#"],
},
{
name: { text: "64Bot", color: "gold", bold: false },
authors: ["64Will64"],
exclaimer: "NINTENDO 64?!?!??!?! 69Bot when??????",
foundation: "NodeJS/Mineflayer",
prefixes: ["w="],
},
{
name: { text: "Nebulabot", color: "dark_purple", bold: false },
authors: ["IuCC"],
exclaimer: "the void",
foundation: "NodeJS/Node-minecraft-protocol",
prefixes: ["["],
},
{
name: [
{ text: "Prism", color: "#00FF9C", bold: true },
{ text: "Bot", color: "white",bold:true },
],
authors: ["IuCC"],
exclaimer: "prismarine :3",
foundation: "NodeJS/Node-minecraft-protocol",
prefixes: ["["],
},
{
name: { text: "SharpBot", color: "aqua", bold: false },
authors: ["64Will64"],
exclaimer:
"sharp as in the tv? idfk im out of jokes also the first c# bot on the list??",
foundation: "C#/MineSharp",
prefixes: ["s="],
},
{
name: { text: "MoonBot", color: "red", bold: false },
authors: ["64Will64"],
exclaimer: "stop mooning/mooing me ",
foundation: "NodeJS/Mineflayer",
prefixes: ["m="],
},
{
name: { text: "TableBot", color: "yellow", bold: false },
authors: ["12alex12"],
exclaimer: "TABLE CLOTH BOT?!?! ",
foundation: "NodeJS/Node-minecraft-protocol",
prefixes: ["t!"],
},
{
name: [
{ text: "Evil", color: "dark_red", bold: false },
{ text: "Bot", color: "dark_purple" },
],
authors: ["FusseligerDev"],
exclaimer: "",
foundation: "Java/Custom",
prefixes: ["!"],
},
{
name: { text: "SBot Java", color: "white", bold: false }, // TODO: Gradient
authors: ["evkc"],
foundation: "Java/MCProtocolLib",
prefixes: [":"],
},
{
name: { text: "SBot Rust", color: "white", bold: false }, // TODO: Gradient
authors: ["evkc"],
foundation: "Rust",
prefixes: ["re:"],
},
{
name: { text: "Z-Boy-Bot", color: "dark_purple", bold: false }, // 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: "not used anymore (replaced by V2)",
authors: [{ text: "_yfd", color: "light_purple" }],
foundation: "NodeJS/Node-Minecraft-Protocol",
prefixes: ["<"],
},
{
name: { text: "ABot-V2", color: "gold", bold: true }, // TODO: Gradient
exclaimer: "",
authors: [{ text: "_yfd", color: "light_purple" }],
foundation: "NodeJS/Node-Minecraft-Protocol",
prefixes: ["<"],
},
{
name: { text: "FardBot", color: "light_purple", bold: false },
authors: ["_yfd"],
exclaimer: "bot is dead lol",
foundation: "NodeJS/Mineflayer",
prefixes: ["<"],
},
{
name: { text: "ChipmunkBot Java", color: "green", bold: false },
authors: ["_ChipMC_"],
exclaimer:
"chips? also shoutout to chip and chayapak for helping in the rewrite",
foundation: "Java/MCProtocolLib",
prefixes: ["'", "/'"],
},
{
name: { text: "ChipmunkBot NodeJS", color: "green", bold: false },
authors: ["_ChipMC_"],
foundation: "NodeJS/Node-Minecraft-Protocol",
},
{
name: { text: "TestBot", color: "aqua", bold: false },
authors: ["Blackilykat"],
foundation: "Java/MCProtocolLib",
prefixes: ["-"],
},
{
name: { text: "UBot", color: "grey", bold: false },
authors: ["HexWoman"],
exclaimer: "UwU OwO",
foundation: "NodeJS/node-minecraft-protocol",
prefixes: ['"'],
},
{
name: { text: "ChomeNS Bot Java", color: "yellow", bold: false },
authors: ["chayapak"],
exclaimer: "wow its my bot !! ! 4374621q43567%^&#%67868-- chayapak",
foundation: "Java/MCProtocolLib",
prefixes: ["*", "cbot ", "/cbot "],
},
{
name: { text: "ChomeNS Bot NodeJS", color: "yellow", bold: false },
authors: ["chayapak"],
foundation: "NodeJS/Node-Minecraft-Protocol",
prefixes: ["*", "cbot", "/cbot"],
},
{
name: { text: "RecycleBot", color: "dark_green", bold: false },
foundation: ["MorganAnkan"],
exclaimer: "nice bot",
language: "NodeJS/node-minecraft-protocol",
prefixes: ["="],
},
{
name: { text: "neobot", color: "blue", bold: false },
exclaimer: "n e o b o t ;oslkdfj;salkdfj;ladsjf",
authors: ["mirkokral"],
foundation: "java/MCProtocolLib",
prefixes: ["_"],
},
{
name: { text: "ManBot", color: "dark_green", bold: false },
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", bold: false },
{ text: "Bot", color: "red" },
],
exclaimer: "",
authors: ["SirLennox"],
foundation: "Java/custom",
prefixes: [","],
},
{
name: [{ text: "SnifferBot", color: "gold", bold: false }],
exclaimer: "sniff sniff FNFBoyfriendBot simp",
authors: ["popbob"],
foundation: "NodeJS/Node-minecraft-protocol",
prefixes: [">"],
},
{
name: [{ text: "XBot", color: "dark_purple", bold: false }],
exclaimer: "",
authors: ["popbob"],
foundation: "ts-Node/Node-minecraft-protocol",
prefixes: ["$"],
},
{
name: [
{ text: "Kitty", color: "gold", bold: false },{text:"Corp", color:'aqua',bold:false},
{ text: "Bot", color: "yellow",bold:false },
],
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: false },
{ text: "Boyfriend", color: "aqua", bold: false },
{ text: "Bot", color: "dark_red", bold: false },
{ text: " nmp", color: "black", bold: false },
],
authors: [
{ text: "Parker2991", color: "dark_red" },
{ text: " _ChipMC_", color: "dark_green", bold: false },
{ text: " chayapak", color: "yellow", bold: false },
{ text: " _yfd", color: "light_purple", bold: false },
{ text: "popbob", color: "gold" },
],
exclaimer: "FNFBoyfriendBot NMP Rewrite",
foundation: "NodeJS/node-minecraft-protocol",
prefixes: ["~ % &"],
},
{
name: [
{ text: "FNF", color: "dark_purple", bold: false },
{ text: "Boyfriend", color: "aqua", bold: false },
{ text: "Bot", color: "dark_red", bold: false },
{ text: " legacy", color: "green", bold: false },
],
authors: [
{ text: "Parker2991", color: "dark_red" },
{ text: " _ChipMC_", color: "dark_green", bold: false },
],
exclaimer:
"1037 LINES OF CODE WTFARD!??! also this version is in console commands only",
foundation: "NodeJS/mineflayer",
prefixes: [],
},
];
const CommandError = require('../CommandModules/command_error')
module.exports = {
name: "bots",
description: ["shows a list of known bots"],
aliases: ["knownbots"],
trustLevel: 0,
execute(context) {
const query = context.arguments.join(" ").toLowerCase();
const bot = context.bot;
if (query.length === 0) {
const list = [];
if(!bot.options.Core.enabled){
throw new CommandError('Coreless mode is active can not execute command!')
}else{
for (const info of bots) {
if (list.length !== 0) list.push({ text: ", ", color: "gray" }); // list.push(info.name)
list.push(info.name);
}
context.source.sendFeedback(
["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([component]);
},
};
//it doing it just for the ones i added lol
// prob a replit moment, it probably thinks there are regexes in the strings

19
commands/bruhify.js Normal file
View file

@ -0,0 +1,19 @@
const CommandError = require('../CommandModules/command_error')
module.exports = {
name: 'bruhify',
description:['bruhify text'],
aliases:['bruhifytext', 'bruh'],
trustLevel: 0,
execute (context) {
const bot = context.bot
const args = context.arguments
const message = context.arguments.join(' ')
bot.bruhifyText = args.join(' ')
context.source.sendFeedback(JSON.stringify(bot.bruhifyText))
}
}

128
commands/changelog.js Normal file
View file

@ -0,0 +1,128 @@
const bots = [
{//
name: { text: 'v5.0.0-Beta', color: 'blue', bold:false },
authors: ['Monochrome'],
foundation: '12/18/23',
exclaimer:'added owner validation to the bot thats about it',
},
{//
name: { text: 'v5.0.0', color: 'dark_red', bold:false },
authors: ['Monochrome'],
foundation: '12/20/23',
exclaimer:'since the old validation system was able to barely handle owner validation it was completely remove and replaced with trust levels which handle validation way better also added command aliases (shoutouts to poopbob with the command aliases). made a whole new changelog command for v5.0.0 and renamed the old one changelogv4.3.4. also fixed the issue with the console not properly refreshing lines that are sent',
},
{//
name: { text: 'v5.0.1', color: 'green', bold:false },
authors: [''],
foundation: 'added botsrun for the funni along with making the bot be able to auto refill its core now and fill the core from a command block(edit: nevermind its very buggy reverting it back to how it originally filled its core) and adding a hover event to netmsg along with having the test command tellraw the players display name in the command and added support for 3 command prefixes',
exclaimer:'12/23/23',
},
{//
name: { text: 'v5.0.2', color: 'green', bold:false },
authors: [''],
foundation: '12/26/23',
exclaimer:'fixed the issue with the cpu checking in the info command added discord hashing back into the bot to work along side the keys made it check to see if the config file is in the directory and if not it will recreate the config from default.js',
},
{//
name: { text: 'v5.0.3', color: 'green', bold:false },
authors: [''],
foundation: '12/29/23',
exclaimer:'mabe the bot last update of 2023 cuz next year will be 2024 www but anyway expanded the disconnect messages for both console and discord but thats pretty much it',
},
{//
name: { text: 'v5.0.4', color: 'green', bold:false },
authors: [''],
foundation: '1/12/24',
exclaimer:'first update of 2024 for the bot but anyway merged the test and errortest commands into cmdtest, changed the colors for the help command public is #00FFFF, trusted is dark_purple and owner remained as dark red. moved the module loader from bot.js to index.js to split the boot time in half which now allows module functions like bot.chat() to be used in bot.js and also since the command manager is a module it also loads the commands thats a w on all ends also removed some modules to improve the bots boot time and moved the functions for the sctoggle command into the command itself and not as a module which helped the boot time as well and last but not least merged the memused usage in the info command with the serverinfo usage and made the memusage command use the bossbar and not the actionbar',
},
{//
name: { text: 'v5.0.5', color: 'dark_red', bold:false },
authors: ['§#f001dbQT §#740000KB §0Termination'],
foundation: '1/26/24',
exclaimer:'added a new feature to the bot called Coreless Mode to where the core can be toggled and most commands using tellraw will use chat instead along with the discord relay chat, fixed the bug with trust and owner commands not running in console along with removing alot of useless commands and made the 3 prefixes a array and added ratelimit for console logging and command usage and added file chat logging back',
},
]//
//back
/*{//
name: { text: '', color: 'gray', bold:false },
authors: [''],
foundation: '',
exclaimer:'',
},*/
module.exports = {
name: 'changelog',
description:['check the bots changelog'],
trustLevel: 0,
aliases:['cl', 'changes'],
execute (context) {
const query = context.arguments.join(' ').toLowerCase()
if (query.length === 0) {
const list = []
for (const info of bots) {
if (list.length !== 0) list.push({ text: ', ', color: 'gray' })
list.push(info.name)
}
const category = {
translate: ' (%s%s%s%s%s%s%s%s%s) ',
bold: false,
color: 'white',
with: [
{ color: 'aqua', text: 'Alpha Release'},
{ color: 'white', text: ' | '},
{ color: 'blue', text: 'Beta Release'},
{ color: 'white', text: ' | '},
{ color: 'green', text: 'Minor release'},
{ color: 'white', text: ' | '},
{ color: 'gold', text: 'Revision Release'},
{ color: 'white', text: ' | '},
{ color: 'dark_red', text: 'Major Release'},
]
}
context.source.sendFeedback(['Changelogs (', bots.length, ')', category, ' - ', ...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('', info.name)
if (info.exclaimer) component.push('\n', ' ', info.exclaimer)
if (info.authors && info.authors.length !== 0) {
component.push('\n', 'Codename ')
for (const author of info.authors) {
component.push(author, { text: ', ', color: 'gray' })
}
component.pop()
}
if (info.foundation) component.push('\n', 'Date: ', info.foundation)
if (info.prefixes && info.prefixes.length !== 0) {
component.push('\n', '')
for (const prefix of info.prefixes) {
component.push(prefix, { text: ' ', color: 'gray' })
}
component.pop()
}
bot.tellraw([component])
}
}//it doing it just for the ones i added lol
// prob a replit moment, it probably thinks there are regexes in the strings

Some files were not shown because too many files have changed in this diff Show more