From 0d8beef65c5022cf32dd2ea758891bad700e2374 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sun, 26 May 2024 18:58:46 +0300 Subject: [PATCH] feat: add gamemode selector in create world screen. always use creative with ?singleplayer=1 --- cypress/e2e/index.spec.ts | 27 ++----------------- cypress/e2e/shared.ts | 15 +++++++++++ .../viewer/prepare/generateTextures.ts | 7 ++--- scripts/esbuildPlugins.mjs | 18 ++++++------- scripts/githubActions.mjs | 8 +++--- src/optionsStorage.ts | 4 ++- src/react/CreateWorld.tsx | 14 +++++++--- src/react/CreateWorldProvider.tsx | 7 ++--- src/react/Crosshair.tsx | 2 +- src/workerWorkaround.ts | 2 ++ tsconfig.json | 2 +- 11 files changed, 56 insertions(+), 50 deletions(-) create mode 100644 cypress/e2e/shared.ts create mode 100644 src/workerWorkaround.ts diff --git a/cypress/e2e/index.spec.ts b/cypress/e2e/index.spec.ts index 455b1283..05b50211 100644 --- a/cypress/e2e/index.spec.ts +++ b/cypress/e2e/index.spec.ts @@ -1,15 +1,5 @@ /// -import type { AppOptions } from '../../src/optionsStorage' - -const cleanVisit = (url?) => { - cy.clearLocalStorage() - visit(url) -} - -const visit = (url = '/') => { - window.localStorage.cypress = 'true' - cy.visit(url) -} +import { setOptions, cleanVisit, visit } from './shared' // todo use ssl @@ -31,14 +21,8 @@ const testWorldLoad = () => { }) } -const setOptions = (options: Partial) => { - cy.window().then(win => { - Object.assign(win['options'], options) - }) -} - it('Loads & renders singleplayer', () => { - visit('/?singleplayer=1') + cleanVisit('/?singleplayer=1') setOptions({ localServerOptions: { generation: { @@ -69,10 +53,3 @@ it('Loads & renders zip world', () => { cy.get('input[type="file"]').selectFile('cypress/superflat.zip', { force: true }) testWorldLoad() }) - -it.skip('Performance test', () => { - // select that world - // from -2 85 24 - // await bot.loadPlugin(pathfinder.pathfinder) - // bot.pathfinder.goto(new pathfinder.goals.GoalXZ(28, -28)) -}) diff --git a/cypress/e2e/shared.ts b/cypress/e2e/shared.ts new file mode 100644 index 00000000..9292a8d5 --- /dev/null +++ b/cypress/e2e/shared.ts @@ -0,0 +1,15 @@ +import { AppOptions } from '../../src/optionsStorage' + +export const cleanVisit = (url?) => { + cy.clearLocalStorage() + visit(url) +} +export const visit = (url = '/') => { + window.localStorage.cypress = 'true' + cy.visit(url) +} +export const setOptions = (options: Partial) => { + cy.window().then(win => { + Object.assign(win['options'], options) + }) +} diff --git a/prismarine-viewer/viewer/prepare/generateTextures.ts b/prismarine-viewer/viewer/prepare/generateTextures.ts index dc838c65..f66fb5d7 100644 --- a/prismarine-viewer/viewer/prepare/generateTextures.ts +++ b/prismarine-viewer/viewer/prepare/generateTextures.ts @@ -19,9 +19,10 @@ const warnings = new Set() Promise.resolve().then(async () => { generateItemsAtlases() console.time('generateTextures') - for (const version of mcAssets.versions as typeof mcAssets['versions']) { + const versions = process.argv.includes('-l') ? [mcAssets.versions.at(-1)!] : mcAssets.versions + for (const version of versions as typeof mcAssets['versions']) { // for debugging (e.g. when above is overridden) - if (!mcAssets.versions.includes(version)) { + if (!versions.includes(version)) { throw new Error(`Version ${version} is not supported by minecraft-assets`) } if (versionToNumber(version) < versionToNumber('1.13')) { @@ -45,7 +46,7 @@ Promise.resolve().then(async () => { fs.copySync(assets.directory, path.resolve(texturesPath, version), { overwrite: true }) } - fs.writeFileSync(path.join(publicPath, 'supportedVersions.json'), '[' + mcAssets.versions.map(v => `"${v}"`).toString() + ']') + fs.writeFileSync(path.join(publicPath, 'supportedVersions.json'), '[' + versions.map(v => `"${v}"`).toString() + ']') warnings.forEach(x => console.warn(x)) console.timeEnd('generateTextures') }) diff --git a/scripts/esbuildPlugins.mjs b/scripts/esbuildPlugins.mjs index f6b539c1..fe4018f3 100644 --- a/scripts/esbuildPlugins.mjs +++ b/scripts/esbuildPlugins.mjs @@ -40,7 +40,7 @@ export const startWatchingHmr = () => { const mesherSharedPlugins = [ { name: 'minecraft-data', - setup (build) { + setup(build) { build.onLoad({ filter: /data[\/\\]pc[\/\\]common[\/\\]legacy.json$/, }, async (args) => { @@ -59,7 +59,7 @@ const plugins = [ ...mesherSharedPlugins, { name: 'strict-aliases', - setup (build) { + setup(build) { build.onResolve({ filter: /^minecraft-protocol$/, }, async ({ kind, resolveDir }) => { @@ -110,7 +110,7 @@ const plugins = [ }, { name: 'data-assets', - setup (build) { + setup(build) { build.onResolve({ filter: /.*/, }, async ({ path, ...rest }) => { @@ -161,7 +161,7 @@ const plugins = [ }, { name: 'prevent-incorrect-linking', - setup (build) { + setup(build) { build.onResolve({ filter: /.+/, }, async ({ resolveDir, path, importer, kind, pluginData }) => { @@ -184,7 +184,7 @@ const plugins = [ }, { name: 'watch-notify', - setup (build) { + setup(build) { let count = 0 let time let prevHash @@ -234,7 +234,7 @@ const plugins = [ }, { name: 'esbuild-readdir', - setup (build) { + setup(build) { build.onResolve({ filter: /^esbuild-readdir:.+$/, }, ({ resolveDir, path }) => { @@ -262,7 +262,7 @@ const plugins = [ }, { name: 'esbuild-import-glob', - setup (build) { + setup(build) { build.onResolve({ filter: /^esbuild-import-glob\(path:(.+),skipFiles:(.+)\)+$/, }, ({ resolveDir, path }) => { @@ -292,7 +292,7 @@ const plugins = [ }, { name: 'fix-dynamic-require', - setup (build) { + setup(build) { build.onResolve({ filter: /1\.14\/chunk/, }, async ({ resolveDir, path }) => { @@ -321,7 +321,7 @@ const plugins = [ }, { name: 'react-displayname', - setup (build) { + setup(build) { build.onLoad({ filter: /.tsx$/, }, async ({ path }) => { diff --git a/scripts/githubActions.mjs b/scripts/githubActions.mjs index ba7b8566..ab786ea9 100644 --- a/scripts/githubActions.mjs +++ b/scripts/githubActions.mjs @@ -6,10 +6,10 @@ const fns = { async getAlias () { const aliasesRaw = process.env.ALIASES if (!aliasesRaw) throw new Error('No aliases found') - const aliases = aliasesRaw.split('\n').map((x) => x.split('=')) + const aliases = aliasesRaw.split('\n').map((x) => x.trim().split('=')) const githubActionsPull = process.env.PULL_URL?.split('/').at(-1) - if (!githubActionsPull) throw new Error(`Not a pull request, got ${process.env.GITHUB_REF}`) - const prNumber = githubActionsPull[1] + if (!githubActionsPull) throw new Error(`Not a pull request, got ${process.env.PULL_URL}`) + const prNumber = githubActionsPull const alias = aliases.find((x) => x[0] === prNumber) if (alias) { // set github output @@ -18,7 +18,7 @@ const fns = { } } -function setOutput(key, value) { +function setOutput (key, value) { // Temporary hack until core actions library catches up with github new recommendations const output = process.env['GITHUB_OUTPUT'] fs.appendFileSync(output, `${key}=${value}${os.EOL}`) diff --git a/src/optionsStorage.ts b/src/optionsStorage.ts index ed71cfdb..2a13abf4 100644 --- a/src/optionsStorage.ts +++ b/src/optionsStorage.ts @@ -52,7 +52,9 @@ const defaultOptions = { excludeCommunicationDebugEvents: [], preventDevReloadWhilePlaying: false, numWorkers: 4, - localServerOptions: {} as any, + localServerOptions: { + gameMode: 1 + } as any, preferLoadReadonly: false, disableLoadPrompts: false, guestUsername: 'guest', diff --git a/src/react/CreateWorld.tsx b/src/react/CreateWorld.tsx index ceed77ec..87b36777 100644 --- a/src/react/CreateWorld.tsx +++ b/src/react/CreateWorld.tsx @@ -8,17 +8,19 @@ import styles from './createWorld.module.css' // const worldTypes = ['default', 'flat', 'largeBiomes', 'amplified', 'customized', 'buffet', 'debug_all_block_states'] const worldTypes = ['default', 'flat'/* , 'void' */] +const gameModes = ['survival', 'creative'/* , 'adventure', 'spectator' */] export const creatingWorldState = proxy({ title: '', type: worldTypes[0], + gameMode: gameModes[0], version: '' }) export default ({ cancelClick, createClick, customizeClick, versions, defaultVersion }) => { const [quota, setQuota] = useState('') - const { title, type, version } = useSnapshot(creatingWorldState) + const { title, type, version, gameMode } = useSnapshot(creatingWorldState) useEffect(() => { creatingWorldState.version = defaultVersion void navigator.storage?.estimate?.().then(({ quota, usage }) => { @@ -54,9 +56,15 @@ export default ({ cancelClick, createClick, customizeClick, versions, defaultVer - + {/* */} +
Default and other world types are WIP
diff --git a/src/react/CreateWorldProvider.tsx b/src/react/CreateWorldProvider.tsx index 728e47ff..0f99ec42 100644 --- a/src/react/CreateWorldProvider.tsx +++ b/src/react/CreateWorldProvider.tsx @@ -3,8 +3,8 @@ import { hideCurrentModal, showModal } from '../globalState' import defaultLocalServerOptions from '../defaultLocalServerOptions' import { mkdirRecursive, uniqueFileNameFromWorldName } from '../browserfs' import CreateWorld, { WorldCustomize, creatingWorldState } from './CreateWorld' -import { useIsModalActive } from './utilsApp' import { getWorldsPath } from './SingleplayerProvider' +import { useIsModalActive } from './utilsApp' export default () => { const activeCreate = useIsModalActive('create-world') @@ -23,7 +23,7 @@ export default () => { }} createClick={async () => { // create new world - const { title, type, version } = creatingWorldState + const { title, type, version, gameMode } = creatingWorldState // todo display path in ui + disable if exist const savePath = await uniqueFileNameFromWorldName(title, getWorldsPath()) await mkdirRecursive(savePath) @@ -51,7 +51,8 @@ export default () => { levelName: title, version, generation, - 'worldFolder': savePath + 'worldFolder': savePath, + gameMode: gameMode === 'survival' ? 0 : 1, }, })) }} diff --git a/src/react/Crosshair.tsx b/src/react/Crosshair.tsx index ab289db8..9079fb66 100644 --- a/src/react/Crosshair.tsx +++ b/src/react/Crosshair.tsx @@ -12,7 +12,7 @@ export const itemBeingUsed = proxy({ export default () => { const { name: usingItem, hand } = useSnapshot(itemBeingUsed) - const [displayIndicator, setDisplayIndicator] = useState(true) + const [displayIndicator, setDisplayIndicator] = useState(false) const [indicatorProgress, setIndicatorProgress] = useState(0) const [alternativeIndicator, setAlternativeIndicator] = useState(false) const boxMaxTimeMs = 1000 diff --git a/src/workerWorkaround.ts b/src/workerWorkaround.ts new file mode 100644 index 00000000..00419b8c --- /dev/null +++ b/src/workerWorkaround.ts @@ -0,0 +1,2 @@ +global = globalThis +globalThis.window = globalThis diff --git a/tsconfig.json b/tsconfig.json index 5d018a46..dbbb9ced 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ "forceConsistentCasingInFileNames": true, "useUnknownInCatchVariables": false, "skipLibCheck": true, - "experimentalDecorators": true, + "strictBindCallApply": true, // this the only options that allows smooth transition from js to ts (by not dropping types from js files) // however might need to consider includeing *only needed libraries* instead of using this "maxNodeModuleJsDepth": 1,