From 74cb815940d29706c379026cc614203d6831c686 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Tue, 10 Dec 2024 07:03:55 +0300 Subject: [PATCH] feat: support for multiple sources for `mapDir` url in case if first source can't be fetched --- src/browserfs.ts | 38 ++++++++++++++++++++++++++++---------- src/downloadAndOpenFile.ts | 4 ++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/browserfs.ts b/src/browserfs.ts index e3675b4c3..ce8fa56ac 100644 --- a/src/browserfs.ts +++ b/src/browserfs.ts @@ -389,7 +389,7 @@ export const copyFilesAsyncWithProgress = async (pathSrc: string, pathDest: stri return } if (!stat.isDirectory()) { - await fs.promises.writeFile(pathDest, await fs.promises.readFile(pathSrc)) + await fs.promises.writeFile(pathDest, await fs.promises.readFile(pathSrc) as any) console.debug('copied single file', pathSrc, pathDest) return } @@ -464,7 +464,7 @@ export const copyFilesAsync = async (pathSrc: string, pathDest: string, fileCopi } else { // Copy file try { - await fs.promises.writeFile(curPathDest, await fs.promises.readFile(curPathSrc)) + await fs.promises.writeFile(curPathDest, await fs.promises.readFile(curPathSrc) as any) console.debug('copied file', curPathSrc, curPathDest) } catch (err) { console.error('Error copying file', curPathSrc, curPathDest, err) @@ -475,17 +475,35 @@ export const copyFilesAsync = async (pathSrc: string, pathDest: string, fileCopi })) } -export const openWorldFromHttpDir = async (fileDescriptorUrl: string/* | undefined */, baseUrl = fileDescriptorUrl.split('/').slice(0, -1).join('/')) => { +export const openWorldFromHttpDir = async (fileDescriptorUrls: string[]/* | undefined */, baseUrlParam) => { // todo try go guess mode let index - const file = await fetch(fileDescriptorUrl).then(async a => a.json()) - if (file.baseUrl) { - baseUrl = new URL(file.baseUrl, baseUrl).toString() - index = file.index - } else { - index = file + let baseUrl + for (const url of fileDescriptorUrls) { + let response: Response | undefined + try { + setLoadingScreenStatus(`Trying to get world descriptor from ${new URL(url).host}`) + const controller = new AbortController() + setTimeout(() => { + controller.abort() + }, 3000) + // eslint-disable-next-line no-await-in-loop + response = await fetch(url, { signal: controller.signal }) + } catch (err) { + console.error('Error fetching file descriptor', url, err) + } + if (!response) continue + // eslint-disable-next-line no-await-in-loop + const file = await response.json() + if (file.baseUrl) { + baseUrl = new URL(file.baseUrl, baseUrl).toString() + index = file.index + } else { + index = file + baseUrl = baseUrlParam ?? url.split('/').slice(0, -1).join('/') + } } - if (!index) throw new Error(`The provided mapDir file is not valid descriptor file! ${fileDescriptorUrl}`) + if (!index) throw new Error(`The provided mapDir file is not valid descriptor file! ${fileDescriptorUrls.join(', ')}`) await new Promise(async resolve => { browserfs.configure({ fs: 'MountableFileSystem', diff --git a/src/downloadAndOpenFile.ts b/src/downloadAndOpenFile.ts index 49fc5c35a..6e59ea025 100644 --- a/src/downloadAndOpenFile.ts +++ b/src/downloadAndOpenFile.ts @@ -9,10 +9,10 @@ export const getFixedFilesize = (bytes: number) => { const inner = async () => { const qs = new URLSearchParams(window.location.search) - const mapUrlDir = qs.get('mapDir') + const mapUrlDir = qs.getAll('mapDir') const mapUrlDirGuess = qs.get('mapDirGuess') const mapUrlDirBaseUrl = qs.get('mapDirBaseUrl') - if (mapUrlDir) { + if (mapUrlDir.length) { await openWorldFromHttpDir(mapUrlDir, mapUrlDirBaseUrl ?? undefined) return true }