From b13c8df46918a99a8ac5c1eb3b1c8aefbae96b89 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Wed, 18 Dec 2024 13:59:55 +0300 Subject: [PATCH] implement auto version configuration for viewer --- src/index.ts | 13 ++++++++---- src/viewerConnector.ts | 47 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0e481cd8..36eda63c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -103,7 +103,7 @@ import { mainMenuState } from './react/MainMenuRenderApp' import { ItemsRenderer } from 'mc-assets/dist/itemsRenderer' import './mobileShim' import { parseFormattedMessagePacket } from './botUtils' -import { getWsProtocolStream } from './viewerConnector' +import { getViewerVersionData, getWsProtocolStream } from './viewerConnector' window.debug = debug window.THREE = THREE @@ -377,7 +377,7 @@ async function connect (connectOptions: ConnectOptions) { signal: errorAbortController.signal }) - if (proxy) { + if (proxy && !connectOptions.viewerWsConnect) { console.log(`using proxy ${proxy.host}:${proxy.port || location.port}`) net['setProxy']({ hostname: proxy.host, port: proxy.port }) @@ -477,6 +477,12 @@ async function connect (connectOptions: ConnectOptions) { clientDataStream = await connectToPeer(connectOptions.peerId!, connectOptions.peerOptions) } if (connectOptions.viewerWsConnect) { + const { version, time } = await getViewerVersionData(connectOptions.viewerWsConnect) + console.log('Latency:', Date.now() - time, 'ms') + // const version = '1.21.1' + connectOptions.botVersion = version + await downloadMcData(version) + setLoadingScreenStatus(`Connecting to WebSocket server ${connectOptions.viewerWsConnect}`) clientDataStream = await getWsProtocolStream(connectOptions.viewerWsConnect) } @@ -571,7 +577,7 @@ async function connect (connectOptions: ConnectOptions) { bot.emit('inject_allowed') bot._client.emit('connect') } else if (connectOptions.viewerWsConnect) { - bot.emit('inject_allowed') + // bot.emit('inject_allowed') bot._client.emit('connect') } else { const setupConnectHandlers = () => { @@ -1056,7 +1062,6 @@ downloadAndOpenFile().then((downloadAction) => { if (viewerWsConnect) { void connect({ username: `viewer-${Math.random().toString(36).slice(2, 10)}`, - botVersion: '1.21.1', viewerWsConnect, }) } diff --git a/src/viewerConnector.ts b/src/viewerConnector.ts index f4984fea..45d85bb0 100644 --- a/src/viewerConnector.ts +++ b/src/viewerConnector.ts @@ -16,15 +16,49 @@ class CustomDuplex extends Duplex { } } -export const getWsProtocolStream = async (url: string) => { +export const getViewerVersionData = async (url: string) => { + const ws = await openWebsocket(url) + ws.send('version') + return new Promise<{ + version: string + time: number, + clientIgnoredPackets?: string[] + }>((resolve, reject) => { + ws.addEventListener('message', async (message) => { + const { data } = message + const parsed = JSON.parse(data.toString()) + resolve(parsed) + ws.close() + // todo + customEvents.on('mineflayerBotCreated', () => { + const client = bot._client as any + const oldWrite = client.write.bind(client) + client.write = (...args) => { + const [name] = args + if (parsed?.clientIgnoredPackets?.includes(name)) { + return + } + oldWrite(...args) + } + }) + }) + }) +} + +const openWebsocket = async (url: string) => { if (url.startsWith(':')) url = `ws://localhost${url}` if (!url.startsWith('ws')) url = `ws://${url}` const ws = new WebSocket(url) await new Promise((resolve, reject) => { ws.onopen = () => resolve() - ws.onerror = (err) => reject(new Error(`Failed to connect to websocket ${url}`)) + ws.onerror = (err) => reject(new Error(`[websocket] Failed to connect to ${url}`)) ws.onclose = (ev) => reject(ev.reason) }) + return ws +} + +export const getWsProtocolStream = async (url: string) => { + const ws = await openWebsocket(url) const clientDuplex = new CustomDuplex(undefined, data => { // console.log('send', Buffer.from(data).toString('hex')) ws.send(data) @@ -40,10 +74,11 @@ export const getWsProtocolStream = async (url: string) => { lastMessageTime = performance.now() }) setInterval(() => { - if (performance.now() - lastMessageTime > 10_000) { - console.log('no packats received in 10s!') - clientDuplex.end() - } + // if (clientDuplex.destroyed) return + // if (performance.now() - lastMessageTime > 10_000) { + // console.log('no packats received in 10s!') + // clientDuplex.end() + // } }, 5000) ws.addEventListener('close', () => {