Skip to content
Open
Show file tree
Hide file tree
Changes from 81 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
3051cc3
up pkg
zardoy Jan 29, 2025
aed5b40
use local
zardoy Jan 29, 2025
380c214
make it finally pass grim checks!
zardoy Jan 30, 2025
044153c
up ver
zardoy Jan 30, 2025
5376584
use gen mineflayer
zardoy Jan 30, 2025
2848ab6
disable silly creative fly patching
zardoy Jan 31, 2025
8db6b5b
fix library versions
zardoy Jan 31, 2025
c626d10
use actually useful server
zardoy Jan 31, 2025
2d7ec12
Merge branch 'next' into nextgen-physics
zardoy Feb 3, 2025
7e74633
Merge branch 'next' into nextgen-physics
zardoy Feb 3, 2025
fb10179
set 1.19.4 for now!
zardoy Feb 3, 2025
9356daa
Merge branch 'next' into nextgen-physics
zardoy Feb 13, 2025
638dd67
Merge branch 'next' into nextgen-physics
zardoy Feb 15, 2025
34972e4
Merge branch 'next' into nextgen-physics
zardoy Feb 27, 2025
c65db9a
a working refactor
zardoy Mar 4, 2025
4381ef4
removing bobbing & panorama
zardoy Mar 4, 2025
d8294d5
even more appViewer usage
zardoy Mar 4, 2025
1861edf
delayLoadUntilFocus
zardoy Mar 4, 2025
d197859
big resourcemanager refactor
zardoy Mar 5, 2025
cefdf53
Merge branch 'next' into nextgen-physics
zardoy Mar 7, 2025
0597a3d
make library versions less annoying
zardoy Mar 9, 2025
7cc562b
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 14, 2025
3a9e2aa
fix
zardoy Mar 14, 2025
8a3c847
test flying!
zardoy Mar 14, 2025
847314d
hide hand in spectator
zardoy Mar 14, 2025
4d4637f
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 15, 2025
d74d860
Merge remote-tracking branch 'origin/next' into renderer-rewrite
zardoy Mar 15, 2025
f230763
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 18, 2025
67d90a5
Merge remote-tracking branch 'origin/next' into renderer-rewrite
zardoy Mar 18, 2025
6eb50cd
last dont crash
zardoy Mar 18, 2025
dc073cd
Merge remote-tracking branch 'origin/next' into renderer-rewrite
zardoy Mar 18, 2025
400f598
update server data for index 0
zardoy Mar 20, 2025
5364085
fix possible crash on non existing server data update
zardoy Mar 20, 2025
f2f1c25
10x inventory performance
zardoy Mar 20, 2025
e851f4f
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 20, 2025
de3edda
a lot of imports update, data cleanup, add thousands errors
zardoy Mar 20, 2025
c1a7765
final code cleanup i think
zardoy Mar 20, 2025
ccb0004
fix reload hand
zardoy Mar 20, 2025
9fedafe
move threejs entities & cursor block to renderer
zardoy Mar 21, 2025
136b051
smooth camera movement!
zardoy Mar 21, 2025
f88e9c8
Refactor renderer state management and move vr
zardoy Mar 21, 2025
cae2b61
fix all remaining reactive state linking
zardoy Mar 21, 2025
82d0638
Merge remote-tracking branch 'origin/next' into renderer-rewrite
zardoy Mar 21, 2025
b483923
rm unused three imports
zardoy Mar 21, 2025
dc2ad7c
disable signs, disable playground since its not used by anyone
zardoy Mar 21, 2025
8ee4dc3
disable displaying unknown non interactible entitites
zardoy Mar 21, 2025
11abbfc
disable check
zardoy Mar 21, 2025
5eedb3c
disable playground
zardoy Mar 21, 2025
8ddac97
dont use bot
zardoy Mar 21, 2025
853e0e1
up readme
zardoy Mar 21, 2025
d450a31
fix typo
zardoy Mar 21, 2025
b579ee1
Revert "disable playground"
zardoy Mar 21, 2025
ed04197
disable in other way
zardoy Mar 21, 2025
e917764
fix lint
zardoy Mar 21, 2025
e2b7833
Merge remote-tracking branch 'origin/renderer-rewrite' into nextgen-p…
zardoy Mar 21, 2025
b501893
ip pkgs
zardoy Mar 23, 2025
9888bd5
fix: allow to go back when not crashed game
zardoy Mar 21, 2025
2056974
fix mesher config pass
zardoy Mar 21, 2025
2630a57
renderers cleanup
zardoy Mar 21, 2025
6a5ac4f
make initial resource pack load optimised, rework it
zardoy Mar 21, 2025
9cede6d
final fixes
zardoy Mar 21, 2025
bf9c47d
fix test
zardoy Mar 21, 2025
547658f
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 25, 2025
9057d3a
revert stuff
zardoy Mar 25, 2025
14e20a2
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 26, 2025
e7c2406
up
zardoy Mar 26, 2025
0648d55
pick only necessary changes
zardoy Mar 26, 2025
b472583
revert unknown chaange
zardoy Mar 26, 2025
e743a03
Merge branch 'nextgen-physics' into protocol-worker
zardoy Mar 26, 2025
b9ca057
restore
zardoy Mar 26, 2025
bc9ca18
restore2
zardoy Mar 26, 2025
07e7c6f
revert physics for test
zardoy Mar 26, 2025
0839889
Merge remote-tracking branch 'origin/next' into nextgen-physics
zardoy Mar 30, 2025
bb6faf9
Merge remote-tracking branch 'origin/nextgen-physics' into protocol-w…
zardoy Mar 30, 2025
07e9725
.
zardoy Mar 31, 2025
290e641
Merge remote-tracking branch 'origin/next' into protocol-worker
zardoy Apr 10, 2025
0787440
.
zardoy Apr 10, 2025
bdcf3d6
finishing! fix all known bugs! chat! websockets! fix ping & username …
zardoy Apr 11, 2025
316fdd8
Merge remote-tracking branch 'origin/next' into protocol-worker
zardoy Apr 11, 2025
4483b73
revert
zardoy Apr 11, 2025
980779c
revertconfig
zardoy Apr 11, 2025
b50215b
fix build
zardoy Apr 12, 2025
92d444a
fix one build, break another
zardoy Apr 12, 2025
df2a337
try fixing single file, no more tries for now
zardoy Apr 12, 2025
ccd1130
Update rsbuild.config.ts
zardoy Apr 12, 2025
4a949d3
Update rsbuild.config.ts
zardoy Apr 12, 2025
475d990
patch
zardoy Apr 12, 2025
d9f1efd
fix
zardoy Apr 12, 2025
1fe6239
Merge branch 'next' into protocol-worker
zardoy Apr 18, 2025
cd84acb
fix single file build
zardoy May 1, 2025
139ee9a
Revert "fix single file build"
zardoy May 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@
"no-bitwise": "off",
"unicorn/filename-case": "off",
"max-depth": "off",
"unicorn/no-typeof-undefined": "off"
"unicorn/no-typeof-undefined": "off",
"unicorn/relative-url-style": "off"
},
"overrides": [
{
Expand Down
6 changes: 6 additions & 0 deletions renderer/viewer/lib/simpleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ export function sectionPos (pos: { x: number, y: number, z: number }) {
const z = Math.floor(pos.z / 16)
return [x, y, z]
}
// doesn't support snapshots

export const toMajorVersion = version => {
const [a, b] = (String(version)).split('.')
return `${a}.${b}`
}
30 changes: 27 additions & 3 deletions renderer/viewer/lib/workerProxy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
export function createWorkerProxy<T extends Record<string, (...args: any[]) => void>> (handlers: T, channel?: MessagePort): { __workerProxy: T } {
export function createWorkerProxy<T extends Record<string, (...args: any[]) => void | Promise<any>>> (handlers: T, channel?: MessagePort): { __workerProxy: T } {
const target = channel ?? globalThis
target.addEventListener('message', (event: any) => {
const { type, args } = event.data
const { type, args, msgId } = event.data
if (handlers[type]) {
handlers[type](...args)
const result = handlers[type](...args)
if (result instanceof Promise) {
void result.then((result) => {
target.postMessage({
type: 'result',
msgId,
args: [result]
})
})
}
}
})
return null as any
Expand All @@ -23,6 +32,7 @@ export function createWorkerProxy<T extends Record<string, (...args: any[]) => v
export const useWorkerProxy = <T extends { __workerProxy: Record<string, (...args: any[]) => void> }> (worker: Worker | MessagePort, autoTransfer = true): T['__workerProxy'] & {
transfer: (...args: Transferable[]) => T['__workerProxy']
} => {
let messageId = 0
// in main thread
return new Proxy({} as any, {
get (target, prop) {
Expand All @@ -41,11 +51,25 @@ export const useWorkerProxy = <T extends { __workerProxy: Record<string, (...arg
}
}
return (...args: any[]) => {
const msgId = messageId++
const transfer = autoTransfer ? args.filter(arg => arg instanceof ArrayBuffer || arg instanceof MessagePort || arg instanceof ImageBitmap || arg instanceof OffscreenCanvas || arg instanceof ImageData) : []
worker.postMessage({
type: prop,
msgId,
args,
}, transfer as any[])
return {
// eslint-disable-next-line unicorn/no-thenable
then (onfulfilled: (value: any) => void) {
const handler = ({ data }: MessageEvent): void => {
if (data.type === 'result' && data.msgId === msgId) {
onfulfilled(data.args[0])
worker.removeEventListener('message', handler as EventListener)
}
}
worker.addEventListener('message', handler as EventListener)
}
}
}
}
})
Expand Down
3 changes: 1 addition & 2 deletions renderer/viewer/lib/worldrendererCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ import { WorldBlockProvider } from 'mc-assets/dist/worldBlockProvider'
import { generateSpiralMatrix } from 'flying-squid/dist/utils'
import { subscribeKey } from 'valtio/utils'
import { dynamicMcDataFiles } from '../../buildMesherConfig.mjs'
import { toMajorVersion } from '../../../src/utils'
import { ResourcesManager } from '../../../src/resourcesManager'
import { DisplayWorldOptions, GraphicsInitOptions, RendererReactiveState } from '../../../src/appViewer'
import { SoundSystem } from '../three/threeJsSound'
import { buildCleanupDecorator } from './cleanupDecorator'
import { HighestBlockInfo, MesherGeometryOutput, CustomBlockModels, BlockStateModelInfo, getBlockAssetsCacheKey, MesherConfig } from './mesher/shared'
import { chunkPos } from './simpleUtils'
import { chunkPos, toMajorVersion } from './simpleUtils'
import { addNewStat, removeAllStats, removeStat, updatePanesVisibility, updateStatText } from './ui/newStats'
import { WorldDataEmitter } from './worldDataEmitter'
import { IPlayerState } from './basePlayerState'
Expand Down
149 changes: 19 additions & 130 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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'
Expand All @@ -97,6 +95,7 @@
import { appViewer } from './appViewer'
import './appViewerLoad'
import { registerOpenBenchmarkListener } from './benchmark'
import { getProtocolClientGetter } from './protocolWorker/protocolMain'

window.debug = debug
window.beforeRenderFrame = []
Expand Down Expand Up @@ -161,11 +160,6 @@
}
})
}
if (sessionStorage.delayLoadUntilClick) {
await new Promise(resolve => {
window.addEventListener('click', resolve)
})
}

miscUiState.hasErrors = false
lastConnectOptions.value = connectOptions
Expand All @@ -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)

Expand Down Expand Up @@ -237,14 +231,13 @@
})
}
}
let lastPacket = undefined as string | undefined
const lastPacket = undefined as string | undefined
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Verify the impact of lastPacket removal.

The lastPacket variable is now a constant with undefined value, and its assignment at line 535 is commented out. However, it's still referenced in the onPossibleErrorDisconnect function (lines 241-243), which will never enter the conditional block.

-const lastPacket = undefined as string | undefined
+// Remove this constant since it's no longer used

And 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

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const lastPacket = undefined as string | undefined
// In src/index.ts around line 239, remove the unused `lastPacket` declaration:
// Remove this constant since it's no longer used
// …later in the same file, update the error‐disconnect handler:
const onPossibleErrorDisconnect = () => {
if (bot?._client && bot._client.state !== states.PLAY) {
appStatusState.descriptionHint = `Disconnected before entering play state`
}
}

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
}
Expand Down Expand Up @@ -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 ?? {})
Expand Down Expand Up @@ -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
if (requiresPass) {
password = prompt('Enter password')
if (!password) {
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -553,49 +488,7 @@
} else if (clientDataStream) {
// bot.emit('inject_allowed')
bot._client.emit('connect')
} else {

Check failure on line 491 in src/index.ts

View workflow job for this annotation

GitHub Actions / build-and-deploy

Empty block statement
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) {
Expand Down Expand Up @@ -628,7 +521,7 @@
})

const packetBeforePlay = (_, __, ___, fullBuffer) => {
lastPacket = fullBuffer.toString()
// lastPacket = fullBuffer.toString()
}
bot._client.on('packet', packetBeforePlay as any)
const playStateSwitch = (newState) => {
Expand All @@ -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()
Expand Down Expand Up @@ -715,7 +605,6 @@
localStorage.removeItem('lastConnectOptions')
}
connectOptions.onSuccessfulPlay?.()
updateDataAfterJoin()
if (connectOptions.autoLoginPassword) {
setTimeout(() => {
bot.chat(`/login ${connectOptions.autoLoginPassword}`)
Expand Down
14 changes: 4 additions & 10 deletions src/mineflayer/mc-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,10 @@ import { getWebsocketStream } from './websocket-core'

let lastPacketTime = 0
customEvents.on('mineflayerBotCreated', () => {
// todo move more code here
if (!appQueryParams.noPacketsValidation) {
(bot._client as unknown as Client).on('packet', (data, packetMeta, buffer, fullBuffer) => {
validatePacket(packetMeta.name, data, fullBuffer, true)
lastPacketTime = performance.now()
});
(bot._client as unknown as Client).on('writePacket', (name, params) => {
validatePacket(name, params, Buffer.alloc(0), false)
})
}
(bot._client as unknown as Client).on('packet', (data, packetMeta, buffer, fullBuffer) => {
lastPacketTime = performance.now()
})

})

setInterval(() => {
Expand Down
Loading
Loading