From 809ff691c0fa39e8def7e831aa3d2d3184e0950d Mon Sep 17 00:00:00 2001 From: Ibrahim Ansari Date: Sun, 14 Apr 2024 22:59:00 +0530 Subject: [PATCH] Support 1.20.3 disconnect, enable 1.20.3/4 support --- README.md | 2 +- src/components/servers/EditServerDialog.tsx | 3 +-- src/minecraft/connection/index.ts | 3 ++- src/minecraft/connection/javascript.ts | 19 +++++++++++++------ src/minecraft/connection/native.ts | 19 +++++++++++++------ src/minecraft/utils.ts | 2 +- src/utilities/connection/connectionBuilder.ts | 14 +++----------- 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 9e0923d..69ddcf8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Disclaimer: This app is NOT an official Minecraft product. It is not associated ## Features (still being worked on) - Fully open-source with no ads! Easily report issues through GitHub and get a direct response. -- Supports connecting to Minecraft 1.16.4 through Minecraft 1.20.2 servers. (Older versions planned.) +- Supports connecting to Minecraft 1.16.4 through Minecraft 1.20.4 servers. (Older versions planned.) - Supports all Minecraft chat features, which sometimes trip up other chat apps. - Send join messages and commands on connecting to a server. - Health change indicator and respawn on death support. diff --git a/src/components/servers/EditServerDialog.tsx b/src/components/servers/EditServerDialog.tsx index df7243b..de029a5 100644 --- a/src/components/servers/EditServerDialog.tsx +++ b/src/components/servers/EditServerDialog.tsx @@ -106,8 +106,7 @@ const EditServerDialog = ({ dropdownIconColor={darkMode ? '#ffffff' : '#000000'} > - {/* FIXME: Update README after enablement. */} - + diff --git a/src/minecraft/connection/index.ts b/src/minecraft/connection/index.ts index eaaa75d..c628001 100644 --- a/src/minecraft/connection/index.ts +++ b/src/minecraft/connection/index.ts @@ -3,6 +3,7 @@ import { type Packet } from '../packet' import { type Certificate } from '../api/mojang' import initiateJavaScriptConnection from './javascript' import initiateNativeConnection, { isNativeConnectionAvailable } from './native' +import { type MinecraftChat } from '../chatToJsx' export interface ConnectionOptions { serverName: string @@ -26,7 +27,7 @@ export interface ServerConnection extends events.EventEmitter { state: ConnectionState closed: boolean msgSalt?: Buffer - disconnectReason?: string // FIXME: This is no longer just a string, it may be NBT too... + disconnectReason?: MinecraftChat writePacket: (packetId: number, data: Buffer) => Promise diff --git a/src/minecraft/connection/javascript.ts b/src/minecraft/connection/javascript.ts index 527fc1a..b227e8e 100644 --- a/src/minecraft/connection/javascript.ts +++ b/src/minecraft/connection/javascript.ts @@ -21,8 +21,15 @@ import { type ConnectionOptions, ConnectionState } from '.' +import { type MinecraftChat } from '../chatToJsx' import { getLoginPacket, handleEncryptionRequest } from './shared' -import { readVarInt, writeVarInt, resolveHostname, protocolMap } from '../utils' +import { + readVarInt, + writeVarInt, + resolveHostname, + protocolMap, + parseChat +} from '../utils' import packetIds from '../packets/ids' export declare interface JavaScriptServerConnection { @@ -45,7 +52,7 @@ export class JavaScriptServerConnection socket: net.Socket options: ConnectionOptions disconnectTimer?: NodeJS.Timeout - disconnectReason?: string + disconnectReason?: MinecraftChat aesDecipher?: Decipher aesCipher?: Cipher @@ -199,10 +206,10 @@ const initiateJavaScriptConnection = async ( (packet.id === packetIds.CLIENTBOUND_DISCONNECT_PLAY(version) && conn.state === ConnectionState.PLAY) ) { - const [chatLength, chatVarIntLength] = readVarInt(packet.data) - conn.disconnectReason = packet.data - .slice(chatVarIntLength, chatVarIntLength + chatLength) - .toString('utf8') + conn.disconnectReason = parseChat( + packet.data, // The Disconnect (login) packet always returns JSON. + conn.state === ConnectionState.LOGIN ? undefined : version + )[0] } else if ( packet.id === 0x04 && conn.state === ConnectionState.LOGIN diff --git a/src/minecraft/connection/native.ts b/src/minecraft/connection/native.ts index 83f43cc..71c1c33 100644 --- a/src/minecraft/connection/native.ts +++ b/src/minecraft/connection/native.ts @@ -9,9 +9,16 @@ import { type ConnectionOptions, ConnectionState } from '.' +import { type MinecraftChat } from '../chatToJsx' import { concatPacketData, type Packet } from '../packet' import { getLoginPacket, handleEncryptionRequest } from './shared' -import { readVarInt, writeVarInt, resolveHostname, protocolMap } from '../utils' +import { + readVarInt, + writeVarInt, + resolveHostname, + protocolMap, + parseChat +} from '../utils' import packetIds from '../packets/ids' const { ConnectionModule } = NativeModules @@ -50,7 +57,7 @@ export class NativeServerConnection id: string options: ConnectionOptions disconnectTimer?: NodeJS.Timeout - disconnectReason?: string + disconnectReason?: MinecraftChat msgSalt?: Buffer constructor(id: string, options: ConnectionOptions) { @@ -118,10 +125,10 @@ export class NativeServerConnection (packet.id === packetIds.CLIENTBOUND_DISCONNECT_PLAY(version) && this.state === ConnectionState.PLAY) ) { - const [chatLength, chatVarIntLength] = readVarInt(packet.data) - this.disconnectReason = packet.data - .slice(chatVarIntLength, chatVarIntLength + chatLength) - .toString('utf8') + this.disconnectReason = parseChat( + packet.data, // The Disconnect (login) packet always returns JSON. + this.state === ConnectionState.LOGIN ? undefined : version + )[0] } else if (packet.id === 0x04 && this.state === ConnectionState.LOGIN) { /* Login Plugin Request */ const [msgId] = readVarInt(packet.data) diff --git a/src/minecraft/utils.ts b/src/minecraft/utils.ts index c2bed82..9cd0a7b 100644 --- a/src/minecraft/utils.ts +++ b/src/minecraft/utils.ts @@ -22,7 +22,7 @@ export const protocolMap = { '1.20.2': 764, '1.20.3': 765, '1.20.4': 765, - latest: 764, // FIXME: Set to 765 when 1.20.4 is supported. + latest: 765, auto: -1 } diff --git a/src/utilities/connection/connectionBuilder.ts b/src/utilities/connection/connectionBuilder.ts index 43522aa..8f734b9 100644 --- a/src/utilities/connection/connectionBuilder.ts +++ b/src/utilities/connection/connectionBuilder.ts @@ -18,12 +18,7 @@ import { refresh } from '../../minecraft/api/yggdrasil' import initiateConnection, { type ServerConnection } from '../../minecraft/connection' -import { - parseIp, - parseJsonChat, - protocolMap, - resolveHostname -} from '../../minecraft/utils' +import { parseIp, protocolMap, resolveHostname } from '../../minecraft/utils' import config from '../../../config.json' export const getSession = async ( @@ -133,11 +128,8 @@ export const createConnection = async ( certificate: settings.enableChatSigning ? session?.certificate : undefined }) const onCloseOrError = (): void => { - closeChatScreen( - newConn.disconnectReason - ? { server, reason: parseJsonChat(newConn.disconnectReason) } - : undefined - ) + const reason = newConn.disconnectReason + closeChatScreen(reason ? { server, reason } : undefined) setConnection(undefined) } newConn.on('close', onCloseOrError)