MCBot/main.js

207 lines
6.3 KiB
JavaScript
Raw Normal View History

2024-07-15 19:08:38 -06:00
const fs = require('fs')
const axios = require('axios')
const mineflayer = require('mineflayer')
const { EventEmitter } = require('events')
2024-07-15 14:24:50 -06:00
const { EmbedBuilder, hyperlink, WebhookClient } = require('discord.js');
2024-07-15 19:08:38 -06:00
const { registerFont, createCanvas } = require('canvas');
2024-07-15 14:24:50 -06:00
2024-07-15 19:08:38 -06:00
function stripChatColors(txt) {
const formattingRegex = /§[0-9a-fklmnor]+|[\[\]:]+/g;
return txt.replace(formattingRegex, '');
}
class GuildMessageSender {
constructor(rawUsername, rawHypixelRank, rawGuildRank) {
this.rawUsername = rawUsername
this.rawHypixelRank = rawHypixelRank
this.rawGuildRank = rawGuildRank
}
getCleanUsername() { return stripChatColors(this.rawUsername) }
getCleanHypixelRank() { return stripChatColors(this.rawHypixelRank) }
getCleanGuildRank() { return stripChatColors(this.rawGuildRank) }
}
2024-07-15 14:24:50 -06:00
2024-07-15 19:08:38 -06:00
class GuildMessage {
constructor(message, sender) {
this.message = message
this.sender = sender
}
2024-07-15 14:24:50 -06:00
}
2024-07-15 19:08:38 -06:00
class OfficerMessage {
constructor(message, sender) {
this.message = message
this.sender = sender
}
}
function parseGuildMessage(jsonMsg) {
const message_details = jsonMsg.json.extra
let message_prefix = message_details[0].text
let hypixel_rank = null
let username = null
let guild_rank = null
let eventType = 'null'
let sender_contents = null
if (message_prefix.includes('§2Guild >')) { eventType = 'guildmsg'; sender_contents = message_prefix.replace('§2Guild >', '') }
else if (message_prefix.includes('§3Officer >')) { eventType = 'officermsg'; sender_contents = message_prefix.replace('§3Officer >', '') }
let message_arr = sender_contents.trim().split(' ')
// Parse guild member details (with hypixel rank)
if (message_arr[0].includes('[')) { hypixel_rank = message_arr[0]; username = message_arr[1]; guild_rank = message_arr[2].replace(':', '') }
// Parse guild member details (nons)
else { hypixel_rank = ''; username = message_arr[0]; guild_rank = message_arr[1].replace(':', '') }
// Skip messages sent by the bot
if (stripChatColors(username) === bot.username) { return }
const sender = new GuildMessageSender(username, hypixel_rank, guild_rank)
let guildMessage = null
if (eventType === 'guildmsg') { guildMessage = new GuildMessage(message_details[1].text, sender) }
else if (eventType === 'officermsg') { guildMessage = new OfficerMessage(message_details[1].text, sender) }
else { console.error('Error parsing guild message: unknown event type'); return }
// Emit GuildMessage event
chatEvents.emit(eventType, guildMessage)
}
async function sendWebhookMessage(guildMsg) {
const canvas = createCanvas(800, 200)
const context = canvas.getContext('2d')
// Fill background
context.fillStyle = '#313338'
context.fillRect(0, 0, canvas.width, canvas.height)
context.font = '24px minecraft'
const username = guildMsg.sender.rawUsername
const hypixelRank = guildMsg.sender.rawHypixelRank
const guildRank = guildMsg.sender.rawGuildRank
const message = guildMsg.message
let x = 10
let y = 50
// Draw text with colors
context.fillStyle = '#FFAA00' // Example color, modify as needed
context.fillText(hypixelRank, x, y)
x += context.measureText(hypixelRank).width + 10
context.fillStyle = '#55FF55' // Example color, modify as needed
context.fillText(username, x, y)
x += context.measureText(username).width + 10
context.fillStyle = '#AAAAFF' // Example color, modify as needed
context.fillText(guildRank, x, y)
x += context.measureText(guildRank).width + 10
context.fillStyle = '#FFFFFF' // Example color, modify as needed
context.fillText(message, x, y)
// Convert canvas to buffer
const buffer = canvas.toBuffer('image/png')
// Send image to Discord webhook
const form = new FormData()
form.append('file', new Blob([Buffer.from(buffer)]), 'message.png')
await axios.post(webhookUrl, form, {})
2024-07-15 14:24:50 -06:00
}
2024-07-15 19:08:38 -06:00
class ProudCircleBot {
constructor(username) {
this.username = username
this.auth = 'microsoft'
this.host = 'play.hypixel.net'
this.version = '1.8.9'
this.shouldReconnect = true
this.initBot()
}
initBot() {
this.bot = mineflayer.createBot({
"username": this.username,
"auth": 'microsoft',
"host": 'play.hypixel.net',
"version": this.version
})
this.initEvents()
this.bot.emit('startup')
this.listenToUserInput()
}
listenToUserInput() {}
initEvents() {
// Bot Startup
this.bot.on('startup', async () => { console.log('Starting bot...') })
// Server login
this.bot.on('login', async () => {
let sock = this.bot._client.socket
console.log(`Logged into ${sock.server ? sock.server : sock._host}`)
})
// Disconnect from server
this.bot.on('end', async (cause) => {
console.log(`Disconnected from server: ${cause}`)
if (reason === 'disconnect.quitting') { return }
else { console.error('Unknown cause of disconnecting!') }
// Auto Reconnect
if (this.shouldReconnect) {
console.log('Attempting to reconnect...')
setTimeout(() => this.initBot(), 5000)
}
})
// Chat Message
this.bot.on('message', async (jsonMsg, position) => {
// Avoid hypixel cancer
if (jsonMsg['extra'] && jsonMsg['extra'].length === 100) { return }
let rawText = jsonMsg.toString()
if (rawText === "Woah there, slow down!") { console.error("Server issued message spam warning") }
if (!jsonMsg?.json?.extra || jsonMsg.json.extra.length === 0 || !jsonMsg.json.extra[0]) { return }
// Check for guild messages
// Guild/Officer chat/member join/member leave
let extra_prefix = jsonMsg.json.extra[0].text
if (extra_prefix.startsWith('§2Guild >') || extra_prefix.startsWith('§3Officer >')) {
parseGuildMessage(jsonMsg)
}
})
// Custom Guild Message Event
chatEvents.on('guildmsg', async (guildMsg) => {
console.log(`Guild: ${guildMsg.sender.getCleanUsername()} ${guildMsg.message}`)
await sendWebhookMessage(guildMsg)
})
// Custom Officer Message Event
chatEvents.on('officermsg', (officerMsg) => {
console.log(`Officer: ${officerMsg.sender.getCleanUsername()} ${officerMsg.message}`)
})
}
2024-07-15 14:24:50 -06:00
}
2024-07-15 19:08:38 -06:00
registerFont('fonts/Minecraftia-Regular.ttf', {family: 'Minecraft'})
const webhookUrl = 'https://discord.com/api/webhooks/1262482329671176232/yAHgxkP2JSBPpdjmz6mdABu5yRkXxatXcbzI91iAjy0jM0z1kRzE1HZqzK5OGXCmkqPk'
const webhookClient = new WebhookClient({ url: webhookUrl });
const chatEvents = new EventEmitter()
const bot = new ProudCircleBot('ProudCircle')