Info in chatparser.js
This commit is contained in:
parent
73851c6132
commit
bedfabab1c
3 changed files with 7966 additions and 0 deletions
824
chatparser.js
Normal file
824
chatparser.js
Normal file
|
@ -0,0 +1,824 @@
|
|||
/**
|
||||
* Minecraft-protocol version: 1.51.0
|
||||
*
|
||||
* Minecraft Version: 1.21.3
|
||||
*
|
||||
* Language File Version: 1.21.3
|
||||
*
|
||||
* ChatParser Version: 1
|
||||
*
|
||||
* Update:
|
||||
* - 1.21.3
|
||||
*
|
||||
* Report Issue: https://code.chipmunk.land/Yaode_owo/Minecraft-protocol-1.21.3-chat-parser/issues/new
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
const lang = require("./en_us.json"); // translate message
|
||||
|
||||
function simplify(data) {
|
||||
try {
|
||||
if (data === undefined || data === null) return undefined;
|
||||
if (typeof data !== "object") return data;
|
||||
function transform(value, type) {
|
||||
if (type === 'compound') {
|
||||
return Object.keys(value).reduce(function (acc, key) {
|
||||
acc[key] = simplify(value[key]);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
if (type === 'list') {
|
||||
return value.value.map(function (v) {
|
||||
return transform(v, value.type);
|
||||
});
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return transform(data.value, data.type);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return '*** An unexpected error occurred while processing the component ***';
|
||||
// return '*** When is component is sus ***';
|
||||
}
|
||||
}
|
||||
|
||||
function FixEmptyKeys(obj) {
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(FixEmptyKeys);
|
||||
} else if (typeof obj === 'object' && obj !== null) {
|
||||
const newObj = {};
|
||||
for (const key in obj) {
|
||||
const newKey = key === '' ? 'text' : key;
|
||||
newObj[newKey] = FixEmptyKeys(obj[key]);
|
||||
}
|
||||
return newObj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function processNBTComponent(data) {
|
||||
try {
|
||||
if (data === undefined || data === null) return undefined;
|
||||
if (typeof data !== "object") return data;
|
||||
return FixEmptyKeys(simplify(data));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return '*** An unexpected error occurred while processing the component ***';
|
||||
}
|
||||
}
|
||||
|
||||
function VaildText(comp) {
|
||||
return (typeof comp === "string" && comp !== "") ||
|
||||
(typeof comp.text === "string" && comp.text !== "") ||
|
||||
(typeof comp.keybind === "string" && comp.keybind !== "") ||
|
||||
(typeof comp.translate === "string" && comp.translate !== "") ||
|
||||
(typeof comp.extra === "object" && Array.isArray(comp.extra));
|
||||
}
|
||||
|
||||
|
||||
function parseMinecraftColor(color) {
|
||||
if (typeof color === 'string' && ansiMap[color] && !color.startsWith('#')) {
|
||||
return { color: ansiMap[color], have: true };
|
||||
} else if (typeof color === 'string' && color.startsWith('#')) {
|
||||
const hexRegex = /#?([a-fA-F\d]{2})([a-fA-F\d]{2})([a-fA-F\d]{2})/;
|
||||
const hexCodes = hexRegex.exec(color);
|
||||
if (hexCodes) {
|
||||
const red = parseInt(hexCodes[1], 16);
|
||||
const green = parseInt(hexCodes[2], 16);
|
||||
const blue = parseInt(hexCodes[3], 16);
|
||||
return { color: `\u001b[38;2;${red};${green};${blue}m`, have: true };
|
||||
}
|
||||
} else {
|
||||
return { color: '', have: false };
|
||||
}
|
||||
}
|
||||
|
||||
function parseMinecraftFormat(format) {
|
||||
let result = '';
|
||||
if (!format) return { format: '', have: false };
|
||||
for (const key in format) { if(format[key] === 0) { result += ansiMap['reset']; break; } };
|
||||
if (format.bold === 1) result += ansiMap['bold'];
|
||||
if (format.italic === 1) result += ansiMap['italic'];
|
||||
if (format.underlined === 1) result += ansiMap['underlined'];
|
||||
if (format.strikethrough === 1) result += ansiMap['strikethrough'];
|
||||
if (format.obfuscated === 1) result += ansiMap['obfuscated'];
|
||||
return result !== '' ? { format: result, have: true } : { format: '', have: false };
|
||||
}
|
||||
|
||||
function inject(bot) {
|
||||
let title = {
|
||||
type: NaN, // This is custom
|
||||
fadeIn: NaN,
|
||||
stay: NaN,
|
||||
fadeOut: NaN,
|
||||
jsonMsg: {
|
||||
message: undefined,
|
||||
subMessage: undefined
|
||||
},
|
||||
withColor: {
|
||||
message: undefined,
|
||||
subMessage: undefined
|
||||
},
|
||||
withoutColor: {
|
||||
message: undefined,
|
||||
subMessage: undefined
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
bot.on('end', () => {
|
||||
title = []; delete title;
|
||||
});
|
||||
|
||||
|
||||
bot.on('set_title_text', (packet) => {
|
||||
const parsedTitleText = processNBTComponent(packet.text);
|
||||
title = {
|
||||
...title,
|
||||
type: 0,
|
||||
jsonMsg: {
|
||||
message: parsedTitleText
|
||||
},
|
||||
withColor: {
|
||||
message: parseMinecraftMessage(parsedTitleText)
|
||||
},
|
||||
withoutColor: {
|
||||
message: parseMinecraftMessageNoColor(parsedTitleText)
|
||||
},
|
||||
}
|
||||
|
||||
bot.emit('custom_title', title.withColor.message, title, packet);
|
||||
bot.emit('custom_allMessage', 'title', title.message, title, packet);
|
||||
|
||||
title = {
|
||||
...title,
|
||||
type: NaN,
|
||||
jsonMsg: {
|
||||
message: undefined
|
||||
},
|
||||
withColor: {
|
||||
message: undefined
|
||||
},
|
||||
withoutColor: {
|
||||
message: undefined
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
bot.on('set_title_subtitle', (packet) => {
|
||||
const parsedSubTitleText = processNBTComponent(packet.text);
|
||||
title = {
|
||||
...title,
|
||||
type: 1,
|
||||
jsonMsg: {
|
||||
subMessage: parsedSubTitleText
|
||||
},
|
||||
withColor: {
|
||||
subMessage: parseMinecraftMessage(parsedSubTitleText)
|
||||
},
|
||||
withoutColor: {
|
||||
subMessage: parseMinecraftMessageNoColor(parsedSubTitleText)
|
||||
},
|
||||
}
|
||||
|
||||
bot.emit('custom_title', title.withColor.subMessage, title, packet);
|
||||
bot.emit('custom_allMessage', 'title', title.withColor.subMessage, title, packet);
|
||||
|
||||
title = {
|
||||
...title,
|
||||
type: NaN,
|
||||
jsonMsg: {
|
||||
subMessage: undefined
|
||||
},
|
||||
withColor: {
|
||||
subMessage: undefined
|
||||
},
|
||||
withoutColor: {
|
||||
subMessage: undefined
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
bot.on('set_title_time', (packet) => {
|
||||
title = {
|
||||
...title,
|
||||
type: 2,
|
||||
fadeIn: packet.fadeIn,
|
||||
stay: packet.stay,
|
||||
fadeOut: packet.fadeOut,
|
||||
}
|
||||
|
||||
bot.emit('custom_title', undefined, title, packet);
|
||||
bot.emit('custom_allMessage', 'title', undefined, title, packet);
|
||||
});
|
||||
|
||||
bot.on('boss_bar', (packet) => {
|
||||
const bossBar = {
|
||||
uuid: packet.entityUUID,
|
||||
action: packet.action,
|
||||
health: NaN,
|
||||
color: NaN,
|
||||
dividers: NaN,
|
||||
flags: NaN,
|
||||
|
||||
jsonMsg: {
|
||||
message: undefined
|
||||
},
|
||||
withColor: {
|
||||
message: undefined
|
||||
},
|
||||
withoutColor: {
|
||||
message: undefined
|
||||
},
|
||||
}
|
||||
|
||||
switch (bossBar.action) {
|
||||
case 0: { // add
|
||||
const parsedBossBarMessage = processNBTComponent(packet.title)
|
||||
bossBar.withoutColor.message = parseMinecraftMessageNoColor(parsedBossBarMessage);
|
||||
bossBar.withColor.message = parseMinecraftMessage(parsedBossBarMessage);
|
||||
bossBar.jsonMsg.message = parsedBossBarMessage;
|
||||
|
||||
bossBar.health = packet.health;
|
||||
bossBar.color = packet.color;
|
||||
bossBar.dividers = packet.dividers;
|
||||
bossBar.flags = packet.flags;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // remove
|
||||
break;
|
||||
|
||||
case 2: // update health
|
||||
bossBar.health = packet.health;
|
||||
break;
|
||||
|
||||
case 3: { // update title
|
||||
const parsedBossBarMessage = processNBTComponent(packet.title)
|
||||
bossBar.withoutColor.message = parseMinecraftMessageNoColor(parsedBossBarMessage);
|
||||
bossBar.withColor.message = parseMinecraftMessage(parsedBossBarMessage);
|
||||
bossBar.jsonMsg.message = parsedBossBarMessage;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // update style
|
||||
bossBar.color = packet.color;
|
||||
bossBar.dividers = packet.dividers;
|
||||
break;
|
||||
|
||||
case 5: // wither, ender dragon etc... , chayapak found it
|
||||
bossBar.flags = packet.flags;
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log(packet);
|
||||
break;
|
||||
}
|
||||
|
||||
bot.emit('custom_bossBar', bossBar.withColor.message, bossBar, packet);
|
||||
bot.emit('custom_allMessage', 'bossBar', bossBar.withColor.message, bossBar, packet);
|
||||
});
|
||||
|
||||
bot.on('action_bar', (packet) => {
|
||||
const parsedText = processNBTComponent(packet.text);
|
||||
|
||||
const actionBar = {
|
||||
jsonMsg: {
|
||||
message: parsedText
|
||||
},
|
||||
withColor: {
|
||||
message: parseMinecraftMessage(parsedText)
|
||||
},
|
||||
withoutColor: {
|
||||
message: parseMinecraftMessageNoColor(parsedText)
|
||||
},
|
||||
};
|
||||
|
||||
bot.emit('custom_actionBar', actionBar.withColor.message, actionBar, packet);
|
||||
bot.emit('custom_allMessage', 'actionBar', actionBar.message, actionBar, packet);
|
||||
});
|
||||
|
||||
|
||||
bot.on('system_chat', (packet) => {
|
||||
if (packet.isActionBar) return;
|
||||
const parsedContent = processNBTComponent(packet.content);
|
||||
|
||||
const systemChat = {
|
||||
jsonMsg: {
|
||||
message: parsedContent
|
||||
},
|
||||
withColor: {
|
||||
message: parseMinecraftMessage(parsedContent)
|
||||
},
|
||||
withoutColor: {
|
||||
message: parseMinecraftMessageNoColor(parsedContent)
|
||||
},
|
||||
};
|
||||
|
||||
bot.emit('custom_systemChat', systemChat.withColor.message, systemChat, packet);
|
||||
bot.emit('custom_allMessage', 'systemChat', systemChat.withColor.message, systemChat, packet);
|
||||
});
|
||||
|
||||
bot.on('profileless_chat', (packet) => { // kinda player_chat
|
||||
const parsedMessage = processNBTComponent(packet.message);
|
||||
const parsedName = processNBTComponent(packet.name);
|
||||
const parsedTarget = processNBTComponent(packet.target);
|
||||
|
||||
const profilelessChat = {
|
||||
type: packet.type.registryIndex,
|
||||
|
||||
jsonMsg: {
|
||||
message: undefined,
|
||||
formattedMessage: parsedMessage,
|
||||
senderName: parsedName,
|
||||
targetName: parsedTarget
|
||||
},
|
||||
withColor: {
|
||||
message: undefined,
|
||||
formattedMessage: parseMinecraftMessage(parsedMessage),
|
||||
senderName: parseMinecraftMessage(parsedName),
|
||||
targetName: parseMinecraftMessage(parsedTarget)
|
||||
},
|
||||
withoutColor: {
|
||||
message: undefined,
|
||||
formattedMessage: parseMinecraftMessageNoColor(parsedMessage),
|
||||
senderName: parseMinecraftMessageNoColor(parsedName),
|
||||
targetName: parseMinecraftMessageNoColor(parsedTarget)
|
||||
},
|
||||
};
|
||||
|
||||
switch (profilelessChat.type) {
|
||||
case 1: // normal profileless chat message
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ "translate": "chat.type.text", "with": [ parsedName, parsedMessage ]});
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ "translate": "chat.type.text", "with": [ parsedName, parsedMessage ]});
|
||||
profilelessChat.jsonMsg.message = { "translate": "chat.type.text", "with": [ parsedName, parsedMessage ]};
|
||||
break;
|
||||
case 2: // /me
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ "translate": "chat.type.emote", "with": [ parsedName, parsedMessage ]});
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ "translate": "chat.type.emote", "with": [ parsedName, parsedMessage ]});
|
||||
profilelessChat.jsonMsg.message = { "translate": "chat.type.emote", "with": [ parsedName, parsedMessage ]}
|
||||
break;
|
||||
case 3: // player /tell
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ translate: "commands.message.display.incoming", with: [ parsedName, parsedMessage ], color: "gray", italic: true });
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: "commands.message.display.incoming", with: [ parsedName, parsedMessage ], color: "gray", italic: true });
|
||||
profilelessChat.jsonMsg.message = { translate: "commands.message.display.incoming", with: [ parsedName, parsedMessage ], color: "gray", italic: true }
|
||||
break;
|
||||
case 4: // you /tell
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ translate: "commands.message.display.outgoing", with: [ parsedTarget, parsedMessage ], color: "gray", italic: true });
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: "commands.message.display.outgoing", with: [ parsedTarget, parsedMessage ], color: "gray", italic: true });
|
||||
profilelessChat.jsonMsg.message = { translate: "commands.message.display.outgoing", with: [ parsedTarget, parsedMessage ], color: "gray", italic: true }
|
||||
break;
|
||||
case 5: // player chat
|
||||
profilelessChat.withColor.message = parseMinecraftMessage(parsedMessage);
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor(parsedMessage);
|
||||
profilelessChat.jsonMsg.message = parsedMessage
|
||||
break;
|
||||
case 6: // /say
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ translate: 'chat.type.announcement', with: [ parsedName, parsedMessage ]});
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: 'chat.type.announcement', with: [ parsedName, parsedMessage ]});
|
||||
profilelessChat.jsonMsg.message = { translate: 'chat.type.announcement', with: [ parsedName, parsedMessage ]}
|
||||
break;
|
||||
case 7: // player /teammsg
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ translate: 'chat.type.team.text', with: [ parsedTarget, parsedName, parsedMessage ]});
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.text', with: [ parsedTarget, parsedName, parsedMessage ]});
|
||||
profilelessChat.jsonMsg.message = { translate: 'chat.type.team.text', with: [ parsedTarget, parsedName, parsedMessage ]}
|
||||
break;
|
||||
case 8: // you /teammsg
|
||||
profilelessChat.withColor.message = parseMinecraftMessage({ translate: 'chat.type.team.sent', with: [ parsedTarget, parsedName, parsedMessage ]});
|
||||
profilelessChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.sent', with: [ parsedTarget, parsedName, parsedMessage ]});
|
||||
profilelessChat.jsonMsg.message = { translate: 'chat.type.team.sent', with: [ parsedTarget, parsedName, parsedMessage ]}
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown profilelessChat packet. Type: ${profilelessChat.type}`);
|
||||
console.log(packet);
|
||||
break;
|
||||
}
|
||||
|
||||
bot.emit('custom_profilelessChat', profilelessChat.withColor.message, profilelessChat, packet);
|
||||
bot.emit('custom_allMessage', 'profilelessChat', profilelessChat.withColor.message, profilelessChat, packet);
|
||||
})
|
||||
|
||||
bot.on('player_chat', (packet) => { // player chat
|
||||
const parsedMessage = processNBTComponent(packet.unsignedChatContent);
|
||||
const parsedName = processNBTComponent(packet.networkName);
|
||||
const parsedTarget = processNBTComponent(packet.networkTargetName);
|
||||
|
||||
const playerChat = {
|
||||
type: packet.type.registryIndex,
|
||||
plainMessage: packet.plainMessage,
|
||||
senderUuid: packet.senderUuid,
|
||||
|
||||
jsonMsg: {
|
||||
message: undefined,
|
||||
unsignedChatContent: parsedMessage,
|
||||
senderName: parsedName,
|
||||
targetName: parsedTarget
|
||||
},
|
||||
withColor: {
|
||||
message: undefined,
|
||||
unsignedChatContent: parseMinecraftMessage(parsedMessage),
|
||||
senderName: parseMinecraftMessage(parsedName),
|
||||
targetName: parseMinecraftMessage(parsedTarget)
|
||||
},
|
||||
withoutColor: {
|
||||
message: undefined,
|
||||
unsignedChatContent: parseMinecraftMessageNoColor(parsedMessage),
|
||||
senderName: parseMinecraftMessageNoColor(parsedName),
|
||||
targetName: parseMinecraftMessageNoColor(parsedTarget)
|
||||
},
|
||||
};
|
||||
|
||||
switch (playerChat.type) { // vanish off
|
||||
case 1: // vanilla chat message
|
||||
playerChat.withColor.message = parseMinecraftMessage({ "translate": "chat.type.text", "with": [ parsedName, playerChat.plainMessage ]});
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ "translate": "chat.type.text", "with": [ parsedName, playerChat.plainMessage ]});
|
||||
playerChat.jsonMsg.message = { "translate": "chat.type.text", "with": [ parsedName, playerChat.plainMessage ]};
|
||||
break;
|
||||
case 2: // /minecraft:me
|
||||
playerChat.withColor.message = parseMinecraftMessage({ "translate": "chat.type.emote", "with": [ parsedName, playerChat.plainMessage ]});
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ "translate": "chat.type.emote", "with": [ parsedName, playerChat.plainMessage ]});
|
||||
playerChat.jsonMsg.message = { "translate": "chat.type.emote", "with": [ parsedName, playerChat.plainMessage ]}
|
||||
break;
|
||||
case 3: // player /minecraft:tell
|
||||
playerChat.withColor.message = parseMinecraftMessage({ translate: "commands.message.display.incoming", with: [ parsedName, playerChat.plainMessage ], color: "gray", italic: true });
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: "commands.message.display.incoming", with: [ parsedName, playerChat.plainMessage ], color: "gray", italic: true });
|
||||
playerChat.jsonMsg.message = { translate: "commands.message.display.incoming", with: [ parsedName, playerChat.plainMessage ], color: "gray", italic: true }
|
||||
break;
|
||||
case 4: // you /minecraft:tell
|
||||
playerChat.withColor.message = parseMinecraftMessage({ translate: "commands.message.display.outgoing", with: [ parsedTarget, playerChat.plainMessage ], color: "gray", italic: true });
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: "commands.message.display.outgoing", with: [ parsedTarget, playerChat.plainMessage ], color: "gray", italic: true });
|
||||
playerChat.jsonMsg.message = { translate: "commands.message.display.outgoing", with: [ parsedTarget, playerChat.plainMessage ], color: "gray", italic: true }
|
||||
break;
|
||||
case 5: // player chat
|
||||
playerChat.withColor.message = parseMinecraftMessage(parsedMessage);
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor(parsedMessage);
|
||||
playerChat.jsonMsg.message = parsedMessage
|
||||
break;
|
||||
case 6: // /say
|
||||
playerChat.withColor.message = parseMinecraftMessage({ translate: 'chat.type.announcement', with: [ parsedName, playerChat.plainMessage ]});
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: 'chat.type.announcement', with: [ parsedName, playerChat.plainMessage ]});
|
||||
playerChat.jsonMsg.message = { translate: 'chat.type.announcement', with: [ parsedName, playerChat.plainMessage ]}
|
||||
break;
|
||||
case 7: // player /minecraft:teammsg || /teammsg
|
||||
playerChat.withColor.message = parseMinecraftMessage({ translate: 'chat.type.team.text', with: [ parsedTarget, parsedName, playerChat.plainMessage ]});
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.text', with: [ parsedTarget, parsedName, playerChat.plainMessage ]});
|
||||
playerChat.jsonMsg.message = { translate: 'chat.type.team.text', with: [ parsedTarget, parsedName, playerChat.plainMessage ]}
|
||||
break;
|
||||
case 8: // you /minecraft:teammsg || /teammsg
|
||||
playerChat.withColor.message = parseMinecraftMessage({ translate: 'chat.type.team.sent', with: [ parsedTarget, parsedName, playerChat.plainMessage ]});
|
||||
playerChat.withoutColor.message = parseMinecraftMessageNoColor({ translate: 'chat.type.team.sent', with: [ parsedTarget, parsedName, playerChat.plainMessage ]});
|
||||
playerChat.jsonMsg.message = { translate: 'chat.type.team.sent', with: [ parsedTarget, parsedName, playerChat.plainMessage ]}
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown player_chat packet. Type: ${playerChat.type}`);
|
||||
console.log(packet);
|
||||
break;
|
||||
}
|
||||
|
||||
bot.emit('custom_playerChat', playerChat.withColor.message, playerChat, packet);
|
||||
bot.emit('custom_allMessage', 'playerChat', playerChat.withColor.message, playerChat, packet)
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const ansiMap = {
|
||||
'§0': '\x1B[30m',
|
||||
'§1': '\x1B[34m',
|
||||
'§2': '\x1B[32m',
|
||||
'§3': '\x1B[36m',
|
||||
'§4': '\x1B[31m',
|
||||
'§5': '\x1B[35m',
|
||||
'§6': '\x1B[33m',
|
||||
'§7': '\x1B[37m',
|
||||
'§8': '\x1B[90m',
|
||||
'§9': '\x1B[94m',
|
||||
'§a': '\x1B[92m',
|
||||
'§b': '\x1B[96m',
|
||||
'§c': '\x1B[91m',
|
||||
'§d': '\x1B[95m',
|
||||
'§e': '\x1B[93m',
|
||||
'§f': '\x1B[97m',
|
||||
black: '\x1B[30m',
|
||||
dark_blue: '\x1B[34m',
|
||||
dark_green: '\x1B[32m',
|
||||
dark_aqua: '\x1B[36m',
|
||||
dark_red: '\x1B[31m',
|
||||
dark_purple: '\x1B[35m',
|
||||
gold: '\x1B[33m',
|
||||
gray: '\x1B[37m',
|
||||
dark_gray: '\x1B[90m',
|
||||
blue: '\x1B[94m',
|
||||
green: '\x1B[92m',
|
||||
aqua: '\x1B[96m',
|
||||
red: '\x1B[91m',
|
||||
light_purple: '\x1B[95m',
|
||||
yellow: '\x1B[93m',
|
||||
white: '\x1B[97m',
|
||||
|
||||
'§l': '\x1B[1m',
|
||||
'§o': '\x1B[3m',
|
||||
'§n': '\x1B[4m',
|
||||
'§m': '\x1B[9m',
|
||||
'§k': '\x1B[5m',
|
||||
'§r': '\x1B[0m',
|
||||
bold: '\x1B[1m',
|
||||
italic: '\x1B[3m',
|
||||
underlined: '\x1B[4m',
|
||||
strikethrough: '\x1B[9m',
|
||||
obfuscated: '\x1B[5m',
|
||||
reset: '\x1B[0m',
|
||||
};
|
||||
|
||||
function parseMinecraftMessage(component) {
|
||||
if (component === undefined || component === null) return undefined;
|
||||
if (typeof component !== "object") return component;
|
||||
function extractText(comp, prevColor = { color: '', have: false }, prevFormat = { format: '', have: false }) {
|
||||
let text = '';
|
||||
|
||||
let shouldReset = false;
|
||||
let NowColor = parseMinecraftColor(comp?.color);
|
||||
let NowFormat = parseMinecraftFormat(comp);
|
||||
|
||||
if (VaildText(comp)) { // Idk, but it work atleast.
|
||||
if (NowFormat.have || prevFormat.have) {
|
||||
if (NowFormat.have) {
|
||||
text += NowFormat.format
|
||||
shouldReset = true;
|
||||
} else if (prevFormat.have) {
|
||||
text += prevFormat.format;
|
||||
}
|
||||
}
|
||||
if (NowColor.have || prevColor.have) {
|
||||
if (NowColor.have) {
|
||||
text += NowColor.color;
|
||||
shouldReset = true;
|
||||
} else if (prevColor.have) {
|
||||
text += prevColor.color;
|
||||
} else {
|
||||
text += ansiMap['white'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof comp.text === 'string' || typeof comp.text === 'number') {
|
||||
text += comp.text;
|
||||
}
|
||||
if (typeof comp === 'string' || typeof comp === 'number') {
|
||||
text += comp;
|
||||
}
|
||||
if (typeof comp.keybind === 'string' || typeof comp.keybind === 'number') {
|
||||
text += lang[comp.keybind] || comp.keybind;
|
||||
}
|
||||
|
||||
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 => extractText(arg, NowColor.have ? NowColor : prevColor, NowFormat.have ? NowFormat : prevFormat) + `${VaildText(comp) ? NowFormat.have ? NowFormat.format : prevFormat.format : ""}${VaildText(comp) ? NowColor.have ? NowColor.color : prevColor.color : ""}`);
|
||||
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 > 32768) return '\x1B[91m*** Component has too many placeholders ***\x1B[0m'; // 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 > 32768) return '\x1B[91m*** Component has too many placeholders ***\x1B[0m'; // Prevent translate crash
|
||||
return `thing__placeholder__${argIndex}`;
|
||||
});
|
||||
|
||||
for (let i = 0; i < withArgs.length; i++) {
|
||||
if (translateString.length + withArgs[i].length > 32768) return '\x1B[91m*** Component has too many placeholders ***\x1B[0m'; // 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 += extractText(subComp, NowColor.have ? NowColor : prevColor, NowFormat.have ? NowFormat : prevFormat) + `${VaildText(comp) ? NowFormat.have ? NowFormat.format : prevFormat.format : ""}${VaildText(comp) ? NowColor.have ? NowColor.color : prevColor.color : ""}`;
|
||||
});
|
||||
}
|
||||
|
||||
if (shouldReset) {
|
||||
text += ansiMap['reset']
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
return extractText(component);
|
||||
}
|
||||
|
||||
function parseMinecraftMessageNoColor(component) {
|
||||
if (component === undefined || component === null) return undefined;
|
||||
if (typeof component !== "object") return component;
|
||||
|
||||
function extractText(comp) {
|
||||
let text = '';
|
||||
|
||||
if (typeof comp.text === 'string' || typeof comp.text === 'number') {
|
||||
text += comp.text;
|
||||
}
|
||||
if (typeof comp === 'string' || typeof comp === 'number') {
|
||||
return comp;
|
||||
}
|
||||
if (typeof comp.keybind === 'string' || typeof comp.keybind === 'number') {
|
||||
text += lang[comp.keybind] || comp.keybind
|
||||
}
|
||||
|
||||
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 => extractText(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 > 32768) return '*** Component has too many placeholders ***'; // 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 > 32768) return '*** Component has too many placeholders ***'; // Prevent translate crash
|
||||
return `thing__placeholder__${argIndex}`;
|
||||
});
|
||||
|
||||
for (let i = 0; i < withArgs.length; i++) {
|
||||
if (translateString.length + withArgs[i].length > 32768) return '*** Component has too many placeholders ***'; // 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 += extractText(subComp);
|
||||
});
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
return extractText(component);
|
||||
}
|
||||
|
||||
function cboutput(component) {
|
||||
if (component === undefined || component === null) return undefined;
|
||||
if (typeof component !== "object") return component;
|
||||
|
||||
function extractText(comp, prevColor = { color: '', have: false }, prevFormat = { format: '', have: false }) {
|
||||
let text = '';
|
||||
|
||||
let shouldReset = false;
|
||||
let NowColor = parseMinecraftColor(comp?.color);
|
||||
let NowFormat = parseMinecraftFormat(comp);
|
||||
|
||||
if (VaildText(comp)) { // Idk, but it work atleast.
|
||||
if (NowFormat.have || prevFormat.have) {
|
||||
if (NowFormat.have) {
|
||||
text += NowFormat.format
|
||||
shouldReset = true;
|
||||
} else if (prevFormat.have) {
|
||||
text += prevFormat.format;
|
||||
}
|
||||
}
|
||||
if (NowColor.have || prevColor.have) {
|
||||
if (NowColor.have) {
|
||||
text += NowColor.color;
|
||||
shouldReset = true;
|
||||
} else if (prevColor.have) {
|
||||
text += prevColor.color;
|
||||
} else {
|
||||
text += ansiMap['white'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof comp.text === 'string' || typeof comp.text === 'number') {
|
||||
text += comp.text;
|
||||
}
|
||||
if (typeof comp === 'string' || typeof comp === 'number') {
|
||||
text += comp;
|
||||
}
|
||||
|
||||
if (comp.extra) {
|
||||
if (!Array.isArray(comp.extra)) comp.extra = [comp.extra]
|
||||
comp.extra.forEach(subComp => {
|
||||
text += extractText(subComp, NowColor.have ? NowColor : prevColor, NowFormat.have ? NowFormat : prevFormat) + `${VaildText(comp) ? NowFormat.have ? NowFormat.format : prevFormat.format : ""}${VaildText(comp) ? NowColor.have ? NowColor.color : prevColor.color : ""}`;
|
||||
});
|
||||
}
|
||||
|
||||
if (shouldReset) {
|
||||
text += ansiMap['reset']
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
return extractText(component);
|
||||
}
|
||||
|
||||
function cboutputNoColor(component) {
|
||||
if (component === undefined || component === null) return undefined;
|
||||
if (typeof component !== "object") return component;
|
||||
|
||||
function extractText(comp) {
|
||||
let text = '';
|
||||
|
||||
if (typeof comp.text === 'string' || typeof comp.text === 'number') {
|
||||
text += comp.text;
|
||||
}
|
||||
if (typeof comp === 'string' || typeof comp === 'number') {
|
||||
text += comp;
|
||||
}
|
||||
|
||||
if (comp.extra) {
|
||||
if (!Array.isArray(comp.extra)) comp.extra = [comp.extra]
|
||||
comp.extra.forEach(subComp => {
|
||||
text += extractText(subComp);
|
||||
});
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
return extractText(component);
|
||||
}
|
||||
|
||||
module.exports = { inject, parseMinecraftMessage, parseMinecraftMessageNoColor, cboutput, cboutputNoColor, simplify, FixEmptyKeys, processNBTComponent, ansiMap };
|
6974
en_us.json
Normal file
6974
en_us.json
Normal file
File diff suppressed because it is too large
Load diff
168
main.js
Normal file
168
main.js
Normal file
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* *Info in chat parser*
|
||||
*
|
||||
* Minecraft Version: 1.21.3
|
||||
* ChatParser Version: 1
|
||||
*
|
||||
*/
|
||||
|
||||
const mc = require('minecraft-protocol');
|
||||
const ChatParse = require("./chatparser.js");
|
||||
|
||||
function createBot() {
|
||||
|
||||
const bot = mc.createClient({
|
||||
// host: '95.216.192.50', // kaboom
|
||||
// host: 'chipmunk.land', // Chipmunk
|
||||
// host: '168.100.225.224', // Neko
|
||||
// host: 'chayapak.chipmunk.land', // chayapak
|
||||
port: 25565,
|
||||
username: 'catparser', // cat
|
||||
version: "1.21.3",
|
||||
hideErrors: true
|
||||
});
|
||||
|
||||
ChatParse.inject(bot); // load catparser function
|
||||
|
||||
bot.on('error', (e) => {
|
||||
if (bot !== undefined) bot.end(e.message);
|
||||
});
|
||||
|
||||
bot.on('end', (reason) => { // Out of memory.
|
||||
console.log(`Bot disconnect: ${reason}\nReconnect in 6 seconds...`);
|
||||
setTimeout(() => {
|
||||
createBot();
|
||||
}, 6e3);
|
||||
return;
|
||||
});
|
||||
|
||||
bot.on('custom_playerChat', (message, playerChat, packet) => {
|
||||
console.log(`[PlayerChat] ${message}`);
|
||||
});
|
||||
|
||||
bot.on('custom_profilelessChat', (message, profilelessChat, packet) => {
|
||||
console.log(`[ProfilelessChat] ${message}`);
|
||||
});
|
||||
|
||||
bot.on('custom_systemChat', (message, systemChat, packet) => {
|
||||
console.log(`[SystemChat] ${message}`);
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
// Kick message and disconnect message
|
||||
bot.on('kick_disconnect', (kick) => {
|
||||
console.log(ChatParse.parseMinecraftMessage(kicked.reason));
|
||||
})
|
||||
bot.on('disconnect', (kick) => {
|
||||
console.log(ChatParse.parseMinecraftMessage(kicked.reason));
|
||||
})
|
||||
bot.on('custom_actionBar', (message, actionBar, packet) => {
|
||||
console.log(`[ActionBar] ${message}`);
|
||||
});
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
bot.on('custom_bossBar', (message, bossBar, packet) => {
|
||||
switch (bossBar.action) {
|
||||
case 0:
|
||||
console.log(`[BossBar Added] Name: ${bossBar.withColor.message}\nHealth: ${bossBar.health}\nColor: ${bossBar.color}\nDividers: ${bossBar.dividers}\nFlags: ${bossBar.flags}`);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
console.log(`[BossBar Removed] ${bossBar.uuid}`);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
console.log(`[BossBar Health] ${bossBar.health}`)
|
||||
break;
|
||||
|
||||
case 3:
|
||||
console.log(`[BossBar Message] ${bossBar.withColor.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) => {
|
||||
switch (title.type) {
|
||||
case 0:
|
||||
console.log(`[Title] ${message}`)
|
||||
break;
|
||||
case 1:
|
||||
console.log(`[SubTitle] ${message}`)
|
||||
break;
|
||||
case 2:
|
||||
console.log(`[TitleSettings] fadeIn: ${title.fadeIn}\nstay: ${title.stay}\nfadeOut: ${title.fadeOut}`);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
bot.on('custom_allMessage', (chatType, message, messagePacket, packet) => {
|
||||
switch (chatType) {
|
||||
case "playerChat":
|
||||
case "profilelessChat":
|
||||
case "actionBar":
|
||||
console.log(`[${chatType}] ${message}`)
|
||||
break;
|
||||
case "systemChat":
|
||||
if (messagePacket.jsonMsg?.message?.translate === "advMode.setCommand.success" || messagePacket.jsonMsg?.message?.translate === "multiplayer.message_not_delivered") return; // Command set: %s OR Can't deliver chat message, check server logs: %s
|
||||
console.log(`[${chatType}] ${message}`)
|
||||
break;
|
||||
case "bossBar": {
|
||||
switch (messagePacket.action) {
|
||||
case 0:
|
||||
console.log(`[BossBar Added] Name: ${messagePacket.withColor.message}\nHealth: ${messagePacket.health}\nColor: ${messagePacket.color}\nDividers: ${messagePacket.dividers}\nFlags: ${messagePacket.flags}`);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
console.log(`[BossBar Removed] ${messagePacket.uuid}`);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
console.log(`[BossBar Health] ${messagePacket.health}`)
|
||||
break;
|
||||
|
||||
case 3:
|
||||
console.log(`[BossBar Message] ${messagePacket.withColor.message}`)
|
||||
break;
|
||||
|
||||
case 4:
|
||||
console.log(`[BossBar Color] ${messagePacket.color}\n[messagePacket Style] ${messagePacket.dividers}`)
|
||||
break;
|
||||
case 5:
|
||||
console.log(`[BossBar Flags] ${messagePacket.flags}`)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "title": {
|
||||
switch (messagePacket.type) {
|
||||
case 0:
|
||||
console.log(`[Title] ${message}`)
|
||||
break;
|
||||
case 1:
|
||||
console.log(`[SubTitle] ${message}`)
|
||||
break;
|
||||
case 2:
|
||||
console.log(`[TitleSettings] fadeIn: ${messagePacket.fadeIn}\nstay: ${messagePacket.stay}\nfadeOut: ${messagePacket.fadeOut}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
createBot();
|
Loading…
Reference in a new issue