Compare commits
3 commits
next
...
world-data
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e4bde18a7 | ||
|
|
4cf578b774 | ||
|
|
7a88b35ae2 |
6 changed files with 221 additions and 47 deletions
62
buildWorkers.mjs
Normal file
62
buildWorkers.mjs
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
// main worker file intended for computing world geometry is built using prismarine-viewer/buildWorker.mjs
|
||||||
|
import { build, context } from 'esbuild'
|
||||||
|
import fs from 'fs'
|
||||||
|
import { sharedPlugins } from './scripts/esbuildPlugins.mjs'
|
||||||
|
|
||||||
|
const watch = process.argv.includes('-w')
|
||||||
|
|
||||||
|
const result = await (watch ? context : build)({
|
||||||
|
bundle: true,
|
||||||
|
platform: 'browser',
|
||||||
|
entryPoints: [/* 'prismarine-viewer/examples/webglRendererWorker.ts', */'src/worldSaveWorker.ts'],
|
||||||
|
outdir: 'prismarine-viewer/public/',
|
||||||
|
sourcemap: watch ? 'inline' : 'external',
|
||||||
|
minify: !watch,
|
||||||
|
treeShaking: true,
|
||||||
|
logLevel: 'info',
|
||||||
|
alias: {
|
||||||
|
'three': './node_modules/three/src/Three.js',
|
||||||
|
events: 'events', // make explicit
|
||||||
|
buffer: 'buffer',
|
||||||
|
'fs': 'browserfs/dist/shims/fs.js',
|
||||||
|
http: 'http-browserify',
|
||||||
|
perf_hooks: './src/perf_hooks_replacement.js',
|
||||||
|
crypto: './src/crypto.js',
|
||||||
|
stream: 'stream-browserify',
|
||||||
|
net: 'net-browserify',
|
||||||
|
assert: 'assert',
|
||||||
|
dns: './src/dns.js'
|
||||||
|
},
|
||||||
|
inject: [
|
||||||
|
'./src/shims.js'
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'writeOutput',
|
||||||
|
setup (build) {
|
||||||
|
build.onEnd(({ outputFiles }) => {
|
||||||
|
for (const file of outputFiles) {
|
||||||
|
for (const dir of ['prismarine-viewer/public', 'dist']) {
|
||||||
|
const baseName = file.path.split('/').pop()
|
||||||
|
fs.writeFileSync(`${dir}/${baseName}`, file.contents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...sharedPlugins
|
||||||
|
],
|
||||||
|
loader: {
|
||||||
|
'.vert': 'text',
|
||||||
|
'.frag': 'text'
|
||||||
|
},
|
||||||
|
mainFields: [
|
||||||
|
'browser', 'module', 'main'
|
||||||
|
],
|
||||||
|
keepNames: true,
|
||||||
|
write: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (watch) {
|
||||||
|
await result.watch()
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ const watchExternal = [
|
||||||
]
|
]
|
||||||
|
|
||||||
/** @type {import('esbuild').Plugin[]} */
|
/** @type {import('esbuild').Plugin[]} */
|
||||||
const plugins = [
|
const sharedPlugins = [
|
||||||
{
|
{
|
||||||
name: 'strict-aliases',
|
name: 'strict-aliases',
|
||||||
setup (build) {
|
setup (build) {
|
||||||
|
|
@ -65,6 +65,53 @@ const plugins = [
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'fix-dynamic-require',
|
||||||
|
setup (build) {
|
||||||
|
build.onResolve({
|
||||||
|
filter: /1\.14\/chunk/,
|
||||||
|
}, async ({ resolveDir, path }) => {
|
||||||
|
if (!resolveDir.includes('prismarine-provider-anvil')) return
|
||||||
|
return {
|
||||||
|
namespace: 'fix-dynamic-require',
|
||||||
|
path,
|
||||||
|
pluginData: {
|
||||||
|
resolvedPath: `${join(resolveDir, path)}.js`,
|
||||||
|
resolveDir
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
build.onLoad({
|
||||||
|
filter: /.+/,
|
||||||
|
namespace: 'fix-dynamic-require',
|
||||||
|
}, async ({ pluginData: { resolvedPath, resolveDir } }) => {
|
||||||
|
const resolvedFile = await fs.promises.readFile(resolvedPath, 'utf8')
|
||||||
|
return {
|
||||||
|
contents: resolvedFile.replace("require(`prismarine-chunk/src/pc/common/BitArray${noSpan ? 'NoSpan' : ''}`)", "noSpan ? require(`prismarine-chunk/src/pc/common/BitArray`) : require(`prismarine-chunk/src/pc/common/BitArrayNoSpan`)"),
|
||||||
|
resolveDir,
|
||||||
|
loader: 'js',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
polyfillNode({
|
||||||
|
polyfills: {
|
||||||
|
fs: false,
|
||||||
|
dns: false,
|
||||||
|
crypto: false,
|
||||||
|
events: false,
|
||||||
|
http: false,
|
||||||
|
stream: false,
|
||||||
|
buffer: false,
|
||||||
|
perf_hooks: false,
|
||||||
|
net: false,
|
||||||
|
assert: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
/** @type {import('esbuild').Plugin[]} */
|
||||||
|
const plugins = [
|
||||||
{
|
{
|
||||||
name: 'data-assets',
|
name: 'data-assets',
|
||||||
setup (build) {
|
setup (build) {
|
||||||
|
|
@ -256,35 +303,6 @@ const plugins = [
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'fix-dynamic-require',
|
|
||||||
setup (build) {
|
|
||||||
build.onResolve({
|
|
||||||
filter: /1\.14\/chunk/,
|
|
||||||
}, async ({ resolveDir, path }) => {
|
|
||||||
if (!resolveDir.includes('prismarine-provider-anvil')) return
|
|
||||||
return {
|
|
||||||
namespace: 'fix-dynamic-require',
|
|
||||||
path,
|
|
||||||
pluginData: {
|
|
||||||
resolvedPath: `${join(resolveDir, path)}.js`,
|
|
||||||
resolveDir
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
build.onLoad({
|
|
||||||
filter: /.+/,
|
|
||||||
namespace: 'fix-dynamic-require',
|
|
||||||
}, async ({ pluginData: { resolvedPath, resolveDir } }) => {
|
|
||||||
const resolvedFile = await fs.promises.readFile(resolvedPath, 'utf8')
|
|
||||||
return {
|
|
||||||
contents: resolvedFile.replace("require(`prismarine-chunk/src/pc/common/BitArray${noSpan ? 'NoSpan' : ''}`)", "noSpan ? require(`prismarine-chunk/src/pc/common/BitArray`) : require(`prismarine-chunk/src/pc/common/BitArrayNoSpan`)"),
|
|
||||||
resolveDir,
|
|
||||||
loader: 'js',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'react-displayname',
|
name: 'react-displayname',
|
||||||
setup (build) {
|
setup (build) {
|
||||||
|
|
@ -310,20 +328,7 @@ const plugins = [
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
polyfillNode({
|
...sharedPlugins
|
||||||
polyfills: {
|
|
||||||
fs: false,
|
|
||||||
dns: false,
|
|
||||||
crypto: false,
|
|
||||||
events: false,
|
|
||||||
http: false,
|
|
||||||
stream: false,
|
|
||||||
buffer: false,
|
|
||||||
perf_hooks: false,
|
|
||||||
net: false,
|
|
||||||
assert: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export { plugins, connectedClients as clients }
|
export { plugins, connectedClients as clients, sharedPlugins }
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,38 @@ export default () => {
|
||||||
chatInputValueGlobal.value = '/warp '
|
chatInputValueGlobal.value = '/warp '
|
||||||
showModal({ reactType: 'chat' })
|
showModal({ reactType: 'chat' })
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
|
|
||||||
|
(localServer as any).loadChunksOptimized = (chunks) => {
|
||||||
|
const workersNum = 5
|
||||||
|
const workers = [] as Worker[]
|
||||||
|
|
||||||
|
for (let i = 0; i < workersNum; i++) {
|
||||||
|
const worker = new Worker('./worldSaveWorker.js')
|
||||||
|
workers.push(worker)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.time('chunks-main')
|
||||||
|
for (const [i, worker] of workers.entries()) {
|
||||||
|
worker.postMessage({
|
||||||
|
type: 'readChunks',
|
||||||
|
chunks: chunks.slice(i * chunks.length / workersNum, (i + 1) * chunks.length / workersNum),
|
||||||
|
folder: localServer!.options.worldFolder + '/region'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let finishedWorkers = 0
|
||||||
|
|
||||||
|
for (const worker of workers) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||||
|
worker.onmessage = (msg) => {
|
||||||
|
if (msg.data.type === 'done') {
|
||||||
|
finishedWorkers++
|
||||||
|
if (finishedWorkers === workersNum) {
|
||||||
|
console.timeEnd('chunks-main')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ export default ({ indicators, effects }: {indicators: typeof defaultIndicatorsSt
|
||||||
}, [effects])
|
}, [effects])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// todo use more precise timer for each effect
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
for (const [index, effect] of effectsRef.current.entries()) {
|
for (const [index, effect] of effectsRef.current.entries()) {
|
||||||
if (effect.time === 0) {
|
if (effect.time === 0) {
|
||||||
|
|
|
||||||
3
src/workerWorkaround.ts
Normal file
3
src/workerWorkaround.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
global = globalThis
|
||||||
|
globalThis.window = globalThis
|
||||||
|
window.mcData = {}
|
||||||
72
src/worldSaveWorker.ts
Normal file
72
src/worldSaveWorker.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
import './workerWorkaround'
|
||||||
|
import fs from 'fs'
|
||||||
|
import './fs2'
|
||||||
|
import { Anvil } from 'prismarine-provider-anvil'
|
||||||
|
import WorldLoader from 'prismarine-world'
|
||||||
|
|
||||||
|
import * as browserfs from 'browserfs'
|
||||||
|
import { generateSpiralMatrix } from 'flying-squid/dist/utils'
|
||||||
|
import '../dist/mc-data/1.14'
|
||||||
|
import { oneOf } from '@zardoy/utils'
|
||||||
|
|
||||||
|
console.log('install')
|
||||||
|
browserfs.install(window)
|
||||||
|
window.fs = fs
|
||||||
|
|
||||||
|
onmessage = (msg) => {
|
||||||
|
globalThis.readSkylight = false
|
||||||
|
if (msg.data.type === 'readChunks') {
|
||||||
|
browserfs.configure({
|
||||||
|
fs: 'MountableFileSystem',
|
||||||
|
options: {
|
||||||
|
'/data': { fs: 'IndexedDB' },
|
||||||
|
},
|
||||||
|
}, async () => {
|
||||||
|
const version = '1.14.4'
|
||||||
|
const AnvilLoader = Anvil(version)
|
||||||
|
const World = WorldLoader(version)
|
||||||
|
// const folder = '/data/worlds/Greenfield v0.5.3-3/region'
|
||||||
|
const { folder } = msg.data
|
||||||
|
const world = new World(() => {
|
||||||
|
throw new Error('Not implemented')
|
||||||
|
}, new AnvilLoader(folder))
|
||||||
|
// const chunks = generateSpiralMatrix(20)
|
||||||
|
const { chunks } = msg.data
|
||||||
|
// const spawn = {
|
||||||
|
// x: 113,
|
||||||
|
// y: 64,
|
||||||
|
|
||||||
|
// }
|
||||||
|
console.log('starting...')
|
||||||
|
console.time('columns')
|
||||||
|
const loadedColumns = [] as any[]
|
||||||
|
const columnToTransfarable = (chunk) => {
|
||||||
|
return {
|
||||||
|
biomes: chunk.biomes,
|
||||||
|
// blockEntities: chunk.blockEntities,
|
||||||
|
// sectionMask: chunk.sectionMask,
|
||||||
|
sections: chunk.sections,
|
||||||
|
// skyLightMask: chunk.skyLightMask,
|
||||||
|
// blockLightMask: chunk.blockLightMask,
|
||||||
|
// skyLightSections: chunk.skyLightSections,
|
||||||
|
// blockLightSections: chunk.blockLightSections
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const chunk of chunks) {
|
||||||
|
const column = await world.getColumn(chunk[0], chunk[1])
|
||||||
|
if (!column) throw new Error(`Column ${chunk[0]} ${chunk[1]} not found`)
|
||||||
|
postMessage({
|
||||||
|
column: columnToTransfarable(column)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
postMessage({
|
||||||
|
type: 'done',
|
||||||
|
})
|
||||||
|
|
||||||
|
console.timeEnd('columns')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// window.fs = fs
|
||||||
Loading…
Add table
Add a link
Reference in a new issue