allow to load worlf from ?map= qs url

This commit is contained in:
Vitaly 2023-09-02 03:37:28 +03:00
commit a228e1cc99
4 changed files with 47 additions and 19 deletions

View file

@ -152,7 +152,7 @@ export const openWorldDirectory = async (/** @type {FileSystemDirectoryHandle?}
loadFolder()
}
export const openWorldZip = async (/** @type {File} */file) => {
export const openWorldZip = async (/** @type {File | ArrayBuffer} */file, name = file['name']) => {
await new Promise(async resolve => {
browserfs.configure({
// todo
@ -161,8 +161,8 @@ export const openWorldZip = async (/** @type {File} */file) => {
"/world": {
fs: "ZipFS",
options: {
zipData: Buffer.from(await file.arrayBuffer()),
name: file.name
zipData: Buffer.from(file instanceof File ? (await file.arrayBuffer()) : file),
name
}
}
},

View file

@ -0,0 +1,36 @@
import { openWorldZip } from './browserfs'
import { setLoadingScreenStatus } from './utils'
import { filesize } from 'filesize'
window.addEventListener('load', async (e) => {
const qs = new URLSearchParams(window.location.search)
const mapUrl = qs.get('map')
if (!mapUrl) return
const menu = document.getElementById('play-screen')
menu.style = 'display: none;'
const name = mapUrl.slice(mapUrl.lastIndexOf('/') + 1).slice(-25)
setLoadingScreenStatus(`Downloading world ${name}...`)
const response = await fetch(mapUrl)
const contentLength = +response.headers.get('Content-Length')
setLoadingScreenStatus(`Downloading world ${name}: have to download ${filesize(contentLength)}...`)
// const reader = response.body!.getReader()
// let doneValue
// while (true) {
// // done is true for the last chunk
// // value is Uint8Array of the chunk bytes
// const { done, value } = await reader.read()
// if (done) {
// doneValue = value
// break
// }
// setLoadingScreenStatus(`Downloading world ${name}: ${filesize(value.length)} / ${filesize(contentLength)}MB...`)
// }
await openWorldZip(await response.arrayBuffer())
})
export default async () => {
}

View file

@ -40,6 +40,8 @@ require('./reactUi.jsx')
require('./botControls')
require('./dragndrop')
require('./browserfs')
require('./eruda')
require('./downloadAndOpenWorld')
const net = require('net')
const Stats = require('stats.js')
@ -56,7 +58,7 @@ const Cursor = require('./cursor').default
global.THREE = require('three')
const { initVR } = require('./vr')
const { activeModalStack, showModal, hideModal, hideCurrentModal, activeModalStacks, replaceActiveModalStack, isGameActive, miscUiState, gameAdditionalState } = require('./globalState')
const { pointerLock, goFullscreen, toNumber, isCypress } = require('./utils')
const { pointerLock, goFullscreen, toNumber, isCypress, loadScript, toMajorVersion, setLoadingScreenStatus } = require('./utils')
const { notification } = require('./menus/notification')
const { removePanorama, addPanoramaCubeMap, initPanoramaOptions } = require('./panorama')
const { startLocalServer, unsupportedLocalServerFeatures } = require('./createLocalServer')
@ -174,17 +176,6 @@ const hud = document.getElementById('hud')
const optionsScrn = document.getElementById('options-screen')
const pauseMenu = document.getElementById('pause-screen')
function setLoadingScreenStatus (status, isError = false) {
// todo update in component instead
showModal(loadingScreen)
if (loadingScreen.hasError) {
miscUiState.gameLoaded = false
return
}
loadingScreen.hasError = isError
loadingScreen.status = status
}
let mouseMovePostHandle = (e) => { }
let lastMouseCall
function onMouseMove (e) {
@ -366,7 +357,7 @@ async function connect (connectOptions) {
})
let singlePlayerServer
try {
Object.assign(serverOptions, _.defaultsDeep({}, connectOptions.serverOverrides, options.localServerOptions, serverOptions))
Object.assign(serverOptions, _.defaultsDeep({}, connectOptions.serverOverrides ?? {}, options.localServerOptions, serverOptions))
let version = connectOptions.botVersion ?? serverOptions.version
if (version) {
setLoadingScreenStatus(`Downloading data for ${version}`)
@ -376,7 +367,6 @@ async function connect (connectOptions) {
if (singeplayer) {
window.serverDataChannel ??= {}
window.worldLoaded = false
Object.assign(serverOptions, _.defaultsDeep({}, connectOptions.serverOverrides, options.localServerOptions, serverOptions))
singlePlayerServer = window.singlePlayerServer = startLocalServer()
// todo need just to call quit if started
// loadingScreen.maybeRecoverable = false

View file

@ -18,6 +18,7 @@ export const fsState = proxy({
const PROPOSE_BACKUP = true
// todo rename to loadWorld
export const loadFolder = async (root = '/world') => {
// todo do it in singleplayer as well
for (const key in forceCachedDataPaths) {
@ -47,7 +48,8 @@ export const loadFolder = async (root = '/world') => {
const parsedRaw = await parseNbt(Buffer.from(levelDatContent))
const levelDat: import('./mcTypes').LevelDat = nbt.simplify(parsedRaw).Data
version = levelDat.Version?.Name
const qs = new URLSearchParams(window.location.search)
version = levelDat.Version?.Name ?? qs.get('version')
if (!version) {
const newVersion = prompt(`In 1.8 and before world save doesn\'t contain version info, please enter version you want to use to load the world.\nSupported versions ${supportedVersions.join(', ')}`, '1.8.8')
if (!newVersion) return
@ -69,7 +71,7 @@ export const loadFolder = async (root = '/world') => {
if (levelDat.generatorName) {
isFlat = levelDat.generatorName === 'flat'
}
if (!isFlat) {
if (!isFlat && levelDat.generatorName !== 'default' && levelDat.generatorName !== 'customized') {
warnings.push(`Generator ${levelDat.generatorName} may not be supported yet`)
}