yeow-api 0.4.3 → 0.6.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeow-api",
3
- "version": "0.4.3",
3
+ "version": "0.6.0",
4
4
  "description": "Yeow API",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -1,27 +1,8 @@
1
- import { post } from './task.js';
2
- import type { TaskOptions } from './task.js';
1
+ // 进度操作已上移到 `player.ts` Player 实例方法(`player.grantAdvancement(...)` 等)
2
+ // ——不再提供顶层 uuid 函数。
3
3
 
4
+ /** 进度完成情况。 */
4
5
  export interface AdvancementProgress {
5
6
  awardedCriteria: string[];
6
7
  remainingCriteria: string[];
7
8
  }
8
-
9
- export function grant(uuid: string, key: string, options?: TaskOptions): Promise<boolean> {
10
- return post<boolean>('advancement.grant', { uuid, key }, options);
11
- }
12
-
13
- export function revoke(uuid: string, key: string, options?: TaskOptions): Promise<boolean> {
14
- return post<boolean>('advancement.revoke', { uuid, key }, options);
15
- }
16
-
17
- export function getProgress(uuid: string, key: string, options?: TaskOptions): Promise<AdvancementProgress | null> {
18
- return post<AdvancementProgress | null>('advancement.getProgress', { uuid, key }, options);
19
- }
20
-
21
- export function awardCriteria(uuid: string, key: string, criteria: string, options?: TaskOptions): Promise<boolean> {
22
- return post<boolean>('advancement.awardCriteria', { uuid, key, criteria }, options);
23
- }
24
-
25
- export function revokeCriteria(uuid: string, key: string, criteria: string, options?: TaskOptions): Promise<boolean> {
26
- return post<boolean>('advancement.revokeCriteria', { uuid, key, criteria }, options);
27
- }
package/src/assets.ts CHANGED
@@ -55,18 +55,19 @@ const readSyncImpl = (path: string, options?: FsEncoding | ReadFileOptions): Uin
55
55
  export const read = readImpl as AssetsReadFn;
56
56
  export const readSync = readSyncImpl as AssetsReadSyncFn;
57
57
 
58
- export async function extract(path: string, dest?: string): Promise<string> {
59
- const p: Record<string, unknown> = { path };
60
- if (dest) p.dest = dest;
61
- const r = await _sendAssetsAsync({ t: 'extract', p }) as { path: string };
58
+ /**
59
+ * 解压单文件资产到磁盘。**`dest` 必填**,基于插件数据目录(`plugins/<插件名>/`)计算,
60
+ * 最终目标必须位于插件目录内。返回解压后的相对服务器根目录路径。
61
+ */
62
+ export async function extract(path: string, dest: string): Promise<string> {
63
+ const r = await _sendAssetsAsync({ t: 'extract', p: { path, dest } }) as { path: string };
62
64
  return r.path;
63
65
  }
64
- export function extractSync(path: string, dest?: string): string {
65
- const p: Record<string, unknown> = { path };
66
- if (dest) p.dest = dest;
67
- return (_sendAssets({ t: 'extract', p }) as { path: string }).path;
66
+ export function extractSync(path: string, dest: string): string {
67
+ return (_sendAssets({ t: 'extract', p: { path, dest } }) as { path: string }).path;
68
68
  }
69
69
 
70
+ /** 解压目录树到磁盘。`dest` 可选(默认 `assets/<path>`),基于插件数据目录计算并限定其内。 */
70
71
  export async function extractDir(path: string, dest?: string): Promise<string> {
71
72
  const p: Record<string, unknown> = { path };
72
73
  if (dest) p.dest = dest;
package/src/block.ts CHANGED
@@ -9,15 +9,16 @@ import {
9
9
  keysBlock as pdcKeys, getAllBlock as pdcGetAll,
10
10
  } from './pdc.js';
11
11
 
12
- /** 方块状态(Minecraft 原版键值对枚举,值统一为字符串)。 */
12
+ /** 方块状态(Minecraft 原版键值对枚举;值为字符串 / 数字 / 布尔——按原版语义保留类型)。 */
13
13
  export interface BlockState {
14
- [key: string]: string;
14
+ [key: string]: string | number | boolean;
15
15
  }
16
16
 
17
17
  /**
18
18
  * Block —— 方块数据描述符 + 可选的世界位置(location)。
19
19
  * 对应 Minecraft 原版的方块概念:类型 + 方块状态(键值对枚举,如
20
- * `facing`、`waterlogged`、`level` 等,值统一为字符串)。
20
+ * `facing`、`waterlogged`、`level` 等;值按原版语义保留类型——布尔 `waterlogged: false`、
21
+ * 数字 `level: 8`、枚举串 `facing: "north"`)。
21
22
  *
22
23
  * **静态数据语义**:`type` / `state` / `location` 均为**获取时刻的快照**,
23
24
  * 之后世界变化不会自动更新;需要最新状态请重新调用 `world.getBlock`。
package/src/bossbar.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { post } from './task.js';
1
+ import { call, post } from './task.js';
2
2
  import type { TaskOptions } from './task.js';
3
3
  import { BossBarHandle } from './instance-id.js';
4
+ import { resolveUuid } from './target.js';
5
+ import type { PlayerTarget } from './target.js';
4
6
 
5
7
  export interface BossBarOptions {
6
8
  color?: string;
@@ -9,52 +11,102 @@ export interface BossBarOptions {
9
11
  visible?: boolean;
10
12
  }
11
13
 
12
- export async function createBossBar(title: string, options?: BossBarOptions, taskOptions?: TaskOptions): Promise<BossBarHandle> {
13
- const h = new BossBarHandle();
14
- await post('bossbar.create', { id: h.toString(), title, ...options }, taskOptions);
15
- return h;
16
- }
14
+ /**
15
+ * BossBar —— 面向玩家的血条对象(OOP)。
16
+ *
17
+ * ```js
18
+ * const bar = await BossBar.create('<red>Loading...</red>', { color: 'RED', progress: 0.0 });
19
+ * await bar.addPlayer(player); // 接受 Player 对象或 uuid
20
+ * await bar.setProgress(0.5);
21
+ * await bar.destroy();
22
+ * ```
23
+ *
24
+ * 事件比对:`bar.toString()` 返回底层句柄 id(与 `inventoryClick` 等比对)。
25
+ * BossBar 颜色/样式/Flag 值域见 [值域附录 · 直接维护的枚举清单]。
26
+ */
27
+ export class BossBar {
28
+ private constructor(readonly id: string) {}
17
29
 
18
- export function destroy(id: BossBarHandle, options?: TaskOptions): Promise<void> {
19
- return post('bossbar.destroy', { id: id.toString() }, options);
20
- }
30
+ /** 创建血条(title 支持 MiniMessage)。 */
31
+ static async create(title: string, options?: BossBarOptions, taskOptions?: TaskOptions): Promise<BossBar> {
32
+ const id = new BossBarHandle().toString();
33
+ await post('bossbar.create', { id, title, ...options }, taskOptions);
34
+ return new BossBar(id);
35
+ }
21
36
 
22
- export function setTitle(id: BossBarHandle, title: string, options?: TaskOptions): Promise<void> {
23
- return post('bossbar.setTitle', { id: id.toString(), title }, options);
24
- }
37
+ /** 底层句柄 id(用于事件比对)。 */
38
+ get handle(): string { return this.id; }
39
+ toString(): string { return this.id; }
25
40
 
26
- export function setProgress(id: BossBarHandle, progress: number, options?: TaskOptions): Promise<void> {
27
- return post('bossbar.setProgress', { id: id.toString(), progress }, options);
28
- }
41
+ // ── 标题 / 进度 / 颜色 / 样式 / 可见性 ──
29
42
 
30
- export function setColor(id: BossBarHandle, color: string, options?: TaskOptions): Promise<void> {
31
- return post('bossbar.setColor', { id: id.toString(), color }, options);
32
- }
43
+ set title(v: string) { call('bossbar.setTitle', { id: this.id, title: v }); }
44
+ setTitle(title: string, options?: TaskOptions): Promise<void> { return post('bossbar.setTitle', { id: this.id, title }, options); }
45
+ setTitleSync(title: string, options?: TaskOptions): void { call('bossbar.setTitle', { id: this.id, title }, options); }
33
46
 
34
- export function setStyle(id: BossBarHandle, style: string, options?: TaskOptions): Promise<void> {
35
- return post('bossbar.setStyle', { id: id.toString(), style }, options);
36
- }
47
+ set progress(v: number) { call('bossbar.setProgress', { id: this.id, progress: v }); }
48
+ setProgress(progress: number, options?: TaskOptions): Promise<void> { return post('bossbar.setProgress', { id: this.id, progress }, options); }
49
+ setProgressSync(progress: number, options?: TaskOptions): void { call('bossbar.setProgress', { id: this.id, progress }, options); }
37
50
 
38
- export function setVisible(id: BossBarHandle, visible: boolean, options?: TaskOptions): Promise<void> {
39
- return post('bossbar.setVisible', { id: id.toString(), visible }, options);
40
- }
51
+ set color(v: string) { call('bossbar.setColor', { id: this.id, color: v }); }
52
+ setColor(color: string, options?: TaskOptions): Promise<void> { return post('bossbar.setColor', { id: this.id, color }, options); }
53
+ setColorSync(color: string, options?: TaskOptions): void { call('bossbar.setColor', { id: this.id, color }, options); }
41
54
 
42
- export function addPlayer(id: BossBarHandle, uuid: string, options?: TaskOptions): Promise<void> {
43
- return post('bossbar.addPlayer', { id: id.toString(), uuid }, options);
44
- }
55
+ set style(v: string) { call('bossbar.setStyle', { id: this.id, style: v }); }
56
+ setStyle(style: string, options?: TaskOptions): Promise<void> { return post('bossbar.setStyle', { id: this.id, style }, options); }
57
+ setStyleSync(style: string, options?: TaskOptions): void { call('bossbar.setStyle', { id: this.id, style }, options); }
45
58
 
46
- export function removePlayer(id: BossBarHandle, uuid: string, options?: TaskOptions): Promise<void> {
47
- return post('bossbar.removePlayer', { id: id.toString(), uuid }, options);
48
- }
59
+ set visible(v: boolean) { call('bossbar.setVisible', { id: this.id, visible: v }); }
60
+ setVisible(visible: boolean, options?: TaskOptions): Promise<void> { return post('bossbar.setVisible', { id: this.id, visible }, options); }
61
+ setVisibleSync(visible: boolean, options?: TaskOptions): void { call('bossbar.setVisible', { id: this.id, visible }, options); }
49
62
 
50
- export function removeAll(id: BossBarHandle, options?: TaskOptions): Promise<void> {
51
- return post('bossbar.removeAll', { id: id.toString() }, options);
52
- }
63
+ // ── 玩家绑定 ──
53
64
 
54
- export function addFlag(id: BossBarHandle, flag: string, options?: TaskOptions): Promise<void> {
55
- return post('bossbar.addFlag', { id: id.toString(), flag }, options);
56
- }
65
+ /** 绑定玩家(接受 `Player` 对象或 uuid)。 */
66
+ addPlayer(player: PlayerTarget, options?: TaskOptions): Promise<void> {
67
+ return post('bossbar.addPlayer', { id: this.id, uuid: resolveUuid(player) }, options);
68
+ }
69
+ addPlayerSync(player: PlayerTarget, options?: TaskOptions): void {
70
+ call('bossbar.addPlayer', { id: this.id, uuid: resolveUuid(player) }, options);
71
+ }
72
+
73
+ /** 移除玩家(接受 `Player` 对象或 uuid)。 */
74
+ removePlayer(player: PlayerTarget, options?: TaskOptions): Promise<void> {
75
+ return post('bossbar.removePlayer', { id: this.id, uuid: resolveUuid(player) }, options);
76
+ }
77
+ removePlayerSync(player: PlayerTarget, options?: TaskOptions): void {
78
+ call('bossbar.removePlayer', { id: this.id, uuid: resolveUuid(player) }, options);
79
+ }
80
+
81
+ /** 移除全部绑定的玩家。 */
82
+ removeAllPlayers(options?: TaskOptions): Promise<void> {
83
+ return post('bossbar.removeAll', { id: this.id }, options);
84
+ }
85
+ removeAllPlayersSync(options?: TaskOptions): void {
86
+ call('bossbar.removeAll', { id: this.id }, options);
87
+ }
88
+
89
+ // ── Flags ──
90
+
91
+ addFlag(flag: string, options?: TaskOptions): Promise<void> {
92
+ return post('bossbar.addFlag', { id: this.id, flag }, options);
93
+ }
94
+ addFlagSync(flag: string, options?: TaskOptions): void {
95
+ call('bossbar.addFlag', { id: this.id, flag }, options);
96
+ }
97
+
98
+ removeFlag(flag: string, options?: TaskOptions): Promise<void> {
99
+ return post('bossbar.removeFlag', { id: this.id, flag }, options);
100
+ }
101
+ removeFlagSync(flag: string, options?: TaskOptions): void {
102
+ call('bossbar.removeFlag', { id: this.id, flag }, options);
103
+ }
57
104
 
58
- export function removeFlag(id: BossBarHandle, flag: string, options?: TaskOptions): Promise<void> {
59
- return post('bossbar.removeFlag', { id: id.toString(), flag }, options);
105
+ /** 销毁血条(此后句柄失效)。 */
106
+ destroy(options?: TaskOptions): Promise<void> {
107
+ return post('bossbar.destroy', { id: this.id }, options);
108
+ }
109
+ destroySync(options?: TaskOptions): void {
110
+ call('bossbar.destroy', { id: this.id }, options);
111
+ }
60
112
  }
package/src/core.ts CHANGED
@@ -64,40 +64,24 @@ export { InstanceId, BossBarHandle, InventoryHandle } from './instance-id.js';
64
64
  export { ItemStack } from './item.js';
65
65
  export type { ItemMeta, PotionEffectData, AttributeModifierData } from './item.js';
66
66
  export type { PotionEffect } from './potion.js';
67
- export { addPotionEffect, removePotionEffect, clearPotionEffects, getActivePotionEffects } from './potion.js';
68
- export { playSound, stopSound, stopAllSounds } from './sound.js';
67
+ export { playSound } from './sound.js';
69
68
  export type { ParticleOptions } from './particle.js';
70
69
  export { spawnParticle } from './particle.js';
70
+ export type { PlayerTarget, LivingTarget, EntityTarget } from './target.js';
71
+ export type { AdvancementProgress } from './advancement.js';
72
+ export { BossBar } from './bossbar.js';
73
+ export type { BossBarOptions } from './bossbar.js';
74
+ export { Scoreboard, Objective, Team } from './scoreboard.js';
75
+ export type { ObjectiveInfo, TeamInfo } from './scoreboard.js';
71
76
  export { get as pdcGet, set as pdcSet, has as pdcHas, remove as pdcRemove, keys as pdcKeys, getAll as pdcGetAll,
72
77
  getRaw as pdcGetRaw, setRaw as pdcSetRaw, getAllRaw as pdcGetAllRaw,
73
78
  getBlock as pdcGetBlock, setBlock as pdcSetBlock, hasBlock as pdcHasBlock, removeBlock as pdcRemoveBlock,
74
79
  keysBlock as pdcKeysBlock, getAllBlock as pdcGetAllBlock, getBlockRaw as pdcGetBlockRaw, setBlockRaw as pdcSetBlockRaw, getAllBlockRaw as pdcGetAllBlockRaw } from './pdc.js';
75
- export { createBossBar, destroy as destroyBossBar,
76
- setTitle as setBossBarTitle, setProgress as setBossBarProgress,
77
- setColor as setBossBarColor, setStyle as setBossBarStyle,
78
- setVisible as setBossBarVisible, addPlayer as addBossBarPlayer,
79
- removePlayer as removeBossBarPlayer, removeAll as removeAllBossBarPlayers,
80
- addFlag as addBossBarFlag, removeFlag as removeBossBarFlag } from './bossbar.js';
81
- export type { BossBarOptions } from './bossbar.js';
82
- export type { AdvancementProgress } from './advancement.js';
83
- export { grant as grantAdvancement, revoke as revokeAdvancement,
84
- getProgress as getAdvancementProgress, awardCriteria, revokeCriteria } from './advancement.js';
85
80
  export { add as addRecipe, remove as removeRecipe, getForItem as getRecipesForItem } from './recipe.js';
86
- export type {
87
- ObjectiveInfo, TeamInfo,
88
- } from './scoreboard.js';
89
- export { createBoard as createScoreboard, deleteBoard as deleteScoreboard,
90
- createObjective, deleteObjective, getObjectives,
91
- setObjectiveDisplay, getScore, setScore, resetScore,
92
- createTeam, deleteTeam, getTeam, getTeams,
93
- setTeamDisplayName, setTeamPrefix, setTeamSuffix, setTeamColor,
94
- setTeamFriendlyFire, setTeamSeeInvisible, setTeamOption,
95
- teamAddEntry, teamRemoveEntry, teamGetEntries,
96
- setPlayerBoard } from './scoreboard.js';
97
81
  export { Material, getMaterials, getBlocks, getItems } from './material.js';
98
82
  export type { MaterialInfo } from './material.js';
99
- export { registerService, registerNativeService, request as serviceRequest, subscribe as serviceSubscribe, publish as servicePublish } from './service.js';
100
- export type { ServiceResult, NativeServiceResult } from './service.js';
83
+ export { Service, PluginService, NativeService, ServiceReply, registerService, registerNativeService, getService, hasService } from './service.js';
84
+ export type { ServiceKind, ServiceRequestOptions, ServiceResponse, NativeTerminateInfo, NativePlatforms } from './service.js';
101
85
  export { log, Logger } from './log.js';
102
86
  export type { Message } from './message.js';
103
87
  export { getEnv } from './env.js';
@@ -107,8 +91,8 @@ export type { Permission, PermissionOptions, PermissionDefault } from './permiss
107
91
  export { createWorker, Worker, onMessage, postMessage } from './worker.js';
108
92
  export type { WorkerOptions } from './worker.js';
109
93
  export {
110
- stringToBytes, stringToBytesAsync,
111
- bytesToString, bytesToStringAsync,
94
+ stringToBytes, stringToBytesSync,
95
+ bytesToString, bytesToStringSync,
112
96
  Gzip,
113
97
  } from './util.js';
114
98
  export type { GzipCompressor, GzipDecompressor, GzipCompressOptions, GzipDecompressOptions } from './util.js';
package/src/entity.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { call, post } from './task.js';
2
2
  import type { TaskOptions } from './task.js';
3
3
  import { Location, LocationData } from './location.js';
4
+ import type { PotionEffect } from './potion.js';
4
5
 
5
6
  export interface BoundingBox {
6
7
  minX: number;
@@ -113,6 +114,15 @@ export class Entity {
113
114
  }
114
115
 
115
116
  export class LivingEntity extends Entity {
117
+ /** 按 uuid 查找活体实体(返回 LivingEntity;目标非活体/不存在返回 null)。 */
118
+ static get(uuid: string, options?: TaskOptions): Promise<LivingEntity | null> {
119
+ return post<{ uuid: string }>('entity.get', { uuid }, options).then((d) => (d ? new LivingEntity(d.uuid) : null));
120
+ }
121
+ static getSync(uuid: string, options?: TaskOptions): LivingEntity | null {
122
+ const d = call<{ uuid: string }>('entity.get', { uuid }, options);
123
+ return d ? new LivingEntity(d.uuid) : null;
124
+ }
125
+
116
126
  get health(): number { return call<number>('entity.getHealth', { uuid: this.uuid }); }
117
127
  set health(v: number) { call('entity.setHealth', { uuid: this.uuid, value: v }); }
118
128
  getHealth(options?: TaskOptions): Promise<number> { return post<number>('entity.getHealth', { uuid: this.uuid }, options); }
@@ -142,4 +152,38 @@ export class LivingEntity extends Entity {
142
152
  setTargetSync(target: { targetUuid: string } | { world: string; x: number; y: number; z: number; speed?: number }, options?: TaskOptions): boolean {
143
153
  return call<boolean>('entity.setTarget', { uuid: this.uuid, ...target }, options);
144
154
  }
155
+
156
+ // ── 药水效果(实体级;Player 经继承自动获得) ──
157
+
158
+ /** 添加药水效果。 */
159
+ addPotionEffect(effect: PotionEffect, options?: TaskOptions): Promise<void> {
160
+ return post('entity.addPotionEffect', { uuid: this.uuid, ...effect }, options);
161
+ }
162
+ addPotionEffectSync(effect: PotionEffect, options?: TaskOptions): void {
163
+ call('entity.addPotionEffect', { uuid: this.uuid, ...effect }, options);
164
+ }
165
+
166
+ /** 移除指定类型的药水效果。 */
167
+ removePotionEffect(type: string, options?: TaskOptions): Promise<void> {
168
+ return post('entity.removePotionEffect', { uuid: this.uuid, type }, options);
169
+ }
170
+ removePotionEffectSync(type: string, options?: TaskOptions): void {
171
+ call('entity.removePotionEffect', { uuid: this.uuid, type }, options);
172
+ }
173
+
174
+ /** 清除全部药水效果。 */
175
+ clearPotionEffects(options?: TaskOptions): Promise<void> {
176
+ return post('entity.clearPotionEffects', { uuid: this.uuid }, options);
177
+ }
178
+ clearPotionEffectsSync(options?: TaskOptions): void {
179
+ call('entity.clearPotionEffects', { uuid: this.uuid }, options);
180
+ }
181
+
182
+ /** 当前生效的药水效果列表(与输入同结构)。 */
183
+ getActivePotionEffects(options?: TaskOptions): Promise<PotionEffect[]> {
184
+ return post<PotionEffect[]>('entity.getActivePotionEffects', { uuid: this.uuid }, options);
185
+ }
186
+ getActivePotionEffectsSync(options?: TaskOptions): PotionEffect[] {
187
+ return call<PotionEffect[]>('entity.getActivePotionEffects', { uuid: this.uuid }, options);
188
+ }
145
189
  }
package/src/fs.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  type FsLevel = 'plugin' | 'server' | 'outer';
2
2
 
3
- import { stringToBytes, bytesToString } from './util.js';
3
+ import { stringToBytesSync, bytesToStringSync } from './util.js';
4
4
 
5
5
  /** 文件编码:utf8 = 文本;base64 = 将字符串视为 Base64 编码的二进制数据。 */
6
6
  export type FsEncoding = 'utf8' | 'base64';
@@ -53,7 +53,7 @@ function _makeUtf8StreamDecoder() {
53
53
  if ((b & 0xE0) === 0xC0) return 2;
54
54
  if ((b & 0xF0) === 0xE0) return 3;
55
55
  if ((b & 0xF8) === 0xF0) return 4;
56
- return 1; // 非法起始字节:交给 bytesToString 以替换字符处理
56
+ return 1; // 非法起始字节:交给 bytesToStringSync 以替换字符处理
57
57
  };
58
58
 
59
59
  return {
@@ -84,12 +84,12 @@ function _makeUtf8StreamDecoder() {
84
84
 
85
85
  pending = cut === buf.length ? new Uint8Array(0) : buf.slice(cut);
86
86
  const complete = cut === buf.length ? buf : buf.subarray(0, cut);
87
- return complete.length ? bytesToString(complete) : null;
87
+ return complete.length ? bytesToStringSync(complete) : null;
88
88
  },
89
89
  /** EOF:把剩余的不完整序列交给 Java 解码(通常产出 U+FFFD)。 */
90
90
  flush(): string | null {
91
91
  if (!pending.length) return null;
92
- const s = bytesToString(pending);
92
+ const s = bytesToStringSync(pending);
93
93
  pending = new Uint8Array(0);
94
94
  return s;
95
95
  },
@@ -394,7 +394,7 @@ function _makeWriteStream(
394
394
  const check = () => { if (closed) throw new Error('write stream closed'); };
395
395
  const toBytes = (chunk: Uint8Array | string): Uint8Array => {
396
396
  if (typeof chunk !== 'string') return chunk; // Uint8Array 始终按原始字节写入
397
- return encoding === 'base64' ? Uint8Array.fromBase64(chunk) : stringToBytes(chunk);
397
+ return encoding === 'base64' ? Uint8Array.fromBase64(chunk) : stringToBytesSync(chunk);
398
398
  };
399
399
  return {
400
400
  encoding,
package/src/global.d.ts CHANGED
@@ -29,12 +29,43 @@ declare global {
29
29
  headers: { get(name: string): string | undefined };
30
30
  text(): Promise<string>;
31
31
  json(): Promise<any>;
32
+ base64(): Promise<string>;
33
+ bytes(): Promise<Uint8Array>;
34
+ arrayBuffer(): Promise<ArrayBuffer>;
32
35
  }
33
36
  function fetch(
34
37
  url: string,
35
- init?: { method?: string; headers?: Record<string, string>; body?: string | null }
38
+ init?: { method?: string; headers?: Record<string, string>; body?: string | Uint8Array | null; encoding?: 'utf8' | 'base64'; timeout?: number }
36
39
  ): Promise<YeowResponse>;
37
40
 
41
+ // ── TextEncoder / TextDecoder(utf-8,polyfill 注入;同步 API)──
42
+ interface TextEncoder {
43
+ readonly encoding: string;
44
+ encode(input?: string): Uint8Array;
45
+ }
46
+ const TextEncoder: {
47
+ new (encoding?: string): TextEncoder;
48
+ prototype: TextEncoder;
49
+ };
50
+
51
+ interface TextDecoder {
52
+ readonly encoding: string;
53
+ decode(input?: ArrayBuffer | ArrayBufferView): string;
54
+ }
55
+ const TextDecoder: {
56
+ new (encoding?: string): TextDecoder;
57
+ prototype: TextDecoder;
58
+ };
59
+
60
+ // ── performance(高精度单调时间)──
61
+ interface Performance {
62
+ /** 相对上下文起点的毫秒数(单调、亚毫秒精度)。 */
63
+ now(): number;
64
+ /** 上下文创建时的 epoch 毫秒。 */
65
+ readonly timeOrigin: number;
66
+ }
67
+ var performance: Performance;
68
+
38
69
  function setTimeout(handler: (...args: any[]) => void, timeout?: number, ...args: any[]): string;
39
70
  function clearTimeout(id: string): void;
40
71
  function setInterval(handler: (...args: any[]) => void, timeout?: number, ...args: any[]): string;
package/src/http.ts CHANGED
@@ -40,7 +40,7 @@ export interface RequestOptions {
40
40
  encoding?: 'utf8' | 'base64';
41
41
  /**
42
42
  * 响应体形态:缺省 `Uint8Array`(原始字节,可在收到后自行解码,
43
- * 如 `bytesToString(body)` 或 `new TextDecoder().decode(body)`);
43
+ * 如 `bytesToStringSync(body)` 或 `new TextDecoder().decode(body)`);
44
44
  * `'utf8'` → UTF-8 字符串;`'base64'` → base64 字符串(原样返回,不解码)。
45
45
  */
46
46
  responseEncoding?: 'utf8' | 'base64';
@@ -115,7 +115,7 @@ _registerCallback(() => {
115
115
  * 请求体与 `fs.writeFile` 同语义(`body: string | Uint8Array`,字符串按
116
116
  * `encoding` 解释);响应体默认 `Uint8Array`(原始字节),可用
117
117
  * `responseEncoding` 直接得到字符串(`'utf8'` / `'base64'`),也可在收到后
118
- * 用 `bytesToString` 自行解码。`timeout` 指定超时毫秒数(连接与读取,缺省
118
+ * 用 `bytesToStringSync` 自行解码。`timeout` 指定超时毫秒数(连接与读取,缺省
119
119
  * 运行时默认)。
120
120
  */
121
121
  export function request(url: string, opts: RequestOptions = {}): Promise<HttpResponse> {
package/src/inventory.ts CHANGED
@@ -2,6 +2,8 @@ import { call, post } from './task.js';
2
2
  import type { TaskOptions } from './task.js';
3
3
  import type { ItemStack } from './item.js';
4
4
  import { InstanceId } from './instance-id.js';
5
+ import { resolveUuid } from './target.js';
6
+ import type { PlayerTarget } from './target.js';
5
7
 
6
8
  /**
7
9
  * Inventory —— 统一容器抽象,三种持有者:
@@ -141,9 +143,9 @@ export class Inventory {
141
143
 
142
144
  // ── 自定义 Inventory 专属 ─────────────────────────────────────────
143
145
 
144
- /** 为玩家打开(自定义 Inventory)。 */
145
- open(uuid: string, options?: TaskOptions): Promise<boolean> {
146
- return post<boolean>('inventory.open', { ...this.address(), uuid }, options);
146
+ /** 为玩家打开(自定义 Inventory;接受 `Player` 对象或 uuid)。 */
147
+ open(player: PlayerTarget, options?: TaskOptions): Promise<boolean> {
148
+ return post<boolean>('inventory.open', { ...this.address(), uuid: resolveUuid(player) }, options);
147
149
  }
148
150
 
149
151
  /** 关闭所有查看者(自定义 Inventory)。 */
@@ -151,9 +153,9 @@ export class Inventory {
151
153
  return post<boolean>('inventory.close', this.address(), options);
152
154
  }
153
155
 
154
- /** 仅关闭指定玩家(自定义 Inventory)。 */
155
- closePlayer(uuid: string, options?: TaskOptions): Promise<boolean> {
156
- return post<boolean>('inventory.closePlayer', { ...this.address(), uuid }, options);
156
+ /** 仅关闭指定玩家(自定义 Inventory;接受 `Player` 对象或 uuid)。 */
157
+ closePlayer(player: PlayerTarget, options?: TaskOptions): Promise<boolean> {
158
+ return post<boolean>('inventory.closePlayer', { ...this.address(), uuid: resolveUuid(player) }, options);
157
159
  }
158
160
 
159
161
  /** 当前查看者 uuid 列表(自定义 Inventory)。 */
package/src/material.ts CHANGED
@@ -55,4 +55,12 @@ export const Material = {
55
55
  isAirSync(type: string, options?: TaskOptions): boolean {
56
56
  return call<boolean>('material.isAir', { type }, options);
57
57
  },
58
+
59
+ /** 最大耐久(非耐用品返回 0;未知类型抛错)。 */
60
+ getMaxDurability(type: string, options?: TaskOptions): Promise<number> {
61
+ return post<number>('material.getMaxDurability', { type }, options);
62
+ },
63
+ getMaxDurabilitySync(type: string, options?: TaskOptions): number {
64
+ return call<number>('material.getMaxDurability', { type }, options);
65
+ },
58
66
  };
package/src/player.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { call, post } from './task.js';
2
2
  import type { TaskOptions } from './task.js';
3
+ import { LivingEntity } from './entity.js';
3
4
  import { Location, LocationData } from './location.js';
4
5
  import type { ItemStack } from './item.js';
5
6
  import { Block } from './block.js';
6
7
  import type { Message } from './message.js';
7
8
  import type { Permission } from './permission.js';
9
+ import type { AdvancementProgress } from './advancement.js';
8
10
  import { Inventory } from './inventory.js';
9
11
  import {
10
12
  get as pdcGet, set as pdcSet, has as pdcHas, remove as pdcRemove,
@@ -16,7 +18,7 @@ interface PlayerData {
16
18
  name: string;
17
19
  }
18
20
 
19
- export class Player {
21
+ export class Player extends LivingEntity {
20
22
  static get(identifier: string, options?: TaskOptions): Promise<Player | null> {
21
23
  return post<PlayerData>('player.get', { identifier }, options).then((d) => (d ? new Player(d.uuid, d.name) : null));
22
24
  }
@@ -31,7 +33,10 @@ export class Player {
31
33
  return call<PlayerData[]>('player.getAll', {}, options).map((r) => new Player(r.uuid, r.name));
32
34
  }
33
35
 
34
- constructor(public readonly uuid: string, private _name?: string) {}
36
+ // uuid Entity 基类持有(readonly);本类扩展玩家特有字段。
37
+ constructor(uuid: string, private _name?: string) {
38
+ super(uuid);
39
+ }
35
40
 
36
41
  /** 玩家名。未提供时首次访问惰性同步获取并缓存(仅一次往返)。 */
37
42
  get name(): string {
@@ -153,6 +158,20 @@ export class Player {
153
158
  playSoundSync(sound: string, volume?: number, pitch?: number, options?: TaskOptions): void {
154
159
  call('player.playSound', { uuid: this.uuid, sound, volume, pitch }, options);
155
160
  }
161
+ /** 停止播放指定音效。 */
162
+ stopSound(sound: string, options?: TaskOptions): Promise<void> {
163
+ return post('player.stopSound', { uuid: this.uuid, sound }, options);
164
+ }
165
+ stopSoundSync(sound: string, options?: TaskOptions): void {
166
+ call('player.stopSound', { uuid: this.uuid, sound }, options);
167
+ }
168
+ /** 停止该玩家所有音效。 */
169
+ stopAllSounds(options?: TaskOptions): Promise<void> {
170
+ return post('player.stopAllSounds', { uuid: this.uuid }, options);
171
+ }
172
+ stopAllSoundsSync(options?: TaskOptions): void {
173
+ call('player.stopAllSounds', { uuid: this.uuid }, options);
174
+ }
156
175
  giveExp(amount: number, options?: TaskOptions): Promise<void> { return post('player.giveExp', { uuid: this.uuid, amount }, options); }
157
176
  giveExpSync(amount: number, options?: TaskOptions): void { call('player.giveExp', { uuid: this.uuid, amount }, options); }
158
177
  /** 检查权限(经 Yeow 权限检查:`permissionCheck` 事件优先,无处理时回退 Bukkit)。node 可为权限节点对象。 */
@@ -169,6 +188,41 @@ export class Player {
169
188
  performCommandSync(cmd: string, options?: TaskOptions): boolean {
170
189
  return call<boolean>('player.performCommand', { uuid: this.uuid, command: cmd.replace(/^\//, '') }, options);
171
190
  }
191
+ /** 授予进度全部条件。 */
192
+ grantAdvancement(key: string, options?: TaskOptions): Promise<boolean> {
193
+ return post<boolean>('advancement.grant', { uuid: this.uuid, key }, options);
194
+ }
195
+ grantAdvancementSync(key: string, options?: TaskOptions): boolean {
196
+ return call<boolean>('advancement.grant', { uuid: this.uuid, key }, options);
197
+ }
198
+ /** 撤销进度全部条件。 */
199
+ revokeAdvancement(key: string, options?: TaskOptions): Promise<boolean> {
200
+ return post<boolean>('advancement.revoke', { uuid: this.uuid, key }, options);
201
+ }
202
+ revokeAdvancementSync(key: string, options?: TaskOptions): boolean {
203
+ return call<boolean>('advancement.revoke', { uuid: this.uuid, key }, options);
204
+ }
205
+ /** 查询进度完成情况。 */
206
+ getAdvancementProgress(key: string, options?: TaskOptions): Promise<AdvancementProgress | null> {
207
+ return post<AdvancementProgress | null>('advancement.getProgress', { uuid: this.uuid, key }, options);
208
+ }
209
+ getAdvancementProgressSync(key: string, options?: TaskOptions): AdvancementProgress | null {
210
+ return call<AdvancementProgress | null>('advancement.getProgress', { uuid: this.uuid, key }, options);
211
+ }
212
+ /** 授予进度单个条件。 */
213
+ awardCriteria(key: string, criteria: string, options?: TaskOptions): Promise<boolean> {
214
+ return post<boolean>('advancement.awardCriteria', { uuid: this.uuid, key, criteria }, options);
215
+ }
216
+ awardCriteriaSync(key: string, criteria: string, options?: TaskOptions): boolean {
217
+ return call<boolean>('advancement.awardCriteria', { uuid: this.uuid, key, criteria }, options);
218
+ }
219
+ /** 撤销进度单个条件。 */
220
+ revokeCriteria(key: string, criteria: string, options?: TaskOptions): Promise<boolean> {
221
+ return post<boolean>('advancement.revokeCriteria', { uuid: this.uuid, key, criteria }, options);
222
+ }
223
+ revokeCriteriaSync(key: string, criteria: string, options?: TaskOptions): boolean {
224
+ return call<boolean>('advancement.revokeCriteria', { uuid: this.uuid, key, criteria }, options);
225
+ }
172
226
  teleport(loc: Location, options?: TaskOptions): Promise<void> { return post('player.teleport', { uuid: this.uuid, ...loc.toObject() }, options); }
173
227
  teleportSync(loc: Location, options?: TaskOptions): void { call('player.teleport', { uuid: this.uuid, ...loc.toObject() }, options); }
174
228
  /** 向玩家发送假方块变化(仅客户端视觉,不改变真实世界)。block 为 Block 对象或字符串(同 world.setBlock,字符串无状态)。 */
@@ -236,14 +290,6 @@ export class Player {
236
290
  return call<boolean>('player.setPlayerListName', { uuid: this.uuid, name }, options);
237
291
  }
238
292
 
239
- /** 设置客户端世界边界(传 null 重置为服务端边界;centerX/centerZ 可选,指定边界中心)。 */
240
- setBorder(size: number | null, centerX?: number, centerZ?: number, options?: TaskOptions): Promise<boolean> {
241
- return post<boolean>('player.setBorder', { uuid: this.uuid, size, centerX, centerZ }, options);
242
- }
243
- setBorderSync(size: number | null, centerX?: number, centerZ?: number, options?: TaskOptions): boolean {
244
- return call<boolean>('player.setBorder', { uuid: this.uuid, size, centerX, centerZ }, options);
245
- }
246
-
247
293
  // ── PDC(玩家持久数据) ──
248
294
 
249
295
  /** 读取并 JSON 反序列化(无值返回 null;旧数据非 JSON 时原样返回字符串)。 */