diff --git a/main/chatparser.js b/main/chatparser.js index ea5ebfe..325cbc4 100644 --- a/main/chatparser.js +++ b/main/chatparser.js @@ -1,7 +1,7 @@ // Don't change this or you gay. -// Version: 1.1 +// Version: 1.3 -const lang = require("../util/en_us.json"); // translate message +const lang = require("./en_us.json"); // translate message function uuidFromIntArray (arr) { const buf = Buffer.alloc(16) @@ -10,7 +10,7 @@ function uuidFromIntArray (arr) { } function simplify (data) { - try { + try { // Prevent RangeError if (data === undefined) return data; function transform (value, type) { if (type === 'compound') { @@ -70,26 +70,58 @@ let systemchat = {}; let profilelesschat = {}; let actionbar = {}; let bossbar = {}; +let title = {}; -bot.on('end', () => { // ok keep this +bot.on('end', () => { // Memory Leak Removed. playerchat = {}; delete playerchat; systemchat = {}; delete systemchat; profilelesschat = {}; delete profilelesschat; actionbar = {}; delete actionbar; bossbar = {}; delete bossbar; + title = {}; delete title; }) +bot.on('set_title_text', (packet) => { + title.message = parseMinecraftMessage(simplify(packet.text)); + title.nocolor_message = parseMinecraftMessageNoColor(simplify(packet.text)); + + bot.emit('custom_title', title.message, title, packet); + bot.emit('custom_allchat', 'title', title.message, title, packet); + + title.message = undefined; + title.nocolor_message = undefined; +}); + +bot.on('set_title_subtitle', (packet) => { + title.submessage = parseMinecraftMessage(simplify(packet.text)); + title.nocolor_submessage = parseMinecraftMessageNoColor(simplify(packet.text)); + + bot.emit('custom_subtitle', title.submessage, title, packet); + bot.emit('custom_allchat', 'subtitle', title.submessage, title, packet); + + title.submessage = undefined; + title.nocolor_submessage = undefined; +}); + +bot.on('set_title_time', (packet) => { + title.fadeIn = packet.fadeIn; + title.stay = packet.stay; + title.fadeOut = packet.fadeOut; + + bot.emit('custom_timetitle', undefined, title, packet); + bot.emit('custom_allchat', 'timetitle', undefined, title, packet); +}); + bot.on('boss_bar', (packet) => { - bossbar = {}; bossbar.uuid = packet.entityUUID; bossbar.action = packet.action; - + switch (bossbar.action) { case 1: // bossbar remove || bossbar visible false || bossbar player !botName break; case 0: // bossbar visible true || bossbar player botName - bossbar.title = parseMinecraftMessage(simplify(packet.title)); + bossbar.message = parseMinecraftMessage(simplify(packet.title)); bossbar.nocolor_title = parseMinecraftMessageNoColor(simplify(packet.title)); bossbar.health = packet.health; bossbar.color = packet.color; @@ -102,8 +134,8 @@ bot.on('boss_bar', (packet) => { break; case 3: // bossbar set name - bossbar.title = parseMinecraftMessage(simplify(packet.title)); - bossbar.nocolor_title = parseMinecraftMessageNoColor(simplify(packet.title)); + bossbar.message = parseMinecraftMessage(simplify(packet.title)); + bossbar.nocolor_message = parseMinecraftMessageNoColor(simplify(packet.title)); break; case 4: @@ -120,8 +152,8 @@ bot.on('boss_bar', (packet) => { break; } - bot.emit('custom_bossbar', bossbar.title, bossbar, packet); - bot.emit('custom_allchat', 'bossbar', bossbar.title, bossbar, packet); + bot.emit('custom_bossbar', bossbar.message, bossbar, packet); + bot.emit('custom_allchat', 'bossbar', bossbar.message, bossbar, packet); }); bot.on('action_bar', (packet) => { @@ -159,31 +191,31 @@ bot.on('profileless_chat', (packet) => { // kinda player_chat switch (profilelesschat.type) { case 1: // /me profilelesschat.message = parseMinecraftMessage({ "translate": "chat.type.emote", "with": [ profilelesschat.senderName, profilelesschat.formattedMessage ]}); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor({ "translate": "chat.type.emote", "with": [ profilelesschat.senderName, profilelesschat.formattedMessage ]}); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor({ "translate": "chat.type.emote", "with": [ profilelesschat.senderName, profilelesschat.formattedMessage ]}); break; case 2: // player /tell profilelesschat.message = parseMinecraftMessage({ translate: "commands.message.display.incoming", with: [ profilelesschat.senderName, profilelesschat.formattedMessage ], color: "gray", italic: true }); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor({ translate: "commands.message.display.incoming", with: [ profilelesschat.senderName, profilelesschat.formattedMessage ], color: "gray", italic: true }); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor({ translate: "commands.message.display.incoming", with: [ profilelesschat.senderName, profilelesschat.formattedMessage ], color: "gray", italic: true }); break; case 3: // you /tell profilelesschat.message = parseMinecraftMessage({ translate: "commands.message.display.outgoing", with: [ profilelesschat.targetName, profilelesschat.formattedMessage ], color: "gray", italic: true }); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor({ translate: "commands.message.display.outgoing", with: [ profilelesschat.targetName, profilelesschat.formattedMessage ], color: "gray", italic: true }); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor({ translate: "commands.message.display.outgoing", with: [ profilelesschat.targetName, profilelesschat.formattedMessage ], color: "gray", italic: true }); break; case 4: // player chat profilelesschat.message = parseMinecraftMessage(profilelesschat.formattedMessage); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor(profilelesschat.formattedMessage); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor(profilelesschat.formattedMessage); break; case 5: // /say profilelesschat.message = parseMinecraftMessage({ translate: 'chat.type.announcement', with: [ profilelesschat.senderName, profilelesschat.formattedMessage ]}); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor({ translate: 'chat.type.announcement', with: [ profilelesschat.senderName, profilelesschat.formattedMessage ]}); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor({ translate: 'chat.type.announcement', with: [ profilelesschat.senderName, profilelesschat.formattedMessage ]}); break; case 6: // player /teammsg profilelesschat.message = parseMinecraftMessage({ translate: 'chat.type.team.text', with: [ profilelesschat.targetName, profilelesschat.senderName, profilelesschat.formattedMessage ]}); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor({ translate: 'chat.type.team.text', with: [ profilelesschat.targetName, profilelesschat.senderName, profilelesschat.formattedMessage ]}); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.text', with: [ profilelesschat.targetName, profilelesschat.senderName, profilelesschat.formattedMessage ]}); break; case 7: // you /teammsg profilelesschat.message = parseMinecraftMessage({ translate: 'chat.type.team.sent', with: [ profilelesschat.targetName, profilelesschat.senderName, profilelesschat.formattedMessage ]}); - profilelesschat.nocolor_msg = parseMinecraftMessageNoColor({ translate: 'chat.type.team.sent', with: [ profilelesschat.targetName, profilelesschat.senderName, profilelesschat.formattedMessage ]}); + profilelesschat.nocolor_message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.sent', with: [ profilelesschat.targetName, profilelesschat.senderName, profilelesschat.formattedMessage ]}); break; default: console.log(`Unknown profilelesschat packet. Type: ${playerchat.type}`); @@ -213,31 +245,31 @@ bot.on('player_chat', (packet) => { // player switch (playerchat.type) { // vanish off case 1: // /minecraft:me playerchat.message = parseMinecraftMessage({ "translate": "chat.type.emote", "with": [ playerchat.senderName, playerchat.plainMessage ]}); - playerchat.nocolor_msg = parseMinecraftMessageNoColor({ "translate": "chat.type.emote", "with": [ playerchat.senderName, playerchat.plainMessage ]}); + playerchat.nocolor_message = parseMinecraftMessageNoColor({ "translate": "chat.type.emote", "with": [ playerchat.senderName, playerchat.plainMessage ]}); break; case 2: // player /minecraft:tell playerchat.message = parseMinecraftMessage({ translate: "commands.message.display.incoming", with: [ playerchat.senderName, playerchat.plainMessage ], color: "gray", italic: true }); - playerchat.nocolor_msg = parseMinecraftMessageNoColor({ translate: "commands.message.display.incoming", with: [ playerchat.senderName, playerchat.plainMessage ], color: "gray", italic: true }); + playerchat.nocolor_message = parseMinecraftMessageNoColor({ translate: "commands.message.display.incoming", with: [ playerchat.senderName, playerchat.plainMessage ], color: "gray", italic: true }); break; case 3: // you /minecraft:tell playerchat.message = parseMinecraftMessage({ translate: "commands.message.display.outgoing", with: [ playerchat.targetName, playerchat.plainMessage ], color: "gray", italic: true }); - playerchat.nocolor_msg = parseMinecraftMessageNoColor({ translate: "commands.message.display.outgoing", with: [ playerchat.targetName, playerchat.plainMessage ], color: "gray", italic: true }); + playerchat.nocolor_message = parseMinecraftMessageNoColor({ translate: "commands.message.display.outgoing", with: [ playerchat.targetName, playerchat.plainMessage ], color: "gray", italic: true }); break; case 4: // player chat playerchat.message = parseMinecraftMessage(playerchat.unsignedContent); - playerchat.nocolor_msg = parseMinecraftMessageNoColor(playerchat.unsignedContent); + playerchat.nocolor_message = parseMinecraftMessageNoColor(playerchat.unsignedContent); break; case 5: // /say playerchat.message = parseMinecraftMessage({ translate: 'chat.type.announcement', with: [ playerchat.senderName, playerchat.plainMessage ]}); - playerchat.nocolor_msg = parseMinecraftMessageNoColor({ translate: 'chat.type.announcement', with: [ playerchat.senderName, playerchat.plainMessage ]}); + playerchat.nocolor_message = parseMinecraftMessageNoColor({ translate: 'chat.type.announcement', with: [ playerchat.senderName, playerchat.plainMessage ]}); break; case 6: // player /minecraft:teammsg || /teammsg playerchat.message = parseMinecraftMessage({ translate: 'chat.type.team.text', with: [ playerchat.targetName, playerchat.senderName, playerchat.plainMessage ]}); - playerchat.nocolor_msg = parseMinecraftMessageNoColor({ translate: 'chat.type.team.text', with: [ playerchat.targetName, playerchat.senderName, playerchat.plainMessage ]}); + playerchat.nocolor_message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.text', with: [ playerchat.targetName, playerchat.senderName, playerchat.plainMessage ]}); break; case 7: // you /minecraft:teammsg || /teammsg playerchat.message = parseMinecraftMessage({ translate: 'chat.type.team.sent', with: [ playerchat.targetName, playerchat.senderName, playerchat.plainMessage ]}); - playerchat.message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.sent', with: [ playerchat.targetName, playerchat.senderName, playerchat.plainMessage ]}); + playerchat.nocolor_message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.sent', with: [ playerchat.targetName, playerchat.senderName, playerchat.plainMessage ]}); break; default: console.log(`Unknown player_chat packet. Type: ${playerchat.type}`); @@ -446,4 +478,128 @@ function parseMinecraftMessageNoColor(component) { return extractText(component); } -module.exports = { inject }; \ No newline at end of file + +function kickparser(component) { + if (component === undefined) return; + if (typeof component === "string") return component; + + function kickparserText(comp) { + let text = ''; + + if (comp.text && typeof comp.text === 'string' || typeof comp.text === 'number') { + text += comp.text; + } + + if (comp[""] && typeof comp[""] === 'string' || typeof comp[""] === 'number') { + text += comp[""]; + } + + if (comp && typeof comp === 'string' || typeof comp === 'number') { + return comp; + } + + if (comp.translate) { + let translateString = lang[comp.translate] || comp.translate; + let DefaultTranslateString = lang[comp.translate] || comp.translate; + let DefaultMsg = false; + let fallbackMsg = false; + if (comp.fallback && !lang[comp.translate]) fallbackMsg = true; + + if (comp.with && !fallbackMsg) { + const withArgs = comp.with.map(arg => kickparserText(arg)); + let usedReplacements = 0; + + translateString = translateString.replace(/thing__placeholder__/g, 'default_thing__placeholder__'); + translateString = translateString.replace(/%s/g, (match, offset, string) => { + if (offset > 0 && string[offset - 1] === '%') { + return 's'; + } + + if (usedReplacements < withArgs.length) { + if (translateString.length + withArgs[usedReplacements].length > 16384) return 'Translate Crash'; // Prevent translate crash + return `thing__placeholder__${usedReplacements++}`; + } + + DefaultMsg = true; + return "%s"; + }); + + translateString = translateString.replace(/%(-?\d+)\$s/g, (match, index, stringindex, string) => { + const argIndex = parseInt(index, 10) - 1; + + if (argIndex < 0 || argIndex >= withArgs.length) { + DefaultMsg = true; + return match; + } + + if (stringindex > 0 && string[stringindex - 1] === '%') { + return match; + } + + if (translateString.length + withArgs[argIndex].length > 16384) return 'Translate Crash'; // Prevent translate crash + return `thing__placeholder__${argIndex}`; + }); + + for (let i = 0; i < withArgs.length; i++) { + if (translateString.length + withArgs[i].length > 16384) return 'Translate Crash'; // Prevent translate crash + translateString = translateString.replace(new RegExp(`thing__placeholder__${i}`, 'g'), (match) => { + const formattedArg = withArgs[i]; + return formattedArg; + }); + } + translateString = translateString.replace(/default_thing__placeholder__/g, 'thing__placeholder__'); + } + + if (DefaultMsg) { + text += DefaultTranslateString; + } else if (fallbackMsg) { + text += comp.fallback; + } else { + text += translateString; + } + } + + if (comp.extra) { + if (!Array.isArray(comp.extra)) comp.extra = [comp.extra] + comp.extra.forEach(subComp => { + text += kickparserText(subComp); + }); + } + + return text; + } + return kickparserText(simplify(component)); +} + +function cboutput(component) { + if (component === undefined) return; + + function extractText(comp) { + + let text = ''; + if (comp.text && typeof comp.text === 'string' || typeof comp.text === 'number') { + text += comp.text; + } + if (comp && typeof comp === 'string' || typeof comp === 'number') { + return comp; + } + + if (comp.extra) { + if (!Array.isArray(comp.extra)) comp.extra = [comp.extra] + comp.extra.forEach(subComp => { + text += formatfunction(comp, extractText(subComp)); + }); + } + + text = parseMinecraftColor(comp.color) + parseMinecraftFormat(comp) + text + ansiFormatCodes['reset']; + return text; + + } + + return extractText(component) + ansiFormatCodes['reset']; +} + + + + +module.exports = { inject, kickparser, cboutput }; \ No newline at end of file diff --git a/main/main.js b/main/main.js index 55108ef..49b265c 100644 --- a/main/main.js +++ b/main/main.js @@ -1,4 +1,4 @@ -// for version 1.0 chatparser +// 1.3 chatparser const mc = require('minecraft-protocol'); const ChatParse = require("./chatparser.js"); @@ -8,7 +8,7 @@ const bot = mc.createClient({ // host: '168.100.225.224', // Neko port: 25565, username: 'catparser', // cat - version: "1.20.4", + version: "1.20.4", // Not support 1.21 }); ChatParse.inject(bot); // load chatparser function @@ -29,14 +29,50 @@ bot.on('custom_actionbar', (message, actionbar, packet) => { console.log(`[ActionBar] ${message}`); }); -bot.on('custom_bossbar', (title, bossbar, packet) => { - console.log(`[BossBar | ${bossbar.action}] ${title}`); +bot.on('custom_bossbar', (message, bossbar, packet) => { + switch (bossbar.action) { + case 1: + console.log(`[BossBar Removed] ${bossbar.uuid}`); + break; + case 0: + console.log(`[BossBar Added] ${bossbar.message}\n${bossbar.health}\n${bossbar.color}\n${bossbar.dividers}\n${bossbar.flags}`); + break; + + case 2: + console.log(`[BossBar Health] ${bossbar.health}`) + break; + + case 3: + console.log(`[BossBar Message] ${bossbar.message}`) + // console.log(`[BossBar NoColor Message] ${bossbar.nocolor_message}`) + break; + + case 4: + console.log(`[BossBar Color] ${bossbar.color}`) + console.log(`[BossBar Style] ${bossbar.dividers}`) + break; + + case 5: + console.log(`[BossBar Flags] ${bossbar.flags}`) + break; + } +}); + +bot.on('custom_title', (message, title, packet) => { + console.log(`[Title] ${message}`) +}); + +bot.on('custom_subtitle', (message, title, packet) => { + console.log(`[SubTitle] ${message}`) +}); + +bot.on('custom_timetitle', (_, title, packet) => { + console.log(`[TitleTimes] fadeIn: ${title.fadeIn}\nstay: ${title.stay}\nfadeOut: ${title.fadeOut}`); }); /* - bot.on('custom_allchat', (chatType, message, messagePacket, packet) => { - if (chatType === "actionbar" || chatType === "bossbar") return; + if (chatType === "actionbar" || chatType === "bossbar" || chatType === "title" || chatType === "subtitle" || chatType === "timetitle") return; if (chatType === "systemchat" && messagePacket?.jsonMsg?.translate === "advMode.setCommand.success") return; // if you have core and dont want see "Command set: %s" console.log(`${chatType}: ${message}`) })