Skip to content

Commit 7c3b831

Browse files
committed
Refactoring for 1.20.4 enablement
1 parent 0c6c7a5 commit 7c3b831

File tree

7 files changed

+105
-47
lines changed

7 files changed

+105
-47
lines changed

src/components/servers/EditServerDialog.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,13 @@ const EditServerDialog = ({
106106
dropdownIconColor={darkMode ? '#ffffff' : '#000000'}
107107
>
108108
<Picker.Item label='Auto' value='auto' />
109+
{/* FIXME: Update README after enablement. */}
110+
<Picker.Item label='1.20.3/1.20.4 (DOES NOT WORK!)' value='1.20.3' />
109111
<Picker.Item label='1.20.2 (WIP)' value='1.20.2' />
110-
<Picker.Item label='1.20/1.20.1 (WIP)' value='1.20.1' />
112+
<Picker.Item label='1.20/1.20.1 (WIP)' value='1.20' />
111113
<Picker.Item label='1.19.4 (WIP)' value='1.19.4' />
112114
<Picker.Item label='1.19.3 (WIP)' value='1.19.3' />
113-
<Picker.Item label='1.19.1/1.19.2 (WIP)' value='1.19.2' />
115+
<Picker.Item label='1.19.1/1.19.2 (WIP)' value='1.19.1' />
114116
<Picker.Item label='1.19 (WIP)' value='1.19' />
115117
<Picker.Item label='1.18.2' value='1.18.2' />
116118
<Picker.Item label='1.18/1.18.1' value='1.18' />

src/minecraft/chatToJsx.tsx

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React from 'react'
22
import { type StyleProp, type TextProps, type TextStyle } from 'react-native'
3+
// import nbt from 'prismarine-nbt'
34
import translationsJson from './translations.json'
5+
import { protocolMap } from './utils'
46

57
const translations: Record<string, string> = translationsJson
68

@@ -309,11 +311,26 @@ export const ChatToJsx = (props: {
309311
props.trim
310312
)
311313

312-
export const parseValidJson = (text: string): any => {
314+
export const parseChat = (
315+
chat: string | Buffer,
316+
version: number
317+
): BaseChat | string => {
318+
if (typeof chat === 'string') return parseJsonChat(chat)
319+
if (version < protocolMap['1.20.3'])
320+
return parseJsonChat(chat.toString('utf8'))
313321
try {
314-
return JSON.parse(text)
322+
throw new Error('NBT parsing is disabled.')
323+
// return nbt.simplify(nbt.parseUncompressed(chat))
315324
} catch (e) {
316-
return text
325+
return parseJsonChat(chat.toString('utf8'))
326+
}
327+
}
328+
329+
export const parseJsonChat = (chat: string): MinecraftChat => {
330+
try {
331+
return JSON.parse(chat)
332+
} catch (e) {
333+
return chat
317334
}
318335
}
319336

src/minecraft/connection/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface ServerConnection extends events.EventEmitter {
2626
state: ConnectionState
2727
closed: boolean
2828
msgSalt?: Buffer
29-
disconnectReason?: string
29+
disconnectReason?: string // FIXME: This is no longer just a string, it may be NBT too...
3030

3131
writePacket: (packetId: number, data: Buffer) => Promise<boolean>
3232

src/minecraft/pingServer.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
parsePacket,
1616
type Packet
1717
} from './packet'
18-
import { parseValidJson, type PlainTextChat } from './chatToJsx'
18+
import { type PlainTextChat } from './chatToJsx'
1919

2020
export interface LegacyPing {
2121
ff: number
@@ -158,7 +158,7 @@ export const modernPing = async (opts: {
158158
const json = responsePacket.data
159159
.slice(varIntLength, varIntLength + jsonLength)
160160
.toString('utf8')
161-
const response = parseValidJson(json)
161+
const response = JSON.parse(json)
162162

163163
resolve({
164164
ping: timeReceived - timeSent,

src/minecraft/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const protocolMap = {
2020
'1.20.2': 764,
2121
'1.20.3': 765,
2222
'1.20.4': 765,
23-
latest: 764,
23+
latest: 764, // FIXME: Set to 765 when 1.20.4 is supported.
2424
auto: -1
2525
}
2626

src/utilities/connection/connectionBuilder.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
} from '../../minecraft/api/microsoft'
1616
import { getPlayerCertificates } from '../../minecraft/api/mojang'
1717
import { refresh } from '../../minecraft/api/yggdrasil'
18-
import { parseValidJson } from '../../minecraft/chatToJsx'
18+
import { parseJsonChat } from '../../minecraft/chatToJsx'
1919
import initiateConnection, {
2020
type ServerConnection
2121
} from '../../minecraft/connection'
@@ -131,7 +131,7 @@ export const createConnection = async (
131131
const onCloseOrError = (): void => {
132132
closeChatScreen(
133133
newConn.disconnectReason
134-
? { server, reason: parseValidJson(newConn.disconnectReason) }
134+
? { server, reason: parseJsonChat(newConn.disconnectReason) }
135135
: undefined
136136
)
137137
setConnection(undefined)

src/utilities/connection/packetHandler.ts

+75-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type React from 'react'
2-
import { type MinecraftChat, parseValidJson } from '../../minecraft/chatToJsx'
2+
// import nbt from 'prismarine-nbt'
3+
import {
4+
type MinecraftChat,
5+
parseChat,
6+
parseJsonChat
7+
} from '../../minecraft/chatToJsx'
38
import {
49
ConnectionState,
510
type ServerConnection
@@ -33,53 +38,92 @@ type HandleError = (
3338
) => (error: unknown) => any
3439

3540
interface PlayerChatMessage {
36-
signedChat: string
37-
unsignedChat?: string
41+
signedChat: MinecraftChat
42+
unsignedChat?: MinecraftChat
3843
type: number
39-
displayName: string
44+
displayName: MinecraftChat
4045
}
4146

42-
const parsePlayerChatMessage = (data: Buffer): PlayerChatMessage => {
43-
const [signedChatLength, signedChatVarIntLength] = readVarInt(data)
44-
data = data.slice(signedChatVarIntLength)
45-
const signedChat = data.slice(0, signedChatLength).toString('utf8')
46-
data = data.slice(signedChatLength)
47+
const parsePlayerChatMessage = (
48+
data: Buffer,
49+
version: number
50+
): PlayerChatMessage => {
51+
let signedChat: MinecraftChat
52+
if (version < protocolMap['1.20.3']) {
53+
const [signedChatLength, signedChatVarIntLength] = readVarInt(data)
54+
data = data.slice(signedChatVarIntLength)
55+
signedChat = parseJsonChat(data.slice(0, signedChatLength).toString('utf8'))
56+
data = data.slice(signedChatLength)
57+
} else {
58+
signedChat = 'FIXME: NBT Chat'
59+
// const signedChatNbt = nbt.parseUncompressed(data)
60+
// signedChat = nbt.simplify(signedChatNbt)
61+
// data = data.slice(nbt.writeUncompressed(signedChatNbt).length)
62+
}
4763
const hasUnsignedChat = data.readInt8()
4864
data = data.slice(1)
49-
let unsignedChat
50-
if (hasUnsignedChat) {
65+
let unsignedChat: MinecraftChat | undefined
66+
if (hasUnsignedChat && version < protocolMap['1.20.3']) {
5167
const [unsignedChatLength, unsignedChatVarIntLength] = readVarInt(data)
5268
data = data.slice(unsignedChatVarIntLength)
53-
unsignedChat = data.slice(0, unsignedChatLength).toString('utf8')
69+
unsignedChat = parseJsonChat(
70+
data.slice(0, unsignedChatLength).toString('utf8')
71+
)
5472
data = data.slice(unsignedChatLength)
73+
} else if (hasUnsignedChat) {
74+
unsignedChat = undefined // FIXME
75+
// const unsignedChatNbt = nbt.parseUncompressed(data)
76+
// unsignedChat = nbt.simplify(unsignedChatNbt)
77+
// data = data.slice(nbt.writeUncompressed(unsignedChatNbt).length)
5578
}
5679
const [type, typeLength] = readVarInt(data)
5780
data = data.slice(typeLength)
5881
data = data.slice(16) // Skip sender UUID
59-
const [displayNameLength, displayNameVarIntLength] = readVarInt(data)
60-
data = data.slice(displayNameVarIntLength)
61-
const displayName = data.slice(0, displayNameLength).toString('utf8')
82+
let displayName: MinecraftChat
83+
if (version < protocolMap['1.20.3']) {
84+
const [displayNameLength, displayNameVarIntLength] = readVarInt(data)
85+
data = data.slice(displayNameVarIntLength)
86+
displayName = parseJsonChat(
87+
data.slice(0, displayNameLength).toString('utf8')
88+
)
89+
data = data.slice(displayNameLength)
90+
} else {
91+
displayName = 'FIXME: NBT Chat'
92+
// const displayNameNbt = nbt.parseUncompressed(data)
93+
// displayName = nbt.simplify(displayNameNbt)
94+
// data = data.slice(nbt.writeUncompressed(displayNameNbt).length)
95+
}
6296
return { signedChat, unsignedChat, type, displayName }
6397
}
6498

6599
const handleSystemMessage = (
66100
packet: Packet,
67101
addMessage: (text: MinecraftChat) => void,
68102
handleError: HandleError,
69-
is1191: boolean
103+
version: number
70104
): void => {
71105
try {
72-
const [chatLength, chatVarIntLength] = readVarInt(packet.data)
73-
const chatJson = packet.data
74-
.slice(chatVarIntLength, chatVarIntLength + chatLength)
75-
.toString('utf8')
106+
let parsedChat: MinecraftChat
107+
let offset
108+
if (version < protocolMap['1.20.3']) {
109+
const [chatLength, chatViLength] = readVarInt(packet.data)
110+
const chat = packet.data.slice(chatViLength, chatViLength + chatLength)
111+
parsedChat = parseJsonChat(chat.toString('utf8'))
112+
offset = chatViLength + chatLength
113+
} else {
114+
parsedChat = 'FIXME: NBT Chat'
115+
offset = packet.data.length - 1
116+
// const chatNbt = nbt.parseUncompressed(packet.data)
117+
// parsedChat = nbt.simplify(chatNbt)
118+
// offset = nbt.writeUncompressed(chatNbt).length
119+
}
76120
// TODO: Support position 2 (action bar), true (action bar) and sender for disableChat/blocked players.
77121
// TODO-1.19: 3 say command, 4 msg command, 5 team msg command, 6 emote command, 7 tellraw command, also in Player Chat Message.
78-
const position = packet.data.readInt8(chatVarIntLength + chatLength)
79-
if (!is1191 && (position === 0 || position === 1)) {
80-
addMessage(parseValidJson(chatJson))
81-
} else if (is1191 && !position) {
82-
addMessage(parseValidJson(chatJson))
122+
const position = packet.data.readInt8(offset)
123+
if (version < protocolMap['1.19.1'] && (position === 0 || position === 1)) {
124+
addMessage(parsedChat)
125+
} else if (version >= protocolMap['1.19.1'] && !position) {
126+
addMessage(parsedChat)
83127
}
84128
} catch (e) {
85129
handleError(addMessage, parseMessageError)(e)
@@ -138,7 +182,6 @@ export const packetHandler =
138182
const { protocolVersion: version } = connection.options
139183
const is117 = version >= protocolMap[1.17]
140184
const is118 = version >= protocolMap[1.18]
141-
const is1191 = version >= protocolMap['1.19.1']
142185

143186
// LOW-TODO: 1.20.2 also has a second Client Information in configuration state, do we send it?
144187
if (connection.state === ConnectionState.PLAY) {
@@ -194,25 +237,22 @@ export const packetHandler =
194237
.catch(handleError(addMessage, sendMessageError))
195238
}
196239
} else if (packet.id === packetIds.CLIENTBOUND_CHAT_MESSAGE(version)) {
197-
handleSystemMessage(packet, addMessage, handleError, is1191)
240+
handleSystemMessage(packet, addMessage, handleError, version)
198241
} else if (
199242
packet.id === packetIds.CLIENTBOUND_SYSTEM_CHAT_MESSAGE(version)
200243
) {
201-
handleSystemMessage(packet, addMessage, handleError, is1191)
244+
handleSystemMessage(packet, addMessage, handleError, version)
202245
} else if (
203246
packet.id === packetIds.CLIENTBOUND_PLAYER_CHAT_MESSAGE(version)
204247
) {
205248
try {
206249
const { type, displayName, signedChat, unsignedChat } =
207-
parsePlayerChatMessage(packet.data)
250+
parsePlayerChatMessage(packet.data, version)
208251
// TODO-1.19: Support sender team name
209252
if (type === 0 || type === 1) {
210253
addMessage({
211254
translate: 'chat.type.text',
212-
with: [
213-
parseValidJson(displayName),
214-
parseValidJson(unsignedChat ?? signedChat)
215-
]
255+
with: [displayName, unsignedChat ?? signedChat]
216256
})
217257
}
218258
} catch (e) {
@@ -238,9 +278,8 @@ export const packetHandler =
238278
data = data.slice(readVarInt(data)[1]) // Remove Player ID
239279
if (version <= protocolMap['1.19.4']) data = data.slice(4) // Remove Killer ID
240280
const [chatLen, chatViLength] = readVarInt(data)
241-
const deathMessage = parseValidJson(
242-
data.slice(chatViLength, chatViLength + chatLen).toString('utf8')
243-
)
281+
const chat = data.slice(chatViLength, chatViLength + chatLen)
282+
const deathMessage = parseChat(chat, version)
244283
if (
245284
(typeof deathMessage === 'string' && deathMessage.trim()) ||
246285
Object.keys(deathMessage).length !== 0

0 commit comments

Comments
 (0)