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/src/potion.ts CHANGED
@@ -1,24 +1,18 @@
1
- import { post } from './task.js';
2
- import type { TaskOptions } from './task.js';
1
+ // 药水效果类型定义。操作已上移到 `entity.ts` LivingEntity 实例方法
2
+ // (`entity.addPotionEffect(...)` 等)——不再提供顶层 uuid 函数。
3
3
 
4
+ /** 药水效果(`entity.addPotionEffect` 任务载荷;与 `getActivePotionEffects` 输出同结构)。 */
4
5
  export interface PotionEffect {
6
+ /** 药水效果类型(值域 R1 注册键,如 `minecraft:speed`;兼容旧枚举名,大小写不敏感)。 */
5
7
  type: string;
8
+ /** 持续时间(tick)。 */
6
9
  duration: number;
10
+ /** 等级(0 = 一级)。 */
7
11
  amplifier: number;
12
+ /** 是否环境指示剂(默认 true)。 */
8
13
  ambient?: boolean;
14
+ /** 是否显示粒子(默认 true)。 */
9
15
  particles?: boolean;
16
+ /** 是否显示图标(默认 true)。 */
10
17
  icon?: boolean;
11
18
  }
12
-
13
- export function addPotionEffect(uuid: string, effect: PotionEffect, options?: TaskOptions): Promise<void> {
14
- return post('entity.addPotionEffect', { uuid, ...effect }, options);
15
- }
16
- export function removePotionEffect(uuid: string, type: string, options?: TaskOptions): Promise<void> {
17
- return post('entity.removePotionEffect', { uuid, type }, options);
18
- }
19
- export function clearPotionEffects(uuid: string, options?: TaskOptions): Promise<void> {
20
- return post('entity.clearPotionEffects', { uuid }, options);
21
- }
22
- export function getActivePotionEffects(uuid: string, options?: TaskOptions): Promise<PotionEffect[]> {
23
- return post<PotionEffect[]>('entity.getActivePotionEffects', { uuid }, options);
24
- }
package/src/scoreboard.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { post } from './task.js';
1
+ import { call, post } from './task.js';
2
2
  import type { TaskOptions } from './task.js';
3
+ import { resolveUuid } from './target.js';
4
+ import type { PlayerTarget } from './target.js';
3
5
 
4
6
  export interface ObjectiveInfo {
5
7
  name: string;
@@ -23,117 +25,280 @@ export interface TeamInfo {
23
25
  };
24
26
  }
25
27
 
26
- function boardParam(board?: string): Record<string, unknown> {
27
- return board ? { board } : {};
28
+ /** 线缆 board 参数:自定义计分板注入 `{ board: <id> }`,主计分板为空。 */
29
+ function wireBoard(boardId: string | null): Record<string, unknown> {
30
+ return boardId != null ? { board: boardId } : {};
28
31
  }
29
32
 
30
- // ── Board ──
31
-
32
- export function createBoard(id: string, options?: TaskOptions): Promise<string> {
33
- return post<string>('scoreboard.createBoard', { id }, options);
34
- }
35
-
36
- export function deleteBoard(id: string, options?: TaskOptions): Promise<void> {
37
- return post('scoreboard.deleteBoard', { id }, options);
33
+ /** 计分板 entry 解析:Player 对象取其玩家名(Bukkit 计分板按玩家名登记),字符串原样。 */
34
+ function resolveEntry(t: PlayerTarget): string {
35
+ return typeof t === 'string' ? t : t.name;
38
36
  }
39
37
 
40
- // ── Objectives ──
41
-
42
38
  /**
43
- * 创建计分项。⚠️ **Folia 平台限制**:Folia 不支持注册新 objective(registerNewObjective
44
- * UnsupportedOperationException)——在 Folia 上本调用会 reject(错误消息含
45
- * "Folia does not support creating new objectives");已存在的 objective 会更新 displayName 后返回。
39
+ * Scoreboard —— 计分板对象(OOP)。主计分板用 `Scoreboard.main()`,自定义用
40
+ * `Scoreboard.create(id)`;Objective / Team / Score 操作都在对应对象上调用,
41
+ * 不再反复传 `board`/裸名。
42
+ *
43
+ * ```js
44
+ * const board = await Scoreboard.create('myBoard');
45
+ * const obj = await board.createObjective('kills', 'dummy', '<red>Kills</red>');
46
+ * await obj.setDisplay('SIDEBAR');
47
+ * await obj.setScore(player, 42); // 接受 Player 对象或 entry 字符串
48
+ * const team = await board.createTeam('red');
49
+ * await team.add(player);
50
+ * await board.attach(player); // 为该玩家设置个人计分板
51
+ * await board.destroy();
52
+ * ```
53
+ *
54
+ * > **Folia 限制**:Folia 不支持注册新 objective/team(`createObjective` / `createTeam`
55
+ * > 会 reject);读取与修改已存在对象(`setScore` / `setTeamPrefix` 等)可用。
46
56
  */
47
- export function createObjective(name: string, criteria: string, displayName: string, board?: string, options?: TaskOptions): Promise<ObjectiveInfo> {
48
- return post<ObjectiveInfo>('scoreboard.createObjective', { name, criteria, displayName, ...boardParam(board) }, options);
49
- }
57
+ export class Scoreboard {
58
+ private constructor(readonly id: string | null) {}
50
59
 
51
- export function deleteObjective(name: string, board?: string, options?: TaskOptions): Promise<void> {
52
- return post('scoreboard.deleteObjective', { name, ...boardParam(board) }, options);
53
- }
60
+ /** 主计分板(服务器默认)。 */
61
+ static main(): Scoreboard {
62
+ return new Scoreboard(null);
63
+ }
54
64
 
55
- export function getObjectives(board?: string, options?: TaskOptions): Promise<ObjectiveInfo[]> {
56
- return post<ObjectiveInfo[]>('scoreboard.getObjectives', { ...boardParam(board) }, options);
57
- }
65
+ /** 创建自定义计分板(返回自身句柄)。 */
66
+ static async create(id: string, options?: TaskOptions): Promise<Scoreboard> {
67
+ await post('scoreboard.createBoard', { id }, options);
68
+ return new Scoreboard(id);
69
+ }
58
70
 
59
- export function setObjectiveDisplay(name: string, slot: string | null, board?: string, options?: TaskOptions): Promise<boolean> {
60
- return post<boolean>('scoreboard.setObjectiveDisplay', { name, slot, ...boardParam(board) }, options);
61
- }
71
+ static createSync(id: string, options?: TaskOptions): Scoreboard {
72
+ call('scoreboard.createBoard', { id }, options);
73
+ return new Scoreboard(id);
74
+ }
62
75
 
63
- export function getScore(objective: string, entry: string, board?: string, options?: TaskOptions): Promise<number | null> {
64
- return post<number | null>('scoreboard.getScore', { objective, entry, ...boardParam(board) }, options);
65
- }
76
+ /** 销毁自定义计分板(主计分板不可销毁,抛错)。 */
77
+ destroy(options?: TaskOptions): Promise<void> {
78
+ if (this.id == null) return Promise.reject(new Error('cannot destroy main scoreboard'));
79
+ return post('scoreboard.deleteBoard', { id: this.id }, options);
80
+ }
81
+ destroySync(options?: TaskOptions): void {
82
+ if (this.id == null) throw new Error('cannot destroy main scoreboard');
83
+ call('scoreboard.deleteBoard', { id: this.id }, options);
84
+ }
66
85
 
67
- export function setScore(objective: string, entry: string, value: number, board?: string, options?: TaskOptions): Promise<void> {
68
- return post('scoreboard.setScore', { objective, entry, value, ...boardParam(board) }, options);
69
- }
86
+ /** 为该玩家设置其个人计分板为本计分板(接受 `Player` 对象或 uuid;重置用 `Scoreboard.main().attach(player)`)。 */
87
+ attach(player: PlayerTarget, options?: TaskOptions): Promise<void> {
88
+ return post('scoreboard.setPlayerBoard', { uuid: resolveUuid(player), ...wireBoard(this.id) }, options);
89
+ }
90
+ attachSync(player: PlayerTarget, options?: TaskOptions): void {
91
+ call('scoreboard.setPlayerBoard', { uuid: resolveUuid(player), ...wireBoard(this.id) }, options);
92
+ }
70
93
 
71
- export function resetScore(objective: string, entry: string, board?: string, options?: TaskOptions): Promise<void> {
72
- return post('scoreboard.resetScore', { objective, entry, ...boardParam(board) }, options);
73
- }
94
+ // ── Objective ──
74
95
 
75
- // ── Teams ──
96
+ createObjective(name: string, criteria: string, displayName: string, options?: TaskOptions): Promise<Objective> {
97
+ return post<{ name: string; criteria: string }>('scoreboard.createObjective', { name, criteria, displayName, ...wireBoard(this.id) }, options)
98
+ .then((o) => new Objective(this.id, o.name, o.criteria, null));
99
+ }
100
+ createObjectiveSync(name: string, criteria: string, displayName: string, options?: TaskOptions): Objective {
101
+ const o = call<{ name: string; criteria: string }>('scoreboard.createObjective', { name, criteria, displayName, ...wireBoard(this.id) }, options);
102
+ return new Objective(this.id, o.name, o.criteria, null);
103
+ }
76
104
 
77
- /**
78
- * 创建队伍。⚠️ **Folia 平台限制**:Folia 不支持注册新 team(registerNewTeam 抛
79
- * UnsupportedOperationException)——在 Folia 上本调用会 reject;已存在的 team 返回其信息。
80
- */
81
- export function createTeam(name: string, board?: string, options?: TaskOptions): Promise<void> {
82
- return post('scoreboard.createTeam', { name, ...boardParam(board) }, options);
83
- }
105
+ getObjectives(options?: TaskOptions): Promise<Objective[]> {
106
+ return post<ObjectiveInfo[]>('scoreboard.getObjectives', { ...wireBoard(this.id) }, options)
107
+ .then((list) => list.map((o) => new Objective(this.id, o.name, o.criteria, o.displaySlot)));
108
+ }
109
+ getObjectivesSync(options?: TaskOptions): Objective[] {
110
+ return call<ObjectiveInfo[]>('scoreboard.getObjectives', { ...wireBoard(this.id) }, options)
111
+ .map((o) => new Objective(this.id, o.name, o.criteria, o.displaySlot));
112
+ }
84
113
 
85
- export function deleteTeam(name: string, board?: string, options?: TaskOptions): Promise<void> {
86
- return post('scoreboard.deleteTeam', { name, ...boardParam(board) }, options);
87
- }
114
+ // ── Team ──
88
115
 
89
- export function getTeam(name: string, board?: string, options?: TaskOptions): Promise<TeamInfo | null> {
90
- return post<TeamInfo | null>('scoreboard.getTeam', { name, ...boardParam(board) }, options);
91
- }
116
+ createTeam(name: string, options?: TaskOptions): Promise<Team> {
117
+ return post('scoreboard.createTeam', { name, ...wireBoard(this.id) }, options)
118
+ .then(() => this.getTeam(name))
119
+ .then((t) => {
120
+ if (!t) throw new Error('team created but not found: ' + name);
121
+ return t;
122
+ });
123
+ }
124
+ createTeamSync(name: string, options?: TaskOptions): Team {
125
+ call('scoreboard.createTeam', { name, ...wireBoard(this.id) }, options);
126
+ const t = this.getTeamSync(name);
127
+ if (!t) throw new Error('team created but not found: ' + name);
128
+ return t;
129
+ }
92
130
 
93
- export function getTeams(board?: string, options?: TaskOptions): Promise<TeamInfo[]> {
94
- return post<TeamInfo[]>('scoreboard.getTeams', { ...boardParam(board) }, options);
95
- }
131
+ getTeam(name: string, options?: TaskOptions): Promise<Team | null> {
132
+ return post<TeamInfo | null>('scoreboard.getTeam', { name, ...wireBoard(this.id) }, options)
133
+ .then((info) => (info ? new Team(this.id, info) : null));
134
+ }
135
+ getTeamSync(name: string, options?: TaskOptions): Team | null {
136
+ const info = call<TeamInfo | null>('scoreboard.getTeam', { name, ...wireBoard(this.id) }, options);
137
+ return info ? new Team(this.id, info) : null;
138
+ }
96
139
 
97
- export function setTeamDisplayName(name: string, displayName: string, board?: string, options?: TaskOptions): Promise<void> {
98
- return post('scoreboard.setTeamDisplayName', { name, displayName, ...boardParam(board) }, options);
140
+ getTeams(options?: TaskOptions): Promise<Team[]> {
141
+ return post<TeamInfo[]>('scoreboard.getTeams', { ...wireBoard(this.id) }, options)
142
+ .then((list) => list.map((info) => new Team(this.id, info)));
143
+ }
144
+ getTeamsSync(options?: TaskOptions): Team[] {
145
+ return call<TeamInfo[]>('scoreboard.getTeams', { ...wireBoard(this.id) }, options)
146
+ .map((info) => new Team(this.id, info));
147
+ }
99
148
  }
100
149
 
101
- export function setTeamPrefix(name: string, prefix: string, board?: string, options?: TaskOptions): Promise<void> {
102
- return post('scoreboard.setTeamPrefix', { name, prefix, ...boardParam(board) }, options);
103
- }
150
+ /** 计分项(objective)句柄。 */
151
+ export class Objective {
152
+ constructor(
153
+ private readonly boardId: string | null,
154
+ public readonly name: string,
155
+ public readonly criteria?: string,
156
+ public readonly displaySlot: string | null = null,
157
+ ) {}
104
158
 
105
- export function setTeamSuffix(name: string, suffix: string, board?: string, options?: TaskOptions): Promise<void> {
106
- return post('scoreboard.setTeamSuffix', { name, suffix, ...boardParam(board) }, options);
107
- }
159
+ /** 设置显示位置(slot BELOW_NAME/PLAYER_LIST/SIDEBAR;null 取消显示)。 */
160
+ setDisplay(slot: string | null, options?: TaskOptions): Promise<boolean> {
161
+ return post<boolean>('scoreboard.setObjectiveDisplay', { name: this.name, slot, ...wireBoard(this.boardId) }, options);
162
+ }
163
+ setDisplaySync(slot: string | null, options?: TaskOptions): boolean {
164
+ return call<boolean>('scoreboard.setObjectiveDisplay', { name: this.name, slot, ...wireBoard(this.boardId) }, options);
165
+ }
108
166
 
109
- export function setTeamColor(name: string, color: string, board?: string, options?: TaskOptions): Promise<void> {
110
- return post('scoreboard.setTeamColor', { name, color, ...boardParam(board) }, options);
111
- }
167
+ /** 设置分数(target `Player` 对象或 entry 字符串)。 */
168
+ setScore(target: PlayerTarget, value: number, options?: TaskOptions): Promise<void> {
169
+ return post('scoreboard.setScore', { objective: this.name, entry: resolveEntry(target), value, ...wireBoard(this.boardId) }, options);
170
+ }
171
+ setScoreSync(target: PlayerTarget, value: number, options?: TaskOptions): void {
172
+ call('scoreboard.setScore', { objective: this.name, entry: resolveEntry(target), value, ...wireBoard(this.boardId) }, options);
173
+ }
112
174
 
113
- export function setTeamFriendlyFire(name: string, allow: boolean, board?: string, options?: TaskOptions): Promise<void> {
114
- return post('scoreboard.setTeamFriendlyFire', { name, allow, ...boardParam(board) }, options);
115
- }
175
+ /** 查询分数(无记录返回 null)。 */
176
+ getScore(target: PlayerTarget, options?: TaskOptions): Promise<number | null> {
177
+ return post<number | null>('scoreboard.getScore', { objective: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
178
+ }
179
+ getScoreSync(target: PlayerTarget, options?: TaskOptions): number | null {
180
+ return call<number | null>('scoreboard.getScore', { objective: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
181
+ }
116
182
 
117
- export function setTeamSeeInvisible(name: string, canSee: boolean, board?: string, options?: TaskOptions): Promise<void> {
118
- return post('scoreboard.setTeamSeeInvisible', { name, canSee, ...boardParam(board) }, options);
119
- }
183
+ /** 重置(清除)分数。 */
184
+ resetScore(target: PlayerTarget, options?: TaskOptions): Promise<void> {
185
+ return post('scoreboard.resetScore', { objective: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
186
+ }
187
+ resetScoreSync(target: PlayerTarget, options?: TaskOptions): void {
188
+ call('scoreboard.resetScore', { objective: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
189
+ }
120
190
 
121
- export function setTeamOption(name: string, option: string, value: string, board?: string, options?: TaskOptions): Promise<void> {
122
- return post('scoreboard.setTeamOption', { name, option, value, ...boardParam(board) }, options);
191
+ /** 删除此计分项。 */
192
+ delete(options?: TaskOptions): Promise<void> {
193
+ return post('scoreboard.deleteObjective', { name: this.name, ...wireBoard(this.boardId) }, options);
194
+ }
195
+ deleteSync(options?: TaskOptions): void {
196
+ call('scoreboard.deleteObjective', { name: this.name, ...wireBoard(this.boardId) }, options);
197
+ }
123
198
  }
124
199
 
125
- export function teamAddEntry(name: string, entry: string, board?: string, options?: TaskOptions): Promise<void> {
126
- return post('scoreboard.teamAddEntry', { name, entry, ...boardParam(board) }, options);
127
- }
200
+ /** 队伍(team)句柄;携带读取时刻的快照字段。 */
201
+ export class Team {
202
+ readonly name: string;
203
+ readonly displayName: string;
204
+ readonly prefix: string;
205
+ readonly suffix: string;
206
+ readonly color: string;
207
+ readonly allowFriendlyFire: boolean;
208
+ readonly canSeeFriendlyInvisibles: boolean;
209
+ readonly entries: string[];
210
+ readonly options: TeamInfo['options'];
128
211
 
129
- export function teamRemoveEntry(name: string, entry: string, board?: string, options?: TaskOptions): Promise<void> {
130
- return post('scoreboard.teamRemoveEntry', { name, entry, ...boardParam(board) }, options);
131
- }
212
+ constructor(private readonly boardId: string | null, info: TeamInfo) {
213
+ this.name = info.name;
214
+ this.displayName = info.displayName;
215
+ this.prefix = info.prefix;
216
+ this.suffix = info.suffix;
217
+ this.color = info.color;
218
+ this.allowFriendlyFire = info.allowFriendlyFire;
219
+ this.canSeeFriendlyInvisibles = info.canSeeFriendlyInvisibles;
220
+ this.entries = info.entries;
221
+ this.options = info.options;
222
+ }
132
223
 
133
- export function teamGetEntries(name: string, board?: string, options?: TaskOptions): Promise<string[]> {
134
- return post<string[]>('scoreboard.teamGetEntries', { name, ...boardParam(board) }, options);
135
- }
224
+ setDisplayName(v: string, options?: TaskOptions): Promise<void> {
225
+ return post('scoreboard.setTeamDisplayName', { name: this.name, displayName: v, ...wireBoard(this.boardId) }, options);
226
+ }
227
+ setDisplayNameSync(v: string, options?: TaskOptions): void {
228
+ call('scoreboard.setTeamDisplayName', { name: this.name, displayName: v, ...wireBoard(this.boardId) }, options);
229
+ }
230
+
231
+ setPrefix(v: string, options?: TaskOptions): Promise<void> {
232
+ return post('scoreboard.setTeamPrefix', { name: this.name, prefix: v, ...wireBoard(this.boardId) }, options);
233
+ }
234
+ setPrefixSync(v: string, options?: TaskOptions): void {
235
+ call('scoreboard.setTeamPrefix', { name: this.name, prefix: v, ...wireBoard(this.boardId) }, options);
236
+ }
237
+
238
+ setSuffix(v: string, options?: TaskOptions): Promise<void> {
239
+ return post('scoreboard.setTeamSuffix', { name: this.name, suffix: v, ...wireBoard(this.boardId) }, options);
240
+ }
241
+ setSuffixSync(v: string, options?: TaskOptions): void {
242
+ call('scoreboard.setTeamSuffix', { name: this.name, suffix: v, ...wireBoard(this.boardId) }, options);
243
+ }
244
+
245
+ setColor(v: string, options?: TaskOptions): Promise<void> {
246
+ return post('scoreboard.setTeamColor', { name: this.name, color: v, ...wireBoard(this.boardId) }, options);
247
+ }
248
+ setColorSync(v: string, options?: TaskOptions): void {
249
+ call('scoreboard.setTeamColor', { name: this.name, color: v, ...wireBoard(this.boardId) }, options);
250
+ }
251
+
252
+ setFriendlyFire(allow: boolean, options?: TaskOptions): Promise<void> {
253
+ return post('scoreboard.setTeamFriendlyFire', { name: this.name, allow, ...wireBoard(this.boardId) }, options);
254
+ }
255
+ setFriendlyFireSync(allow: boolean, options?: TaskOptions): void {
256
+ call('scoreboard.setTeamFriendlyFire', { name: this.name, allow, ...wireBoard(this.boardId) }, options);
257
+ }
258
+
259
+ setSeeInvisible(canSee: boolean, options?: TaskOptions): Promise<void> {
260
+ return post('scoreboard.setTeamSeeInvisible', { name: this.name, canSee, ...wireBoard(this.boardId) }, options);
261
+ }
262
+ setSeeInvisibleSync(canSee: boolean, options?: TaskOptions): void {
263
+ call('scoreboard.setTeamSeeInvisible', { name: this.name, canSee, ...wireBoard(this.boardId) }, options);
264
+ }
265
+
266
+ setOption(option: string, value: string, options?: TaskOptions): Promise<void> {
267
+ return post('scoreboard.setTeamOption', { name: this.name, option, value, ...wireBoard(this.boardId) }, options);
268
+ }
269
+ setOptionSync(option: string, value: string, options?: TaskOptions): void {
270
+ call('scoreboard.setTeamOption', { name: this.name, option, value, ...wireBoard(this.boardId) }, options);
271
+ }
272
+
273
+ /** 添加成员(`Player` 对象取其名,或 entry 字符串)。 */
274
+ add(target: PlayerTarget, options?: TaskOptions): Promise<void> {
275
+ return post('scoreboard.teamAddEntry', { name: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
276
+ }
277
+ addSync(target: PlayerTarget, options?: TaskOptions): void {
278
+ call('scoreboard.teamAddEntry', { name: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
279
+ }
280
+
281
+ /** 移除成员。 */
282
+ remove(target: PlayerTarget, options?: TaskOptions): Promise<void> {
283
+ return post('scoreboard.teamRemoveEntry', { name: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
284
+ }
285
+ removeSync(target: PlayerTarget, options?: TaskOptions): void {
286
+ call('scoreboard.teamRemoveEntry', { name: this.name, entry: resolveEntry(target), ...wireBoard(this.boardId) }, options);
287
+ }
288
+
289
+ /** 成员列表(快照)。 */
290
+ getEntries(options?: TaskOptions): Promise<string[]> {
291
+ return post<string[]>('scoreboard.teamGetEntries', { name: this.name, ...wireBoard(this.boardId) }, options);
292
+ }
293
+ getEntriesSync(options?: TaskOptions): string[] {
294
+ return call<string[]>('scoreboard.teamGetEntries', { name: this.name, ...wireBoard(this.boardId) }, options);
295
+ }
136
296
 
137
- export function setPlayerBoard(uuid: string, board?: string, options?: TaskOptions): Promise<void> {
138
- return post('scoreboard.setPlayerBoard', { uuid, ...boardParam(board) }, options);
297
+ /** 删除队伍。 */
298
+ delete(options?: TaskOptions): Promise<void> {
299
+ return post('scoreboard.deleteTeam', { name: this.name, ...wireBoard(this.boardId) }, options);
300
+ }
301
+ deleteSync(options?: TaskOptions): void {
302
+ call('scoreboard.deleteTeam', { name: this.name, ...wireBoard(this.boardId) }, options);
303
+ }
139
304
  }