Skip to content

Commit 5bd33a5

Browse files
authored
More build configs & optimise reconnect and immediate game enter (#398)
feat(custom-builds): Add a way to bundle only specific minecraft version data, this does not affect assets though env: MIN_MC_VERSION MAX_MC_VERSION new SKIP_MC_DATA_RECIPES - if recipes are not used in game fix: refactor QS params handling to ensure panorama & main menu never loaded when immedieate game enter action is expected (eg ?autoConnect=1)
1 parent e9c7840 commit 5bd33a5

9 files changed

+246
-152
lines changed

rsbuild.config.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ const appConfig = defineConfig({
139139
// 50kb limit for data uri
140140
dataUriLimit: SINGLE_FILE_BUILD ? 1 * 1024 * 1024 * 1024 : 50 * 1024
141141
},
142+
performance: {
143+
// prefetch: {
144+
// include(filename) {
145+
// return filename.includes('mc-data') || filename.includes('mc-assets')
146+
// },
147+
// },
148+
},
142149
source: {
143150
entry: {
144151
index: './src/index.ts',
@@ -154,7 +161,7 @@ const appConfig = defineConfig({
154161
'process.platform': '"browser"',
155162
'process.env.GITHUB_URL':
156163
JSON.stringify(`https://github.com/${process.env.GITHUB_REPOSITORY || `${process.env.VERCEL_GIT_REPO_OWNER}/${process.env.VERCEL_GIT_REPO_SLUG}` || githubRepositoryFallback}`),
157-
'process.env.DEPS_VERSIONS': JSON.stringify({}),
164+
'process.env.ALWAYS_MINIMAL_SERVER_UI': JSON.stringify(process.env.ALWAYS_MINIMAL_SERVER_UI),
158165
'process.env.RELEASE_TAG': JSON.stringify(releaseTag),
159166
'process.env.RELEASE_LINK': JSON.stringify(releaseLink),
160167
'process.env.RELEASE_CHANGELOG': JSON.stringify(releaseChangelog),
@@ -190,7 +197,7 @@ const appConfig = defineConfig({
190197
childProcess.execSync('tsx ./scripts/optimizeBlockCollisions.ts', { stdio: 'inherit' })
191198
}
192199
// childProcess.execSync(['tsx', './scripts/genLargeDataAliases.ts', ...(SINGLE_FILE_BUILD ? ['--compressed'] : [])].join(' '), { stdio: 'inherit' })
193-
genLargeDataAliases(SINGLE_FILE_BUILD)
200+
genLargeDataAliases(SINGLE_FILE_BUILD || process.env.ALWAYS_COMPRESS_LARGE_DATA === 'true')
194201
fsExtra.copySync('./node_modules/mc-assets/dist/other-textures/latest/entity', './dist/textures/entity')
195202
fsExtra.copySync('./assets/background', './dist/background')
196203
fs.copyFileSync('./assets/favicon.png', './dist/favicon.png')

scripts/genLargeDataAliases.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export const genLargeDataAliases = async (isCompressed: boolean) => {
1616

1717
let str = `${decoderCode}\nexport const importLargeData = async (mod: ${Object.keys(modules).map(x => `'${x}'`).join(' | ')}) => {\n`
1818
for (const [module, { compressed, raw }] of Object.entries(modules)) {
19-
let importCode = `(await import('${isCompressed ? compressed : raw}')).default`;
19+
const chunkName = module === 'mcData' ? 'mc-data' : 'mc-assets';
20+
let importCode = `(await import(/* webpackChunkName: "${chunkName}" */ '${isCompressed ? compressed : raw}')).default`;
2021
if (isCompressed) {
2122
importCode = `JSON.parse(decompressFromBase64(${importCode}))`
2223
}
@@ -30,6 +31,8 @@ export const genLargeDataAliases = async (isCompressed: boolean) => {
3031
const decoderCode = /* ts */ `
3132
import pako from 'pako';
3233
34+
globalThis.pako = { inflate: pako.inflate.bind(pako) }
35+
3336
function decompressFromBase64(input) {
3437
console.time('decompressFromBase64')
3538
// Decode the Base64 string

scripts/makeOptimizedMcData.mjs

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { dirname } from 'node:path'
66
import supportedVersions from '../src/supportedVersions.mjs'
77
import { gzipSizeFromFileSync } from 'gzip-size'
88
import fs from 'fs'
9-
import {default as _JsonOptimizer} from '../src/optimizeJson'
10-
import { gzipSync } from 'zlib';
9+
import { default as _JsonOptimizer } from '../src/optimizeJson'
10+
import { gzipSync } from 'zlib'
1111
import MinecraftData from 'minecraft-data'
1212
import MCProtocol from 'minecraft-protocol'
1313

@@ -21,12 +21,12 @@ const require = Module.createRequire(import.meta.url)
2121

2222
const dataPaths = require('minecraft-data/minecraft-data/data/dataPaths.json')
2323

24-
function toMajor (version) {
24+
function toMajor(version) {
2525
const [a, b] = (version + '').split('.')
2626
return `${a}.${b}`
2727
}
2828

29-
const versions = {}
29+
let versions = {}
3030
const dataTypes = new Set()
3131

3232
for (const [version, dataSet] of Object.entries(dataPaths.pc)) {
@@ -42,6 +42,31 @@ const versionToNumber = (ver) => {
4242
return +`${x.padStart(2, '0')}${y.padStart(2, '0')}${z.padStart(2, '0')}`
4343
}
4444

45+
// Version clipping support
46+
const minVersion = process.env.MIN_MC_VERSION
47+
const maxVersion = process.env.MAX_MC_VERSION
48+
49+
// Filter versions based on MIN_VERSION and MAX_VERSION if provided
50+
if (minVersion || maxVersion) {
51+
const filteredVersions = {}
52+
const minVersionNum = minVersion ? versionToNumber(minVersion) : 0
53+
const maxVersionNum = maxVersion ? versionToNumber(maxVersion) : Infinity
54+
55+
for (const [version, dataSet] of Object.entries(versions)) {
56+
const versionNum = versionToNumber(version)
57+
if (versionNum >= minVersionNum && versionNum <= maxVersionNum) {
58+
filteredVersions[version] = dataSet
59+
}
60+
}
61+
62+
versions = filteredVersions
63+
64+
console.log(`Version clipping applied: ${minVersion || 'none'} to ${maxVersion || 'none'}`)
65+
console.log(`Processing ${Object.keys(versions).length} versions:`, Object.keys(versions).sort((a, b) => versionToNumber(a) - versionToNumber(b)))
66+
}
67+
68+
console.log('Bundling version range:', Object.keys(versions)[0], 'to', Object.keys(versions).at(-1))
69+
4570
// if not included here (even as {}) will not be bundled & accessible!
4671
// const compressedOutput = !!process.env.SINGLE_FILE_BUILD
4772
const compressedOutput = true
@@ -57,18 +82,20 @@ const dataTypeBundling2 = {
5782
}
5883
}
5984
const dataTypeBundling = {
60-
language: {
85+
language: process.env.SKIP_MC_DATA_LANGUAGE === 'true' ? {
86+
raw: {}
87+
} : {
6188
ignoreRemoved: true,
6289
ignoreChanges: true
6390
},
6491
blocks: {
6592
arrKey: 'name',
66-
processData (current, prev) {
93+
processData(current, prev) {
6794
for (const block of current) {
6895
if (block.transparent) {
6996
const forceOpaque = block.name.includes('shulker_box') || block.name.match(/^double_.+_slab\d?$/) || ['melon_block', 'lit_pumpkin', 'lit_redstone_ore', 'lit_furnace'].includes(block.name)
7097

71-
const prevBlock = prev?.find(x => x.name === block.name);
98+
const prevBlock = prev?.find(x => x.name === block.name)
7299
if (forceOpaque || (prevBlock && !prevBlock.transparent)) {
73100
block.transparent = false
74101
}
@@ -136,7 +163,9 @@ const dataTypeBundling = {
136163
blockLoot: {
137164
arrKey: 'block'
138165
},
139-
recipes: {
166+
recipes: process.env.SKIP_MC_DATA_RECIPES === 'true' ? {
167+
raw: {}
168+
} : {
140169
raw: true
141170
// processData: processRecipes
142171
},
@@ -150,7 +179,7 @@ const dataTypeBundling = {
150179
// }
151180
}
152181

153-
function processRecipes (current, prev, getData, version) {
182+
function processRecipes(current, prev, getData, version) {
154183
// can require the same multiple times per different versions
155184
if (current._proccessed) return
156185
const items = getData('items')
@@ -242,30 +271,39 @@ for (const [i, [version, dataSet]] of versionsArr.reverse().entries()) {
242271
for (const [dataType, dataPath] of Object.entries(dataSet)) {
243272
const config = dataTypeBundling[dataType]
244273
if (!config) continue
245-
if (dataType === 'blockCollisionShapes' && versionToNumber(version) >= versionToNumber('1.13')) {
246-
// contents += ` get ${dataType} () { return window.globalGetCollisionShapes?.("${version}") },\n`
247-
continue
248-
}
274+
const ignoreCollisionShapes = dataType === 'blockCollisionShapes' && versionToNumber(version) >= versionToNumber('1.13')
275+
249276
let injectCode = ''
250-
const getData = (type) => {
277+
const getRealData = (type) => {
251278
const loc = `minecraft-data/data/${dataSet[type]}/`
252279
const dataPathAbsolute = require.resolve(`minecraft-data/${loc}${type}`)
253280
// const data = fs.readFileSync(dataPathAbsolute, 'utf8')
254281
const dataRaw = require(dataPathAbsolute)
255282
return dataRaw
256283
}
257-
const dataRaw = getData(dataType)
284+
const dataRaw = getRealData(dataType)
258285
let rawData = dataRaw
259286
if (config.raw) {
260287
rawDataVersions[dataType] ??= {}
261288
rawDataVersions[dataType][version] = rawData
262-
rawData = dataRaw
289+
if (config.raw === true) {
290+
rawData = dataRaw
291+
} else {
292+
rawData = config.raw
293+
}
294+
295+
if (ignoreCollisionShapes && dataType === 'blockCollisionShapes') {
296+
rawData = {
297+
blocks: {},
298+
shapes: {}
299+
}
300+
}
263301
} else {
264302
if (!diffSources[dataType]) {
265303
diffSources[dataType] = new JsonOptimizer(config.arrKey, config.ignoreChanges, config.ignoreRemoved)
266304
}
267305
try {
268-
config.processData?.(dataRaw, previousData[dataType], getData, version)
306+
config.processData?.(dataRaw, previousData[dataType], getRealData, version)
269307
diffSources[dataType].recordDiff(version, dataRaw)
270308
injectCode = `restoreDiff(sources, ${JSON.stringify(dataType)}, ${JSON.stringify(version)})`
271309
} catch (err) {
@@ -297,16 +335,16 @@ console.log('total size (mb)', totalSize / 1024 / 1024)
297335
console.log(
298336
'size per data type (mb, %)',
299337
Object.fromEntries(Object.entries(sizePerDataType).map(([dataType, size]) => {
300-
return [dataType, [size / 1024 / 1024, Math.round(size / totalSize * 100)]];
338+
return [dataType, [size / 1024 / 1024, Math.round(size / totalSize * 100)]]
301339
}).sort((a, b) => {
302340
//@ts-ignore
303-
return b[1][1] - a[1][1];
341+
return b[1][1] - a[1][1]
304342
}))
305343
)
306344

307345
function compressToBase64(input) {
308-
const buffer = gzipSync(input);
309-
return buffer.toString('base64');
346+
const buffer = gzipSync(input)
347+
return buffer.toString('base64')
310348
}
311349

312350
const filePath = './generated/minecraft-data-optimized.json'

src/downloadAndOpenFile.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ export const getFixedFilesize = (bytes: number) => {
1111
return prettyBytes(bytes, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
1212
}
1313

14+
export const isInterestedInDownload = () => {
15+
const { map, texturepack, replayFileUrl } = appQueryParams
16+
const { mapDir } = appQueryParamsArray
17+
return !!map || !!texturepack || !!replayFileUrl || !!mapDir
18+
}
19+
1420
const inner = async () => {
1521
const { map, texturepack, replayFileUrl } = appQueryParams
1622
const { mapDir } = appQueryParamsArray

src/env.d.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,36 @@ declare namespace NodeJS {
22
interface ProcessEnv {
33
// Build configuration
44
NODE_ENV: 'development' | 'production'
5-
SINGLE_FILE_BUILD?: string
5+
MIN_MC_VERSION?: string
6+
MAX_MC_VERSION?: string
7+
ALWAYS_COMPRESS_LARGE_DATA?: 'true' | 'false'
8+
SINGLE_FILE_BUILD?: 'true' | 'false'
69
WS_PORT?: string
7-
DISABLE_SERVICE_WORKER?: string
10+
DISABLE_SERVICE_WORKER?: 'true' | 'false'
811
CONFIG_JSON_SOURCE?: 'BUNDLED' | 'REMOTE'
912
LOCAL_CONFIG_FILE?: string
1013
BUILD_VERSION?: string
1114

12-
// GitHub and Vercel related
15+
// Build internals
1316
GITHUB_REPOSITORY?: string
1417
VERCEL_GIT_REPO_OWNER?: string
1518
VERCEL_GIT_REPO_SLUG?: string
1619

17-
// UI and Features
20+
// UI
1821
MAIN_MENU_LINKS?: string
22+
ALWAYS_MINIMAL_SERVER_UI?: 'true' | 'false'
23+
24+
// App features
1925
ENABLE_COOKIE_STORAGE?: string
2026
COOKIE_STORAGE_PREFIX?: string
2127

22-
// Release information
28+
// Build info. Release information
2329
RELEASE_TAG?: string
2430
RELEASE_LINK?: string
2531
RELEASE_CHANGELOG?: string
2632

27-
// Other configurations
28-
DEPS_VERSIONS?: string
33+
// Build info
2934
INLINED_APP_CONFIG?: string
35+
GITHUB_URL?: string
3036
}
3137
}

0 commit comments

Comments
 (0)