Minecraft-protocol-1.20.4-k.../kick.js
2024-10-18 15:04:45 -04:00

147 lines
No EOL
3.6 KiB
JavaScript

const lang = require("./en_us.json"); // translate message
const nbt = require('prismarine-nbt');
function uuidFromIntArray (arr) {
const buf = Buffer.alloc(16)
arr.forEach((num, index) => { buf.writeInt32BE(num, index * 4) })
return buf.toString('hex')
}
function processNbtMessage(msg) {
try {
if (typeof msg === 'string') { // just create simple nbt structure
msg = {
id: 'string',
value: msg
};
}
if (!msg || msg.type === 'end') return msg;
const simplified = nbt.simplify(msg); // Ensure nbt is defined elsewhere
const json = JSON.stringify(simplified, (key, val) => {
if (key === 'id' && Array.isArray(val)) return uuidFromIntArray(val);
return val;
});
return json;
} catch (e) {
return '{"text":""}';
}
}
const msg = {
reason: '{"translate":"multiplayer.disconnect.unverified_username"}'
}
const msg2 = {
"reason": {
"type": "compound",
"value": {
"with": {
"type": "list",
"value": {
"type": "string",
"value": [ "Internal Exception: io.netty.handler.codec.EncoderException: java.io.UTFDataFormatException: encoded string (t§k腻腻腻腻腻...腻腻腻腻§rno) too long: 97869 bytes" ]
}
},
"translate": {
"type": "string",
"value": "disconnect.genericReason"
}
}
}
}
console.log(kickparser(processNbtMessage(msg.reason)));
console.log(kickparser(processNbtMessage(msg2.reason)));
// lazy to make it color
function kickparser(component) {
if (component === undefined) return;
try {
jsonComponent = JSON.parse(component);
} catch (e) {
console.error("Invalid JSON format:", component);
return '';
}
function kickparserText(comp) {
let text = '';
if (typeof comp === 'string') {
text += comp;
}
if (typeof comp.value === 'string') {
text += comp.value;
}
if (comp.with) {
text += kickparserText(comp.with);
}
if (comp.value) {
[comp.value].forEach(subComp => {
if (typeof subComp === 'string') text += subComp;
text += kickparserText(subComp);
});
}
if (comp.translate) {
let translateString = lang[comp.translate] || comp.translate;
let DefaultTranslateString = lang[comp.translate] || comp.translate;
let DefaultMsg = false;
if (comp.with) {
const withArgs = comp.with.map(arg => extractText(arg));
let usedReplacements = 0;
translateString = translateString.replace(/%s/g, (match, offset, string) => {
if (offset > 0 && string[offset - 1] === '%') {
return 's';
}
if (usedReplacements < withArgs.length) {
const formattedArg = withArgs[usedReplacements];
if (translateString.length + formattedArg.length > 2048) return 'Translate Crash';
usedReplacements++;
return formattedArg;
}
DefaultMsg = true;
return "%s";
});
translateString = translateString.replace(/%(\d+)\$s/g, (match, index, stringindex, string) => {
const argIndex = parseInt(index) - 1;
if (argIndex >= withArgs.length) {
DefaultMsg = true;
return match;
}
if (stringindex > 0 && string[stringindex - 1] === '%') {
return match;
}
const formattedArg = withArgs[argIndex];
if (translateString.length + formattedArg.length > 2048) return 'Translate Crash';
return formattedArg;
});
}
if (DefaultMsg) {
text += DefaultTranslateString;
} else {
text += translateString;
}
}
return text;
}
return kickparserText(jsonComponent);
}