- 
                Notifications
    
You must be signed in to change notification settings  - Fork 120
 
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 81 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.