-
Notifications
You must be signed in to change notification settings - Fork 132
Move minecraft protocol into worker! #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Changes from 82 commits
3051cc3
aed5b40
380c214
044153c
5376584
2848ab6
8db6b5b
c626d10
2d7ec12
7e74633
fb10179
9356daa
638dd67
34972e4
c65db9a
4381ef4
d8294d5
1861edf
d197859
cefdf53
0597a3d
7cc562b
3a9e2aa
8a3c847
847314d
4d4637f
d74d860
f230763
67d90a5
6eb50cd
dc073cd
400f598
5364085
f2f1c25
e851f4f
de3edda
c1a7765
ccb0004
9fedafe
136b051
f88e9c8
cae2b61
82d0638
b483923
dc2ad7c
8ee4dc3
11abbfc
5eedb3c
8ddac97
853e0e1
d450a31
b579ee1
ed04197
e917764
e2b7833
b501893
9888bd5
2056974
2630a57
6a5ac4f
9cede6d
bf9c47d
547658f
9057d3a
14e20a2
e7c2406
0648d55
b472583
e743a03
b9ca057
bc9ca18
07e7c6f
0839889
bb6faf9
07e9725
290e641
0787440
bdcf3d6
316fdd8
4483b73
980779c
b50215b
92d444a
df2a337
ccd1130
4a949d3
475d990
d9f1efd
1fe6239
cd84acb
139ee9a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,8 +17,6 @@ | |||||||||||||||||||||
| import { getServerInfo } from './mineflayer/mc-protocol' | ||||||||||||||||||||||
| import { onGameLoad } from './inventoryWindows' | ||||||||||||||||||||||
| import initCollisionShapes from './getCollisionInteractionShapes' | ||||||||||||||||||||||
| import protocolMicrosoftAuth from 'minecraft-protocol/src/client/microsoftAuth' | ||||||||||||||||||||||
| import microsoftAuthflow from './microsoftAuthflow' | ||||||||||||||||||||||
| import { Duplex } from 'stream' | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import './scaleInterface' | ||||||||||||||||||||||
|
|
@@ -75,7 +73,7 @@ | |||||||||||||||||||||
| import './devReload' | ||||||||||||||||||||||
| import './water' | ||||||||||||||||||||||
| import { ConnectOptions, loadMinecraftData, getVersionAutoSelect, downloadOtherGameData, downloadAllMinecraftData } from './connect' | ||||||||||||||||||||||
| import { ref, subscribe } from 'valtio' | ||||||||||||||||||||||
| import { subscribe } from 'valtio' | ||||||||||||||||||||||
| import { signInMessageState } from './react/SignInMessageProvider' | ||||||||||||||||||||||
| import { updateAuthenticatedAccountData, updateLoadedServerData, updateServerConnectionHistory } from './react/serversStorage' | ||||||||||||||||||||||
| import packetsPatcher from './mineflayer/plugins/packetsPatcher' | ||||||||||||||||||||||
|
|
@@ -97,6 +95,7 @@ | |||||||||||||||||||||
| import { appViewer } from './appViewer' | ||||||||||||||||||||||
| import './appViewerLoad' | ||||||||||||||||||||||
| import { registerOpenBenchmarkListener } from './benchmark' | ||||||||||||||||||||||
| import { getProtocolClientGetter } from './protocolWorker/protocolMain' | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| window.debug = debug | ||||||||||||||||||||||
| window.beforeRenderFrame = [] | ||||||||||||||||||||||
|
|
@@ -161,11 +160,6 @@ | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (sessionStorage.delayLoadUntilClick) { | ||||||||||||||||||||||
| await new Promise(resolve => { | ||||||||||||||||||||||
| window.addEventListener('click', resolve) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| miscUiState.hasErrors = false | ||||||||||||||||||||||
| lastConnectOptions.value = connectOptions | ||||||||||||||||||||||
|
|
@@ -183,21 +177,21 @@ | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| const { renderDistance: renderDistanceSingleplayer, multiplayerRenderDistance } = options | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const parsedServer = parseServerAddress(connectOptions.server) | ||||||||||||||||||||||
| const server = { host: parsedServer.host, port: parsedServer.port } | ||||||||||||||||||||||
| const serverParsed = parseServerAddress(connectOptions.server) | ||||||||||||||||||||||
| const server = { host: serverParsed.host, port: serverParsed.port } | ||||||||||||||||||||||
| if (connectOptions.proxy?.startsWith(':')) { | ||||||||||||||||||||||
| connectOptions.proxy = `${location.protocol}//${location.hostname}${connectOptions.proxy}` | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (connectOptions.proxy && location.port !== '80' && location.port !== '443' && !/:\d+$/.test(connectOptions.proxy)) { | ||||||||||||||||||||||
| const https = connectOptions.proxy.startsWith('https://') || location.protocol === 'https:' | ||||||||||||||||||||||
| connectOptions.proxy = `${connectOptions.proxy}:${https ? 443 : 80}` | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| const parsedProxy = parseServerAddress(connectOptions.proxy, false) | ||||||||||||||||||||||
| const proxy = { host: parsedProxy.host, port: parsedProxy.port } | ||||||||||||||||||||||
| const proxyParsed = parseServerAddress(connectOptions.proxy, false) | ||||||||||||||||||||||
| const proxy = { host: proxyParsed.host, port: proxyParsed.port } | ||||||||||||||||||||||
| let { username } = connectOptions | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (connectOptions.server) { | ||||||||||||||||||||||
| console.log(`connecting to ${server.host}:${server.port ?? 25_565}`) | ||||||||||||||||||||||
| console.log(`connecting to ${serverParsed.serverIpFull}`) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| console.log('using player username', username) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -237,14 +231,13 @@ | |||||||||||||||||||||
| }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| let lastPacket = undefined as string | undefined | ||||||||||||||||||||||
| const lastPacket = undefined as string | undefined | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Verify the impact of lastPacket removal. The -const lastPacket = undefined as string | undefined
+// Remove this constant since it's no longer usedAnd update the error handling function: const onPossibleErrorDisconnect = () => {
- if (lastPacket && bot?._client && bot._client.state !== states.PLAY) {
+ if (bot?._client && bot._client.state !== states.PLAY) {
- appStatusState.descriptionHint = `Last Server Packet: ${lastPacket}`
+ appStatusState.descriptionHint = `Disconnected before entering play state`
}
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||
| const onPossibleErrorDisconnect = () => { | ||||||||||||||||||||||
| if (lastPacket && bot?._client && bot._client.state !== states.PLAY) { | ||||||||||||||||||||||
| appStatusState.descriptionHint = `Last Server Packet: ${lastPacket}` | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| const handleError = (err) => { | ||||||||||||||||||||||
| console.error(err) | ||||||||||||||||||||||
| if (err === 'ResizeObserver loop completed with undelivered notifications.') { | ||||||||||||||||||||||
| return | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
@@ -278,16 +271,14 @@ | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| let clientDataStream: Duplex | undefined | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (connectOptions.server && !connectOptions.viewerWsConnect && !parsedServer.isWebSocket) { | ||||||||||||||||||||||
| if (connectOptions.server && !connectOptions.viewerWsConnect && !serverParsed.isWebSocket) { | ||||||||||||||||||||||
| console.log(`using proxy ${proxy.host}:${proxy.port || location.port}`) | ||||||||||||||||||||||
| net['setProxy']({ hostname: proxy.host, port: proxy.port }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const renderDistance = singleplayer ? renderDistanceSingleplayer : multiplayerRenderDistance | ||||||||||||||||||||||
| let updateDataAfterJoin = () => { } | ||||||||||||||||||||||
| let localServer | ||||||||||||||||||||||
| let localReplaySession: ReturnType<typeof startLocalReplayServer> | undefined | ||||||||||||||||||||||
| let lastKnownKickReason = undefined as string | undefined | ||||||||||||||||||||||
| try { | ||||||||||||||||||||||
| const serverOptions = defaultsDeep({}, connectOptions.serverOverrides ?? {}, options.localServerOptions, defaultServerOptions) | ||||||||||||||||||||||
| Object.assign(serverOptions, connectOptions.serverOverridesFlat ?? {}) | ||||||||||||||||||||||
|
|
@@ -406,30 +397,12 @@ | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| setLoadingScreenStatus(initialLoadingText) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (parsedServer.isWebSocket) { | ||||||||||||||||||||||
| clientDataStream = (await getWebsocketStream(server.host)).mineflayerStream | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| let newTokensCacheResult = null as any | ||||||||||||||||||||||
| const cachedTokens = typeof connectOptions.authenticatedAccount === 'object' ? connectOptions.authenticatedAccount.cachedTokens : {} | ||||||||||||||||||||||
| const authData = connectOptions.authenticatedAccount ? await microsoftAuthflow({ | ||||||||||||||||||||||
| tokenCaches: cachedTokens, | ||||||||||||||||||||||
| proxyBaseUrl: connectOptions.proxy, | ||||||||||||||||||||||
| setProgressText (text) { | ||||||||||||||||||||||
| setLoadingScreenStatus(text) | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| setCacheResult (result) { | ||||||||||||||||||||||
| newTokensCacheResult = result | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| connectingServer: server.host | ||||||||||||||||||||||
| }) : undefined | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (p2pMultiplayer) { | ||||||||||||||||||||||
| clientDataStream = await connectToPeer(connectOptions.peerId!, connectOptions.peerOptions) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (connectOptions.viewerWsConnect) { | ||||||||||||||||||||||
| const { version, time, requiresPass } = await getViewerVersionData(connectOptions.viewerWsConnect) | ||||||||||||||||||||||
| let password | ||||||||||||||||||||||
| let password: string | null = null | ||||||||||||||||||||||
zardoy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| if (requiresPass) { | ||||||||||||||||||||||
| password = prompt('Enter password') | ||||||||||||||||||||||
| if (!password) { | ||||||||||||||||||||||
|
|
@@ -454,6 +427,8 @@ | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const brand = clientDataStream ? 'minecraft-web-client' : undefined | ||||||||||||||||||||||
| const createClient = await getProtocolClientGetter(proxy, connectOptions, serverParsed) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| bot = mineflayer.createBot({ | ||||||||||||||||||||||
| host: server.host, | ||||||||||||||||||||||
| port: server.port ? +server.port : undefined, | ||||||||||||||||||||||
|
|
@@ -474,53 +449,13 @@ | |||||||||||||||||||||
| connect () { }, | ||||||||||||||||||||||
| Client: CustomChannelClient as any, | ||||||||||||||||||||||
| } : {}, | ||||||||||||||||||||||
| onMsaCode (data) { | ||||||||||||||||||||||
| signInMessageState.code = data.user_code | ||||||||||||||||||||||
| signInMessageState.link = data.verification_uri | ||||||||||||||||||||||
| signInMessageState.expiresOn = Date.now() + data.expires_in * 1000 | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| sessionServer: authData?.sessionEndpoint?.toString(), | ||||||||||||||||||||||
| auth: connectOptions.authenticatedAccount ? async (client, options) => { | ||||||||||||||||||||||
| authData!.setOnMsaCodeCallback(options.onMsaCode) | ||||||||||||||||||||||
| authData?.setConnectingVersion(client.version) | ||||||||||||||||||||||
| //@ts-expect-error | ||||||||||||||||||||||
| client.authflow = authData!.authFlow | ||||||||||||||||||||||
| try { | ||||||||||||||||||||||
| signInMessageState.abortController = ref(new AbortController()) | ||||||||||||||||||||||
| await Promise.race([ | ||||||||||||||||||||||
| protocolMicrosoftAuth.authenticate(client, options), | ||||||||||||||||||||||
| new Promise((_r, reject) => { | ||||||||||||||||||||||
| signInMessageState.abortController.signal.addEventListener('abort', () => { | ||||||||||||||||||||||
| reject(new UserError('Aborted by user')) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| ]) | ||||||||||||||||||||||
| if (signInMessageState.shouldSaveToken) { | ||||||||||||||||||||||
| updateAuthenticatedAccountData(accounts => { | ||||||||||||||||||||||
| const existingAccount = accounts.find(a => a.username === client.username) | ||||||||||||||||||||||
| if (existingAccount) { | ||||||||||||||||||||||
| existingAccount.cachedTokens = { ...existingAccount.cachedTokens, ...newTokensCacheResult } | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| accounts.push({ | ||||||||||||||||||||||
| username: client.username, | ||||||||||||||||||||||
| cachedTokens: { ...cachedTokens, ...newTokensCacheResult } | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return accounts | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| updateDataAfterJoin = () => { | ||||||||||||||||||||||
| updateLoadedServerData(s => ({ ...s, authenticatedAccountOverride: client.username }), connectOptions.serverIndex) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| updateDataAfterJoin = () => { | ||||||||||||||||||||||
| updateLoadedServerData(s => ({ ...s, authenticatedAccountOverride: undefined }), connectOptions.serverIndex) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| setLoadingScreenStatus('Authentication successful. Logging in to server') | ||||||||||||||||||||||
| } finally { | ||||||||||||||||||||||
| signInMessageState.code = '' | ||||||||||||||||||||||
| get client () { | ||||||||||||||||||||||
| if (clientDataStream || singleplayer || p2pMultiplayer || localReplaySession || connectOptions.viewerWsConnect || (!options.protocolWorkerOptimisation && !serverParsed.isWebSocket)) { | ||||||||||||||||||||||
| return undefined | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } : undefined, | ||||||||||||||||||||||
| return createClient.call(this) | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| // auth: connectOptions.authenticatedAccount ? : undefined, | ||||||||||||||||||||||
| username, | ||||||||||||||||||||||
| viewDistance: renderDistance, | ||||||||||||||||||||||
| checkTimeoutInterval: 240 * 1000, | ||||||||||||||||||||||
|
|
@@ -553,49 +488,7 @@ | |||||||||||||||||||||
| } else if (clientDataStream) { | ||||||||||||||||||||||
| // bot.emit('inject_allowed') | ||||||||||||||||||||||
| bot._client.emit('connect') | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| const setupConnectHandlers = () => { | ||||||||||||||||||||||
| Socket.prototype['handleStringMessage'] = function (message: string) { | ||||||||||||||||||||||
| if (message.startsWith('proxy-message') || message.startsWith('proxy-command:')) { // for future | ||||||||||||||||||||||
| return false | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (message.startsWith('proxy-shutdown:')) { | ||||||||||||||||||||||
| lastKnownKickReason = message.slice('proxy-shutdown:'.length) | ||||||||||||||||||||||
| return false | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return true | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| bot._client.socket.on('connect', () => { | ||||||||||||||||||||||
| console.log('Proxy WebSocket connection established') | ||||||||||||||||||||||
| //@ts-expect-error | ||||||||||||||||||||||
| bot._client.socket._ws.addEventListener('close', () => { | ||||||||||||||||||||||
| console.log('WebSocket connection closed') | ||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||
| if (bot) { | ||||||||||||||||||||||
| bot.emit('end', 'WebSocket connection closed with unknown reason') | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }, 1000) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| bot._client.socket.on('close', () => { | ||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||
| if (bot) { | ||||||||||||||||||||||
| bot.emit('end', 'WebSocket connection closed with unknown reason') | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| // socket setup actually can be delayed because of dns lookup | ||||||||||||||||||||||
| if (bot._client.socket) { | ||||||||||||||||||||||
| setupConnectHandlers() | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| const originalSetSocket = bot._client.setSocket.bind(bot._client) | ||||||||||||||||||||||
| bot._client.setSocket = (socket) => { | ||||||||||||||||||||||
| if (!bot) return | ||||||||||||||||||||||
| originalSetSocket(socket) | ||||||||||||||||||||||
| setupConnectHandlers() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } catch (err) { | ||||||||||||||||||||||
|
|
@@ -628,7 +521,7 @@ | |||||||||||||||||||||
| }) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const packetBeforePlay = (_, __, ___, fullBuffer) => { | ||||||||||||||||||||||
| lastPacket = fullBuffer.toString() | ||||||||||||||||||||||
| // lastPacket = fullBuffer.toString() | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| bot._client.on('packet', packetBeforePlay as any) | ||||||||||||||||||||||
| const playStateSwitch = (newState) => { | ||||||||||||||||||||||
|
|
@@ -641,9 +534,6 @@ | |||||||||||||||||||||
| bot.on('end', (endReason) => { | ||||||||||||||||||||||
| if (ended) return | ||||||||||||||||||||||
| console.log('disconnected for', endReason) | ||||||||||||||||||||||
| if (endReason === 'socketClosed') { | ||||||||||||||||||||||
| endReason = lastKnownKickReason ?? 'Connection with proxy server lost' | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| setLoadingScreenStatus(`You have been disconnected from the server. End reason:\n${endReason}`, true) | ||||||||||||||||||||||
| appStatusState.showReconnect = true | ||||||||||||||||||||||
| onPossibleErrorDisconnect() | ||||||||||||||||||||||
|
|
@@ -715,7 +605,6 @@ | |||||||||||||||||||||
| localStorage.removeItem('lastConnectOptions') | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| connectOptions.onSuccessfulPlay?.() | ||||||||||||||||||||||
| updateDataAfterJoin() | ||||||||||||||||||||||
| if (connectOptions.autoLoginPassword) { | ||||||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||||||
| bot.chat(`/login ${connectOptions.autoLoginPassword}`) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.