|
| 1 | +import type { MinecraftChat } from '../chatToJsx' |
1 | 2 | import { concatPacketData, type PacketDataTypes } from '../packet' |
2 | | -import { protocolMap, writeVarInt } from '../utils' |
| 3 | +import { parseChat, protocolMap, readVarInt, writeVarInt } from '../utils' |
3 | 4 | import packetIds from './ids' |
4 | 5 |
|
| 6 | +interface PlayerChatMessage { |
| 7 | + signedChat: MinecraftChat |
| 8 | + unsignedChat?: MinecraftChat |
| 9 | + type: number |
| 10 | + displayName: MinecraftChat |
| 11 | +} |
| 12 | + |
| 13 | +export const parsePlayerChatMessage = (data: Buffer, version: number): PlayerChatMessage => { |
| 14 | + return version >= protocolMap['1.19.3'] |
| 15 | + ? parsePlayerChatMessage1193(data, version) |
| 16 | + : version >= protocolMap['1.19.1'] |
| 17 | + ? parsePlayerChatMessage1191(data, version) |
| 18 | + : parsePlayerChatMessage119(data, version) |
| 19 | +} |
| 20 | + |
| 21 | +const parsePlayerChatMessage119 = (data: Buffer, version: number): PlayerChatMessage => { |
| 22 | + const [signedChat, signedChatLength] = parseChat(data, version) |
| 23 | + data = data.slice(signedChatLength) |
| 24 | + const hasUnsignedChat = data.readInt8() |
| 25 | + data = data.slice(1) |
| 26 | + let unsignedChat: MinecraftChat | undefined |
| 27 | + if (hasUnsignedChat) { |
| 28 | + let unsignedChatLength |
| 29 | + ;[unsignedChat, unsignedChatLength] = parseChat(data, version) |
| 30 | + data = data.slice(unsignedChatLength) |
| 31 | + } |
| 32 | + const [type, typeLength] = readVarInt(data) |
| 33 | + data = data.slice(typeLength) |
| 34 | + data = data.slice(16) // Skip sender UUID |
| 35 | + const [displayName, displayNameLength] = parseChat(data, version) |
| 36 | + data = data.slice(displayNameLength) |
| 37 | + return { signedChat, unsignedChat, type, displayName } |
| 38 | +} |
| 39 | + |
| 40 | +const parsePlayerChatMessage1191 = (data: Buffer, version: number): PlayerChatMessage => { |
| 41 | + // TODO-1.19: https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol?oldid=2772944 |
| 42 | + // This is completely busted for now. Is it worth implementing? Who is using 1.19.1/1.19.2 anyway? |
| 43 | + return parsePlayerChatMessage119(data, version) |
| 44 | +} |
| 45 | + |
| 46 | +const parsePlayerChatMessage1193 = (data: Buffer, version: number): PlayerChatMessage => { |
| 47 | + data = data.slice(16) // Skip sender UUID |
| 48 | + data = data.slice(readVarInt(data)[1]) // Skip index |
| 49 | + const hasSignature = data.readInt8() |
| 50 | + data = data.slice(1) // Has signature |
| 51 | + if (hasSignature) data = data.slice(256) // Skip signature |
| 52 | + const [signedChat, signedChatLength] = parseChat(data) |
| 53 | + data = data.slice(signedChatLength + 8 + 8) // Skip timestamp and salt |
| 54 | + const [signatures, signaturesLength] = readVarInt(data) |
| 55 | + data = data.slice(signaturesLength) |
| 56 | + for (let i = 0; i < signatures; i++) { |
| 57 | + const [, idLength] = readVarInt(data) |
| 58 | + data = data.slice(idLength + 256) // Skip message ID and signature |
| 59 | + } |
| 60 | + const hasUnsignedChat = data.readInt8() |
| 61 | + data = data.slice(1) |
| 62 | + let unsignedChat: MinecraftChat | undefined |
| 63 | + if (hasUnsignedChat) { |
| 64 | + let unsignedChatLength |
| 65 | + ;[unsignedChat, unsignedChatLength] = parseChat(data, version) |
| 66 | + data = data.slice(unsignedChatLength) |
| 67 | + } |
| 68 | + const [filterType, filterTypeLength] = readVarInt(data) |
| 69 | + data = data.slice(filterTypeLength) |
| 70 | + if (filterType === 2) { |
| 71 | + const [filterTypeBits, filterTypeBitsLength] = readVarInt(data) |
| 72 | + data = data.slice(filterTypeBitsLength + filterTypeBits * 8) |
| 73 | + } |
| 74 | + const [type, typeLength] = readVarInt(data) |
| 75 | + data = data.slice(typeLength) |
| 76 | + const [displayName, displayNameLength] = parseChat(data, version) |
| 77 | + data = data.slice(displayNameLength) |
| 78 | + // Skip target name |
| 79 | + return { signedChat, unsignedChat, type, displayName } |
| 80 | +} |
| 81 | + |
5 | 82 | export const makeChatMessagePacket = ( |
6 | 83 | msg: string, |
7 | 84 | protocolVersion: number, |
|
0 commit comments