@spyglassmc/java-edition 0.3.52 → 0.3.54

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.
@@ -1,4 +1,4 @@
1
- import { fileUtil, Range, TaggableResourceLocationCategories, } from '@spyglassmc/core';
1
+ import { ErrorSeverity, fileUtil, Range, TaggableResourceLocationCategories, } from '@spyglassmc/core';
2
2
  import { localeQuote, localize } from '@spyglassmc/locales';
3
3
  import { ReleaseVersion } from '../dependency/index.js';
4
4
  const Resources = new Map();
@@ -61,9 +61,11 @@ resource('pig_variant', { since: '1.21.5' });
61
61
  resource('test_instance', { since: '1.21.5' });
62
62
  resource('test_environment', { since: '1.21.5' });
63
63
  resource('timeline', { since: '1.21.11' });
64
+ resource('trade_set', { since: '26.1' });
64
65
  resource('trial_spawner', { since: '1.21.2' });
65
66
  resource('trim_pattern', { since: '1.19.4' });
66
67
  resource('trim_material', { since: '1.19.4' });
68
+ resource('villager_trade', { since: '26.1' });
67
69
  resource('wolf_sound_variant', { since: '1.21.5' });
68
70
  resource('wolf_variant', { since: '1.20.5' });
69
71
  resource('zombie_nautilus_variant', { since: '1.21.11' });
@@ -275,10 +277,10 @@ export function reportDissectError(realPath, expectedPath, ctx) {
275
277
  return;
276
278
  }
277
279
  if (expectedPath) {
278
- ctx.err.report(localize('java-edition.binder.wrong-folder', localeQuote(realPath), release, localeQuote(expectedPath)), Range.Beginning, 0 /* ErrorSeverity.Hint */);
280
+ ctx.err.report(localize('java-edition.binder.wrong-folder', localeQuote(realPath), release, localeQuote(expectedPath)), Range.Beginning, ErrorSeverity.Hint);
279
281
  }
280
282
  else {
281
- ctx.err.report(localize('java-edition.binder.wrong-version', localeQuote(realPath), release), Range.Beginning, 0 /* ErrorSeverity.Hint */);
283
+ ctx.err.report(localize('java-edition.binder.wrong-version', localeQuote(realPath), release), Range.Beginning, ErrorSeverity.Hint);
282
284
  }
283
285
  }
284
286
  function uriBuilder(resources) {
@@ -1,5 +1,5 @@
1
1
  import type * as core from '@spyglassmc/core';
2
- export type ReleaseVersion = `1.${number}`;
2
+ export type ReleaseVersion = `${bigint}.${bigint}.${bigint}` | `${bigint}.${bigint}`;
3
3
  export declare namespace ReleaseVersion {
4
4
  /**
5
5
  * @returns
@@ -18,6 +18,8 @@ export interface VersionInfo {
18
18
  release: ReleaseVersion;
19
19
  id: string;
20
20
  name: string;
21
+ data_pack_version: number;
22
+ resource_pack_version: number;
21
23
  }
22
24
  export declare namespace PackMcmeta {
23
25
  function readPackFormat(data: any): number;
@@ -7,8 +7,11 @@ export var ReleaseVersion;
7
7
  * * `1` if `a` is newer than `b`.
8
8
  */
9
9
  function cmp(a, b) {
10
- const [minorA, patchA = 0] = a.slice(2).split('.');
11
- const [minorB, patchB = 0] = b.slice(2).split('.');
10
+ const [majorA, minorA, patchA = 0] = a.split('.');
11
+ const [majorB, minorB, patchB = 0] = b.split('.');
12
+ if (majorA !== majorB) {
13
+ return Math.sign(Number(majorA) - Number(majorB));
14
+ }
12
15
  if (minorA !== minorB) {
13
16
  return Math.sign(Number(minorA) - Number(minorB));
14
17
  }
@@ -1,7 +1,12 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import type { PackInfo, VersionInfo } from './common.js';
3
3
  import { ReleaseVersion } from './common.js';
4
- export declare const NEXT_RELEASE_VERSION = "1.21.11";
4
+ /**
5
+ * Determines the latest development release for which a release target could be determined
6
+ * @param versions List of all versions in mcmeta
7
+ * @returns latest development release
8
+ */
9
+ export declare function getLatestSnapshot(versions: McmetaVersions): VersionInfo;
5
10
  /**
6
11
  * @param inputVersion {@link core.Config.env.gameVersion}
7
12
  */
@@ -1,33 +1,57 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import { ReleaseVersion } from './common.js';
3
- // DOCS: Update this when a new snapshot cycle begins
4
- export const NEXT_RELEASE_VERSION = '1.21.11';
3
+ // Matches development versions with the release version in its name
4
+ const DevelopmentVersionPattern = /^(\d\d\.\d(?:\.\d?\d)?)\-\w+\-\d+$/;
5
+ function toVersionInfo(version, release) {
6
+ return {
7
+ id: version.id,
8
+ name: version.name,
9
+ release: release ?? version.id,
10
+ data_pack_version: version.data_pack_version,
11
+ resource_pack_version: version.resource_pack_version,
12
+ };
13
+ }
14
+ /**
15
+ * Determines the latest development release for which a release target could be determined
16
+ * @param versions List of all versions in mcmeta
17
+ * @returns latest development release
18
+ */
19
+ export function getLatestSnapshot(versions) {
20
+ for (const version of versions) {
21
+ if (version.type === 'release') {
22
+ return toVersionInfo(version);
23
+ }
24
+ const matches = version.id.match(DevelopmentVersionPattern);
25
+ if (matches) {
26
+ return toVersionInfo(version, matches[1]);
27
+ }
28
+ }
29
+ throw new Error('no next release version found');
30
+ }
5
31
  /**
6
32
  * @param inputVersion {@link core.Config.env.gameVersion}
7
33
  */
8
34
  export function resolveConfiguredVersion(inputVersion, versions, packs, logger) {
9
- function findReleaseTarget(version) {
10
- if (version.release_target) {
11
- return version.release_target;
12
- }
35
+ // Gets the release version id for any version, only used when specifically selecting release in config
36
+ function getReleaseVersion(version) {
37
+ // Is release, so return own id
13
38
  if (version.type === 'release') {
14
39
  return version.id;
15
40
  }
41
+ // Development versions with release version in name
42
+ const matches = version.id.match(DevelopmentVersionPattern);
43
+ if (matches) {
44
+ return matches[1];
45
+ }
46
+ // Old snapshots without release version in name
16
47
  const index = versions.findIndex((v) => v.id === version.id);
17
48
  for (let i = index; i >= 0; i -= 1) {
18
49
  if (versions[i].type === 'release') {
19
50
  return versions[i].id;
20
51
  }
21
52
  }
22
- return NEXT_RELEASE_VERSION;
23
- }
24
- function toVersionInfo(version) {
25
- version = version ?? versions[0];
26
- return {
27
- id: version.id,
28
- name: version.name,
29
- release: findReleaseTarget(version),
30
- };
53
+ // No release version found. This should only happen in exceptional circumstances, such as april fools or experimental versions.
54
+ return undefined;
31
55
  }
32
56
  if (versions.length === 0) {
33
57
  throw new Error('mcmeta version list is empty');
@@ -40,28 +64,33 @@ export function resolveConfiguredVersion(inputVersion, versions, packs, logger)
40
64
  }
41
65
  inputVersion = inputVersion.toLowerCase();
42
66
  versions = versions.sort((a, b) => b.data_version - a.data_version);
43
- const latestRelease = versions.find((v) => v.type === 'release');
67
+ const latestReleaseMcmeta = versions.find((v) => v.type === 'release');
68
+ if (latestReleaseMcmeta === undefined) {
69
+ throw new Error('mcmeta version list does not contain any releases');
70
+ }
71
+ const latestRelease = toVersionInfo(latestReleaseMcmeta);
72
+ const latestSnaphot = getLatestSnapshot(versions);
44
73
  if (inputVersion === 'auto') {
45
74
  if (packs.length === 0) {
46
75
  // Fall back to the latest release if pack mcmeta is not available
47
76
  logger.info(`[resolveConfiguredVersion] No pack format detected, selecting latest release ${latestRelease?.id}`);
48
- return toVersionInfo(latestRelease);
77
+ return latestRelease;
49
78
  }
50
79
  packs.sort((a, b) => b.format - a.format);
51
80
  const maxData = packs.filter(p => p.type === 'data')[0];
52
81
  const maxAssets = packs.filter(p => p.type === 'assets')[0];
53
82
  // Look for versions from recent to oldest, picking the most recent release that matches
54
- let oldestRelease = versions[0];
83
+ let nextReleaseVersionInfo = latestSnaphot;
55
84
  const releases = versions.filter(v => v.type === 'release');
56
85
  for (const version of releases) {
57
86
  // If we already passed the pack format, use the oldest release so far
58
87
  if (maxData && maxData.format > version.data_pack_version) {
59
- logger.info(`[resolveConfiguredVersion] Detected data pack format ${maxData.format} in ${maxData.packRoot}, selecting version ${oldestRelease.id}`);
60
- return toVersionInfo(oldestRelease);
88
+ logger.info(`[resolveConfiguredVersion] Detected data pack format ${maxData.format} in ${maxData.packRoot}, selecting version ${nextReleaseVersionInfo.id}`);
89
+ return nextReleaseVersionInfo;
61
90
  }
62
91
  if (maxAssets && maxAssets.format > version.resource_pack_version) {
63
- logger.info(`[resolveConfiguredVersion] Detected resource pack format ${maxAssets.format} in ${maxAssets.packRoot}, selecting version ${oldestRelease.id}`);
64
- return toVersionInfo(oldestRelease);
92
+ logger.info(`[resolveConfiguredVersion] Detected resource pack format ${maxAssets.format} in ${maxAssets.packRoot}, selecting version ${nextReleaseVersionInfo.id}`);
93
+ return nextReleaseVersionInfo;
65
94
  }
66
95
  if (maxData && maxData.format === version.data_pack_version) {
67
96
  logger.info(`[resolveConfiguredVersion] Detected data pack format ${maxData.format} in ${maxData.packRoot}, selecting version ${version.id}`);
@@ -71,23 +100,32 @@ export function resolveConfiguredVersion(inputVersion, versions, packs, logger)
71
100
  logger.info(`[resolveConfiguredVersion] Detected resource pack format ${maxAssets.format} in ${maxAssets.packRoot}, selecting version ${version.id}`);
72
101
  return toVersionInfo(version);
73
102
  }
74
- oldestRelease = version;
103
+ nextReleaseVersionInfo = toVersionInfo(version);
75
104
  }
76
105
  // If the pack format is still lower, use the oldest known release version
77
- logger.info(`[resolveConfiguredVersion] Detected pack format too low, selecting oldest supported release ${oldestRelease?.id}`);
78
- return toVersionInfo(oldestRelease);
106
+ logger.info(`[resolveConfiguredVersion] Detected pack format too low, selecting oldest supported release ${nextReleaseVersionInfo?.id}`);
107
+ return nextReleaseVersionInfo;
79
108
  }
80
109
  else if (inputVersion === 'latest release') {
81
- logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${latestRelease?.id}`);
82
- return toVersionInfo(latestRelease);
110
+ logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${latestRelease.id}`);
111
+ return latestRelease;
83
112
  }
84
113
  else if (inputVersion === 'latest snapshot') {
85
- logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${versions[0]?.id}`);
86
- return toVersionInfo(versions[0]);
114
+ logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${latestSnaphot.id}`);
115
+ return latestSnaphot;
87
116
  }
88
117
  const configVersion = versions.find((v) => inputVersion === v.id.toLowerCase() || inputVersion === v.name.toLowerCase());
118
+ if (configVersion === undefined) {
119
+ logger.info(`[resolveConfiguredVersion] Could not find config version "${inputVersion}", selecting version ${latestSnaphot.id}`);
120
+ return latestSnaphot;
121
+ }
122
+ const configReleaseVersion = getReleaseVersion(configVersion);
123
+ if (configReleaseVersion === undefined) {
124
+ logger.info(`[resolveConfiguredVersion] Could not determine release version of config "${inputVersion}", selecting version ${latestSnaphot.id}`);
125
+ return latestSnaphot;
126
+ }
89
127
  logger.info(`[resolveConfiguredVersion] Using config "${inputVersion}", selecting version ${configVersion?.id}`);
90
- return toVersionInfo(configVersion);
128
+ return toVersionInfo(configVersion, configReleaseVersion);
91
129
  }
92
130
  export function symbolRegistrar(summary, release) {
93
131
  const McmetaSummaryUri = 'mcmeta://summary/registries.json';
@@ -1,6 +1,6 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import * as mcdoc from '@spyglassmc/mcdoc';
3
- import { NEXT_RELEASE_VERSION, ReleaseVersion } from './dependency/index.js';
3
+ import { getLatestSnapshot, ReleaseVersion } from './dependency/index.js';
4
4
  const validator = mcdoc.runtime.attribute.validator;
5
5
  const gameRuleValidator = validator.tree({
6
6
  type: validator.options('boolean', 'int'),
@@ -62,9 +62,10 @@ export function registerMcdocAttributes(meta, commands, release) {
62
62
  export function registerPackFormatAttribute(meta, versions, packs) {
63
63
  const dataFormats = new Map();
64
64
  const assetsFormats = new Map();
65
- if (versions[0]?.type !== 'release') {
66
- dataFormats.set(versions[0].data_pack_version, [NEXT_RELEASE_VERSION]);
67
- assetsFormats.set(versions[0].resource_pack_version, [NEXT_RELEASE_VERSION]);
65
+ const latestSnapshot = getLatestSnapshot(versions);
66
+ if (latestSnapshot.release !== latestSnapshot.id) {
67
+ dataFormats.set(latestSnapshot.data_pack_version, [latestSnapshot.release]);
68
+ assetsFormats.set(latestSnapshot.resource_pack_version, [latestSnapshot.release]);
68
69
  }
69
70
  for (const version of versions) {
70
71
  if (version.type === 'release') {
@@ -150,7 +150,7 @@ const itemStack = (node, ctx) => {
150
150
  for (const [_, group] of groupedComponents) {
151
151
  if (group.length > 1) {
152
152
  for (const node of group) {
153
- ctx.err.report(localize('mcfunction.parser.duplicate-components'), node.range, 2 /* core.ErrorSeverity.Warning */);
153
+ ctx.err.report(localize('mcfunction.parser.duplicate-components'), node.range, core.ErrorSeverity.Warning);
154
154
  }
155
155
  }
156
156
  }
@@ -665,6 +665,51 @@ export function getPatch(release) {
665
665
  },
666
666
  },
667
667
  },
668
+ ...(ReleaseVersion.cmp(release, '1.21.11') >= 0
669
+ ? {
670
+ stopwatch: {
671
+ children: {
672
+ create: {
673
+ children: {
674
+ id: {
675
+ properties: {
676
+ category: 'stopwatch',
677
+ usageType: 'definition',
678
+ },
679
+ },
680
+ },
681
+ },
682
+ query: {
683
+ children: {
684
+ id: {
685
+ properties: {
686
+ category: 'stopwatch',
687
+ },
688
+ },
689
+ },
690
+ },
691
+ remove: {
692
+ children: {
693
+ id: {
694
+ properties: {
695
+ category: 'stopwatch',
696
+ },
697
+ },
698
+ },
699
+ },
700
+ restart: {
701
+ children: {
702
+ id: {
703
+ properties: {
704
+ category: 'stopwatch',
705
+ },
706
+ },
707
+ },
708
+ },
709
+ },
710
+ },
711
+ }
712
+ : {}),
668
713
  summon: {
669
714
  children: {
670
715
  entity: {
@@ -1018,6 +1063,15 @@ const ExecuteCondition = Object.freeze({
1018
1063
  },
1019
1064
  },
1020
1065
  },
1066
+ stopwatch: {
1067
+ children: {
1068
+ id: {
1069
+ properties: {
1070
+ category: 'stopwatch',
1071
+ },
1072
+ },
1073
+ },
1074
+ },
1021
1075
  },
1022
1076
  });
1023
1077
  const ExecuteStoreTarget = Object.freeze({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/java-edition",
3
- "version": "0.3.52",
3
+ "version": "0.3.54",
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 --tag latest --dry-run"
18
18
  },
19
19
  "dependencies": {
20
- "@spyglassmc/core": "0.4.40",
21
- "@spyglassmc/json": "0.3.44",
22
- "@spyglassmc/locales": "0.3.20",
23
- "@spyglassmc/mcfunction": "0.2.43",
24
- "@spyglassmc/mcdoc": "0.3.44",
25
- "@spyglassmc/nbt": "0.3.46"
20
+ "@spyglassmc/core": "0.4.42",
21
+ "@spyglassmc/json": "0.3.46",
22
+ "@spyglassmc/locales": "0.3.21",
23
+ "@spyglassmc/mcfunction": "0.2.45",
24
+ "@spyglassmc/mcdoc": "0.3.46",
25
+ "@spyglassmc/nbt": "0.3.48"
26
26
  },
27
27
  "devDependencies": {},
28
28
  "publishConfig": {