From 1abc28f36961f91a38b694daa06fccf37f8dd4ff Mon Sep 17 00:00:00 2001 From: Misode Date: Wed, 27 Nov 2024 06:01:05 +0100 Subject: [PATCH] Get project data for worldgen previews --- .../previews/BiomeSourcePreview.tsx | 5 ++-- .../previews/DensityFunctionPreview.tsx | 5 ++-- .../previews/NoiseSettingsPreview.tsx | 5 ++-- src/app/contexts/Project.tsx | 24 ++++++++++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/app/components/previews/BiomeSourcePreview.tsx b/src/app/components/previews/BiomeSourcePreview.tsx index a767b189c..ac01c061b 100644 --- a/src/app/components/previews/BiomeSourcePreview.tsx +++ b/src/app/components/previews/BiomeSourcePreview.tsx @@ -1,7 +1,7 @@ import { clampedMap } from 'deepslate' import { mat3 } from 'gl-matrix' import { useCallback, useRef, useState } from 'preact/hooks' -import { useLocale, useProject, useStore, useVersion } from '../../contexts/index.js' +import { getWorldgenProjectData, useLocale, useProject, useStore, useVersion } from '../../contexts/index.js' import { useAsync } from '../../hooks/index.js' import { checkVersion } from '../../services/Versions.js' import { Store } from '../../Store.js' @@ -37,7 +37,8 @@ export const BiomeSourcePreview = ({ docAndNode, shown }: PreviewProps) => { const hasRandomness = type === 'multi_noise' || type === 'the_end' const { value } = useAsync(async function loadBiomeSource() { - await DEEPSLATE.loadVersion(version, {}) // TODO: get project data + const projectData = await getWorldgenProjectData(project) + await DEEPSLATE.loadVersion(version, projectData) await DEEPSLATE.loadChunkGenerator(data?.generator?.settings, data?.generator?.biome_source, seed) return { biomeSource: { loaded: true }, diff --git a/src/app/components/previews/DensityFunctionPreview.tsx b/src/app/components/previews/DensityFunctionPreview.tsx index a8b3fdcaf..9dcaee740 100644 --- a/src/app/components/previews/DensityFunctionPreview.tsx +++ b/src/app/components/previews/DensityFunctionPreview.tsx @@ -2,7 +2,7 @@ import type { Voxel } from 'deepslate/render' import { clampedMap, VoxelRenderer } from 'deepslate/render' import type { mat3, mat4 } from 'gl-matrix' import { useCallback, useEffect, useRef, useState } from 'preact/hooks' -import { useLocale, useProject, useVersion } from '../../contexts/index.js' +import { getWorldgenProjectData, useLocale, useProject, useVersion } from '../../contexts/index.js' import { useAsync } from '../../hooks/useAsync.js' import { useLocalStorage } from '../../hooks/useLocalStorage.js' import { Store } from '../../Store.js' @@ -32,7 +32,8 @@ export const DensityFunctionPreview = ({ docAndNode, shown }: PreviewProps) => { const text = docAndNode.doc.getText() const { value: df } = useAsync(async () => { - await DEEPSLATE.loadVersion(version, {}) // TODO: get project data + const projectData = await getWorldgenProjectData(project) + await DEEPSLATE.loadVersion(version, projectData) const df = DEEPSLATE.loadDensityFunction(safeJsonParse(text) ?? {}, minY, height, seed) return df }, [version, project, minY, height, seed, text]) diff --git a/src/app/components/previews/NoiseSettingsPreview.tsx b/src/app/components/previews/NoiseSettingsPreview.tsx index e06dc14a5..147a4c692 100644 --- a/src/app/components/previews/NoiseSettingsPreview.tsx +++ b/src/app/components/previews/NoiseSettingsPreview.tsx @@ -2,7 +2,7 @@ import { clampedMap } from 'deepslate' import type { mat3 } from 'gl-matrix' import { vec2 } from 'gl-matrix' import { useCallback, useRef, useState } from 'preact/hooks' -import { useLocale, useProject, useVersion } from '../../contexts/index.js' +import { getWorldgenProjectData, useLocale, useProject, useVersion } from '../../contexts/index.js' import { useAsync } from '../../hooks/index.js' import { fetchRegistries } from '../../services/index.js' import { Store } from '../../Store.js' @@ -27,7 +27,8 @@ export const NoiseSettingsPreview = ({ docAndNode, shown }: PreviewProps) => { const { value, error } = useAsync(async () => { const data = safeJsonParse(text) ?? {} - await DEEPSLATE.loadVersion(version, {}) // TODO: get project data + const projectData = await getWorldgenProjectData(project) + await DEEPSLATE.loadVersion(version, projectData) const biomeSource = { type: 'fixed', biome } await DEEPSLATE.loadChunkGenerator(data, biomeSource, seed) const noiseSettings = DEEPSLATE.getNoiseSettings() diff --git a/src/app/contexts/Project.tsx b/src/app/contexts/Project.tsx index 42daa9a59..da3cfef6b 100644 --- a/src/app/contexts/Project.tsx +++ b/src/app/contexts/Project.tsx @@ -2,13 +2,14 @@ import { Identifier } from 'deepslate' import type { ComponentChildren } from 'preact' import { createContext } from 'preact' import { useCallback, useContext, useState } from 'preact/hooks' +import type { ProjectData } from '../components/previews/Deepslate.js' import config from '../Config.js' import { useAsync } from '../hooks/useAsync.js' import type { VersionId } from '../services/index.js' import { DEFAULT_VERSION } from '../services/index.js' import { DRAFTS_URI, PROJECTS_URI, SpyglassClient } from '../services/Spyglass.js' import { Store } from '../Store.js' -import { genPath, hexId, message } from '../Utils.js' +import { genPath, hexId, message, safeJsonParse } from '../Utils.js' export type ProjectMeta = { name: string, @@ -167,3 +168,24 @@ export function getProjectRoot(project: ProjectMeta) { } throw new Error(`Unsupported project storage ${project.storage?.type}`) } + +export async function getWorldgenProjectData(project: ProjectMeta): Promise { + const projectRoot = getProjectRoot(project) + const categories = ['worldgen/noise_settings', 'worldgen/noise', 'worldgen/density_function'] + const result: ProjectData = Object.fromEntries(categories.map(c => [c, {}])) + const entries = await SpyglassClient.FS.readdir(projectRoot) + for (const entry of entries) { + for (const category of categories) { + if (entry.name.includes(category)) { + const pattern = RegExp(`data/([a-z0-9_.-]+)/${category}/([a-z0-9_./-]+).json$`) + const match = entry.name.match(pattern) + if (match) { + const data = await SpyglassClient.FS.readFile(entry.name) + const text = new TextDecoder().decode(data) + result[category][`${match[1]}:${match[2]}`] = safeJsonParse(text) + } + } + } + } + return result +}