Skip to content

Commit

Permalink
download minecraft-data on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
zardoy committed Sep 2, 2023
1 parent ce7ddd5 commit a652af9
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 23 deletions.
14 changes: 9 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"version": "1.5.0",
"description": "A minecraft client running in a browser",
"scripts": {
"start": "node scripts/build.js copyFilesDev && node esbuild.mjs --minify --watch",
"start": "node scripts/build.js copyFilesDev && node scripts/prepareData.mjs && node esbuild.mjs --minify --watch",
"start-watch-script": "nodemon -w esbuild.mjs esbuild.mjs",
"build": "node scripts/build.js copyFiles && node esbuild.mjs --minify --prod",
"build": "node scripts/build.js copyFiles && node scripts/prepareData.mjs && node esbuild.mjs --minify --prod",
"watch": "node scripts/build.js copyFilesDev && webpack serve --config webpack.dev.js --progress",
"test:cypress": "cypress run",
"test:e2e": "start-test http-get://localhost:8080 test:cypress",
Expand All @@ -32,6 +32,7 @@
"compression": "^1.7.4",
"cypress-plugin-snapshots": "^1.4.4",
"diamond-square": "^1.2.0",
"eruda": "^3.0.1",
"esbuild": "^0.19.2",
"esbuild-loader": "^4.0.0",
"esbuild-plugin-polyfill-node": "^0.3.0",
Expand Down Expand Up @@ -73,6 +74,7 @@
"https-browserify": "^1.0.0",
"lodash-webpack-plugin": "^0.11.6",
"memfs": "^3.5.3",
"minecraft-inventory-gui": "file:../minecraft-inventory-gui",
"mineflayer": "github:zardoy/mineflayer#custom",
"mineflayer-pathfinder": "^2.4.4",
"npm-run-all": "^4.1.5",
Expand All @@ -92,14 +94,16 @@
"webpack-dev-middleware": "^6.1.1",
"webpack-dev-server": "^4.15.1",
"webpack-merge": "^5.9.0",
"workbox-webpack-plugin": "^6.6.0",
"minecraft-inventory-gui": "github:zardoy/minecraft-inventory-gui#next"
"workbox-webpack-plugin": "^6.6.0"
},
"pnpm": {
"overrides": {
"minecraft-data": "latest",
"prismarine-provider-anvil": "github:zardoy/prismarine-provider-anvil#chunk-impl-require-fix",
"minecraft-protocol": "github:zardoy/minecraft-protocol#custom-client-extra"
"minecraft-protocol": "file:../minecraft-protocol",
"space-squid": "file:../space-squid",
"@dimaka/interface": "file:../interface",
"mineflayer": "file:../mineflayer"
}
}
}
37 changes: 19 additions & 18 deletions scripts/esbuildPlugins.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@ const plugins = [
path: (await build.resolve('minecraft-protocol/src/index.js', { kind, resolveDir })).path,
}
})
// build.onResolve({
// filter: /^\.\/data.js$/,
// }, ({ resolveDir, path }) => {
// if (!resolveDir.endsWith('minecraft-data')) return
// return {
// namespace: 'load-global-minecraft-data',
// path
// }
// })
// build.onLoad({
// filter: /.+/,
// namespace: 'load-global-minecraft-data',
// }, () => {
// return {
// contents: 'module.exports = window.minecraftData',
// loader: 'js',
// }
// })
build.onResolve({
filter: /^\.\/data.js$/,
}, ({ resolveDir, path }) => {
if (!resolveDir.endsWith('minecraft-data')) return
return {
namespace: 'load-global-minecraft-data',
path
}
})
build.onLoad({
filter: /.+/,
namespace: 'load-global-minecraft-data',
}, () => {
return {
contents: 'window.mcData ??= {};module.exports = { pc: window.mcData }',
loader: 'js',
}
})
// build.onResolve({
// filter: /^minecraft-assets$/,
// }, ({ resolveDir, path }) => {
Expand Down Expand Up @@ -89,6 +89,7 @@ const plugins = [
filter: /.*/,
namespace: customMcDataNs,
}, async ({ path, ...rest }) => {
throw new Error('unreachable')
const resolvedPath = await build.resolve('minecraft-data/minecraft-data/data/dataPaths.json', { kind: 'require-call', resolveDir: process.cwd() })
const dataPaths = JSON.parse(await fs.promises.readFile(resolvedPath.path, 'utf8'))

Expand Down
79 changes: 79 additions & 0 deletions scripts/prepareData.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//@ts-check
import { build } from 'esbuild'
import Module from "node:module"
import { dirname } from 'node:path'

const require = Module.createRequire(import.meta.url)

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

function toMajor (version) {
const [a, b] = (version + '').split('.')
return `${a}.${b}`
}

const ignoredVersionsRegex = /(^0\.30c$)|w|-pre|-rc/

const grouped = {}

for (const [version, data] of Object.entries(dataPaths.pc)) {
if (ignoredVersionsRegex.test(version)) continue
const major = toMajor(version)
grouped[major] ??= {}
grouped[major][version] = data
}

console.log('preparing data')
for (const [major, versions] of Object.entries(grouped)) {
let contents = 'Object.assign(window.mcData, {\n'
for (const [version, dataSet] of Object.entries(versions)) {
contents += ` '${version}': {\n`
for (const [dataType, dataPath] of Object.entries(dataSet)) {
const loc = `minecraft-data/data/${dataPath}/`
contents += ` get ${dataType} () { return require("./${loc}${dataType}.json") },\n`
}
contents += ' },\n'
}
contents += '})'

build({
bundle: true,
outfile: `dist/mc-data/${major}.js`,
// entryPoints: ['mcData.js'],
stdin: {
contents,

resolveDir: dirname(require.resolve('minecraft-data')),
sourcefile: `mcData${major}.js`,
loader: 'js',
},
plugins: [
// {
// name: 'mcData',
// setup (build) {
// build.onResolve({
// filter: /^mcData\.js$/,
// }, ({ path, pluginData }) => {
// return {
// path,
// namespace: 'mc-data',
// }
// })
// build.onLoad({
// filter: /.*/,
// namespace: 'mc-data',
// }, ({ namespace, path }) => {
// const version = path.split('/')[2]
// const data = versions[version]
// if (!data) throw new Error(`No data for ${version}`)
// return {
// contents: `export const data = ${JSON.stringify(data, null, 2)}`,
// loader: 'js',
// }
// })
// }
// }
],
})
}
console.log('data prepared')
7 changes: 7 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ async function connect (connectOptions) {
})
let singlePlayerServer
try {
Object.assign(serverOptions, _.defaultsDeep({}, connectOptions.serverOverrides, options.localServerOptions, serverOptions))
let version = connectOptions.botVersion ?? serverOptions.version
if (version) {
setLoadingScreenStatus(`Downloading data for ${version}`)
await loadScript(`./mc-data/${toMajorVersion(version)}.js`)
}

if (singeplayer) {
window.serverDataChannel ??= {}
window.worldLoaded = false
Expand Down
27 changes: 27 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,30 @@ function javaUUID (s) {
export function nameToMcOfflineUUID (name) {
return (new UUID(javaUUID('OfflinePlayer:' + name))).toString()
}
export const loadScript = async function (/** @type {string} */ scriptSrc) {
if (document.querySelector(`script[src="${scriptSrc}"]`)) {
return
}

return new Promise((resolve, reject) => {
const scriptElement = document.createElement('script')
scriptElement.src = scriptSrc
scriptElement.async = true

scriptElement.onload = () => {
resolve(scriptElement)
}

scriptElement.onerror = (error) => {
reject(error)
}

document.head.appendChild(scriptElement)
})
}

// doesn't support snapshots
export const toMajorVersion = (version) => {
const [a, b] = (version + '').split('.')
return `${a}.${b}`
}

0 comments on commit a652af9

Please sign in to comment.