@spyglassmc/java-edition 0.3.38 → 0.3.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ export declare function dissectUri(uri: string, ctx: UriBinderContext): {
17
17
  namespace: string;
18
18
  identifier: string;
19
19
  path: string;
20
- category: "function" | "advancement" | "banner_pattern" | "cat_variant" | "chat_type" | "cow_variant" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "frog_variant" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "pig_variant" | "predicate" | "recipe" | "structure" | "test_environment" | "test_instance" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_sound_variant" | "wolf_variant" | "tag/function" | "tag/activity" | "tag/armor_material" | "tag/attribute" | "tag/block" | "tag/block_entity_type" | "tag/block_predicate_type" | "tag/block_type" | "tag/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_predicate_type" | "tag/data_component_type" | "tag/decorated_pot_pattern" | "tag/decorated_pot_patterns" | "tag/enchantment_effect_component_type" | "tag/enchantment_entity_effect_type" | "tag/enchantment_level_based_value_type" | "tag/enchantment_location_based_effect_type" | "tag/enchantment_provider_type" | "tag/enchantment_value_effect_type" | "tag/entity_sub_predicate_type" | "tag/entity_type" | "tag/float_provider_type" | "tag/fluid" | "tag/game_event" | "tag/height_provider_type" | "tag/instrument" | "tag/int_provider_type" | "tag/item" | "tag/item_sub_predicate_type" | "tag/loot_condition_type" | "tag/loot_function_type" | "tag/loot_nbt_provider_type" | "tag/loot_number_provider_type" | "tag/loot_pool_entry_type" | "tag/loot_score_provider_type" | "tag/map_decoration_type" | "tag/memory_module_type" | "tag/menu" | "tag/mob_effect" | "tag/motive" | "tag/number_format_type" | "tag/particle_type" | "tag/point_of_interest_type" | "tag/pos_rule_test" | "tag/position_source_type" | "tag/potion" | "tag/recipe_book_category" | "tag/recipe_display" | "tag/recipe_serializer" | "tag/recipe_type" | "tag/rule_block_entity_modifier" | "tag/rule_test" | "tag/schedule" | "tag/sensor_type" | "tag/slot_display" | "tag/sound_event" | "tag/spawn_condition_type" | "tag/stat_type" | "tag/test_environment_definition_type" | "tag/test_function" | "tag/test_instance_type" | "tag/trigger_type" | "tag/ticket_type" | "tag/villager_profession" | "tag/villager_type" | "tag/worldgen/biome_source" | "tag/worldgen/block_placer_type" | "tag/worldgen/block_state_provider_type" | "tag/worldgen/carver" | "tag/worldgen/chunk_generator" | "tag/worldgen/decorator" | "tag/worldgen/density_function_type" | "tag/worldgen/feature" | "tag/worldgen/feature_size_type" | "tag/worldgen/foliage_placer_type" | "tag/worldgen/material_condition" | "tag/worldgen/material_rule" | "tag/worldgen/placement_modifier_type" | "tag/worldgen/pool_alias_binding" | "tag/worldgen/root_placer_type" | "tag/worldgen/structure_feature" | "tag/worldgen/structure_piece" | "tag/worldgen/structure_placement" | "tag/worldgen/structure_pool_element" | "tag/worldgen/structure_processor" | "tag/worldgen/structure_type" | "tag/worldgen/surface_builder" | "tag/worldgen/tree_decorator_type" | "tag/worldgen/trunk_placer_type" | "tag/advancement" | "tag/banner_pattern" | "tag/cat_variant" | "tag/chat_type" | "tag/cow_variant" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/frog_variant" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/pig_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/test_environment" | "tag/test_instance" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_sound_variant" | "tag/wolf_variant" | "tag/worldgen/biome" | "tag/worldgen/configured_carver" | "tag/worldgen/configured_feature" | "tag/worldgen/configured_structure_feature" | "tag/worldgen/configured_surface_builder" | "tag/worldgen/density_function" | "tag/worldgen/flat_level_generator_preset" | "tag/worldgen/multi_noise_biome_source_parameter_list" | "tag/worldgen/noise" | "tag/worldgen/noise_settings" | "tag/worldgen/placed_feature" | "tag/worldgen/processor_list" | "tag/worldgen/structure" | "tag/worldgen/structure_set" | "tag/worldgen/template_pool" | "tag/worldgen/world_preset" | "worldgen/biome" | "worldgen/configured_carver" | "worldgen/configured_feature" | "worldgen/configured_structure_feature" | "worldgen/configured_surface_builder" | "worldgen/density_function" | "worldgen/flat_level_generator_preset" | "worldgen/multi_noise_biome_source_parameter_list" | "worldgen/noise" | "worldgen/noise_settings" | "worldgen/placed_feature" | "worldgen/processor_list" | "worldgen/structure" | "worldgen/structure_set" | "worldgen/template_pool" | "worldgen/world_preset" | "atlas" | "block_definition" | "equipment" | "font" | "font/ttf" | "font/otf" | "font/unihex" | "gpu_warnlist" | "item_definition" | "lang" | "lang/deprecated" | "model" | "particle" | "post_effect" | "regional_compliancies" | "shader" | "shader/fragment" | "shader/vertex" | "sound" | "sounds" | "texture" | "texture_meta";
20
+ category: "function" | "advancement" | "banner_pattern" | "cat_variant" | "chat_type" | "cow_variant" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "frog_variant" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "pig_variant" | "predicate" | "recipe" | "structure" | "test_environment" | "test_instance" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_sound_variant" | "wolf_variant" | "tag/function" | "tag/activity" | "tag/armor_material" | "tag/attribute" | "tag/block" | "tag/block_entity_type" | "tag/block_predicate_type" | "tag/block_type" | "tag/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_predicate_type" | "tag/data_component_type" | "tag/decorated_pot_pattern" | "tag/decorated_pot_patterns" | "tag/enchantment_effect_component_type" | "tag/enchantment_entity_effect_type" | "tag/enchantment_level_based_value_type" | "tag/enchantment_location_based_effect_type" | "tag/enchantment_provider_type" | "tag/enchantment_value_effect_type" | "tag/entity_sub_predicate_type" | "tag/entity_type" | "tag/float_provider_type" | "tag/fluid" | "tag/game_event" | "tag/height_provider_type" | "tag/instrument" | "tag/int_provider_type" | "tag/item" | "tag/item_sub_predicate_type" | "tag/loot_condition_type" | "tag/loot_function_type" | "tag/loot_nbt_provider_type" | "tag/loot_number_provider_type" | "tag/loot_pool_entry_type" | "tag/loot_score_provider_type" | "tag/map_decoration_type" | "tag/memory_module_type" | "tag/menu" | "tag/mob_effect" | "tag/motive" | "tag/number_format_type" | "tag/particle_type" | "tag/point_of_interest_type" | "tag/pos_rule_test" | "tag/position_source_type" | "tag/potion" | "tag/recipe_book_category" | "tag/recipe_display" | "tag/recipe_serializer" | "tag/recipe_type" | "tag/rule_block_entity_modifier" | "tag/rule_test" | "tag/schedule" | "tag/sensor_type" | "tag/slot_display" | "tag/sound_event" | "tag/spawn_condition_type" | "tag/stat_type" | "tag/test_environment_definition_type" | "tag/test_function" | "tag/test_instance_type" | "tag/trigger_type" | "tag/ticket_type" | "tag/villager_profession" | "tag/villager_type" | "tag/worldgen/biome_source" | "tag/worldgen/block_placer_type" | "tag/worldgen/block_state_provider_type" | "tag/worldgen/carver" | "tag/worldgen/chunk_generator" | "tag/worldgen/decorator" | "tag/worldgen/density_function_type" | "tag/worldgen/feature" | "tag/worldgen/feature_size_type" | "tag/worldgen/foliage_placer_type" | "tag/worldgen/material_condition" | "tag/worldgen/material_rule" | "tag/worldgen/placement_modifier_type" | "tag/worldgen/pool_alias_binding" | "tag/worldgen/root_placer_type" | "tag/worldgen/structure_feature" | "tag/worldgen/structure_piece" | "tag/worldgen/structure_placement" | "tag/worldgen/structure_pool_element" | "tag/worldgen/structure_processor" | "tag/worldgen/structure_type" | "tag/worldgen/surface_builder" | "tag/worldgen/tree_decorator_type" | "tag/worldgen/trunk_placer_type" | "tag/advancement" | "tag/banner_pattern" | "tag/cat_variant" | "tag/chat_type" | "tag/cow_variant" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/frog_variant" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/pig_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/test_environment" | "tag/test_instance" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_sound_variant" | "tag/wolf_variant" | "tag/worldgen/biome" | "tag/worldgen/configured_carver" | "tag/worldgen/configured_feature" | "tag/worldgen/configured_structure_feature" | "tag/worldgen/configured_surface_builder" | "tag/worldgen/density_function" | "tag/worldgen/flat_level_generator_preset" | "tag/worldgen/multi_noise_biome_source_parameter_list" | "tag/worldgen/noise" | "tag/worldgen/noise_settings" | "tag/worldgen/placed_feature" | "tag/worldgen/processor_list" | "tag/worldgen/structure" | "tag/worldgen/structure_set" | "tag/worldgen/template_pool" | "tag/worldgen/world_preset" | "worldgen/biome" | "worldgen/configured_carver" | "worldgen/configured_feature" | "worldgen/configured_structure_feature" | "worldgen/configured_surface_builder" | "worldgen/density_function" | "worldgen/flat_level_generator_preset" | "worldgen/multi_noise_biome_source_parameter_list" | "worldgen/noise" | "worldgen/noise_settings" | "worldgen/placed_feature" | "worldgen/processor_list" | "worldgen/structure" | "worldgen/structure_set" | "worldgen/template_pool" | "worldgen/world_preset" | "atlas" | "block_definition" | "equipment" | "font" | "font/ttf" | "font/otf" | "font/unihex" | "gpu_warnlist" | "item_definition" | "lang" | "lang/deprecated" | "model" | "particle" | "post_effect" | "regional_compliancies" | "shader" | "shader/fragment" | "shader/vertex" | "sound" | "sounds" | "texture" | "texture_meta" | "waypoint_style";
21
21
  ext: `.${string}`;
22
22
  pack: "assets" | "data";
23
23
  since?: `1.${number}` | undefined;
@@ -126,6 +126,7 @@ resource('shaders', { pack: 'assets', category: 'shader/vertex', ext: '.vsh' });
126
126
  resource('sounds', { pack: 'assets', category: 'sound', ext: '.ogg' });
127
127
  resource('textures', { pack: 'assets', category: 'texture', ext: '.png' });
128
128
  resource('textures', { pack: 'assets', category: 'texture_meta', ext: '.png.mcmeta' });
129
+ resource('waypoint_style', { pack: 'assets', since: '1.21.6' });
129
130
  resource('lang', { pack: 'assets', category: 'lang/deprecated', identifier: 'deprecated' });
130
131
  resource('', { pack: 'assets', category: 'sounds', identifier: 'sounds' });
131
132
  resource('', {
@@ -14,27 +14,19 @@ export declare namespace ReleaseVersion {
14
14
  */
15
15
  function isBetween(version: ReleaseVersion, since: ReleaseVersion, until: ReleaseVersion): boolean;
16
16
  }
17
- export type VersionInfoReason = 'auto' | 'config' | 'fallback';
18
17
  export interface VersionInfo {
19
18
  release: ReleaseVersion;
20
19
  id: string;
21
20
  name: string;
22
21
  isLatest: boolean;
23
- reason: VersionInfoReason;
24
- }
25
- export interface PackMcmeta {
26
- pack: {
27
- pack_format: number;
28
- };
29
22
  }
30
23
  export declare namespace PackMcmeta {
31
- function assert(data: any): asserts data is PackMcmeta;
24
+ function readPackFormat(data: any): number;
32
25
  function getType(packRoot: string, externals: core.Externals): Promise<"assets" | "data">;
33
26
  }
34
27
  export interface PackInfo {
35
28
  type: 'data' | 'assets';
36
29
  packRoot: string;
37
- packMcmeta: PackMcmeta | undefined;
38
- versionInfo: VersionInfo;
30
+ format: number;
39
31
  }
40
32
  //# sourceMappingURL=common.d.ts.map
@@ -21,13 +21,21 @@ export var ReleaseVersion;
21
21
  })(ReleaseVersion || (ReleaseVersion = {}));
22
22
  export var PackMcmeta;
23
23
  (function (PackMcmeta) {
24
- function assert(data) {
25
- const format = data?.pack?.pack_format?.toString();
26
- if (!format) {
27
- throw new Error('“pack.pack_format” undefined');
24
+ function readPackFormat(data) {
25
+ const supported = data?.pack?.supported_formats;
26
+ if (Array.isArray(supported) && supported.length === 2 && typeof supported[1] === 'number') {
27
+ return supported[1];
28
28
  }
29
+ if (typeof supported === 'object' && typeof supported?.max_inclusive === 'number') {
30
+ return supported.max_inclusive;
31
+ }
32
+ const format = data?.pack?.pack_format;
33
+ if (typeof format === 'number') {
34
+ return format;
35
+ }
36
+ throw new Error('“pack.pack_format” is not a number');
29
37
  }
30
- PackMcmeta.assert = assert;
38
+ PackMcmeta.readPackFormat = readPackFormat;
31
39
  async function getType(packRoot, externals) {
32
40
  const dir = await externals.fs.readdir(packRoot);
33
41
  const isResourcePack = dir.some(e => e.isDirectory() && e.name === 'assets')
@@ -1,11 +1,11 @@
1
1
  import * as core from '@spyglassmc/core';
2
- import type { PackMcmeta, VersionInfo } from './common.js';
2
+ import type { PackInfo, VersionInfo } from './common.js';
3
3
  import { ReleaseVersion } from './common.js';
4
4
  export declare const NEXT_RELEASE_VERSION = "1.21.6";
5
5
  /**
6
6
  * @param inputVersion {@link core.Config.env.gameVersion}
7
7
  */
8
- export declare function resolveConfiguredVersion(inputVersion: string, versions: McmetaVersions, packMcmeta: PackMcmeta | undefined, packType: 'assets' | 'data' | undefined, logger: core.Logger): VersionInfo;
8
+ export declare function resolveConfiguredVersion(inputVersion: string, versions: McmetaVersions, packs: PackInfo[], logger: core.Logger): VersionInfo;
9
9
  export declare function getMcmetaSummaryUris(version: string, isLatest: boolean, source: string): {
10
10
  blocks: core.RemoteUriString;
11
11
  commands: core.RemoteUriString;
@@ -5,7 +5,7 @@ export const NEXT_RELEASE_VERSION = '1.21.6';
5
5
  /**
6
6
  * @param inputVersion {@link core.Config.env.gameVersion}
7
7
  */
8
- export function resolveConfiguredVersion(inputVersion, versions, packMcmeta, packType, logger) {
8
+ export function resolveConfiguredVersion(inputVersion, versions, packs, logger) {
9
9
  function findReleaseTarget(version) {
10
10
  if (version.release_target) {
11
11
  return version.release_target;
@@ -21,14 +21,13 @@ export function resolveConfiguredVersion(inputVersion, versions, packMcmeta, pac
21
21
  }
22
22
  return NEXT_RELEASE_VERSION;
23
23
  }
24
- function toVersionInfo(version, reason) {
24
+ function toVersionInfo(version) {
25
25
  version = version ?? versions[0];
26
26
  return {
27
27
  id: version.id,
28
28
  name: version.name,
29
29
  release: findReleaseTarget(version),
30
30
  isLatest: version === versions[0],
31
- reason,
32
31
  };
33
32
  }
34
33
  if (versions.length === 0) {
@@ -44,45 +43,52 @@ export function resolveConfiguredVersion(inputVersion, versions, packMcmeta, pac
44
43
  versions = versions.sort((a, b) => b.data_version - a.data_version);
45
44
  const latestRelease = versions.find((v) => v.type === 'release');
46
45
  if (inputVersion === 'auto') {
47
- const packFormat = packMcmeta?.pack.pack_format;
48
- if (packFormat && latestRelease) {
49
- // If the pack format is larger than the latest release, use the latest snapshot
50
- if (packFormat > (packType === 'assets'
51
- ? latestRelease.resource_pack_version
52
- : latestRelease.data_pack_version)) {
53
- return toVersionInfo(versions[0], 'auto');
46
+ if (packs.length === 0) {
47
+ // Fall back to the latest release if pack mcmeta is not available
48
+ logger.info(`[resolveConfiguredVersion] No pack format detected, selecting latest release ${latestRelease?.id}`);
49
+ return toVersionInfo(latestRelease);
50
+ }
51
+ packs.sort((a, b) => b.format - a.format);
52
+ const maxData = packs.filter(p => p.type === 'data')[0];
53
+ const maxAssets = packs.filter(p => p.type === 'assets')[0];
54
+ // Look for versions from recent to oldest, picking the most recent release that matches
55
+ let oldestRelease = versions[0];
56
+ const releases = versions.filter(v => v.type === 'release');
57
+ for (const version of releases) {
58
+ // If we already passed the pack format, use the oldest release so far
59
+ if (maxData && maxData.format > version.data_pack_version) {
60
+ logger.info(`[resolveConfiguredVersion] Detected data pack format ${maxData.format} in ${maxData.packRoot}, selecting version ${oldestRelease.id}`);
61
+ return toVersionInfo(oldestRelease);
54
62
  }
55
- // Look for versions from recent to oldest, picking the most recent release that matches
56
- let oldestRelease = undefined;
57
- for (const version of versions) {
58
- if (version.type === 'release') {
59
- // If we already passed the pack format, use the oldest release so far
60
- if (packFormat > (packType === 'assets'
61
- ? version.resource_pack_version
62
- : version.data_pack_version)) {
63
- return toVersionInfo(oldestRelease, 'auto');
64
- }
65
- if (packFormat === (packType === 'assets'
66
- ? version.resource_pack_version
67
- : version.data_pack_version)) {
68
- return toVersionInfo(version, 'auto');
69
- }
70
- oldestRelease = version;
71
- }
63
+ if (maxAssets && maxAssets.format > version.resource_pack_version) {
64
+ logger.info(`[resolveConfiguredVersion] Detected resource pack format ${maxAssets.format} in ${maxAssets.packRoot}, selecting version ${oldestRelease.id}`);
65
+ return toVersionInfo(oldestRelease);
66
+ }
67
+ if (maxData && maxData.format === version.data_pack_version) {
68
+ logger.info(`[resolveConfiguredVersion] Detected data pack format ${maxData.format} in ${maxData.packRoot}, selecting version ${version.id}`);
69
+ return toVersionInfo(version);
70
+ }
71
+ if (maxAssets && maxAssets.format === version.resource_pack_version) {
72
+ logger.info(`[resolveConfiguredVersion] Detected resource pack format ${maxAssets.format} in ${maxAssets.packRoot}, selecting version ${version.id}`);
73
+ return toVersionInfo(version);
72
74
  }
73
- // If the pack format is still lower, use the oldest known release version
74
- return toVersionInfo(oldestRelease, 'auto');
75
+ oldestRelease = version;
75
76
  }
76
- // Fall back to the latest release if pack mcmeta is not available
77
- return toVersionInfo(latestRelease, 'fallback');
77
+ // If the pack format is still lower, use the oldest known release version
78
+ logger.info(`[resolveConfiguredVersion] Detected pack format too low, selecting oldest supported release ${oldestRelease?.id}`);
79
+ return toVersionInfo(oldestRelease);
78
80
  }
79
81
  else if (inputVersion === 'latest release') {
80
- return toVersionInfo(latestRelease, 'config');
82
+ logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${latestRelease?.id}`);
83
+ return toVersionInfo(latestRelease);
81
84
  }
82
85
  else if (inputVersion === 'latest snapshot') {
83
- return toVersionInfo(versions[0], 'config');
86
+ logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${versions[0]?.id}`);
87
+ return toVersionInfo(versions[0]);
84
88
  }
85
- return toVersionInfo(versions.find((v) => inputVersion === v.id.toLowerCase() || inputVersion === v.name.toLowerCase()), 'config');
89
+ const configVersion = versions.find((v) => inputVersion === v.id.toLowerCase() || inputVersion === v.name.toLowerCase());
90
+ logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${configVersion?.id}`);
91
+ return toVersionInfo(configVersion);
86
92
  }
87
93
  const DataSources = {
88
94
  fastly: 'https://fastly.jsdelivr.net/gh/${user}/${repo}@${tag}/${path}',
package/lib/index.js CHANGED
@@ -14,11 +14,10 @@ export * from './mcdocAttributes.js';
14
14
  export * as mcf from './mcfunction/index.js';
15
15
  export const initialize = async (ctx) => {
16
16
  const { config, downloader, externals, logger, meta, projectRoots } = ctx;
17
- async function readPackMcmeta(uri) {
17
+ async function readPackFormat(uri) {
18
18
  try {
19
19
  const data = await core.fileUtil.readJson(externals, uri);
20
- PackMcmeta.assert(data);
21
- return data;
20
+ return PackMcmeta.readPackFormat(data);
22
21
  }
23
22
  catch (e) {
24
23
  if (!externals.error.isKind(e, 'ENOENT')) {
@@ -28,7 +27,7 @@ export const initialize = async (ctx) => {
28
27
  }
29
28
  return undefined;
30
29
  }
31
- async function findPackMcmetas(versions) {
30
+ async function findPackMcmetas() {
32
31
  const searchedUris = new Set();
33
32
  const packs = [];
34
33
  for (let depth = 0; depth <= 2; depth += 1) {
@@ -40,12 +39,13 @@ export const initialize = async (ctx) => {
40
39
  }
41
40
  searchedUris.add(uri);
42
41
  const packRoot = core.fileUtil.dirname(uri);
43
- const [packMcmeta, type] = await Promise.all([
44
- readPackMcmeta(uri),
42
+ const [format, type] = await Promise.all([
43
+ readPackFormat(uri),
45
44
  PackMcmeta.getType(packRoot, externals),
46
45
  ]);
47
- const versionInfo = resolveConfiguredVersion(config.env.gameVersion, versions, packMcmeta, type, logger);
48
- packs.push({ type, packRoot, packMcmeta, versionInfo });
46
+ if (format !== undefined) {
47
+ packs.push({ type, packRoot, format });
48
+ }
49
49
  }
50
50
  }
51
51
  }
@@ -53,34 +53,15 @@ export const initialize = async (ctx) => {
53
53
  }
54
54
  meta.registerUriBinder(uriBinder);
55
55
  registerUriBuilders(meta);
56
- const versions = await getVersions(ctx.externals, ctx.downloader);
56
+ const [versions, packs] = await Promise.all([
57
+ getVersions(ctx.externals, ctx.downloader),
58
+ findPackMcmetas(),
59
+ ]);
57
60
  if (!versions) {
58
61
  ctx.logger.error('[je-initialize] Failed loading game version list. Expect everything to be broken.');
59
62
  return;
60
63
  }
61
- const packs = await findPackMcmetas(versions);
62
- function selectVersionInfo(packs, versions) {
63
- // Select the first valid pack.mcmeta, prioritizing data packs
64
- const pack = packs.find(p => p.packMcmeta !== undefined && p.type === 'data')
65
- ?? packs.find(p => p.packMcmeta !== undefined && p.type === 'assets');
66
- const version = pack === undefined
67
- ? resolveConfiguredVersion(config.env.gameVersion, versions, undefined, undefined, logger)
68
- : pack.versionInfo;
69
- const packMessage = pack === undefined
70
- ? 'Failed finding a valid pack.mcmeta'
71
- : `Found a valid pack.mcmeta ${pack.packRoot}/pack.mcmeta`;
72
- const reasonMessage = pack && version.reason === 'auto'
73
- ? `using ${pack.type} pack format ${pack.packMcmeta?.pack.pack_format} to select`
74
- : version.reason === 'config'
75
- ? `but using config override "${config.env.gameVersion}" to select`
76
- : version.reason === 'fallback'
77
- ? 'using fallback'
78
- : 'impossible'; // should never occur
79
- const versionMessage = `version ${version.release}${version.id === version.release ? '' : ` (${version.id})`}`;
80
- ctx.logger.info(`[je.initialize] ${packMessage}, ${reasonMessage} ${versionMessage}`);
81
- return version;
82
- }
83
- const version = selectVersionInfo(packs, versions);
64
+ const version = resolveConfiguredVersion(config.env.gameVersion, versions, packs, logger);
84
65
  const release = version.release;
85
66
  meta.registerDependencyProvider('@vanilla-datapack', () => getVanillaDatapack(downloader, version.id, version.isLatest));
86
67
  meta.registerDependencyProvider('@vanilla-resourcepack', () => getVanillaResourcepack(downloader, version.id, version.isLatest));
@@ -110,7 +91,7 @@ export const initialize = async (ctx) => {
110
91
  && !n.symbol?.path[0]?.startsWith('::minecraft')),
111
92
  });
112
93
  registerMcdocAttributes(meta, summary.commands, release);
113
- registerPackFormatAttribute(meta, release, versions, packs);
94
+ registerPackFormatAttribute(meta, versions, packs);
114
95
  meta.registerLanguage('zip', { extensions: ['.zip'] });
115
96
  meta.registerLanguage('png', { extensions: ['.png'] });
116
97
  meta.registerLanguage('ogg', { extensions: ['.ogg'] });
@@ -2,5 +2,5 @@ import * as core from '@spyglassmc/core';
2
2
  import { ReleaseVersion } from './dependency/index.js';
3
3
  import type { McmetaCommands, McmetaVersions, PackInfo } from './dependency/index.js';
4
4
  export declare function registerMcdocAttributes(meta: core.MetaRegistry, commands: McmetaCommands, release: ReleaseVersion): void;
5
- export declare function registerPackFormatAttribute(meta: core.MetaRegistry, release: ReleaseVersion, versions: McmetaVersions, packs: PackInfo[]): void;
5
+ export declare function registerPackFormatAttribute(meta: core.MetaRegistry, versions: McmetaVersions, packs: PackInfo[]): void;
6
6
  //# sourceMappingURL=mcdocAttributes.d.ts.map
@@ -1,5 +1,4 @@
1
1
  import * as core from '@spyglassmc/core';
2
- import { localize } from '@spyglassmc/locales';
3
2
  import * as mcdoc from '@spyglassmc/mcdoc';
4
3
  import { NEXT_RELEASE_VERSION, ReleaseVersion } from './dependency/index.js';
5
4
  const validator = mcdoc.runtime.attribute.validator;
@@ -60,7 +59,7 @@ export function registerMcdocAttributes(meta, commands, release) {
60
59
  });
61
60
  }
62
61
  }
63
- export function registerPackFormatAttribute(meta, release, versions, packs) {
62
+ export function registerPackFormatAttribute(meta, versions, packs) {
64
63
  const dataFormats = new Map();
65
64
  const assetsFormats = new Map();
66
65
  if (versions[0]?.type !== 'release') {
@@ -84,21 +83,6 @@ export function registerPackFormatAttribute(meta, release, versions, packs) {
84
83
  return thisPack?.type === 'assets' ? assetsFormats : dataFormats;
85
84
  }
86
85
  mcdoc.runtime.registerAttribute(meta, 'pack_format', () => undefined, {
87
- checker: (_, typeDef) => {
88
- if (typeDef.kind !== 'literal' || typeof typeDef.value.value !== 'number') {
89
- return undefined;
90
- }
91
- const target = typeDef.value.value;
92
- return (node, ctx) => {
93
- const targetVersions = getFormats(ctx.doc.uri).get(target);
94
- if (!targetVersions) {
95
- ctx.err.report(localize('java-edition.pack-format.unsupported', target), node, 2 /* core.ErrorSeverity.Warning */);
96
- }
97
- else if (!targetVersions.some(v => v === release)) {
98
- ctx.err.report(localize('java-edition.pack-format.not-loaded', target, release), node, 2 /* core.ErrorSeverity.Warning */);
99
- }
100
- };
101
- },
102
86
  numericCompleter: (_, ctx) => {
103
87
  return [...getFormats(ctx.doc.uri).entries()].map(([k, v], i) => ({
104
88
  range: core.Range.create(ctx.offset),
@@ -11,6 +11,7 @@ const commandValidator = validator.alternatives(validator.tree({
11
11
  slash: validator.optional(validator.options('allowed', 'required', 'chat')),
12
12
  max_length: validator.optional(validator.number),
13
13
  empty: validator.optional(validator.options('allowed')),
14
+ incomplete: validator.optional(validator.options('allowed')),
14
15
  }), () => ({}));
15
16
  const entityValidator = validator.alternatives(validator.tree({
16
17
  amount: validator.options('multiple', 'single'),
@@ -22,17 +23,23 @@ const scoreHolderValidator = validator.alternatives(validator.tree({
22
23
  export function registerMcdocAttributes(meta, rootTreeNode) {
23
24
  mcdoc.runtime.registerAttribute(meta, 'command', commandValidator, {
24
25
  // TODO: fix completer inside commands
25
- stringParser: ({ slash, max_length, empty }) => {
26
+ stringParser: ({ slash, max_length, empty, incomplete }) => {
26
27
  return (src, ctx) => {
27
28
  if ((empty && !src.canRead()) || (slash === 'chat' && src.peek() !== '/')) {
28
29
  return core.string({
29
30
  unquotable: { blockList: new Set(), allowEmpty: true },
30
31
  })(src, ctx);
31
32
  }
32
- return mcf.command(rootTreeNode, parser.argument, {
33
+ const tmpCtx = { ...ctx, err: new core.ErrorReporter(ctx.err.source) };
34
+ const result = mcf.command(rootTreeNode, parser.argument, {
33
35
  slash: slash === 'chat' ? 'allowed' : slash,
34
36
  maxLength: max_length,
35
- })(src, ctx);
37
+ })(src, tmpCtx);
38
+ if (incomplete) {
39
+ tmpCtx.err.errors = tmpCtx.err.errors.filter(e => e.range.end < result.range.end);
40
+ }
41
+ ctx.err.absorb(tmpCtx.err);
42
+ return result;
36
43
  };
37
44
  },
38
45
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/java-edition",
3
- "version": "0.3.38",
3
+ "version": "0.3.40",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -17,12 +17,12 @@
17
17
  "release:dry": "npm publish --dry-run"
18
18
  },
19
19
  "dependencies": {
20
- "@spyglassmc/core": "0.4.28",
21
- "@spyglassmc/json": "0.3.32",
22
- "@spyglassmc/locales": "0.3.14",
23
- "@spyglassmc/mcfunction": "0.2.30",
24
- "@spyglassmc/mcdoc": "0.3.32",
25
- "@spyglassmc/nbt": "0.3.33"
20
+ "@spyglassmc/core": "0.4.30",
21
+ "@spyglassmc/json": "0.3.34",
22
+ "@spyglassmc/locales": "0.3.15",
23
+ "@spyglassmc/mcfunction": "0.2.32",
24
+ "@spyglassmc/mcdoc": "0.3.34",
25
+ "@spyglassmc/nbt": "0.3.35"
26
26
  },
27
27
  "devDependencies": {},
28
28
  "publishConfig": {