diff --git a/__snapshots__/packages/java-edition/test-out/binder/index.spec.js b/__snapshots__/packages/java-edition/test-out/binder/index.spec.js index 96f6b6555..340650c98 100644 --- a/__snapshots__/packages/java-edition/test-out/binder/index.spec.js +++ b/__snapshots__/packages/java-edition/test-out/binder/index.spec.js @@ -7,6 +7,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/advancements/data/foo/ "path": "advancements", "category": "advancement", "ext": ".json", + "pack": "data", "until": "1.21", "namespace": "minecraft", "identifier": "data/foo/predicates/bar" @@ -21,6 +22,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/loot_table/foo.json" i "path": "loot_table", "category": "loot_table", "ext": ".json", + "pack": "data", "since": "1.21", "namespace": "minecraft", "identifier": "foo" @@ -31,6 +33,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/loot_tables/foo.json" "path": "loot_tables", "category": "loot_table", "ext": ".json", + "pack": "data", "until": "1.21", "namespace": "minecraft", "identifier": "foo" @@ -41,6 +44,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/tags/block/bar.json" 1 "path": "tags/block", "category": "tag/block", "ext": ".json", + "pack": "data", "since": "1.21", "namespace": "minecraft", "identifier": "bar", @@ -52,6 +56,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/tags/block/bar.json" i "path": "tags/block", "category": "tag/block", "ext": ".json", + "pack": "data", "since": "1.21", "namespace": "minecraft", "identifier": "bar" @@ -62,6 +67,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/tags/blocks/bar.json" "path": "tags/blocks", "category": "tag/block", "ext": ".json", + "pack": "data", "until": "1.21", "namespace": "minecraft", "identifier": "bar" @@ -72,6 +78,7 @@ exports['dissectUri() Dissect Uri "file:///data/minecraft/tags/blocks/bar.json" "path": "tags/blocks", "category": "tag/block", "ext": ".json", + "pack": "data", "until": "1.21", "namespace": "minecraft", "identifier": "bar", @@ -83,6 +90,7 @@ exports['dissectUri() Dissect Uri "file:///data/qux/dimension/foo/baz.json" in 1 "path": "dimension", "category": "dimension", "ext": ".json", + "pack": "data", "since": "1.16", "namespace": "qux", "identifier": "foo/baz" @@ -97,6 +105,7 @@ exports['dissectUri() with customResources Dissect Uri "file:///data/minecraft/a "path": "advancement", "category": "advancement", "ext": ".json", + "pack": "data", "since": "1.21", "namespace": "minecraft", "identifier": "foo" @@ -107,6 +116,7 @@ exports['dissectUri() with customResources Dissect Uri "file:///data/minecraft/l "path": "loot_tables", "category": "loot_table", "ext": ".json", + "pack": "data", "until": "1.21", "namespace": "minecraft", "identifier": "foo" @@ -117,6 +127,7 @@ exports['dissectUri() with customResources Dissect Uri "file:///data/qux/biome_m "path": "biome_modifiers", "category": "fabric:biome_modifier", "ext": ".json", + "pack": "data", "namespace": "qux", "identifier": "snowy" } @@ -126,6 +137,7 @@ exports['dissectUri() with customResources Dissect Uri "file:///data/qux/tags/cu "path": "tags/custom_registry", "category": "tag/custom_registry", "ext": ".json", + "pack": "data", "namespace": "qux", "identifier": "nested/bar" } diff --git a/__snapshots__/packages/java-edition/test-out/dependency/mcmeta.spec.js b/__snapshots__/packages/java-edition/test-out/dependency/mcmeta.spec.js index b742ad294..4108b56cb 100644 --- a/__snapshots__/packages/java-edition/test-out/dependency/mcmeta.spec.js +++ b/__snapshots__/packages/java-edition/test-out/dependency/mcmeta.spec.js @@ -26,49 +26,56 @@ exports['mcmeta resolveConfiguredVersion() Should resolve "1.16.5" 1'] = { "id": "1.16.5", "name": "1.16.5", "release": "1.16.5", - "isLatest": false + "isLatest": false, + "reason": "config" } exports['mcmeta resolveConfiguredVersion() Should resolve "20w06a" 1'] = { "id": "20w06a", "name": "Snapshot 20w06a", "release": "1.16", - "isLatest": false + "isLatest": false, + "reason": "config" } exports['mcmeta resolveConfiguredVersion() Should resolve "22w03a" 1'] = { "id": "22w03a", "name": "22w03a", "release": "1.18.2", - "isLatest": true + "isLatest": true, + "reason": "config" } exports['mcmeta resolveConfiguredVersion() Should resolve "Auto" 1'] = { "id": "1.16.5", "name": "1.16.5", "release": "1.16.5", - "isLatest": false + "isLatest": false, + "reason": "auto" } exports['mcmeta resolveConfiguredVersion() Should resolve "Latest Release" 1'] = { "id": "1.18.1", "name": "1.18.1", "release": "1.18.1", - "isLatest": false + "isLatest": false, + "reason": "config" } exports['mcmeta resolveConfiguredVersion() Should resolve "Latest Snapshot" 1'] = { "id": "22w03a", "name": "22w03a", "release": "1.18.2", - "isLatest": true + "isLatest": true, + "reason": "config" } exports['mcmeta resolveConfiguredVersion() Should resolve "unknown" 1'] = { "id": "22w03a", "name": "22w03a", "release": "1.18.2", - "isLatest": true + "isLatest": true, + "reason": "config" } exports['mcmeta symbolRegistrar() Should register correctly 1'] = ` diff --git a/packages/core/src/service/fileUtil.ts b/packages/core/src/service/fileUtil.ts index d508824b0..b028212ba 100644 --- a/packages/core/src/service/fileUtil.ts +++ b/packages/core/src/service/fileUtil.ts @@ -108,6 +108,14 @@ export namespace fileUtil { return i >= 0 ? uri.slice(i + 1) : uri } + /** + * @returns The part from the beginning of the URI to the last `/`. + */ + export function dirname(uri: string): string { + const i = uri.lastIndexOf('/') + return i >= 0 ? uri.slice(0, i) : uri + } + /* istanbul ignore next */ export function getParentOfFile(externals: Externals, path: FsLocation): FsLocation { return new Uri('.', path) diff --git a/packages/core/src/symbol/Symbol.ts b/packages/core/src/symbol/Symbol.ts index 33fa51231..e3eb70760 100644 --- a/packages/core/src/symbol/Symbol.ts +++ b/packages/core/src/symbol/Symbol.ts @@ -170,12 +170,12 @@ export const TagFileCategories = Object.freeze( ) export type TagFileCategory = (typeof TagFileCategories)[number] -export const FileCategories = Object.freeze( +export const DataFileCategories = Object.freeze( [...NormalFileCategories, ...TagFileCategories, ...WorldgenFileCategories] as const, ) -export type FileCategory = (typeof FileCategories)[number] +export type DataFileCategory = (typeof DataFileCategories)[number] -export const MiscCategories = Object.freeze( +export const DataMiscCategories = Object.freeze( [ 'attribute_modifier', 'bossbar', @@ -184,7 +184,7 @@ export const MiscCategories = Object.freeze( 'storage', ] as const, ) -export type MiscCategory = (typeof MiscCategories)[number] +export type DataMiscCategory = (typeof DataMiscCategories)[number] export const DatapackCategories = Object.freeze( [ @@ -193,22 +193,71 @@ export const DatapackCategories = Object.freeze( 'score_holder', 'tag', 'team', - ...FileCategories, - ...MiscCategories, + ...DataFileCategories, + ...DataMiscCategories, ] as const, ) export type DatapackCategory = (typeof DatapackCategories)[number] // #endregion +// #region Resource Pack Categories +export const AssetsFileCategories = Object.freeze( + [ + 'atlas', + 'block_definition', // blockstates + 'font', + 'font/ttf', + 'font/otf', + 'font/unihex', + 'lang', + 'model', + 'particle', + 'post_effect', + 'shader', + 'shader/fragment', + 'shader/vertex', + 'sound', + 'texture', + ] as const, +) +export type AssetsFileCategory = (typeof AssetsFileCategories)[number] + +export const AssetsMiscCategories = Object.freeze( + [ + 'shader_target', + ] as const, +) +export type AssetsMiscCategory = (typeof AssetsMiscCategories)[number] + +export const ResourcepackCategories = Object.freeze( + [ + ...AssetsMiscCategories, + ...AssetsFileCategories, + ] as const, +) +export type ResourcepackCategory = (typeof ResourcepackCategories)[number] +// #endregion + +export const FileCategories = Object.freeze( + [...DataFileCategories, ...AssetsFileCategories] as const, +) +export type FileCategory = (typeof FileCategories)[number] + export const AllCategories = Object.freeze( - [...DatapackCategories, ...McdocCategories, ...RegistryCategories] as const, + [ + ...DatapackCategories, + ...ResourcepackCategories, + ...McdocCategories, + ...RegistryCategories, + ] as const, ) export type AllCategory = (typeof AllCategories)[number] export const ResourceLocationCategories = Object.freeze( [ 'mcdoc/dispatcher', - ...MiscCategories, + ...DataMiscCategories, + ...AssetsMiscCategories, ...FileCategories, ...RegistryCategories, ] as const, diff --git a/packages/java-edition/src/binder/index.ts b/packages/java-edition/src/binder/index.ts index 6a73821c2..9f4778f11 100644 --- a/packages/java-edition/src/binder/index.ts +++ b/packages/java-edition/src/binder/index.ts @@ -20,21 +20,27 @@ interface Resource { path: string category: FileCategory ext: `.${string}` + pack: 'data' | 'assets' since?: ReleaseVersion until?: ReleaseVersion } -const Resources = new Map() +const Resources = new Map() function resource(path: string, resource: Partial & { category: FileCategory }): void function resource(path: FileCategory, resource: Partial): void function resource(path: string, resource: Partial = {}) { - Resources.set(path, { - path, - category: resource.category ?? path as FileCategory, - ext: resource.ext ?? '.json', - ...resource, - }) + const previous = Resources.get(path) ?? [] + Resources.set(path, [ + ...previous, + { + path, + category: resource.category ?? path as FileCategory, + ext: resource.ext ?? '.json', + pack: resource.pack ?? 'data', + ...resource, + }, + ]) } // Pre-1.21 data pack plurals @@ -120,6 +126,24 @@ for (const registry of TaggableResourceLocationCategories) { resource(`tags/${registry}`, { category: `tag/${registry}`, since: '1.18' }) } +// Resource pack +resource('atlases', { pack: 'assets', category: 'atlas', since: '1.19.3' }) +resource('blockstates', { pack: 'assets', category: 'block_definition' }) +resource('fonts', { pack: 'assets', category: 'font', since: '1.16' }) +resource('fonts', { pack: 'assets', category: 'font/ttf', since: '1.16', ext: '.ttf' }) +resource('fonts', { pack: 'assets', category: 'font/otf', since: '1.16', ext: '.otf' }) +resource('fonts', { pack: 'assets', category: 'font/unihex', since: '1.20', ext: '.zip' }) +resource('lang', { pack: 'assets', category: 'lang' }) +resource('models', { pack: 'assets', category: 'model' }) +resource('particles', { pack: 'assets', category: 'particle' }) +resource('post_effect', { pack: 'assets', since: '1.21.2' }) +resource('shaders/post', { pack: 'assets', category: 'post_effect', until: '1.21.2' }) +resource('shaders', { pack: 'assets', category: 'shader' }) +resource('shaders', { pack: 'assets', category: 'shader/fragment', ext: '.fsh' }) +resource('shaders', { pack: 'assets', category: 'shader/vertex', ext: '.vsh' }) +resource('sounds', { pack: 'assets', category: 'sound', ext: '.ogg' }) +resource('textures', { pack: 'assets', category: 'texture', ext: '.png' }) + export function* getRels( uri: string, rootUris: readonly RootUriString[], @@ -128,7 +152,7 @@ export function* getRels( const parts = uri.split('/') for (let i = parts.length - 2; i >= 0; i--) { - if (parts[i] === 'data') { // TODO: support assets + if (parts[i] === 'data' || parts[i] === 'assets') { yield parts.slice(i).join('/') } } @@ -149,30 +173,38 @@ export function dissectUri(uri: string, ctx: UriBinderContext) { continue } const [pack, namespace, ...rest] = parts - if (pack !== 'data') { - continue // TODO: support assets + if (pack !== 'data' && pack !== 'assets') { + continue } - let resource: Resource | undefined = undefined - let matchIndex = 0 + const candidateResources: [Resource, string][] = [] for (let i = 1; i < rest.length; i += 1) { - const res = Resources.get(rest.slice(0, i).join('/')) - if (res) { - resource = res - matchIndex = i + const resources = Resources.get(rest.slice(0, i).join('/')) + for (const res of resources ?? []) { + if (res.pack !== pack) { + continue + } + let identifier = rest.slice(i).join('/') + if (!identifier.endsWith(res.ext)) { + continue + } + identifier = identifier.slice(0, -res.ext.length) + candidateResources.push([res, identifier]) } } - if (!resource) { + if (candidateResources.length === 0) { continue } - let identifier = rest.slice(matchIndex).join('/') - if (!identifier.endsWith(resource.ext)) { - continue + // Finding the last, because that will be the deepest match + let res = candidateResources.findLast(([res]) => matchVersion(release, res.since, res.until)) + if (res !== undefined) { + return { ok: true, ...res[0], namespace, identifier: res[1], expected: undefined } } - identifier = identifier.slice(0, -resource.ext.length) - if (!matchVersion(release, resource.since, resource.until)) { - let expected: string | undefined = undefined - for (const [path, other] of Resources) { - if (other.category !== resource.category) { + // Try to find the expected path that matches the current version + res = candidateResources[candidateResources.length - 1] + let expected: string | undefined = undefined + for (const [path, others] of Resources) { + for (const other of others) { + if (other.category !== res[0].category) { continue } if (matchVersion(release, other.since, other.until)) { @@ -180,9 +212,8 @@ export function dissectUri(uri: string, ctx: UriBinderContext) { break } } - return { ok: false, ...resource, namespace, identifier, expected } } - return { ok: true, ...resource, namespace, identifier, expected: undefined } + return { ok: false, ...res[0], namespace, identifier: res[1], expected } } return undefined diff --git a/packages/java-edition/src/dependency/common.ts b/packages/java-edition/src/dependency/common.ts index d7be31cbf..f6b5ba16f 100644 --- a/packages/java-edition/src/dependency/common.ts +++ b/packages/java-edition/src/dependency/common.ts @@ -1,3 +1,5 @@ +import type * as core from '@spyglassmc/core' + export type ReleaseVersion = `1.${number}` export namespace ReleaseVersion { /** @@ -23,11 +25,14 @@ export namespace ReleaseVersion { } } +export type VersionInfoReason = 'auto' | 'config' | 'fallback' + export interface VersionInfo { release: ReleaseVersion id: string name: string isLatest: boolean + reason: VersionInfoReason } export interface PackMcmeta { @@ -40,4 +45,18 @@ export namespace PackMcmeta { throw new Error('“pack.pack_format” undefined') } } + + export async function getType(packRoot: string, externals: core.Externals) { + const dir = await externals.fs.readdir(packRoot) + const isResourcePack = dir.some(e => e.isDirectory() && e.name === 'assets') + && !dir.some(e => e.isDirectory() && e.name === 'data') + return isResourcePack ? 'assets' : 'data' + } +} + +export interface PackInfo { + type: 'data' | 'assets' + packRoot: string + packMcmeta: PackMcmeta | undefined + versionInfo: VersionInfo } diff --git a/packages/java-edition/src/dependency/mcmeta.ts b/packages/java-edition/src/dependency/mcmeta.ts index 4be61e942..616cb38e9 100644 --- a/packages/java-edition/src/dependency/mcmeta.ts +++ b/packages/java-edition/src/dependency/mcmeta.ts @@ -1,14 +1,17 @@ import * as core from '@spyglassmc/core' -import type { PackMcmeta, ReleaseVersion, VersionInfo } from './common.js' +import type { PackMcmeta, ReleaseVersion, VersionInfo, VersionInfoReason } from './common.js' + +// DOCS: Update this when a new snapshot cycle begins +export const NEXT_RELEASE_VERSION = '1.21.2' /** * @param inputVersion {@link core.Config.env.gameVersion} */ -export async function resolveConfiguredVersion( +export function resolveConfiguredVersion( inputVersion: string, versions: McmetaVersions, - getPackMcmeta: () => Promise, -): Promise { + packMcmeta: PackMcmeta | undefined, +): VersionInfo { function findReleaseTarget(version: McmetaVersion): string { if (version.release_target) { return version.release_target @@ -22,17 +25,20 @@ export async function resolveConfiguredVersion( return versions[i].id } } - // DOCS: Update this when a new snapshot cycle begins - return '1.21.2' + return NEXT_RELEASE_VERSION } - function toVersionInfo(version: McmetaVersion | undefined): VersionInfo { + function toVersionInfo( + version: McmetaVersion | undefined, + reason: VersionInfoReason, + ): VersionInfo { version = version ?? versions[0] return { id: version.id, name: version.name, release: findReleaseTarget(version) as ReleaseVersion, isLatest: version === versions[0], + reason, } } @@ -44,40 +50,41 @@ export async function resolveConfiguredVersion( versions = versions.sort((a, b) => b.data_version - a.data_version) const latestRelease = versions.find((v) => v.type === 'release') if (inputVersion === 'auto') { - const packMcmeta = await getPackMcmeta() - if (packMcmeta && latestRelease) { + const packFormat = packMcmeta?.pack.pack_format + if (packFormat && latestRelease) { // If the pack format is larger than the latest release, use the latest snapshot - if (packMcmeta.pack.pack_format > latestRelease.data_pack_version) { - return toVersionInfo(versions[0]) + if (packFormat > latestRelease.data_pack_version) { + return toVersionInfo(versions[0], 'auto') } // Look for versions from recent to oldest, picking the most recent release that matches let oldestRelease = undefined for (const version of versions) { if (version.type === 'release') { // If we already passed the pack format, use the oldest release so far - if (packMcmeta.pack.pack_format > version.data_pack_version) { - return toVersionInfo(oldestRelease) + if (packFormat > version.data_pack_version) { + return toVersionInfo(oldestRelease, 'auto') } - if (packMcmeta.pack.pack_format === version.data_pack_version) { - return toVersionInfo(version) + if (packFormat === version.data_pack_version) { + return toVersionInfo(version, 'auto') } oldestRelease = version } } // If the pack format is still lower, use the oldest known release version - return toVersionInfo(oldestRelease) + return toVersionInfo(oldestRelease, 'auto') } // Fall back to the latest release if pack mcmeta is not available - return toVersionInfo(latestRelease) + return toVersionInfo(latestRelease, 'fallback') } else if (inputVersion === 'latest release') { - return toVersionInfo(latestRelease) + return toVersionInfo(latestRelease, 'config') } else if (inputVersion === 'latest snapshot') { - return toVersionInfo(versions[0]) + return toVersionInfo(versions[0], 'config') } return toVersionInfo( versions.find((v) => inputVersion === v.id.toLowerCase() || inputVersion === v.name.toLowerCase() ), + 'config', ) } diff --git a/packages/java-edition/src/index.ts b/packages/java-edition/src/index.ts index 9bbb6a2dd..7c4ca8f4f 100644 --- a/packages/java-edition/src/index.ts +++ b/packages/java-edition/src/index.ts @@ -4,12 +4,13 @@ import { localize } from '@spyglassmc/locales' import * as mcdoc from '@spyglassmc/mcdoc' import * as nbt from '@spyglassmc/nbt' import { uriBinder } from './binder/index.js' -import type { McmetaSummary, McmetaVersion } from './dependency/index.js' +import type { McmetaSummary, McmetaVersion, McmetaVersions, PackInfo } from './dependency/index.js' import { getMcmetaSummary, getVanillaDatapack, getVanillaMcdoc, getVersions, + NEXT_RELEASE_VERSION, PackMcmeta, ReleaseVersion, resolveConfiguredVersion, @@ -40,28 +41,32 @@ export const initialize: core.ProjectInitializer = async (ctx) => { return undefined } - async function findPackMcmeta(): Promise { - const searched = new Set() + async function findPackMcmetas(versions: McmetaVersions): Promise { + const searchedUris = new Set() + const packs: PackInfo[] = [] for (let depth = 0; depth <= 2; depth += 1) { for (const projectRoot of projectRoots) { const files = await core.fileUtil.getAllFiles(externals, projectRoot, depth + 1) for (const uri of files.filter(uri => uri.endsWith('/pack.mcmeta'))) { - if (searched.has(uri)) { + if (searchedUris.has(uri)) { continue } - searched.add(uri) - const data = await readPackMcmeta(uri) - if (data) { - logger.info( - `[je.initialize] Found a valid pack.mcmeta ${uri} with pack_format ${data.pack.pack_format}`, - ) - return data - } + searchedUris.add(uri) + const packRoot = core.fileUtil.dirname(uri) + const [packMcmeta, type] = await Promise.all([ + readPackMcmeta(uri), + PackMcmeta.getType(packRoot, externals), + ]) + const versionInfo = resolveConfiguredVersion( + config.env.gameVersion, + versions, + packMcmeta, + ) + packs.push({ type, packRoot, packMcmeta, versionInfo }) } } } - logger.warn('[je.initialize] Failed finding a valid pack.mcmeta') - return undefined + return packs } meta.registerUriBinder(uriBinder) @@ -74,7 +79,31 @@ export const initialize: core.ProjectInitializer = async (ctx) => { return } - const version = await resolveConfiguredVersion(config.env.gameVersion, versions, findPackMcmeta) + const packs = await findPackMcmetas(versions) + + function selectVersionInfo(packs: PackInfo[], versions: McmetaVersions) { + // Select the first valid data pack.mcmeta + const pack = packs.find(p => p.packMcmeta !== undefined && p.type === 'data') + const version = pack === undefined + ? resolveConfiguredVersion(config.env.gameVersion, versions, undefined) + : pack.versionInfo + const packMessage = pack === undefined + ? 'Failed finding a valid pack.mcmeta' + : `Found a valid pack.mcmeta ${pack.packRoot}/pack.mcmeta` + const reasonMessage = pack && version.reason === 'auto' + ? `using pack format ${pack.packMcmeta?.pack.pack_format} to select` + : version.reason === 'config' + ? `but using config override "${config.env.gameVersion}" to select` + : version.reason === 'fallback' + ? 'using fallback' + : 'loading' // should never occur + const versionMessage = `version ${version.release}${ + version.id === version.release ? '' : ` (${version.id})` + }` + ctx.logger.info(`[je.initialize] ${packMessage}, ${reasonMessage} ${versionMessage}`) + return version + } + const version = selectVersionInfo(packs, versions) const release = version.release meta.registerDependencyProvider( @@ -159,12 +188,29 @@ export const initialize: core.ProjectInitializer = async (ctx) => { }, }, ) - const packFormats = new Map() + + const dataFormats = new Map() + const assetsFormats = new Map() + if (versions[0]?.type !== 'release') { + dataFormats.set(versions[0].data_pack_version, [NEXT_RELEASE_VERSION]) + assetsFormats.set(versions[0].resource_pack_version, [NEXT_RELEASE_VERSION]) + } for (const version of versions) { - if (version.type === 'release' && !packFormats.has(version.data_pack_version)) { - packFormats.set(version.data_pack_version, version) + if (version.type === 'release') { + dataFormats.set(version.data_pack_version, [ + ...dataFormats.get(version.data_pack_version) ?? [], + version.id, + ]) + assetsFormats.set(version.resource_pack_version, [ + ...assetsFormats.get(version.resource_pack_version) ?? [], + version.id, + ]) } } + function getFormats(packMcmetaUri: string) { + const thisPack = packs.find(p => core.fileUtil.isSubUriOf(packMcmetaUri, p.packRoot)) + return thisPack?.type === 'assets' ? assetsFormats : dataFormats + } mcdoc.runtime.registerAttribute(meta, 'pack_format', () => undefined, { checker: (_, typeDef) => { if (typeDef.kind !== 'literal' || typeof typeDef.value.value !== 'number') { @@ -172,14 +218,14 @@ export const initialize: core.ProjectInitializer = async (ctx) => { } const target = typeDef.value.value return (node, ctx) => { - const targetVersion = packFormats.get(target) - if (!targetVersion) { + const targetVersions = getFormats(ctx.doc.uri).get(target) + if (!targetVersions) { ctx.err.report( localize('java-edition.pack-format.unsupported', target), node, core.ErrorSeverity.Warning, ) - } else if (targetVersion.id !== release) { + } else if (!targetVersions.some(v => v === release)) { ctx.err.report( localize('java-edition.pack-format.not-loaded', target, release), node, @@ -189,10 +235,10 @@ export const initialize: core.ProjectInitializer = async (ctx) => { } }, numericCompleter: (_, ctx) => { - return [...packFormats.values()].map((v, i) => ({ + return [...getFormats(ctx.doc.uri).entries()].map(([k, v], i) => ({ range: core.Range.create(ctx.offset), - label: `${v.data_pack_version}`, - labelSuffix: ` (${v.id})`, + label: `${k}`, + labelSuffix: ` (${v[0]})`, sortText: `${i}`.padStart(4, '0'), } satisfies core.CompletionItem)) }, diff --git a/packages/java-edition/test/dependency/mcmeta.spec.ts b/packages/java-edition/test/dependency/mcmeta.spec.ts index ef263fdc4..e0b4a75e3 100644 --- a/packages/java-edition/test/dependency/mcmeta.spec.ts +++ b/packages/java-edition/test/dependency/mcmeta.spec.ts @@ -52,10 +52,10 @@ describe('mcmeta', () => { ] for (const { version, packMcmeta } of suites) { it(`Should resolve "${version}"`, async () => { - const actual = await resolveConfiguredVersion( + const actual = resolveConfiguredVersion( version, Fixtures.Versions, - async () => packMcmeta, + packMcmeta, ) snapshot(actual) }) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 66e586a9d..7d35d535f 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -83,6 +83,14 @@ { "fileMatch": [ "pack.mcmeta", + "assets/*/atlases/**/*.json", + "assets/*/blockstates/**/*.json", + "assets/*/fonts/**/*.json", + "assets/*/lang/**/*.json", + "assets/*/models/**/*.json", + "assets/*/particles/**/*.json", + "assets/*/post_effect/**/*.json", + "assets/*/shaders/**/*.json", "data/*/advancement/**/*.json", "data/*/advancements/**/*.json", "data/*/banner_pattern/**/*.json", diff --git a/packages/vscode-extension/src/extension.mts b/packages/vscode-extension/src/extension.mts index ccae4e534..d008c5122 100644 --- a/packages/vscode-extension/src/extension.mts +++ b/packages/vscode-extension/src/extension.mts @@ -44,6 +44,7 @@ export async function activate(context: vsc.ExtensionContext) { { language: 'snbt' }, { language: 'mcmeta' }, { language: 'json', pattern: '**/data/*/*/**/*.json' }, + { language: 'json', pattern: '**/assets/*/*/**/*.json' }, ] const gameVersion = vsc.workspace.getConfiguration('spyglassmc.env').get('gameVersion')