From b162e926437172da0c275a801666dabef8b71e6d Mon Sep 17 00:00:00 2001 From: U9G Date: Tue, 6 Dec 2022 23:06:52 -0500 Subject: [PATCH] move chat implementation to src/ a move chat implementation to src/ Finish typings --- examples/client_chat/client_chat.js | 44 +++++------------------------ package.json | 1 + src/client/chat.js | 43 ++++++++++++++++++++++++++++ src/createClient.js | 2 ++ src/index.d.ts | 6 ++++ 5 files changed, 59 insertions(+), 37 deletions(-) create mode 100644 src/client/chat.js diff --git a/examples/client_chat/client_chat.js b/examples/client_chat/client_chat.js index 8ba7c15..e17de15 100644 --- a/examples/client_chat/client_chat.js +++ b/examples/client_chat/client_chat.js @@ -37,47 +37,17 @@ client.on('error', function (err) { }) client.on('connect', () => { - const mcData = require('minecraft-data')(client.version) const ChatMessage = require('prismarine-chat')(client.version) - const players = {} // 1.19+ console.log('Connected to server') - client.chat = (message) => { - if (mcData.supportFeature('signedChat')) { - const timestamp = BigInt(Date.now()) - client.write('chat_message', { - message, - timestamp, - salt: 0, - signature: client.signMessage(message, timestamp) - }) - } else { - client.write('chat', { message }) - } - } - - function onChat (packet) { - const message = packet.message || packet.unsignedChatContent || packet.signedChatContent - const j = JSON.parse(message) - const chat = new ChatMessage(j) - - if (packet.signature) { - const verified = client.verifyMessage(players[packet.senderUuid].publicKey, packet) - console.info(verified ? 'Verified: ' : 'UNVERIFIED: ', chat.toAnsi()) - } else { - console.info(chat.toAnsi()) - } - } - - client.on('chat', onChat) - client.on('player_chat', onChat) - client.on('player_info', (packet) => { - if (packet.action === 0) { // add player - for (const player of packet.data) { - players[player.UUID] = player.crypto - } - } + client.on('chat_received', ({ verified, message, isServerChat }) => { + const chat = ChatMessage.fromNotch(message) + let prefix = '' + if (verified === true) prefix = 'Player > Verified: ' + else if (verified === false) prefix = 'Player > Unverified: ' + else if (isServerChat) prefix = 'Server: ' + console.info(prefix + chat.toAnsi()) }) }) diff --git a/package.json b/package.json index a491185..bc6925d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "node-fetch": "^2.6.1", "node-rsa": "^0.4.2", "prismarine-auth": "^2.0.0", + "prismarine-chat": "^1.7.2", "prismarine-nbt": "^2.0.0", "protodef": "^1.8.0", "readable-stream": "^4.1.0", diff --git a/src/client/chat.js b/src/client/chat.js new file mode 100644 index 0000000..ec9864c --- /dev/null +++ b/src/client/chat.js @@ -0,0 +1,43 @@ +const states = require('../states') + +module.exports = (client, options) => { + const mcData = require('minecraft-data')(client.version) + const players = {} // 1.19+ + + function onChat (packet, isServerChat = false) { + let message = packet.message ?? packet.unsignedChatContent ?? packet.signedChatContent + if (isServerChat) message = packet.content + + const verified = packet.signature ? client.verifyMessage(players[packet.senderUuid].publicKey, packet) : null + client.emit('chat_received', { verified, message, isServerChat }) + } + + client.on('chat', packet => onChat(packet)) + client.on('player_chat', packet => onChat(packet)) + client.on('system_chat', packet => onChat(packet, true)) + client.on('player_info', (packet) => { + if (packet.action === 0) { // add player + for (const player of packet.data) { + players[player.UUID] = player.crypto + } + } + }) + + client.on('state', function (newState) { + if (newState === states.PLAY) { + client.chat = (message) => { + if (mcData.supportFeature('signedChat')) { + const timestamp = BigInt(Date.now()) + client.write('chat_message', { + message, + timestamp, + salt: 0, + signature: client.signMessage(message, timestamp) + }) + } else { + client.write('chat', { message }) + } + } + } + }) +} diff --git a/src/createClient.js b/src/createClient.js index aeea6ac..c64e17a 100644 --- a/src/createClient.js +++ b/src/createClient.js @@ -14,6 +14,7 @@ const tcpDns = require('./client/tcp_dns') const autoVersion = require('./client/autoVersion') const pluginChannels = require('./client/pluginChannels') const versionChecking = require('./client/versionChecking') +const chat = require('./client/chat') module.exports = createClient @@ -60,6 +61,7 @@ function createClient (options) { compress(client, options) pluginChannels(client, options) versionChecking(client, options) + chat(client, options) return client } diff --git a/src/index.d.ts b/src/index.d.ts index c522d7e..1b55179 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -26,6 +26,8 @@ declare module 'minecraft-protocol' { protocolVersion: number version: string write(name: string, params: any): void + /** @param message the json version of the message to send*/ + chat(message: string): void writeRaw(buffer: any): void compressionThreshold: string ended: boolean @@ -44,6 +46,10 @@ declare module 'minecraft-protocol' { on(event: 'state', handler: (newState: States, oldState: States) => PromiseLike): this on(event: 'end', handler: (reason: string) => PromiseLike): this on(event: 'connect', handler: () => PromiseLike): this + /** + * @param handler verified & isServerChat is null when on a < 1.19 server + */ + on(event: 'chat_received', handler: (chat: { verified: boolean | null, message: string, isServerChat: boolean | null }) => PromiseLike) on(event: string, handler: (data: any, packetMeta: PacketMeta) => PromiseLike): this on(event: `raw.${string}`, handler: (buffer: Buffer, packetMeta: PacketMeta) => PromiseLike): this once(event: 'error', listener: (error: Error) => PromiseLike): this