const { parseText } = require('../util/chat/utility') const plainStringify = require('../util/chat/stringify/plain') const colorCodeStringify = require('../util/chat/stringify/color_code') const htmlStringify = require('../util/chat/stringify/html') const ansiStringify = require('../util/chat/stringify/ansi') const ircStringify = require('../util/chat/stringify/irc') const vanillaParser = require('../util/chat/message_parser/vanilla') const kaboomParser = require('../util/chat/message_parser/kaboom') const kaboomVanillaLikeParser = require('../util/chat/message_parser/kaboom_vanilla_like') function inject (bot) { bot.chat = { queue: [], parsers: [vanillaParser, kaboomParser, kaboomVanillaLikeParser], message (message) { if (!bot.supportFeature('signedChat')) { bot._client.write('chat', { message }) return } bot._client.write('chat_message', { message, timestamp: BigInt(Date.now()), salt: 0n, offset: 0, acknowledged: Buffer.alloc(3) }) }, command (command) { if (!bot.supportFeature('signedChat')) { bot._client.write('chat', { message: '/' + command }) return } bot._client.write('chat_command', { command, timestamp: BigInt(Date.now()), salt: 0n, argumentSignatures: [], signedPreview: false, messageCount: 0, acknowledged: Buffer.alloc(3), previousMessages: [] }) }, shouldLog (message) { if (message?.translate === 'advMode.setCommand.success') return false return true } } setInterval(() => { if (!bot.loggedIn) return bot.emit('chat_queue_tick') const message = bot.chat.queue.shift() if (message != null) { if (message[0] === '/') bot.chat.command(message.substring(1)) else bot.chat.message(message) } }, 200) bot.on('packet.profileless_chat', (packet) => { const message = parseText(packet.message) const senderName = parseText(packet.name) const type = bot.registry?.chatFormattingById[packet.type] bot.emit('profileless_chat', { message, senderName, type }) bot.emit('chat', message) tryParsingMessage(message, { senderName, players: bot.players, lang: bot.registry.language }) }) bot.on('packet.player_chat', (packet) => { const plain = packet.plainMessage const unsigned = parseText(packet.unsignedChatContent) let sender = bot.players.find(player => player.uuid === packet.senderUuid) const type = bot.registry?.chatFormattingById[packet.type] if (!sender) { bot.console.warn(`Unable to find player_chat sender in player list (uuid: ${packet.senderUuid})`) sender = undefined } bot.emit('player_chat', { plain, unsigned, sender, type: type.name }) bot.emit('chat', unsigned) tryParsingMessage(unsigned, { senderUuid: sender?.uuid, players: bot.players, lang: bot.registry.language, plain }) }) bot.on('packet.system_chat', (packet) => { if (packet.isActionBar) return const message = parseText(packet.content) bot.emit('system_chat', message) bot.emit('chat', message) }) // legacy (1.18.2 and older) bot.on('packet.chat', packet => { const message = parseText(packet.message) bot.emit('chat', message) // if only it were this easy nowadays... switch (packet.position) { case 0: tryParsingMessage(message, { senderUuid: packet.sender, players: bot.players, lang: bot.registry.language }); break case 1: bot.emit('system_chat', message); break // TODO: 2 } }) bot.on('chat', message => { const stringifyOptions = { lang: bot.registry.language } bot.emit('chat_plain', plainStringify(message, stringifyOptions), message) bot.emit('chat_color_code', colorCodeStringify(message, stringifyOptions), message) bot.emit('chat_ansi', ansiStringify(message, stringifyOptions), message) bot.emit('chat_html', htmlStringify(message, stringifyOptions), message) bot.emit('chat_irc', ircStringify(message, stringifyOptions), message) if (bot.chat.shouldLog(message)) bot.console.log(message) }) function tryParsingMessage (message, data) { let parsed for (const parser of bot.chat.parsers) { parsed = parser(message, data) if (parsed) break } if (!parsed) return bot.emit('message', parsed) } } module.exports = inject