Skip to content

Commit

Permalink
Add packetFilter API, lazily decode Base64 data.
Browse files Browse the repository at this point in the history
Further fruit for optimisations:
- Improve Base64 decode performance with fast-base64 or js-base64.
- Use packetFilter API.
- Use TurboModules/JSI for decoding.
  • Loading branch information
retrixe committed Nov 20, 2022
1 parent a86e7e9 commit aed52ce
Showing 2 changed files with 40 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -121,6 +121,14 @@ class ConnectionModule(reactContext: ReactApplicationContext)
// val accessToken = opts.getString("accessToken")
// val certificate = opts.getMap("certificate")
val loginPacket = opts.getString("loginPacket")
val packetFilter = opts.getArray("packetFilter")?.let {
val hashSet = hashSetOf<Int>()
for (i in 0 until it.size()) {
val value = it.getDynamic(i)
if (value.type == ReadableType.Number) hashSet.add(value.asInt())
}
hashSet
}

// Start thread which handles creating the connection and then reads packets from it.
// This avoids blocking the main thread on writeLock and keeps the UI thread responsive.
@@ -248,19 +256,21 @@ class ConnectionModule(reactContext: ReactApplicationContext)
}

// Forward the packet to JavaScript.
val packetLengthLength =
packet.totalLength - (packet.data.size + packet.id.data.size)
val params = Arguments.createMap().apply {
putString("connectionId", connectionId.toString())
putDouble("id", packet.id.value.toDouble())
putString("data", Base64.encodeToString(packet.data, Base64.DEFAULT))
putBoolean("compressed", compressionEnabled)
putDouble("idLength", packet.id.data.size.toDouble())
putDouble("dataLength", packet.data.size.toDouble())
putDouble("packetLength", packet.totalLength.toDouble())
putDouble("lengthLength", packetLengthLength.toDouble())
if (packetFilter?.contains(packet.id.value) != false) {
val packetLengthLength =
packet.totalLength - (packet.data.size + packet.id.data.size)
val params = Arguments.createMap().apply {
putString("connectionId", connectionId.toString())
putDouble("id", packet.id.value.toDouble())
putString("data", Base64.encodeToString(packet.data, Base64.DEFAULT))
putBoolean("compressed", compressionEnabled)
putDouble("idLength", packet.id.data.size.toDouble())
putDouble("dataLength", packet.data.size.toDouble())
putDouble("packetLength", packet.totalLength.toDouble())
putDouble("lengthLength", packetLengthLength.toDouble())
}
sendEvent(reactContext = reactApplicationContext, "ecm:packet", params)
}
sendEvent(reactContext = reactApplicationContext, "ecm:packet", params)
}
lock.readLock().unlock()
lockAcquired = false
26 changes: 18 additions & 8 deletions src/minecraft/connection/native.ts
Original file line number Diff line number Diff line change
@@ -65,14 +65,24 @@ export class NativeServerConnection
if (event.connectionId !== this.id) return
// Run after interactions to improve user experience.
InteractionManager.runAfterInteractions(() => {
const packet: Packet = {
id: event.id,
data: Buffer.from(event.data, 'base64'),
idLength: event.idLength,
dataLength: event.dataLength,
packetLength: event.packetLength,
lengthLength: event.lengthLength
}
const packet: Packet = new Proxy(
{
id: event.id,
data: event.data, // Buffer.from(event.data, 'base64'),
idLength: event.idLength,
dataLength: event.dataLength,
packetLength: event.packetLength,
lengthLength: event.lengthLength
} as unknown as Packet,
{
get(target, p, receiver) {
if (p === 'data' && typeof target.data === 'string') {
target.data = Buffer.from(target.data, 'base64')
}
return Reflect.get(target, p, receiver)
}
}
)

// Internally handle login packets. We aren't handling these in native to share code.
const is1164 = options.protocolVersion >= protocolMap['1.16.4']

0 comments on commit aed52ce

Please sign in to comment.