Skip to content

Commit

Permalink
Prepare for 1.20.2 with CONFIGURATION conn state.
Browse files Browse the repository at this point in the history
  • Loading branch information
retrixe committed Aug 16, 2023
1 parent 8e330a3 commit 23c8a81
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ConnectionModule(reactContext: ReactApplicationContext)
private var compressionEnabled = false
private var aesDecipher: Cipher? = null
private var aesCipher: Cipher? = null
private var loggedIn = false
private var state = ConnectionState.LOGIN

override fun getName() = "ConnectionModule"

Expand All @@ -47,7 +47,7 @@ class ConnectionModule(reactContext: ReactApplicationContext)
compressionEnabled = false
aesDecipher = null
aesCipher = null
loggedIn = false
state = ConnectionState.LOGIN
}

private fun directlyWritePacket(id: Int, data: ByteArray): Boolean {
Expand Down Expand Up @@ -253,12 +253,12 @@ class ConnectionModule(reactContext: ReactApplicationContext)
// No write lock since writePacket isn't called during login sequence (usually).
if (packet.id.value == keepAliveClientBoundId) {
directlyWritePacket(keepAliveServerBoundId, packet.data)
} else if (packet.id.value == setCompressionId && !loggedIn) {
} else if (packet.id.value == setCompressionId && state == ConnectionState.LOGIN) {
val threshold = VarInt.read(packet.data)?.value ?: 0
compressionThreshold = threshold
compressionEnabled = threshold >= 0
} else if (packet.id.value == loginSuccessId && !loggedIn) {
loggedIn = true
} else if (packet.id.value == loginSuccessId && state == ConnectionState.LOGIN) {
state = ConnectionState.PLAY
}

// Forward the packet to JavaScript.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import java.io.ByteArrayOutputStream
import java.util.zip.Deflater
import java.util.zip.Inflater

enum class ConnectionState {
LOGIN,
PLAY
}

const val PROTOCOL_VERSION_1164 = 754
const val PROTOCOL_VERSION_117 = 755
const val PROTOCOL_VERSION_119 = 759
Expand Down
8 changes: 7 additions & 1 deletion src/minecraft/connection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ export interface ConnectionOptions {
certificate?: Certificate
}

export enum ConnectionState {
LOGIN,
CONFIGURATION,
PLAY
}

export interface ServerConnection extends events.EventEmitter {
options: ConnectionOptions
loggedIn: boolean
state: ConnectionState
closed: boolean
msgSalt?: Buffer
disconnectReason?: string
Expand Down
34 changes: 25 additions & 9 deletions src/minecraft/connection/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import {
parseCompressedPacket,
parsePacket
} from '../packet'
import { type ServerConnection, type ConnectionOptions } from '.'
import {
type ServerConnection,
type ConnectionOptions,
ConnectionState
} from '.'
import { getLoginPacket, handleEncryptionRequest } from './shared'
import { readVarInt, writeVarInt, resolveHostname } from '../utils'
import packetIds from '../packets/ids'
Expand All @@ -38,7 +42,7 @@ export class JavaScriptServerConnection
bufferedData: Buffer = Buffer.from([])
compressionThreshold = -1
compressionEnabled = false
loggedIn = false
state = ConnectionState.LOGIN
closed = false
socket: net.Socket
options: ConnectionOptions
Expand Down Expand Up @@ -140,12 +144,18 @@ const initiateJavaScriptConnection = async (
: conn.bufferedData.slice(packet.packetLength)
// Internally handle login packets.
const { protocolVersion: version } = conn.options
if (packet.id === 0x03 && !conn.loggedIn /* Set Compression */) {
if (
packet.id === 0x03 &&
conn.state === ConnectionState.LOGIN /* Set Compression */
) {
const [threshold] = readVarInt(packet.data)
conn.compressionThreshold = threshold
conn.compressionEnabled = threshold >= 0
} else if (packet.id === 0x02 && !conn.loggedIn) {
conn.loggedIn = true // Login Success
} else if (
packet.id === 0x02 &&
conn.state === ConnectionState.LOGIN /* Login Success */
) {
conn.state = ConnectionState.PLAY
} else if (
packet.id === packetIds.CLIENTBOUND_KEEP_ALIVE(version)
) {
Expand All @@ -155,20 +165,26 @@ const initiateJavaScriptConnection = async (
.catch(err => conn.emit('error', err))
} else if (
// Disconnect (login) or Disconnect (play)
(packet.id === 0x00 && !conn.loggedIn) ||
(packet.id === 0x00 && conn.state === ConnectionState.LOGIN) ||
(packet.id === packetIds.CLIENTBOUND_DISCONNECT_PLAY(version) &&
conn.loggedIn)
conn.state === ConnectionState.PLAY)
) {
const [chatLength, chatVarIntLength] = readVarInt(packet.data)
conn.disconnectReason = packet.data
.slice(chatVarIntLength, chatVarIntLength + chatLength)
.toString('utf8')
} else if (packet.id === 0x04 && !conn.loggedIn) {
} else if (
packet.id === 0x04 &&
conn.state === ConnectionState.LOGIN
) {
/* Login Plugin Request */
const [msgId] = readVarInt(packet.data)
const rs = concatPacketData([writeVarInt(msgId), false])
conn.writePacket(0x02, rs).catch(err => conn.emit('error', err))
} else if (packet.id === 0x01 && !conn.loggedIn) {
} else if (
packet.id === 0x01 &&
conn.state === ConnectionState.LOGIN
) {
/* Encryption Request */
if (!accessToken || !selectedProfile) {
conn.disconnectReason =
Expand Down
23 changes: 15 additions & 8 deletions src/minecraft/connection/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import {
NativeModules
} from 'react-native'
import events from 'events'
import { type ServerConnection, type ConnectionOptions } from '.'
import {
type ServerConnection,
type ConnectionOptions,
ConnectionState
} from '.'
import { concatPacketData, type Packet } from '../packet'
import { getLoginPacket, handleEncryptionRequest } from './shared'
import { readVarInt, writeVarInt, resolveHostname } from '../utils'
Expand Down Expand Up @@ -43,7 +47,7 @@ export class NativeServerConnection
{
/* eslint-enable @typescript-eslint/brace-style */
eventEmitter = new NativeEventEmitter(ConnectionModule)
loggedIn = false
state = ConnectionState.LOGIN
closed = false
id: string
options: ConnectionOptions
Expand Down Expand Up @@ -89,24 +93,27 @@ export class NativeServerConnection
const { protocolVersion: version } = options
// Set Compression and Keep Alive are handled in native for now.
// When modifying this code, apply the same changes to the JavaScript back-end.
if (packet.id === 0x02 && !this.loggedIn /* Login Success */) {
this.loggedIn = true
if (
packet.id === 0x02 &&
this.state === ConnectionState.LOGIN /* Login Success */
) {
this.state = ConnectionState.PLAY
} else if (
// Disconnect (login) or Disconnect (play)
(packet.id === 0x00 && !this.loggedIn) ||
(packet.id === 0x00 && this.state === ConnectionState.LOGIN) ||
(packet.id === packetIds.CLIENTBOUND_DISCONNECT_PLAY(version) &&
this.loggedIn)
this.state === ConnectionState.PLAY)
) {
const [chatLength, chatVarIntLength] = readVarInt(packet.data)
this.disconnectReason = packet.data
.slice(chatVarIntLength, chatVarIntLength + chatLength)
.toString('utf8')
} else if (packet.id === 0x04 && !this.loggedIn) {
} else if (packet.id === 0x04 && this.state === ConnectionState.LOGIN) {
/* Login Plugin Request */
const [msgId] = readVarInt(packet.data)
const rs = concatPacketData([writeVarInt(msgId), false])
this.writePacket(0x02, rs).catch(err => this.emit('error', err))
} else if (packet.id === 0x01 && !this.loggedIn) {
} else if (packet.id === 0x01 && this.state === ConnectionState.LOGIN) {
/* Encryption Request */
const { accessToken, selectedProfile } = options
if (!accessToken || !selectedProfile) {
Expand Down
4 changes: 2 additions & 2 deletions src/minecraft/pingServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const legacyPing = async (opts: {
len: data.readUInt16BE(1),
protocol: +parts[1],
version: parts[2],
ping: time / 2,
ping: time,
motd: parts[3],
online: +parts[4],
maxPlayers: +parts[5]
Expand Down Expand Up @@ -155,7 +155,7 @@ export const modernPing = async (opts: {
const response = parseValidJson(json)

resolve({
ping: (timeReceived - timeSent) / 2,
ping: timeReceived - timeSent,
version: response.version,
players: response.players,
favicon: response.favicon,
Expand Down
10 changes: 8 additions & 2 deletions src/screens/chat/packetHandler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type React from 'react'
import { type Status } from './ChatScreen'
import { type MinecraftChat, parseValidJson } from '../../minecraft/chatToJsx'
import { type ServerConnection } from '../../minecraft/connection'
import {
ConnectionState,
type ServerConnection
} from '../../minecraft/connection'
import {
concatPacketData,
type Packet,
Expand Down Expand Up @@ -99,7 +102,10 @@ export const packetHandler =
) =>
(packet: Packet) => {
const { protocolVersion: version } = connection.options
if (statusRef.current === 'CONNECTING' && connection.loggedIn) {
if (
statusRef.current === 'CONNECTING' &&
connection.state === ConnectionState.LOGIN
) {
setLoading('')
statusRef.current = 'CONNECTED'
const messageToSend = joinMessage.substring(0, charLimit).trim()
Expand Down

0 comments on commit 23c8a81

Please sign in to comment.