Skip to content

Commit

Permalink
feat: wait for resource pack install before displaying world to avoid…
Browse files Browse the repository at this point in the history
… chunks reloading
  • Loading branch information
zardoy committed Feb 3, 2025
1 parent 72058f1 commit 4148913
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 18 deletions.
14 changes: 12 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ import { startLocalServer, unsupportedLocalServerFeatures } from './createLocalS
import defaultServerOptions from './defaultLocalServerOptions'
import dayCycle from './dayCycle'

import { onAppLoad, resourcepackReload } from './resourcePack'
import { onAppLoad, resourcepackReload, resourcePackState } from './resourcePack'
import { ConnectPeerOptions, connectToPeer } from './localServerMultiplayer'
import CustomChannelClient from './customClient'
import { registerServiceWorker } from './serviceWorker'
Expand Down Expand Up @@ -671,7 +671,17 @@ export async function connect (connectOptions: ConnectOptions) {

const spawnEarlier = !singleplayer && !p2pMultiplayer
// don't use spawn event, player can be dead
bot.once(spawnEarlier ? 'forcedMove' : 'health', () => {
bot.once(spawnEarlier ? 'forcedMove' : 'health', async () => {
if (resourcePackState.isServerInstalling) {
showNotification('Resource pack is being installed, please wait...')
await new Promise<void>(resolve => {
subscribe(resourcePackState, () => {
if (!resourcePackState.isServerInstalling) {
resolve()
}
})
})
}
window.focus?.()
errorAbortController.abort()
const mcData = MinecraftData(bot.version)
Expand Down
37 changes: 29 additions & 8 deletions src/mineflayer/minecraft-protocol-extra.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,26 @@ export const pingServerVersion = async (ip: string, port?: number, preferredVers
}

const MAX_PACKET_SIZE = 2_097_152 // 2mb
const MAX_PACKET_DEPTH = 20
const CHAT_MAX_PACKET_DEPTH = 30

const CHAT_VALIDATE_PACKETS = new Set([
'chat',
'system_chat',
'player_chat',
'profileless_chat',
'kick_disconnect',
'resource_pack_send',
'action_bar',
'set_title_text',
'set_title_subtitle',
'title',
'death_combat_event',
'server_data',
'scoreboard_objective',
'scoreboard_team',
'playerlist_header',
'boss_bar'
])

export const validatePacket = (name: string, data: any, fullBuffer: Buffer, isFromServer: boolean) => {
// todo find out why chat is so slow with react
Expand All @@ -43,13 +62,15 @@ export const validatePacket = (name: string, data: any, fullBuffer: Buffer, isFr
throw new Error(`Packet ${name} is too large: ${fullBuffer.length} bytes`)
}

// todo count total number of objects instead of max depth
const maxDepth = getObjectMaxDepth(data)
if (maxDepth > MAX_PACKET_DEPTH) {
console.groupCollapsed(`Packet ${name} have too many nested objects: ${maxDepth}`)
console.log(data)
console.groupEnd()
throw new Error(`Packet ${name} have too many nested objects: ${maxDepth}`)
if (CHAT_VALIDATE_PACKETS.has(name)) {
// todo count total number of objects instead of max depth
const maxDepth = getObjectMaxDepth(data)
if (maxDepth > CHAT_MAX_PACKET_DEPTH) {
console.groupCollapsed(`Packet ${name} have too many nested objects: ${maxDepth}`)
console.log(data)
console.groupEnd()
throw new Error(`Packet ${name} have too many nested objects: ${maxDepth}`)
}
}
}

Expand Down
27 changes: 19 additions & 8 deletions src/resourcePack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { watchUnloadForCleanup } from './gameUnload'

export const resourcePackState = proxy({
resourcePackInstalled: false,
isServerInstalling: false
})

const getLoadedImage = async (url: string) => {
Expand Down Expand Up @@ -336,14 +337,24 @@ const prepareBlockstatesAndModels = async () => {
}

const downloadAndUseResourcePack = async (url: string): Promise<void> => {
console.log('Downloading server resource pack', url)
const response = await fetch(url)
const resourcePackData = await response.arrayBuffer()
showNotification('Installing resource pack...')
installTexturePack(resourcePackData, undefined, undefined, true).catch((err) => {
console.error(err)
showNotification('Failed to install resource pack: ' + err.message)
})
try {
resourcePackState.isServerInstalling = true
console.log('Downloading server resource pack', url)
const response = await fetch(url).catch((err) => {
console.log(`Ensure server on ${url} support CORS which is not required for regular client, but is required for the web client`)
console.error(err)
showNotification('Failed to download resource pack: ' + err.message)
})
if (!response) return
const resourcePackData = await response.arrayBuffer()
showNotification('Installing resource pack...')
await installTexturePack(resourcePackData, undefined, undefined, true).catch((err) => {
console.error(err)
showNotification('Failed to install resource pack: ' + err.message)
})
} finally {
resourcePackState.isServerInstalling = false
}
}

const waitForGameEvent = async () => {
Expand Down

0 comments on commit 4148913

Please sign in to comment.