tiaoom 0.0.1

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.
@@ -0,0 +1,383 @@
1
+ //#region lib/client.d.ts
2
+ type TiaoomEvents = {
3
+ /**
4
+ * 连接准备就绪事件
5
+ */
6
+ "sys.ready": () => void;
7
+ /**
8
+ * 连接错误事件
9
+ * @param error 错误信息
10
+ */
11
+ "sys.error": (error: any) => void;
12
+ /**
13
+ * 连接关闭事件
14
+ */
15
+ "sys.close": () => void;
16
+ /**
17
+ * 全局命令事件
18
+ * @param data 命令内容
19
+ */
20
+ "global.command": (data: any & {
21
+ sender: Player;
22
+ }) => void;
23
+ /**
24
+ * 玩家列表更新事件
25
+ * @param players 玩家列表
26
+ */
27
+ "player.list": (players: Player[]) => void;
28
+ /**
29
+ * 玩家登录事件
30
+ * @param player 玩家信息
31
+ */
32
+ "player.login": (player: Player) => void;
33
+ /**
34
+ * 玩家登出事件
35
+ * @param player 玩家信息
36
+ */
37
+ "player.logout": (player: Player) => void;
38
+ /**
39
+ * 玩家状态更新事件
40
+ * @param player 玩家信息
41
+ * @param status 状态
42
+ * @param roomId 房间ID(可选)
43
+ */
44
+ "player.status": (player: Player, status: string, roomId?: string) => void;
45
+ /**
46
+ * 玩家命令事件
47
+ * @param command 命令内容
48
+ */
49
+ "player.command": (command: any & {
50
+ sender: Player;
51
+ }) => void;
52
+ /**
53
+ * 玩家消息事件
54
+ * @param message 消息内容
55
+ */
56
+ "player.message": (message: any & {
57
+ sender: Player;
58
+ }) => void;
59
+ /**
60
+ * 房间列表更新事件
61
+ * @param rooms 房间列表
62
+ */
63
+ "room.list": (rooms: Room[]) => void;
64
+ /**
65
+ * 房间创建事件
66
+ * @param room 房间信息
67
+ */
68
+ "room.create": (room: Room) => void;
69
+ /**
70
+ * 房间更新事件
71
+ * @param room 房间信息
72
+ */
73
+ "room.update": (room: Room) => void;
74
+ /**
75
+ * 房间关闭事件
76
+ * @param room 房间信息
77
+ */
78
+ "room.close": (room: Room) => void;
79
+ /**
80
+ * 玩家加入房间事件
81
+ * @param room 房间信息
82
+ * @param player 玩家信息
83
+ */
84
+ "room.join": (room: Room, player: Player) => void;
85
+ /**
86
+ * 玩家离开房间事件
87
+ * @param room 房间信息
88
+ * @param player 玩家信息
89
+ */
90
+ "room.leave": (room: Room, player: Player) => void;
91
+ /**
92
+ * 房间开始游戏事件
93
+ * @param room 房间信息
94
+ */
95
+ "room.start": (room: Room) => void;
96
+ /**
97
+ * 房间结束游戏事件
98
+ * @param room 房间信息
99
+ */
100
+ "room.end": (room: Room) => void;
101
+ /**
102
+ * 房间玩家全部准备事件
103
+ * @param room 房间信息
104
+ */
105
+ "room.all-ready": (room: Room) => void;
106
+ /**
107
+ * 房间命令事件
108
+ * @param command 命令内容
109
+ */
110
+ "room.command": (command: any & {
111
+ sender: Player;
112
+ }) => void;
113
+ /**
114
+ * 房间消息事件
115
+ * @param message 消息内容
116
+ */
117
+ "room.message": (message: any & {
118
+ sender: Player;
119
+ }) => void;
120
+ /**
121
+ * 房间玩家准备事件
122
+ * @param player 玩家信息
123
+ * @param roomId 房间ID(可选)
124
+ */
125
+ "room.player-ready": (player: Player, roomId?: string) => void;
126
+ /**
127
+ * 房间玩家取消准备事件
128
+ * @param player 玩家信息
129
+ * @param roomId 房间ID(可选)
130
+ */
131
+ "room.player-unready": (player: Player, roomId?: string) => void;
132
+ /**
133
+ * 玩家列表更新事件(内部)
134
+ * @param players 玩家列表
135
+ */
136
+ "onPlayerList": (players: Player[]) => void;
137
+ /**
138
+ * 房间列表更新事件(内部)
139
+ * @param rooms 房间列表
140
+ */
141
+ "onRoomList": (rooms: Room[]) => void;
142
+ /**
143
+ * 房间开始游戏事件(内部)
144
+ * @param room 房间信息
145
+ */
146
+ "onRoomStart": (room: Room) => void;
147
+ /**
148
+ * 房间结束游戏事件(内部)
149
+ * @param room 房间信息
150
+ */
151
+ "onRoomEnd": (room: Room) => void;
152
+ /**
153
+ * 房间玩家全部准备事件(内部)
154
+ * @param room 房间信息
155
+ */
156
+ "onRoomAllReady": (room: Room) => void;
157
+ };
158
+ declare class Player {
159
+ id: string;
160
+ name: string;
161
+ attributes: Record<string, any>;
162
+ status: string;
163
+ constructor(player: Player);
164
+ }
165
+ declare class RoomPlayer extends Player {
166
+ role: string;
167
+ isReady: boolean;
168
+ isCreator: boolean;
169
+ constructor(player: RoomPlayer);
170
+ }
171
+ declare class Room {
172
+ id: string;
173
+ name: string;
174
+ players: RoomPlayer[];
175
+ size: number;
176
+ minSize: number;
177
+ status: string;
178
+ attrs: Record<string, any>;
179
+ constructor(room: Room);
180
+ }
181
+ /**
182
+ * Tiaoom 客户端
183
+ * @description 用于连接 Tiaoom 服务器并进行游戏交互,如创建房间、加入房间、发送命令等。
184
+ * 需继承后实现具体的连接和消息发送逻辑。
185
+ */
186
+ declare class Tiaoom {
187
+ listeners: Record<string, Function[]>;
188
+ rooms: Room[];
189
+ players: Player[];
190
+ currentPlayer: Player | null;
191
+ constructor();
192
+ /**
193
+ * 启动游戏
194
+ */
195
+ run(): this;
196
+ /**
197
+ * 连接服务器实现
198
+ */
199
+ connect(): void;
200
+ /**
201
+ * 发送消息实现
202
+ */
203
+ send(_: {
204
+ type: string;
205
+ data?: any;
206
+ }): void;
207
+ /**
208
+ * 登录
209
+ * @param {Player} player 玩家信息
210
+ */
211
+ login(player: Player): this;
212
+ /**
213
+ * 创建房间
214
+ * @param {string} name 房间名称
215
+ * @param {number} size 房间人数上限
216
+ * @param {number} minSize 房间人数下限
217
+ * @param {object} attrs 房间属性
218
+ */
219
+ createRoom({
220
+ name,
221
+ size,
222
+ minSize,
223
+ attrs
224
+ }: {
225
+ name: string;
226
+ size: number;
227
+ minSize: number;
228
+ attrs?: Record<string, any>;
229
+ }): Promise<void>;
230
+ /**
231
+ * 加入房间
232
+ * @param {string} roomId 房间ID
233
+ */
234
+ joinRoom(roomId: string): this;
235
+ /**
236
+ * 离开房间
237
+ * @param {string} roomId 房间ID
238
+ */
239
+ leaveRoom(roomId: string): this;
240
+ /**
241
+ * 开始游戏
242
+ * @param {string} id 房间ID
243
+ */
244
+ startGame(id: string): this;
245
+ /**
246
+ * 准备/取消准备
247
+ * @param {string} roomId 房间ID
248
+ * @param {boolean} isReady 是否准备
249
+ */
250
+ ready(roomId: string, isReady?: boolean): this;
251
+ /**
252
+ * 发送房间指令
253
+ * @param {string} roomId 房间ID
254
+ * @param {any} command 指令内容
255
+ */
256
+ command(command: any): this;
257
+ command(roomId: string, command: any): this;
258
+ /**
259
+ * 连接准备监听
260
+ * @param {function} cb 监听函数
261
+ */
262
+ onReady(cb: (...args: any[]) => void): this;
263
+ /**
264
+ * 玩家列表变更监听
265
+ * @param {function} cb 监听函数
266
+ */
267
+ onPlayerList(cb: (...args: any[]) => void): this;
268
+ /**
269
+ * 房间列表变更监听
270
+ * @param {function} cb 监听函数
271
+ * @param {boolean} on 开启/关闭监听
272
+ * @returns
273
+ */
274
+ onRoomList(cb: (...args: any[]) => void, on?: boolean): this;
275
+ /**
276
+ * 玩家加入监听
277
+ * @param {function} cb 监听函数
278
+ * @param {boolean} on 开启/关闭监听
279
+ * @returns
280
+ */
281
+ onPlayerJoin(cb: (...args: any[]) => void, on?: boolean): this;
282
+ /**
283
+ * 玩家离开监听
284
+ * @param {function} cb 监听函数
285
+ * @param {boolean} on 开启/关闭监听
286
+ * @returns
287
+ */
288
+ onPlayerLeave(cb: (...args: any[]) => void, on?: boolean): this;
289
+ /**
290
+ * 玩家准备监听
291
+ * @param {function} cb 监听函数
292
+ * @param {boolean} on 开启/关闭监听
293
+ * @returns
294
+ */
295
+ onPlayerReady(cb: (...args: any[]) => void, on?: boolean): this;
296
+ /**
297
+ * 玩家取消准备监听
298
+ * @param {function} cb 监听函数
299
+ * @param {boolean} on 开启/关闭监听
300
+ * @returns
301
+ */
302
+ onPlayerUnready(cb: (...args: any[]) => void, on?: boolean): this;
303
+ /**
304
+ * 玩家状态更新监听
305
+ * @param {function} cb 监听函数
306
+ * @param {boolean} on 开启/关闭监听
307
+ * @returns
308
+ */
309
+ onPlayerStatus(cb: (...args: any[]) => void, on?: boolean): this;
310
+ /**
311
+ * 房间开始游戏监听
312
+ * @param {function} cb 监听函数
313
+ * @param {boolean} on 开启/关闭监听
314
+ * @returns
315
+ */
316
+ onRoomStart(cb: (...args: any[]) => void, on?: boolean): this;
317
+ /**
318
+ * 房间结束游戏监听
319
+ * @param {function} cb 监听函数
320
+ * @param {boolean} on 开启/关闭监听
321
+ * @returns
322
+ */
323
+ onRoomEnd(cb: (...args: any[]) => void, on?: boolean): this;
324
+ /**
325
+ * 房间全部准备监听
326
+ * @param {function} cb 监听函数
327
+ * @param {boolean} on 开启/关闭监听
328
+ * @returns
329
+ */
330
+ onRoomAllReady(cb: (...args: any[]) => void, on?: boolean): this;
331
+ /**
332
+ * 房间消息监听
333
+ * @param {function} cb 监听函数
334
+ * @param {boolean} on 开启/关闭监听
335
+ * @returns
336
+ */
337
+ onRoomMessage(cb: (...args: any[]) => void, on?: boolean): this;
338
+ /**
339
+ * 玩家消息监听
340
+ * @param {function} cb 监听函数
341
+ * @param {boolean} on 开启/关闭监听
342
+ * @returns
343
+ */
344
+ onPlayerMessage(cb: (...args: any[]) => void, on?: boolean): this;
345
+ /**
346
+ * 房间指令监听
347
+ * @param {function} cb 监听函数
348
+ * @param {boolean} on 开启/关闭监听
349
+ * @returns
350
+ */
351
+ onRoomCommand(cb: (...args: any[]) => void, on?: boolean): this;
352
+ /**
353
+ * 玩家指令监听
354
+ * @param {function} cb 监听函数
355
+ * @param {boolean} on 开启/关闭监听
356
+ * @returns
357
+ */
358
+ onPlayerCommand(cb: (...args: any[]) => void, on?: boolean): this;
359
+ /**
360
+ * 事件监听
361
+ * @param {string} event 事件名称
362
+ * @param {function} listener 监听函数
363
+ * @returns
364
+ */
365
+ on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this;
366
+ /**
367
+ * 事件取消监听
368
+ * @param {string} event 事件名称
369
+ * @param {function} listener 监听函数
370
+ * @returns
371
+ */
372
+ off<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this;
373
+ /**
374
+ * 事件触发
375
+ * @param {string} event 事件名称
376
+ * @param {...any} args 参数
377
+ * @returns
378
+ */
379
+ emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): this;
380
+ }
381
+ //#endregion
382
+ export { Player, Room, RoomPlayer, Tiaoom, TiaoomEvents };
383
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1,2 @@
1
+ var Tiaoom=(function(e){var t=class{constructor(e){this.id=e.id,this.name=e.name,this.attributes=e.attributes,this.status=e.status}},n=class extends t{constructor(e){super(e),this.role=e.role,this.isReady=e.isReady,this.isCreator=e.isCreator}},r=class{constructor(e){this.id=e.id,this.name=e.name,this.players=e.players.map(e=>new n(e)),this.size=e.size,this.minSize=e.minSize,this.status=e.status,this.attrs=e.attrs}},i=class{constructor(){this.listeners={},this.rooms=[],this.players=[],this.currentPlayer=null}run(){return this.connect(),this.onReady(()=>{this.send({type:`room.list`}),this.send({type:`player.list`})}),this.on(`player.list`,e=>{this.players=e.map(e=>new t(e)),this.emit(`onPlayerList`,[...this.players])}),this.on(`player.login`,e=>{this.players.push(new t(e)),this.emit(`onPlayerList`,[...this.players])}),this.on(`player.logout`,e=>{this.players=this.players.filter(t=>t.id!==e.id),this.emit(`onPlayerList`,[...this.players])}),this.on(`room.list`,e=>{this.rooms=e.map(e=>new r(e)),this.emit(`onRoomList`,[...this.rooms])}),this.on(`room.create`,e=>{this.rooms.push(new r(e)),this.emit(`onRoomList`,this.rooms)}),this.on(`room.update`,e=>{let t=this.rooms.find(t=>t.id===e.id);t?Object.assign(t,e):this.rooms.push(new r(e)),this.emit(`onRoomList`,this.rooms)}),this.on(`room.close`,e=>{this.rooms=this.rooms.filter(t=>t.id!==e.id),this.emit(`onRoomList`,this.rooms)}),this.on(`room.update`,e=>{let t=this.rooms.find(t=>t.id===e.id);t&&(Object.assign(t,e),this.emit(`onRoomList`,this.rooms))}),this}connect(){throw Error(`Must be implement connect method`)}send(e){throw Error(`Must be implement send method`)}login(e){return this.currentPlayer=new t(e),this.send({type:`player.login`,data:e}),this}createRoom({name:e,size:t,minSize:n,attrs:r}){return new Promise(i=>{this.send({type:`room.create`,data:{name:e,size:t,minSize:n,attrs:r}}),this.on(`room.create`,e=>{i()})})}joinRoom(e){return this.send({type:`player.join`,data:{roomId:e}}),this}leaveRoom(e){return this.send({type:`player.leave`,data:{roomId:e}}),this}startGame(e){return this.send({type:`room.start`,data:{id:e}}),this}ready(e,t=!0){return this.send({type:t?`player.ready`:`player.unready`,data:{roomId:e}}),this}command(e,t){return typeof e==`string`?this.send({type:`room.player-command`,data:{id:e,...t}}):(t=e,this.send({type:`global.command`,data:t})),this}onReady(e){return this.on(`sys.ready`,e)}onPlayerList(e){return this.on(`onPlayerList`,e),this}onRoomList(e,t=!0){return t?this.on(`onRoomList`,e):this.off(`onRoomList`,e),this}onPlayerJoin(e,t=!0){return t?this.on(`room.join`,e):this.off(`room.join`,e),this}onPlayerLeave(e,t=!0){return t?this.on(`room.leave`,e):this.off(`room.leave`,e),this}onPlayerReady(e,t=!0){return t?this.on(`room.player-ready`,e):this.off(`room.player-ready`,e),this}onPlayerUnready(e,t=!0){return t?this.on(`room.player-unready`,e):this.off(`room.player-unready`,e),this}onPlayerStatus(e,t=!0){return t?this.on(`player.status`,e):this.off(`player.status`,e),this}onRoomStart(e,t=!0){return this.listeners[`room.start`]||this.on(`room.start`,e=>this.emit(`onRoomStart`,new r(e))),t?this.on(`onRoomStart`,e):this.off(`onRoomStart`,e),this}onRoomEnd(e,t=!0){return this.listeners[`room.end`]||this.on(`room.end`,e=>this.emit(`onRoomEnd`,new r(e))),t?this.on(`onRoomEnd`,e):this.off(`onRoomEnd`,e),this}onRoomAllReady(e,t=!0){return this.listeners[`room.all-ready`]||this.on(`room.all-ready`,e=>this.emit(`onRoomAllReady`,new r(e))),t?this.on(`onRoomAllReady`,e):this.off(`onRoomAllReady`,e),this}onRoomMessage(e,t=!0){return t?this.on(`room.message`,e):this.off(`room.message`,e),this}onPlayerMessage(e,t=!0){return t?this.on(`player.message`,e):this.off(`player.message`,e),this}onRoomCommand(e,t=!0){return t?this.on(`room.command`,e):this.off(`room.command`,e),this}onPlayerCommand(e,t=!0){return t?this.on(`player.command`,e):this.off(`player.command`,e),this}on(e,t){return this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(t),this}off(e,t){let n=this.listeners[e]||[],r=n.indexOf(t);return r!==-1&&n.splice(r,1),this}emit(e,...t){return(this.listeners[e]||[]).forEach(e=>e(...t)),this}};return e.Player=t,e.Room=r,e.RoomPlayer=n,e.Tiaoom=i,e})({});
2
+ //# sourceMappingURL=client.iife.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.iife.js","names":[],"sources":["../lib/client.ts"],"sourcesContent":["export type TiaoomEvents = {\n /**\n * 连接准备就绪事件\n */\n \"sys.ready\": () => void;\n /**\n * 连接错误事件\n * @param error 错误信息\n */\n \"sys.error\": (error: any) => void;\n /**\n * 连接关闭事件\n */\n \"sys.close\": () => void;\n /**\n * 全局命令事件\n * @param data 命令内容\n */\n \"global.command\": (data: any & { sender: Player }) => void;\n /**\n * 玩家列表更新事件\n * @param players 玩家列表\n */\n \"player.list\": (players: Player[]) => void;\n /**\n * 玩家登录事件\n * @param player 玩家信息\n */\n \"player.login\": (player: Player) => void;\n /**\n * 玩家登出事件\n * @param player 玩家信息\n */\n \"player.logout\": (player: Player) => void;\n /**\n * 玩家状态更新事件\n * @param player 玩家信息\n * @param status 状态\n * @param roomId 房间ID(可选)\n */\n \"player.status\": (player: Player, status: string, roomId?: string) => void;\n /**\n * 玩家命令事件\n * @param command 命令内容\n */\n \"player.command\": (command: any & { sender: Player }) => void;\n /**\n * 玩家消息事件\n * @param message 消息内容\n */\n \"player.message\": (message: any & { sender: Player }) => void;\n /**\n * 房间列表更新事件\n * @param rooms 房间列表\n */\n \"room.list\": (rooms: Room[]) => void;\n /**\n * 房间创建事件\n * @param room 房间信息\n */\n \"room.create\": (room: Room) => void;\n /**\n * 房间更新事件\n * @param room 房间信息\n */\n \"room.update\": (room: Room) => void;\n /**\n * 房间关闭事件\n * @param room 房间信息\n */\n \"room.close\": (room: Room) => void;\n /**\n * 玩家加入房间事件\n * @param room 房间信息\n * @param player 玩家信息\n */\n \"room.join\": (room: Room, player: Player) => void;\n /**\n * 玩家离开房间事件\n * @param room 房间信息\n * @param player 玩家信息\n */\n \"room.leave\": (room: Room, player: Player) => void;\n /**\n * 房间开始游戏事件\n * @param room 房间信息\n */\n \"room.start\": (room: Room) => void;\n /**\n * 房间结束游戏事件\n * @param room 房间信息\n */\n \"room.end\": (room: Room) => void;\n /**\n * 房间玩家全部准备事件\n * @param room 房间信息\n */\n \"room.all-ready\": (room: Room) => void;\n /**\n * 房间命令事件\n * @param command 命令内容\n */\n \"room.command\": (command: any & { sender: Player }) => void;\n /**\n * 房间消息事件\n * @param message 消息内容\n */\n \"room.message\": (message: any & { sender: Player }) => void;\n /**\n * 房间玩家准备事件\n * @param player 玩家信息\n * @param roomId 房间ID(可选)\n */\n \"room.player-ready\": (player: Player, roomId?: string) => void;\n /**\n * 房间玩家取消准备事件\n * @param player 玩家信息\n * @param roomId 房间ID(可选)\n */\n \"room.player-unready\": (player: Player, roomId?: string) => void;\n /**\n * 玩家列表更新事件(内部)\n * @param players 玩家列表\n */\n \"onPlayerList\": (players: Player[]) => void;\n /**\n * 房间列表更新事件(内部)\n * @param rooms 房间列表\n */\n \"onRoomList\": (rooms: Room[]) => void;\n /**\n * 房间开始游戏事件(内部)\n * @param room 房间信息\n */\n \"onRoomStart\": (room: Room) => void;\n /**\n * 房间结束游戏事件(内部)\n * @param room 房间信息\n */\n \"onRoomEnd\": (room: Room) => void;\n /**\n * 房间玩家全部准备事件(内部)\n * @param room 房间信息\n */\n \"onRoomAllReady\": (room: Room) => void;\n};\n\nexport class Player {\n id: string;\n name: string;\n attributes: Record<string, any>;\n status: string;\n constructor(player: Player) {\n this.id = player.id;\n this.name = player.name;\n this.attributes = player.attributes;\n this.status = player.status;\n }\n}\n\nexport class RoomPlayer extends Player {\n role: string;\n isReady: boolean;\n isCreator: boolean;\n constructor(player: RoomPlayer) {\n super(player);\n this.role = player.role;\n this.isReady = player.isReady;\n this.isCreator = player.isCreator;\n }\n}\n\nexport class Room {\n id: string;\n name: string;\n players: RoomPlayer[];\n size: number;\n minSize: number;\n status: string;\n attrs: Record<string, any>;\n constructor(room: Room) {\n this.id = room.id;\n this.name = room.name;\n this.players = room.players.map(player => new RoomPlayer(player));\n this.size = room.size;\n this.minSize = room.minSize;\n this.status = room.status;\n this.attrs = room.attrs;\n }\n}\n\n/**\n * Tiaoom 客户端\n * @description 用于连接 Tiaoom 服务器并进行游戏交互,如创建房间、加入房间、发送命令等。\n * 需继承后实现具体的连接和消息发送逻辑。\n */\nexport class Tiaoom {\n listeners: Record<string, Function[]>;\n rooms: Room[];\n players: Player[];\n currentPlayer: Player | null;\n constructor() {\n this.listeners = {};\n this.rooms = [];\n this.players = [];\n this.currentPlayer = null;\n }\n\n /**\n * 启动游戏\n */\n run() {\n this.connect();\n this.onReady(() => {\n this.send({ type: \"room.list\" });\n this.send({ type: \"player.list\" });\n });\n\n this.on(\"player.list\", (players) => {\n this.players = players.map(player => new Player(player));\n this.emit('onPlayerList', [...this.players]);\n });\n this.on(\"player.login\", (player) => {\n this.players.push(new Player(player));\n this.emit('onPlayerList', [...this.players]);\n });\n this.on(\"player.logout\", (player) => {\n this.players = this.players.filter(p => p.id !== player.id);\n this.emit('onPlayerList', [...this.players]);\n });\n\n\n this.on(\"room.list\", (rooms) => {\n this.rooms = rooms.map(room => new Room(room));\n this.emit('onRoomList', [...this.rooms]);\n });\n this.on(\"room.create\", (room) => {\n this.rooms.push(new Room(room));\n this.emit('onRoomList', this.rooms);\n });\n this.on(\"room.update\", (room) => {\n const existingRoom = this.rooms.find(r => r.id === room.id);\n if (!existingRoom) {\n this.rooms.push(new Room(room));\n } else {\n Object.assign(existingRoom, room);\n }\n this.emit('onRoomList', this.rooms);\n });\n this.on(\"room.close\", (room) => {\n this.rooms = this.rooms.filter(r => r.id !== room.id);\n this.emit('onRoomList', this.rooms);\n });\n this.on(\"room.update\", (room) => {\n const updatedRoom = this.rooms.find(r => r.id === room.id);\n if (updatedRoom) {\n Object.assign(updatedRoom, room);\n this.emit('onRoomList', this.rooms);\n }\n });\n\n return this;\n }\n\n /**\n * 连接服务器实现\n */\n connect() {\n throw new Error('Must be implement connect method');\n }\n\n /**\n * 发送消息实现\n */\n send(_: { type: string, data?: any }) {\n throw new Error('Must be implement send method');\n }\n\n /**\n * 登录\n * @param {Player} player 玩家信息\n */\n login(player: Player) {\n this.currentPlayer = new Player(player);\n this.send({ type: \"player.login\", data: player });\n return this;\n }\n\n /**\n * 创建房间\n * @param {string} name 房间名称\n * @param {number} size 房间人数上限\n * @param {number} minSize 房间人数下限\n * @param {object} attrs 房间属性\n */\n createRoom({ name, size, minSize, attrs }: { name: string, size: number, minSize: number, attrs?: Record<string, any> }) {\n return new Promise<void>((resolve) => {\n this.send({ type: \"room.create\", data: { name, size, minSize, attrs } });\n this.on(\"room.create\", (room) => {\n resolve();\n });\n });\n }\n\n /**\n * 加入房间\n * @param {string} roomId 房间ID\n */\n joinRoom(roomId: string) {\n this.send({ type: \"player.join\", data: { roomId } });\n return this;\n }\n\n /**\n * 离开房间\n * @param {string} roomId 房间ID\n */\n leaveRoom(roomId: string) {\n this.send({ type: \"player.leave\", data: { roomId } });\n return this;\n }\n\n /**\n * 开始游戏\n * @param {string} id 房间ID\n */\n startGame(id: string) {\n this.send({ type: \"room.start\", data: { id } });\n return this;\n }\n\n /**\n * 准备/取消准备\n * @param {string} roomId 房间ID\n * @param {boolean} isReady 是否准备\n */\n ready(roomId: string, isReady=true) {\n this.send({ type: isReady ? \"player.ready\" : \"player.unready\", data: { roomId } });\n return this;\n }\n\n /**\n * 发送房间指令\n * @param {string} roomId 房间ID\n * @param {any} command 指令内容\n */\n command(command: any): this;\n command(roomId: string, command: any): this;\n command(roomId: string | any, command?: any) {\n if (typeof roomId != 'string') {\n command = roomId;\n this.send({ type: \"global.command\", data: command });\n } else {\n this.send({ type: \"room.player-command\", data: { id: roomId, ...command } });\n }\n return this;\n }\n\n /**\n * 连接准备监听\n * @param {function} cb 监听函数\n */\n onReady(cb: (...args: any[]) => void) {\n return this.on(\"sys.ready\", cb);\n }\n\n /**\n * 玩家列表变更监听\n * @param {function} cb 监听函数\n */\n onPlayerList(cb: (...args: any[]) => void) {\n this.on(\"onPlayerList\", cb);\n return this;\n }\n\n /**\n * 房间列表变更监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomList(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"onRoomList\", cb);\n else this.off(\"onRoomList\", cb);\n return this;\n }\n\n /**\n * 玩家加入监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerJoin(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.join\", cb);\n else this.off(\"room.join\", cb);\n return this;\n }\n\n /**\n * 玩家离开监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerLeave(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.leave\", cb);\n else this.off(\"room.leave\", cb);\n return this;\n }\n\n /**\n * 玩家准备监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerReady(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.player-ready\", cb);\n else this.off(\"room.player-ready\", cb);\n return this;\n }\n\n /**\n * 玩家取消准备监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerUnready(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.player-unready\", cb);\n else this.off(\"room.player-unready\", cb);\n return this;\n }\n\n /**\n * 玩家状态更新监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerStatus(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"player.status\", cb);\n else this.off(\"player.status\", cb);\n return this;\n }\n\n /**\n * 房间开始游戏监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomStart(cb: (...args: any[]) => void, on=true) {\n if (!this.listeners[\"room.start\"]) {\n this.on(\"room.start\", (room) => this.emit(\"onRoomStart\", new Room(room)));\n }\n if (on) this.on(\"onRoomStart\", cb);\n else this.off(\"onRoomStart\", cb);\n return this;\n }\n\n /**\n * 房间结束游戏监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns\n */\n onRoomEnd(cb: (...args: any[]) => void, on=true) {\n if (!this.listeners[\"room.end\"]) {\n this.on(\"room.end\", (room) => this.emit(\"onRoomEnd\", new Room(room)));\n }\n if (on) this.on(\"onRoomEnd\", cb);\n else this.off(\"onRoomEnd\", cb);\n return this;\n }\n\n /**\n * 房间全部准备监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomAllReady(cb: (...args: any[]) => void, on=true) {\n if (!this.listeners[\"room.all-ready\"]) {\n this.on(\"room.all-ready\", (room) => this.emit(\"onRoomAllReady\", new Room(room)));\n }\n if (on) this.on(\"onRoomAllReady\", cb);\n else this.off(\"onRoomAllReady\", cb);\n return this;\n }\n\n /**\n * 房间消息监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomMessage(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.message\", cb);\n else this.off(\"room.message\", cb);\n return this;\n }\n\n /**\n * 玩家消息监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerMessage(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"player.message\", cb);\n else this.off(\"player.message\", cb);\n return this;\n }\n\n /**\n * 房间指令监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomCommand(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.command\", cb);\n else this.off(\"room.command\", cb);\n return this;\n }\n\n /**\n * 玩家指令监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerCommand(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"player.command\", cb);\n else this.off(\"player.command\", cb);\n return this;\n }\n\n /**\n * 事件监听\n * @param {string} event 事件名称\n * @param {function} listener 监听函数\n * @returns \n */\n on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n this.listeners[event] = this.listeners[event] || [];\n this.listeners[event].push(listener);\n return this;\n }\n\n /**\n * 事件取消监听\n * @param {string} event 事件名称\n * @param {function} listener 监听函数\n * @returns \n */\n off<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n const listeners = this.listeners[event] || [];\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n return this;\n }\n\n /**\n * 事件触发\n * @param {string} event 事件名称\n * @param {...any} args 参数\n * @returns \n */\n emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): this {\n const listeners = this.listeners[event] || [];\n listeners.forEach(listener => listener(...args));\n return this;\n }\n}\n"],"mappings":"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"}
package/src/client.mjs ADDED
@@ -0,0 +1,2 @@
1
+ var e=class{constructor(e){this.id=e.id,this.name=e.name,this.attributes=e.attributes,this.status=e.status}},t=class extends e{constructor(e){super(e),this.role=e.role,this.isReady=e.isReady,this.isCreator=e.isCreator}},n=class{constructor(e){this.id=e.id,this.name=e.name,this.players=e.players.map(e=>new t(e)),this.size=e.size,this.minSize=e.minSize,this.status=e.status,this.attrs=e.attrs}},r=class{constructor(){this.listeners={},this.rooms=[],this.players=[],this.currentPlayer=null}run(){return this.connect(),this.onReady(()=>{this.send({type:`room.list`}),this.send({type:`player.list`})}),this.on(`player.list`,t=>{this.players=t.map(t=>new e(t)),this.emit(`onPlayerList`,[...this.players])}),this.on(`player.login`,t=>{this.players.push(new e(t)),this.emit(`onPlayerList`,[...this.players])}),this.on(`player.logout`,e=>{this.players=this.players.filter(t=>t.id!==e.id),this.emit(`onPlayerList`,[...this.players])}),this.on(`room.list`,e=>{this.rooms=e.map(e=>new n(e)),this.emit(`onRoomList`,[...this.rooms])}),this.on(`room.create`,e=>{this.rooms.push(new n(e)),this.emit(`onRoomList`,this.rooms)}),this.on(`room.update`,e=>{let t=this.rooms.find(t=>t.id===e.id);t?Object.assign(t,e):this.rooms.push(new n(e)),this.emit(`onRoomList`,this.rooms)}),this.on(`room.close`,e=>{this.rooms=this.rooms.filter(t=>t.id!==e.id),this.emit(`onRoomList`,this.rooms)}),this.on(`room.update`,e=>{let t=this.rooms.find(t=>t.id===e.id);t&&(Object.assign(t,e),this.emit(`onRoomList`,this.rooms))}),this}connect(){throw Error(`Must be implement connect method`)}send(e){throw Error(`Must be implement send method`)}login(t){return this.currentPlayer=new e(t),this.send({type:`player.login`,data:t}),this}createRoom({name:e,size:t,minSize:n,attrs:r}){return new Promise(i=>{this.send({type:`room.create`,data:{name:e,size:t,minSize:n,attrs:r}}),this.on(`room.create`,e=>{i()})})}joinRoom(e){return this.send({type:`player.join`,data:{roomId:e}}),this}leaveRoom(e){return this.send({type:`player.leave`,data:{roomId:e}}),this}startGame(e){return this.send({type:`room.start`,data:{id:e}}),this}ready(e,t=!0){return this.send({type:t?`player.ready`:`player.unready`,data:{roomId:e}}),this}command(e,t){return typeof e==`string`?this.send({type:`room.player-command`,data:{id:e,...t}}):(t=e,this.send({type:`global.command`,data:t})),this}onReady(e){return this.on(`sys.ready`,e)}onPlayerList(e){return this.on(`onPlayerList`,e),this}onRoomList(e,t=!0){return t?this.on(`onRoomList`,e):this.off(`onRoomList`,e),this}onPlayerJoin(e,t=!0){return t?this.on(`room.join`,e):this.off(`room.join`,e),this}onPlayerLeave(e,t=!0){return t?this.on(`room.leave`,e):this.off(`room.leave`,e),this}onPlayerReady(e,t=!0){return t?this.on(`room.player-ready`,e):this.off(`room.player-ready`,e),this}onPlayerUnready(e,t=!0){return t?this.on(`room.player-unready`,e):this.off(`room.player-unready`,e),this}onPlayerStatus(e,t=!0){return t?this.on(`player.status`,e):this.off(`player.status`,e),this}onRoomStart(e,t=!0){return this.listeners[`room.start`]||this.on(`room.start`,e=>this.emit(`onRoomStart`,new n(e))),t?this.on(`onRoomStart`,e):this.off(`onRoomStart`,e),this}onRoomEnd(e,t=!0){return this.listeners[`room.end`]||this.on(`room.end`,e=>this.emit(`onRoomEnd`,new n(e))),t?this.on(`onRoomEnd`,e):this.off(`onRoomEnd`,e),this}onRoomAllReady(e,t=!0){return this.listeners[`room.all-ready`]||this.on(`room.all-ready`,e=>this.emit(`onRoomAllReady`,new n(e))),t?this.on(`onRoomAllReady`,e):this.off(`onRoomAllReady`,e),this}onRoomMessage(e,t=!0){return t?this.on(`room.message`,e):this.off(`room.message`,e),this}onPlayerMessage(e,t=!0){return t?this.on(`player.message`,e):this.off(`player.message`,e),this}onRoomCommand(e,t=!0){return t?this.on(`room.command`,e):this.off(`room.command`,e),this}onPlayerCommand(e,t=!0){return t?this.on(`player.command`,e):this.off(`player.command`,e),this}on(e,t){return this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(t),this}off(e,t){let n=this.listeners[e]||[],r=n.indexOf(t);return r!==-1&&n.splice(r,1),this}emit(e,...t){return(this.listeners[e]||[]).forEach(e=>e(...t)),this}};export{e as Player,n as Room,t as RoomPlayer,r as Tiaoom};
2
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../lib/client.ts"],"sourcesContent":["export type TiaoomEvents = {\n /**\n * 连接准备就绪事件\n */\n \"sys.ready\": () => void;\n /**\n * 连接错误事件\n * @param error 错误信息\n */\n \"sys.error\": (error: any) => void;\n /**\n * 连接关闭事件\n */\n \"sys.close\": () => void;\n /**\n * 全局命令事件\n * @param data 命令内容\n */\n \"global.command\": (data: any & { sender: Player }) => void;\n /**\n * 玩家列表更新事件\n * @param players 玩家列表\n */\n \"player.list\": (players: Player[]) => void;\n /**\n * 玩家登录事件\n * @param player 玩家信息\n */\n \"player.login\": (player: Player) => void;\n /**\n * 玩家登出事件\n * @param player 玩家信息\n */\n \"player.logout\": (player: Player) => void;\n /**\n * 玩家状态更新事件\n * @param player 玩家信息\n * @param status 状态\n * @param roomId 房间ID(可选)\n */\n \"player.status\": (player: Player, status: string, roomId?: string) => void;\n /**\n * 玩家命令事件\n * @param command 命令内容\n */\n \"player.command\": (command: any & { sender: Player }) => void;\n /**\n * 玩家消息事件\n * @param message 消息内容\n */\n \"player.message\": (message: any & { sender: Player }) => void;\n /**\n * 房间列表更新事件\n * @param rooms 房间列表\n */\n \"room.list\": (rooms: Room[]) => void;\n /**\n * 房间创建事件\n * @param room 房间信息\n */\n \"room.create\": (room: Room) => void;\n /**\n * 房间更新事件\n * @param room 房间信息\n */\n \"room.update\": (room: Room) => void;\n /**\n * 房间关闭事件\n * @param room 房间信息\n */\n \"room.close\": (room: Room) => void;\n /**\n * 玩家加入房间事件\n * @param room 房间信息\n * @param player 玩家信息\n */\n \"room.join\": (room: Room, player: Player) => void;\n /**\n * 玩家离开房间事件\n * @param room 房间信息\n * @param player 玩家信息\n */\n \"room.leave\": (room: Room, player: Player) => void;\n /**\n * 房间开始游戏事件\n * @param room 房间信息\n */\n \"room.start\": (room: Room) => void;\n /**\n * 房间结束游戏事件\n * @param room 房间信息\n */\n \"room.end\": (room: Room) => void;\n /**\n * 房间玩家全部准备事件\n * @param room 房间信息\n */\n \"room.all-ready\": (room: Room) => void;\n /**\n * 房间命令事件\n * @param command 命令内容\n */\n \"room.command\": (command: any & { sender: Player }) => void;\n /**\n * 房间消息事件\n * @param message 消息内容\n */\n \"room.message\": (message: any & { sender: Player }) => void;\n /**\n * 房间玩家准备事件\n * @param player 玩家信息\n * @param roomId 房间ID(可选)\n */\n \"room.player-ready\": (player: Player, roomId?: string) => void;\n /**\n * 房间玩家取消准备事件\n * @param player 玩家信息\n * @param roomId 房间ID(可选)\n */\n \"room.player-unready\": (player: Player, roomId?: string) => void;\n /**\n * 玩家列表更新事件(内部)\n * @param players 玩家列表\n */\n \"onPlayerList\": (players: Player[]) => void;\n /**\n * 房间列表更新事件(内部)\n * @param rooms 房间列表\n */\n \"onRoomList\": (rooms: Room[]) => void;\n /**\n * 房间开始游戏事件(内部)\n * @param room 房间信息\n */\n \"onRoomStart\": (room: Room) => void;\n /**\n * 房间结束游戏事件(内部)\n * @param room 房间信息\n */\n \"onRoomEnd\": (room: Room) => void;\n /**\n * 房间玩家全部准备事件(内部)\n * @param room 房间信息\n */\n \"onRoomAllReady\": (room: Room) => void;\n};\n\nexport class Player {\n id: string;\n name: string;\n attributes: Record<string, any>;\n status: string;\n constructor(player: Player) {\n this.id = player.id;\n this.name = player.name;\n this.attributes = player.attributes;\n this.status = player.status;\n }\n}\n\nexport class RoomPlayer extends Player {\n role: string;\n isReady: boolean;\n isCreator: boolean;\n constructor(player: RoomPlayer) {\n super(player);\n this.role = player.role;\n this.isReady = player.isReady;\n this.isCreator = player.isCreator;\n }\n}\n\nexport class Room {\n id: string;\n name: string;\n players: RoomPlayer[];\n size: number;\n minSize: number;\n status: string;\n attrs: Record<string, any>;\n constructor(room: Room) {\n this.id = room.id;\n this.name = room.name;\n this.players = room.players.map(player => new RoomPlayer(player));\n this.size = room.size;\n this.minSize = room.minSize;\n this.status = room.status;\n this.attrs = room.attrs;\n }\n}\n\n/**\n * Tiaoom 客户端\n * @description 用于连接 Tiaoom 服务器并进行游戏交互,如创建房间、加入房间、发送命令等。\n * 需继承后实现具体的连接和消息发送逻辑。\n */\nexport class Tiaoom {\n listeners: Record<string, Function[]>;\n rooms: Room[];\n players: Player[];\n currentPlayer: Player | null;\n constructor() {\n this.listeners = {};\n this.rooms = [];\n this.players = [];\n this.currentPlayer = null;\n }\n\n /**\n * 启动游戏\n */\n run() {\n this.connect();\n this.onReady(() => {\n this.send({ type: \"room.list\" });\n this.send({ type: \"player.list\" });\n });\n\n this.on(\"player.list\", (players) => {\n this.players = players.map(player => new Player(player));\n this.emit('onPlayerList', [...this.players]);\n });\n this.on(\"player.login\", (player) => {\n this.players.push(new Player(player));\n this.emit('onPlayerList', [...this.players]);\n });\n this.on(\"player.logout\", (player) => {\n this.players = this.players.filter(p => p.id !== player.id);\n this.emit('onPlayerList', [...this.players]);\n });\n\n\n this.on(\"room.list\", (rooms) => {\n this.rooms = rooms.map(room => new Room(room));\n this.emit('onRoomList', [...this.rooms]);\n });\n this.on(\"room.create\", (room) => {\n this.rooms.push(new Room(room));\n this.emit('onRoomList', this.rooms);\n });\n this.on(\"room.update\", (room) => {\n const existingRoom = this.rooms.find(r => r.id === room.id);\n if (!existingRoom) {\n this.rooms.push(new Room(room));\n } else {\n Object.assign(existingRoom, room);\n }\n this.emit('onRoomList', this.rooms);\n });\n this.on(\"room.close\", (room) => {\n this.rooms = this.rooms.filter(r => r.id !== room.id);\n this.emit('onRoomList', this.rooms);\n });\n this.on(\"room.update\", (room) => {\n const updatedRoom = this.rooms.find(r => r.id === room.id);\n if (updatedRoom) {\n Object.assign(updatedRoom, room);\n this.emit('onRoomList', this.rooms);\n }\n });\n\n return this;\n }\n\n /**\n * 连接服务器实现\n */\n connect() {\n throw new Error('Must be implement connect method');\n }\n\n /**\n * 发送消息实现\n */\n send(_: { type: string, data?: any }) {\n throw new Error('Must be implement send method');\n }\n\n /**\n * 登录\n * @param {Player} player 玩家信息\n */\n login(player: Player) {\n this.currentPlayer = new Player(player);\n this.send({ type: \"player.login\", data: player });\n return this;\n }\n\n /**\n * 创建房间\n * @param {string} name 房间名称\n * @param {number} size 房间人数上限\n * @param {number} minSize 房间人数下限\n * @param {object} attrs 房间属性\n */\n createRoom({ name, size, minSize, attrs }: { name: string, size: number, minSize: number, attrs?: Record<string, any> }) {\n return new Promise<void>((resolve) => {\n this.send({ type: \"room.create\", data: { name, size, minSize, attrs } });\n this.on(\"room.create\", (room) => {\n resolve();\n });\n });\n }\n\n /**\n * 加入房间\n * @param {string} roomId 房间ID\n */\n joinRoom(roomId: string) {\n this.send({ type: \"player.join\", data: { roomId } });\n return this;\n }\n\n /**\n * 离开房间\n * @param {string} roomId 房间ID\n */\n leaveRoom(roomId: string) {\n this.send({ type: \"player.leave\", data: { roomId } });\n return this;\n }\n\n /**\n * 开始游戏\n * @param {string} id 房间ID\n */\n startGame(id: string) {\n this.send({ type: \"room.start\", data: { id } });\n return this;\n }\n\n /**\n * 准备/取消准备\n * @param {string} roomId 房间ID\n * @param {boolean} isReady 是否准备\n */\n ready(roomId: string, isReady=true) {\n this.send({ type: isReady ? \"player.ready\" : \"player.unready\", data: { roomId } });\n return this;\n }\n\n /**\n * 发送房间指令\n * @param {string} roomId 房间ID\n * @param {any} command 指令内容\n */\n command(command: any): this;\n command(roomId: string, command: any): this;\n command(roomId: string | any, command?: any) {\n if (typeof roomId != 'string') {\n command = roomId;\n this.send({ type: \"global.command\", data: command });\n } else {\n this.send({ type: \"room.player-command\", data: { id: roomId, ...command } });\n }\n return this;\n }\n\n /**\n * 连接准备监听\n * @param {function} cb 监听函数\n */\n onReady(cb: (...args: any[]) => void) {\n return this.on(\"sys.ready\", cb);\n }\n\n /**\n * 玩家列表变更监听\n * @param {function} cb 监听函数\n */\n onPlayerList(cb: (...args: any[]) => void) {\n this.on(\"onPlayerList\", cb);\n return this;\n }\n\n /**\n * 房间列表变更监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomList(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"onRoomList\", cb);\n else this.off(\"onRoomList\", cb);\n return this;\n }\n\n /**\n * 玩家加入监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerJoin(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.join\", cb);\n else this.off(\"room.join\", cb);\n return this;\n }\n\n /**\n * 玩家离开监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerLeave(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.leave\", cb);\n else this.off(\"room.leave\", cb);\n return this;\n }\n\n /**\n * 玩家准备监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerReady(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.player-ready\", cb);\n else this.off(\"room.player-ready\", cb);\n return this;\n }\n\n /**\n * 玩家取消准备监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerUnready(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.player-unready\", cb);\n else this.off(\"room.player-unready\", cb);\n return this;\n }\n\n /**\n * 玩家状态更新监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerStatus(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"player.status\", cb);\n else this.off(\"player.status\", cb);\n return this;\n }\n\n /**\n * 房间开始游戏监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomStart(cb: (...args: any[]) => void, on=true) {\n if (!this.listeners[\"room.start\"]) {\n this.on(\"room.start\", (room) => this.emit(\"onRoomStart\", new Room(room)));\n }\n if (on) this.on(\"onRoomStart\", cb);\n else this.off(\"onRoomStart\", cb);\n return this;\n }\n\n /**\n * 房间结束游戏监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns\n */\n onRoomEnd(cb: (...args: any[]) => void, on=true) {\n if (!this.listeners[\"room.end\"]) {\n this.on(\"room.end\", (room) => this.emit(\"onRoomEnd\", new Room(room)));\n }\n if (on) this.on(\"onRoomEnd\", cb);\n else this.off(\"onRoomEnd\", cb);\n return this;\n }\n\n /**\n * 房间全部准备监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomAllReady(cb: (...args: any[]) => void, on=true) {\n if (!this.listeners[\"room.all-ready\"]) {\n this.on(\"room.all-ready\", (room) => this.emit(\"onRoomAllReady\", new Room(room)));\n }\n if (on) this.on(\"onRoomAllReady\", cb);\n else this.off(\"onRoomAllReady\", cb);\n return this;\n }\n\n /**\n * 房间消息监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomMessage(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.message\", cb);\n else this.off(\"room.message\", cb);\n return this;\n }\n\n /**\n * 玩家消息监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerMessage(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"player.message\", cb);\n else this.off(\"player.message\", cb);\n return this;\n }\n\n /**\n * 房间指令监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onRoomCommand(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"room.command\", cb);\n else this.off(\"room.command\", cb);\n return this;\n }\n\n /**\n * 玩家指令监听\n * @param {function} cb 监听函数\n * @param {boolean} on 开启/关闭监听\n * @returns \n */\n onPlayerCommand(cb: (...args: any[]) => void, on=true) {\n if (on) this.on(\"player.command\", cb);\n else this.off(\"player.command\", cb);\n return this;\n }\n\n /**\n * 事件监听\n * @param {string} event 事件名称\n * @param {function} listener 监听函数\n * @returns \n */\n on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n this.listeners[event] = this.listeners[event] || [];\n this.listeners[event].push(listener);\n return this;\n }\n\n /**\n * 事件取消监听\n * @param {string} event 事件名称\n * @param {function} listener 监听函数\n * @returns \n */\n off<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n const listeners = this.listeners[event] || [];\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n return this;\n }\n\n /**\n * 事件触发\n * @param {string} event 事件名称\n * @param {...any} args 参数\n * @returns \n */\n emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): this {\n const listeners = this.listeners[event] || [];\n listeners.forEach(listener => listener(...args));\n return this;\n }\n}\n"],"mappings":"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"}