tiaoom 0.0.2 → 0.0.3
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/README.md +5 -4
- package/package.json +3 -19
- package/src/client.cjs +1 -1
- package/src/client.cjs.map +1 -1
- package/src/client.d.cts +12 -0
- package/src/client.d.mts +12 -0
- package/src/client.iife.js +1 -1
- package/src/client.iife.js.map +1 -1
- package/src/client.mjs +1 -1
- package/src/client.mjs.map +1 -1
- package/src/index.cjs +37 -0
- package/src/index.cjs.map +1 -1
- package/src/index.d.cts +9 -0
- package/src/index.d.mts +9 -0
- package/src/index.mjs +37 -0
- package/src/index.mjs.map +1 -1
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ class YourGameClient extends Tiaoom {
|
|
|
42
42
|
|
|
43
43
|
## 🎮 实现游戏示例
|
|
44
44
|
|
|
45
|
-
本仓库内置一个基于 Websocket
|
|
45
|
+
本仓库内置一个基于 Websocket 为通信协议的游戏服务,实现新的游戏只需编写两个文件:
|
|
46
46
|
|
|
47
47
|
- game/backend/src/games/yourgame.js - 游戏逻辑入口与配置信息;
|
|
48
48
|
- game/frontend/src/components/yourgame/YourGameRoom.vue - 游戏前端组件;
|
|
@@ -56,9 +56,10 @@ class YourGameClient extends Tiaoom {
|
|
|
56
56
|
- 黑白棋
|
|
57
57
|
- 谁是卧底
|
|
58
58
|
|
|
59
|
-
## ⚙️
|
|
60
|
-
1.
|
|
61
|
-
2. 使用 Visual Studio Code 运行调试(直接按下`F5
|
|
59
|
+
## ⚙️ 调试/运行
|
|
60
|
+
1. cd 到 `game`, 执行 `npm install`;
|
|
61
|
+
2. 使用 Visual Studio Code 运行调试(直接按下`F5`即可),或执行 `npm run dev:backend` 启动后端开发服务器。
|
|
62
|
+
3. 执行 `npm run dev:frontend` 启动前端开发服务器,访问 `http://localhost:5173`。
|
|
62
63
|
|
|
63
64
|
> 本地调试可修改 `game/frontend/src/views/Login.vue` 中的`const loginType = ref('fishpi')` 为 `normal`,即可切换为用户名登录模式。
|
|
64
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiaoom",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.cjs",
|
|
6
6
|
"module": "./src/index.mjs",
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"prepare": "npm run build",
|
|
17
|
-
"test": "node -r tsconfig-paths/register -r ts-node/register ./game/index.ts",
|
|
18
17
|
"build": "tsdown"
|
|
19
18
|
},
|
|
20
19
|
"files": [
|
|
@@ -30,23 +29,8 @@
|
|
|
30
29
|
"typescript": "^5.0.4"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
|
-
"@types/
|
|
34
|
-
"
|
|
35
|
-
"@types/express": "^4.17.17",
|
|
36
|
-
"@types/express-session": "^1.17.7",
|
|
37
|
-
"@types/node": "^18.15.11",
|
|
38
|
-
"@types/node-fetch": "^2.6.3",
|
|
39
|
-
"@types/node-schedule": "^2.1.0",
|
|
40
|
-
"@types/session-file-store": "^1.2.2",
|
|
41
|
-
"@types/ws": "^8.5.5",
|
|
42
|
-
"cookie-parser": "^1.4.6",
|
|
43
|
-
"ejs": "^3.1.9",
|
|
44
|
-
"express": "^4.18.2",
|
|
45
|
-
"express-session": "^1.17.3",
|
|
46
|
-
"glob": "^11.0.3",
|
|
47
|
-
"session-file-store": "^1.5.0",
|
|
48
|
-
"tsdown": "^0.17.0-beta.5",
|
|
49
|
-
"ws": "^8.13.0"
|
|
32
|
+
"@types/node": "^24.10.1",
|
|
33
|
+
"tsdown": "^0.17.0-beta.5"
|
|
50
34
|
},
|
|
51
35
|
"unpkg": "./src/client.iife.js",
|
|
52
36
|
"jsdelivr": "./src/client.iife.js",
|
package/src/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=class{constructor(e){this.id=e.id||Date.now().toString(),this.name=e.name||`玩家`+this.id,this.attributes=e.attributes||{},this.status=e.status||`online`}},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}};exports.Player=e,exports.Room=n,exports.RoomPlayer=t,exports.Tiaoom=r;
|
|
1
|
+
var e=class{constructor(e){this.id=e.id||Date.now().toString(),this.name=e.name||`玩家`+this.id,this.attributes=e.attributes||{},this.status=e.status||`online`}},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}kickPlayer(e,t){return this.send({type:`room.kick`,data:{roomId:e,playerId:t}}),this}transferRoom(e,t){return this.send({type:`room.transfer`,data:{roomId:e,playerId:t}}),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}};exports.Player=e,exports.Room=n,exports.RoomPlayer=t,exports.Tiaoom=r;
|
|
2
2
|
//# sourceMappingURL=client.cjs.map
|
package/src/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","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: Partial<Player>) {\n this.id = player.id || Date.now().toString();\n this.name = player.name || '玩家' + this.id;\n this.attributes = player.attributes || {};\n this.status = player.status || 'online';\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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"}
|
|
1
|
+
{"version":3,"file":"client.cjs","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: Partial<Player>) {\n this.id = player.id || Date.now().toString();\n this.name = player.name || '玩家' + this.id;\n this.attributes = player.attributes || {};\n this.status = player.status || 'online';\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} roomId 房间ID\n * @param {string} playerId 玩家ID\n */\n kickPlayer(roomId: string, playerId: string) {\n this.send({ type: \"room.kick\", data: { roomId, playerId } });\n return this;\n }\n\n /**\n * 转让房主\n * @param {string} roomId 房间ID\n * @param {string} playerId 目标玩家ID\n */\n transferRoom(roomId: string, playerId: string) {\n this.send({ type: \"room.transfer\", data: { roomId, playerId } });\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.d.cts
CHANGED
|
@@ -237,6 +237,18 @@ declare class Tiaoom {
|
|
|
237
237
|
* @param {string} roomId 房间ID
|
|
238
238
|
*/
|
|
239
239
|
leaveRoom(roomId: string): this;
|
|
240
|
+
/**
|
|
241
|
+
* 踢出玩家
|
|
242
|
+
* @param {string} roomId 房间ID
|
|
243
|
+
* @param {string} playerId 玩家ID
|
|
244
|
+
*/
|
|
245
|
+
kickPlayer(roomId: string, playerId: string): this;
|
|
246
|
+
/**
|
|
247
|
+
* 转让房主
|
|
248
|
+
* @param {string} roomId 房间ID
|
|
249
|
+
* @param {string} playerId 目标玩家ID
|
|
250
|
+
*/
|
|
251
|
+
transferRoom(roomId: string, playerId: string): this;
|
|
240
252
|
/**
|
|
241
253
|
* 开始游戏
|
|
242
254
|
* @param {string} id 房间ID
|
package/src/client.d.mts
CHANGED
|
@@ -237,6 +237,18 @@ declare class Tiaoom {
|
|
|
237
237
|
* @param {string} roomId 房间ID
|
|
238
238
|
*/
|
|
239
239
|
leaveRoom(roomId: string): this;
|
|
240
|
+
/**
|
|
241
|
+
* 踢出玩家
|
|
242
|
+
* @param {string} roomId 房间ID
|
|
243
|
+
* @param {string} playerId 玩家ID
|
|
244
|
+
*/
|
|
245
|
+
kickPlayer(roomId: string, playerId: string): this;
|
|
246
|
+
/**
|
|
247
|
+
* 转让房主
|
|
248
|
+
* @param {string} roomId 房间ID
|
|
249
|
+
* @param {string} playerId 目标玩家ID
|
|
250
|
+
*/
|
|
251
|
+
transferRoom(roomId: string, playerId: string): this;
|
|
240
252
|
/**
|
|
241
253
|
* 开始游戏
|
|
242
254
|
* @param {string} id 房间ID
|
package/src/client.iife.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var Tiaoom=(function(e){var t=class{constructor(e){this.id=e.id||Date.now().toString(),this.name=e.name||`玩家`+this.id,this.attributes=e.attributes||{},this.status=e.status||`online`}},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})({});
|
|
1
|
+
var Tiaoom=(function(e){var t=class{constructor(e){this.id=e.id||Date.now().toString(),this.name=e.name||`玩家`+this.id,this.attributes=e.attributes||{},this.status=e.status||`online`}},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}kickPlayer(e,t){return this.send({type:`room.kick`,data:{roomId:e,playerId:t}}),this}transferRoom(e,t){return this.send({type:`room.transfer`,data:{roomId:e,playerId:t}}),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
2
|
//# sourceMappingURL=client.iife.js.map
|
package/src/client.iife.js.map
CHANGED
|
@@ -1 +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: Partial<Player>) {\n this.id = player.id || Date.now().toString();\n this.name = player.name || '玩家' + this.id;\n this.attributes = player.attributes || {};\n this.status = player.status || 'online';\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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"}
|
|
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: Partial<Player>) {\n this.id = player.id || Date.now().toString();\n this.name = player.name || '玩家' + this.id;\n this.attributes = player.attributes || {};\n this.status = player.status || 'online';\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} roomId 房间ID\n * @param {string} playerId 玩家ID\n */\n kickPlayer(roomId: string, playerId: string) {\n this.send({ type: \"room.kick\", data: { roomId, playerId } });\n return this;\n }\n\n /**\n * 转让房主\n * @param {string} roomId 房间ID\n * @param {string} playerId 目标玩家ID\n */\n transferRoom(roomId: string, playerId: string) {\n this.send({ type: \"room.transfer\", data: { roomId, playerId } });\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
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=class{constructor(e){this.id=e.id||Date.now().toString(),this.name=e.name||`玩家`+this.id,this.attributes=e.attributes||{},this.status=e.status||`online`}},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};
|
|
1
|
+
var e=class{constructor(e){this.id=e.id||Date.now().toString(),this.name=e.name||`玩家`+this.id,this.attributes=e.attributes||{},this.status=e.status||`online`}},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}kickPlayer(e,t){return this.send({type:`room.kick`,data:{roomId:e,playerId:t}}),this}transferRoom(e,t){return this.send({type:`room.transfer`,data:{roomId:e,playerId:t}}),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
2
|
//# sourceMappingURL=client.mjs.map
|
package/src/client.mjs.map
CHANGED
|
@@ -1 +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: Partial<Player>) {\n this.id = player.id || Date.now().toString();\n this.name = player.name || '玩家' + this.id;\n this.attributes = player.attributes || {};\n this.status = player.status || 'online';\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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"}
|
|
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: Partial<Player>) {\n this.id = player.id || Date.now().toString();\n this.name = player.name || '玩家' + this.id;\n this.attributes = player.attributes || {};\n this.status = player.status || 'online';\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} roomId 房间ID\n * @param {string} playerId 玩家ID\n */\n kickPlayer(roomId: string, playerId: string) {\n this.send({ type: \"room.kick\", data: { roomId, playerId } });\n return this;\n }\n\n /**\n * 转让房主\n * @param {string} roomId 房间ID\n * @param {string} playerId 目标玩家ID\n */\n transferRoom(roomId: string, playerId: string) {\n this.send({ type: \"room.transfer\", data: { roomId, playerId } });\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/index.cjs
CHANGED
|
@@ -187,6 +187,17 @@ var Room = class extends events.default {
|
|
|
187
187
|
});
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
|
+
setCreator(player) {
|
|
191
|
+
const roomPlayer = this.searchPlayer(player);
|
|
192
|
+
if (roomPlayer) {
|
|
193
|
+
this.players.forEach((p) => {
|
|
194
|
+
p.isCreator = false;
|
|
195
|
+
});
|
|
196
|
+
roomPlayer.isCreator = true;
|
|
197
|
+
this.emit("update", this);
|
|
198
|
+
}
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
190
201
|
addPlayer(player, isCreator = false) {
|
|
191
202
|
if (this.players.some((p) => p.id == player.id)) return;
|
|
192
203
|
let roomPlayer = this.searchPlayer(player);
|
|
@@ -299,6 +310,8 @@ var Tiaoom = class extends events.EventEmitter {
|
|
|
299
310
|
case "player.leave": return this.leavePlayer(message.sender, message.data);
|
|
300
311
|
case "room.get": return cb === null || cb === void 0 ? void 0 : cb(null, this.searchRoom(message.data));
|
|
301
312
|
case "room.start": return this.startRoom(message.sender, message.data);
|
|
313
|
+
case "room.kick": return this.kickPlayer(message.sender, message.data);
|
|
314
|
+
case "room.transfer": return this.transferOwner(message.sender, message.data);
|
|
302
315
|
case "room.close": return this.closeRoom(message.sender, message.data);
|
|
303
316
|
case "player.login": return this.loginPlayer(message.data);
|
|
304
317
|
case "player.logout": return this.removePlayer(message.data);
|
|
@@ -412,6 +425,30 @@ var Tiaoom = class extends events.EventEmitter {
|
|
|
412
425
|
roomInstance.emit("close");
|
|
413
426
|
return room;
|
|
414
427
|
}
|
|
428
|
+
kickPlayer(sender, data) {
|
|
429
|
+
const room = this.searchRoom(data.roomId);
|
|
430
|
+
if (!room) throw new Error("room not found.");
|
|
431
|
+
const senderInRoom = room.searchPlayer(sender);
|
|
432
|
+
if (!senderInRoom || !senderInRoom.isCreator) throw new Error("permission denied.");
|
|
433
|
+
const targetPlayer = room.players.find((p) => p.id === data.playerId);
|
|
434
|
+
if (!targetPlayer) throw new Error("player not found in room.");
|
|
435
|
+
const roomPlayer = room.kickPlayer(targetPlayer);
|
|
436
|
+
if (roomPlayer) this.emit("room-player", room);
|
|
437
|
+
return roomPlayer;
|
|
438
|
+
}
|
|
439
|
+
transferOwner(sender, data) {
|
|
440
|
+
const room = this.searchRoom(data.roomId);
|
|
441
|
+
if (!room) throw new Error("room not found.");
|
|
442
|
+
const senderInRoom = room.searchPlayer(sender);
|
|
443
|
+
if (!senderInRoom || !senderInRoom.isCreator) throw new Error("permission denied.");
|
|
444
|
+
const targetPlayer = room.players.find((p) => p.id === data.playerId);
|
|
445
|
+
if (!targetPlayer) throw new Error("player not found in room.");
|
|
446
|
+
if (targetPlayer.id === sender.id) return;
|
|
447
|
+
senderInRoom.isCreator = false;
|
|
448
|
+
targetPlayer.isCreator = true;
|
|
449
|
+
this.emit("room-player", room);
|
|
450
|
+
return room;
|
|
451
|
+
}
|
|
415
452
|
loginPlayer(player, cb) {
|
|
416
453
|
let playerInstance = this.searchPlayer(player);
|
|
417
454
|
if (!playerInstance) {
|
package/src/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["EventEmitter","EventEmitter","player","EventEmitter","room"],"sources":["../lib/models/player.ts","../lib/models/room.ts","../lib/models/message.ts","../lib/index.ts"],"sourcesContent":["import { PlayerEvents } from \"@lib/events/player\";\nimport EventEmitter from \"events\";\n\nexport interface PlayerOptions {\n id: string;\n name: string;\n attributes?: any;\n sender?: (type: string, ...message: any) => void;\n}\n\nexport enum PlayerStatus {\n ready = 'ready',\n unready = 'unready',\n online = 'online',\n playing = 'playing',\n}\n\nexport interface IPlayer extends PlayerOptions {\n status: PlayerStatus;\n}\n\nexport class Player extends EventEmitter implements IPlayer {\n on<K extends keyof PlayerEvents>(event: K, listener: PlayerEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof PlayerEvents>(event: K, ...args: Parameters<PlayerEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n \n id: string = \"\";\n name: string = \"\";\n attributes?: any;\n status: PlayerStatus = PlayerStatus.online;\n sender?: (type: string, ...message: any) => void;\n\n constructor({ id = new Date().getTime().toString(), name = '', attributes, sender }: PlayerOptions) {\n super();\n this.id = id;\n this.name = name;\n this.attributes = attributes;\n this.sender = sender;\n\n this.on('status', (status: PlayerStatus) => {\n this.status = status;\n });\n \n const events: Array<keyof PlayerEvents> = ['command', 'message', 'join', 'leave', 'status'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n }); \n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n attributes: this.attributes,\n status: this.status,\n };\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}","import { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./player\";\nimport EventEmitter from \"events\";\nimport { RoomEvents } from \"@lib/events\";\n\nexport interface IRoomOptions {\n /**\n * 房间号\n */\n id?: string, \n /**\n * 房间名称\n */\n name?: string,\n /**\n * 房间容量\n */\n size?: number, \n /**\n * 最小容量\n */\n minSize?: number,\n /**\n * 其他属性\n */\n attrs?: Record<string, any>,\n}\n\nexport enum PlayerRole {\n player = 'player',\n watcher = 'watcher',\n}\n\nexport enum RoomStatus {\n waiting = 'waiting',\n ready = 'ready',\n playing = 'playing',\n}\n\nexport interface IRoom extends IRoomOptions {\n players: RoomPlayer[];\n}\n\nexport interface IRoomPlayerOptions extends PlayerOptions {\n roomId?: string;\n}\nexport interface IRoomPlayer extends IRoomPlayerOptions, IPlayer {\n isReady: boolean;\n role: PlayerRole;\n isCreator: boolean;\n}\n\nexport class RoomPlayer extends Player implements IRoomPlayer {\n isReady: boolean = false;\n role: PlayerRole = PlayerRole.player;\n isCreator: boolean = false;\n roomId?: string;\n\n constructor(player: IPlayer | Player, role: PlayerRole = PlayerRole.player) {\n super(player);\n this.role = role;\n if (player instanceof Player && player.sender) super.setSender(player.sender);\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n role: this.role,\n isReady: this.isReady,\n isCreator: this.isCreator,\n };\n }\n}\n\nexport class Room extends EventEmitter implements IRoom {\n on<K extends keyof RoomEvents>(event: K, listener: RoomEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof RoomEvents>(event: K, ...args: Parameters<RoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n id: string; // room id\n size: number = 10; // room size\n name: string = ''; // room name\n minSize: number = 2; // room min size\n attrs?: Record<string, any>; // other attributes\n players: RoomPlayer[] = []; // player list\n\n get validPlayers() {\n return this.players.filter((player) => player.role === PlayerRole.player);\n }\n\n get watchers() {\n return this.players.filter((player) => player.role === PlayerRole.watcher);\n }\n\n private sender?: (type: string, ...message: any) => void;\n\n get isReady(): boolean {\n return this.players.length >= this.minSize\n && this.players.every((target) => target.isReady || target.role === PlayerRole.watcher); // is all player ready\n }\n\n get status(): RoomStatus {\n if (!this.isReady) return RoomStatus.waiting;\n if (this.players.findIndex((target) => target.status === PlayerStatus.playing) != -1) return RoomStatus.playing;\n return RoomStatus.ready;\n }\n\n get isPlaying(): boolean {\n return this.status === RoomStatus.playing;\n }\n\n // is room full\n get isFull(): boolean {\n return this.validPlayers.length == this.size;\n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n size: this.size || 10,\n minSize: this.minSize,\n status: this.status,\n players: this.players.map((player) => player.toJSON()),\n attrs: this.attrs,\n }\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n constructor({\n id = new Date().getTime().toString(), name = '', size = 10, minSize = 2, attrs\n }: IRoomOptions) {\n super();\n this.id = id;\n this.name = name;\n this.size = size;\n this.minSize = minSize;\n this.attrs = attrs;\n \n const events: Array<keyof RoomEvents> = ['message', 'command', 'start', 'end', 'close', 'error', 'all-ready', 'player-unready', 'player-ready', 'join', 'leave'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n });\n }\n\n addPlayer(player: Player, isCreator: boolean = false) {\n if (this.players.some((p) => p.id == player.id)) return;\n let roomPlayer = this.searchPlayer(player);\n if (!roomPlayer) {\n roomPlayer = new RoomPlayer(player, this.isFull || this.isPlaying ? PlayerRole.watcher : PlayerRole.player);\n roomPlayer.isCreator = isCreator;\n roomPlayer.roomId = this.id;\n this.players.push(roomPlayer);\n this.emit(\"join\", { roomId: this.id, ...roomPlayer });\n }\n return roomPlayer;\n }\n\n kickPlayer(playerId: string): RoomPlayer;\n kickPlayer(player: IPlayer): RoomPlayer;\n\n kickPlayer(player: IPlayer | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n const index = this.players.findIndex((p) => p.id == playerId);\n const roomPlayer = this.players[index];\n if (index > -1) {\n this.emit(\"leave\", { roomId: this.id, ...roomPlayer});\n this.players.splice(index, 1);\n if (roomPlayer.isCreator && this.players.length > 0) {\n this.players[0].isCreator = true;\n this.emit(\"update\", this);\n }\n }\n return roomPlayer;\n }\n\n searchPlayer(playerId: string): RoomPlayer | undefined;\n searchPlayer(playerId: IPlayer): RoomPlayer | undefined;\n\n searchPlayer(player: string | IPlayer) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((player) => player.id == playerId);\n }\n\n start() {\n if (!this.isReady) {\n throw new Error('room is not ready.');\n }\n if (this.status === RoomStatus.playing) {\n throw new Error('room is already started.');\n }\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.playing);\n });\n this.emit(\"update\", this);\n return this.emit(\"start\", this);\n }\n\n end() {\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.unready);\n });\n this.emit(\"update\", this);\n return this.emit(\"end\", this);\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}\n","import EventEmitter from \"events\";\nimport { IPlayer, PlayerOptions } from \"./player\";\nimport { IRoom, IRoomPlayer, IRoomOptions } from \"./room\";\nimport { MessageEvents } from \"@lib/events/message\";\n\nexport enum MessageTypes {\n RoomList = \"room.list\",\n RoomCreate = \"room.create\",\n RoomReady = \"room.ready\",\n RoomStart = \"room.start\",\n RoomEnd = \"room.end\",\n RoomClose = \"room.close\",\n RoomAllReady = \"room.allready\",\n RoomCommand = \"room.command\",\n RoomMessage = \"room.message\",\n PlayerOffline = \"player.offline\",\n PlayerList = \"player.list\",\n PlayerLogin = \"player.login\",\n PlayerLogout = \"player.logout\",\n PlayerJoin = \"player.join\",\n PlayerLeave = \"player.leave\",\n PlayerReady = \"player.ready\",\n PlayerUnready = \"player.unready\",\n PlayerCommand = \"player.command\",\n}\n\nexport interface MessagePackage {\n type: MessageTypes | string;\n data?: PlayerOptions | IRoomOptions | IPlayer | IRoom | IRoomPlayer | any;\n sender?: IPlayer | IRoom | IRoomPlayer;\n}\n\nexport interface Message extends EventEmitter {\n on<K extends keyof MessageEvents>(event: K, listener: MessageEvents[K]): this;\n emit<K extends keyof MessageEvents>(event: K, ...args: Parameters<MessageEvents[K]>): boolean;\n close(): void;\n send(message: MessagePackage): void;\n}\n","import { EventEmitter } from \"events\";\nimport { TiaoomEvents } from \"./events\";\nimport { Message } from \"./models/message\";\nimport { IRoom, IRoomPlayer, Room, IRoomOptions, IRoomPlayerOptions } from \"./models/room\";\nimport { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./models/player\";\n\nexport interface ITiaoomOptions {\n socket: Message;\n}\n\nexport class Tiaoom extends EventEmitter {\n rooms: Room[] = []; // room list\n players: Player[] = []; // player list\n messageInstance?: Message;\n\n constructor({ socket }: ITiaoomOptions) {\n super();\n this.messageInstance = socket;\n }\n\n on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n super.on(event, listener);\n return this\n }\n\n emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n run() {\n this.messageInstance?.on(\"message\", (message: any, cb?: (err: Error | null, data?: any) => any) => {\n try {\n switch (message.type) {\n case \"room.list\":\n return cb?.(null, this.rooms);\n case \"player.list\":\n return cb?.(null, this.players);\n case \"room.create\":\n return this.createRoom(message.sender, message.data);\n case \"player.join\":\n return this.joinPlayer(message.sender, message.data);\n case \"player.leave\":\n return this.leavePlayer(message.sender, message.data);\n case \"room.get\":\n return cb?.(null, this.searchRoom(message.data));\n case \"room.start\":\n return this.startRoom(message.sender, message.data);\n case \"room.close\":\n return this.closeRoom(message.sender, message.data);\n case \"player.login\":\n return this.loginPlayer(message.data);\n case \"player.logout\":\n return this.removePlayer(message.data);\n case \"player.ready\":\n return this.readyPlayer(message.sender, message.data);\n case \"player.unready\":\n return this.unReadyPlayer(message.sender, message.data);\n case \"room.player-command\":\n return this.searchRoom(message.data)?.emit(\"player-command\", { ...message.data , sender: message.sender });\n case \"room.message\":\n return this.searchRoom(message.data)?.emit(\"message\", message.data);\n case \"global.command\":\n return this.emit(\"command\", { ...message.data , sender: message.sender });\n default:\n throw new Error('unknown message type.');\n }\n } catch (error) {\n cb?.(error as Error);\n }\n });\n\n this.on('player', (player, online) => {\n this.messageInstance?.send({ type: online ? 'player.login' : 'player.logout', data: player });\n });\n\n this.on('players', (players) => {\n this.messageInstance?.send({ type: 'player.list', data: players });\n });\n\n this.on('room', (room) => {\n this.messageInstance?.send({ type: 'room.create', data: room });\n });\n\n this.on('room-player', (room) => {\n this.messageInstance?.send({ type: 'room.update', data: room });\n });\n\n this.on('rooms', (rooms) => {\n this.messageInstance?.send({ type: 'room.list', data: rooms });\n });\n\n this.on('command', (data) => {\n this.messageInstance?.send({ type: 'global.command', data });\n });\n\n return this;\n }\n\n searchPlayer(player: string): Player | undefined;\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions): Player | undefined;\n\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((target) => target.id === playerId);\n }\n\n searchRoom(room: string): Room | undefined;\n searchRoom(room: Partial<IRoomOptions>): Room | undefined;\n\n searchRoom(room: Partial<IRoomOptions> | string) {\n const roomId = typeof room === \"string\" ? room : room.id;\n return this.rooms.find((target) => target.id === roomId);\n }\n\n createRoom(sender: IPlayer, options: IRoomOptions) {\n if (!options.name) {\n throw new Error('missing room id or name.');\n }\n const roomInstance = this.searchRoom(options);\n if (roomInstance) {\n throw new Error('room already exists.');\n }\n\n if (this.rooms.some(r => r.players.some(p => p.id === sender.id))) {\n throw new Error('you are already in a room.');\n }\n\n const room = new Room(options);\n room.setSender((type, message) => {\n this.messageInstance?.send({ type: `room.${type}`, data: message, sender: room });\n });\n \n this.emit(\"room\", room);\n this.rooms.push(room);\n\n this.joinPlayer(sender, { roomId: room.id, ...sender }, true);\n return room;\n }\n\n startRoom(sender: IPlayer, room: IRoom) {\n const roomInstance = this.searchRoom(room);\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n roomInstance.start();\n\n return this.emit(\"room-player\", roomInstance);\n }\n\n closeRoom(sender: IPlayer, room: IRoom) {\n const roomIndex = this.rooms.findIndex((r) => r.id === room.id);\n const roomInstance = this.rooms[roomIndex];\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n\n if (roomInstance.players.length && !roomInstance.players.some(p => p.id === sender.id && p.isCreator)) {\n throw new Error('only room creator can close the room.');\n }\n\n room = this.rooms.splice(roomIndex, 1)[0];\n\n this.emit(\"rooms\", this.rooms);\n roomInstance.emit('close');\n return room;\n }\n\n loginPlayer (player: PlayerOptions, cb?: (data: { player: Player }) => void): Player {\n let playerInstance = this.searchPlayer(player);\n if (!playerInstance) {\n playerInstance = new Player(player);\n playerInstance.setSender((type, message) => {\n this.messageInstance?.send({ type: `player.${type}`, data: message, sender: playerInstance });\n });\n this.players.push(playerInstance);\n this.emit(\"player\", playerInstance, true);\n }\n \n playerInstance.emit(\"status\", PlayerStatus.online);\n cb?.({ player: playerInstance });\n return playerInstance;\n }\n\n joinPlayer(sender: IPlayer, player: IRoomPlayerOptions, isCreator: boolean = false) {\n let playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n playerInstance = this.loginPlayer(sender);\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.addPlayer(playerInstance, isCreator);\n if (!roomPlayer) {\n throw new Error('room is full.');\n }\n\n this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n leavePlayer(sender: IPlayer, player: IRoomPlayerOptions) {\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const playerInstance = room.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not in room.');\n }\n\n const roomPlayer = room.kickPlayer(playerInstance);\n\n if (roomPlayer) this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n readyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = true;\n\n if (room.isReady) {\n room.emit(\"all-ready\", room.players);\n }\n\n playerInstance.emit(\"status\", PlayerStatus.ready);\n\n room.emit(\"player-ready\", { ...player, ...roomPlayer });\n\n return this;\n }\n \n unReadyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = false;\n playerInstance.emit(\"status\", PlayerStatus.unready);\n room.emit(\"player-unready\", roomPlayer);\n\n return this;\n }\n\n removePlayer(sender: IPlayer) {\n const playerIndex = this.players.findIndex((p) => p.id === sender.id);\n const player = this.players[playerIndex];\n if (playerIndex > -1) {\n this.players.splice(playerIndex, 1)[0];\n this.emit(\"player\", player, false);\n if (this.rooms.some(r => r.searchPlayer(player))) {\n setTimeout(() => {\n if (this.players.some(p => p.id === sender.id)) return; // player is online\n this.rooms.filter(r => r.searchPlayer(player)).forEach(r => {\n this.leavePlayer(sender, { ...sender, roomId: r.id });\n });\n }, 5 * 60 * 1000); // 5 minutes later\n }\n }\n return player;\n }\n}\n\nexport * from \"./models/message\";\nexport * from \"./models/room\";\nexport * from \"./models/player\";\nexport * from \"./events\";"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["EventEmitter","EventEmitter","player","EventEmitter","room"],"sources":["../lib/models/player.ts","../lib/models/room.ts","../lib/models/message.ts","../lib/index.ts"],"sourcesContent":["import { PlayerEvents } from \"@lib/events/player\";\nimport EventEmitter from \"events\";\n\nexport interface PlayerOptions {\n id: string;\n name: string;\n attributes?: any;\n sender?: (type: string, ...message: any) => void;\n}\n\nexport enum PlayerStatus {\n ready = 'ready',\n unready = 'unready',\n online = 'online',\n playing = 'playing',\n}\n\nexport interface IPlayer extends PlayerOptions {\n status: PlayerStatus;\n}\n\nexport class Player extends EventEmitter implements IPlayer {\n on<K extends keyof PlayerEvents>(event: K, listener: PlayerEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof PlayerEvents>(event: K, ...args: Parameters<PlayerEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n \n id: string = \"\";\n name: string = \"\";\n attributes?: any;\n status: PlayerStatus = PlayerStatus.online;\n sender?: (type: string, ...message: any) => void;\n\n constructor({ id = new Date().getTime().toString(), name = '', attributes, sender }: PlayerOptions) {\n super();\n this.id = id;\n this.name = name;\n this.attributes = attributes;\n this.sender = sender;\n\n this.on('status', (status: PlayerStatus) => {\n this.status = status;\n });\n \n const events: Array<keyof PlayerEvents> = ['command', 'message', 'join', 'leave', 'status'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n }); \n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n attributes: this.attributes,\n status: this.status,\n };\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}","import { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./player\";\nimport EventEmitter from \"events\";\nimport { RoomEvents } from \"@lib/events\";\n\nexport interface IRoomOptions {\n /**\n * 房间号\n */\n id?: string, \n /**\n * 房间名称\n */\n name?: string,\n /**\n * 房间容量\n */\n size?: number, \n /**\n * 最小容量\n */\n minSize?: number,\n /**\n * 其他属性\n */\n attrs?: Record<string, any>,\n}\n\nexport enum PlayerRole {\n player = 'player',\n watcher = 'watcher',\n}\n\nexport enum RoomStatus {\n waiting = 'waiting',\n ready = 'ready',\n playing = 'playing',\n}\n\nexport interface IRoom extends IRoomOptions {\n players: RoomPlayer[];\n}\n\nexport interface IRoomPlayerOptions extends PlayerOptions {\n roomId?: string;\n}\nexport interface IRoomPlayer extends IRoomPlayerOptions, IPlayer {\n isReady: boolean;\n role: PlayerRole;\n isCreator: boolean;\n}\n\nexport class RoomPlayer extends Player implements IRoomPlayer {\n isReady: boolean = false;\n role: PlayerRole = PlayerRole.player;\n isCreator: boolean = false;\n roomId?: string;\n\n constructor(player: IPlayer | Player, role: PlayerRole = PlayerRole.player) {\n super(player);\n this.role = role;\n if (player instanceof Player && player.sender) super.setSender(player.sender);\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n role: this.role,\n isReady: this.isReady,\n isCreator: this.isCreator,\n };\n }\n}\n\nexport class Room extends EventEmitter implements IRoom {\n on<K extends keyof RoomEvents>(event: K, listener: RoomEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof RoomEvents>(event: K, ...args: Parameters<RoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n id: string; // room id\n size: number = 10; // room size\n name: string = ''; // room name\n minSize: number = 2; // room min size\n attrs?: Record<string, any>; // other attributes\n players: RoomPlayer[] = []; // player list\n\n get validPlayers() {\n return this.players.filter((player) => player.role === PlayerRole.player);\n }\n\n get watchers() {\n return this.players.filter((player) => player.role === PlayerRole.watcher);\n }\n\n private sender?: (type: string, ...message: any) => void;\n\n get isReady(): boolean {\n return this.players.length >= this.minSize\n && this.players.every((target) => target.isReady || target.role === PlayerRole.watcher); // is all player ready\n }\n\n get status(): RoomStatus {\n if (!this.isReady) return RoomStatus.waiting;\n if (this.players.findIndex((target) => target.status === PlayerStatus.playing) != -1) return RoomStatus.playing;\n return RoomStatus.ready;\n }\n\n get isPlaying(): boolean {\n return this.status === RoomStatus.playing;\n }\n\n // is room full\n get isFull(): boolean {\n return this.validPlayers.length == this.size;\n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n size: this.size || 10,\n minSize: this.minSize,\n status: this.status,\n players: this.players.map((player) => player.toJSON()),\n attrs: this.attrs,\n }\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n constructor({\n id = new Date().getTime().toString(), name = '', size = 10, minSize = 2, attrs\n }: IRoomOptions) {\n super();\n this.id = id;\n this.name = name;\n this.size = size;\n this.minSize = minSize;\n this.attrs = attrs;\n \n const events: Array<keyof RoomEvents> = ['message', 'command', 'start', 'end', 'close', 'error', 'all-ready', 'player-unready', 'player-ready', 'join', 'leave'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n });\n }\n\n setCreator(player: Player) {\n const roomPlayer = this.searchPlayer(player);\n if (roomPlayer) {\n this.players.forEach((p) => {\n p.isCreator = false;\n });\n roomPlayer.isCreator = true;\n this.emit(\"update\", this);\n }\n return this;\n }\n\n addPlayer(player: Player, isCreator: boolean = false) {\n if (this.players.some((p) => p.id == player.id)) return;\n let roomPlayer = this.searchPlayer(player);\n if (!roomPlayer) {\n roomPlayer = new RoomPlayer(player, this.isFull || this.isPlaying ? PlayerRole.watcher : PlayerRole.player);\n roomPlayer.isCreator = isCreator;\n roomPlayer.roomId = this.id;\n this.players.push(roomPlayer);\n this.emit(\"join\", { roomId: this.id, ...roomPlayer });\n }\n return roomPlayer;\n }\n\n kickPlayer(playerId: string): RoomPlayer;\n kickPlayer(player: IPlayer): RoomPlayer;\n\n kickPlayer(player: IPlayer | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n const index = this.players.findIndex((p) => p.id == playerId);\n const roomPlayer = this.players[index];\n if (index > -1) {\n this.emit(\"leave\", { roomId: this.id, ...roomPlayer});\n this.players.splice(index, 1);\n if (roomPlayer.isCreator && this.players.length > 0) {\n this.players[0].isCreator = true;\n this.emit(\"update\", this);\n }\n }\n return roomPlayer;\n }\n\n searchPlayer(playerId: string): RoomPlayer | undefined;\n searchPlayer(playerId: IPlayer): RoomPlayer | undefined;\n\n searchPlayer(player: string | IPlayer) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((player) => player.id == playerId);\n }\n\n start() {\n if (!this.isReady) {\n throw new Error('room is not ready.');\n }\n if (this.status === RoomStatus.playing) {\n throw new Error('room is already started.');\n }\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.playing);\n });\n this.emit(\"update\", this);\n return this.emit(\"start\", this);\n }\n\n end() {\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.unready);\n });\n this.emit(\"update\", this);\n return this.emit(\"end\", this);\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}\n","import EventEmitter from \"events\";\nimport { IPlayer, PlayerOptions } from \"./player\";\nimport { IRoom, IRoomPlayer, IRoomOptions } from \"./room\";\nimport { MessageEvents } from \"@lib/events/message\";\n\nexport enum MessageTypes {\n RoomList = \"room.list\",\n RoomCreate = \"room.create\",\n RoomReady = \"room.ready\",\n RoomStart = \"room.start\",\n RoomEnd = \"room.end\",\n RoomClose = \"room.close\",\n RoomAllReady = \"room.allready\",\n RoomCommand = \"room.command\",\n RoomMessage = \"room.message\",\n PlayerOffline = \"player.offline\",\n PlayerList = \"player.list\",\n PlayerLogin = \"player.login\",\n PlayerLogout = \"player.logout\",\n PlayerJoin = \"player.join\",\n PlayerLeave = \"player.leave\",\n PlayerReady = \"player.ready\",\n PlayerUnready = \"player.unready\",\n PlayerCommand = \"player.command\",\n}\n\nexport interface MessagePackage {\n type: MessageTypes | string;\n data?: PlayerOptions | IRoomOptions | IPlayer | IRoom | IRoomPlayer | any;\n sender?: IPlayer | IRoom | IRoomPlayer;\n}\n\nexport interface Message extends EventEmitter {\n on<K extends keyof MessageEvents>(event: K, listener: MessageEvents[K]): this;\n emit<K extends keyof MessageEvents>(event: K, ...args: Parameters<MessageEvents[K]>): boolean;\n close(): void;\n send(message: MessagePackage): void;\n}\n","import { EventEmitter } from \"events\";\nimport { TiaoomEvents } from \"./events\";\nimport { Message } from \"./models/message\";\nimport { IRoom, IRoomPlayer, Room, IRoomOptions, IRoomPlayerOptions } from \"./models/room\";\nimport { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./models/player\";\n\nexport interface ITiaoomOptions {\n socket: Message;\n}\n\nexport class Tiaoom extends EventEmitter {\n rooms: Room[] = []; // room list\n players: Player[] = []; // player list\n messageInstance?: Message;\n\n constructor({ socket }: ITiaoomOptions) {\n super();\n this.messageInstance = socket;\n }\n\n on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n super.on(event, listener);\n return this\n }\n\n emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n run() {\n this.messageInstance?.on(\"message\", (message: any, cb?: (err: Error | null, data?: any) => any) => {\n try {\n switch (message.type) {\n case \"room.list\":\n return cb?.(null, this.rooms);\n case \"player.list\":\n return cb?.(null, this.players);\n case \"room.create\":\n return this.createRoom(message.sender, message.data);\n case \"player.join\":\n return this.joinPlayer(message.sender, message.data);\n case \"player.leave\":\n return this.leavePlayer(message.sender, message.data);\n case \"room.get\":\n return cb?.(null, this.searchRoom(message.data));\n case \"room.start\":\n return this.startRoom(message.sender, message.data);\n case \"room.kick\":\n return this.kickPlayer(message.sender, message.data);\n case \"room.transfer\":\n return this.transferOwner(message.sender, message.data);\n case \"room.close\":\n return this.closeRoom(message.sender, message.data);\n case \"player.login\":\n return this.loginPlayer(message.data);\n case \"player.logout\":\n return this.removePlayer(message.data);\n case \"player.ready\":\n return this.readyPlayer(message.sender, message.data);\n case \"player.unready\":\n return this.unReadyPlayer(message.sender, message.data);\n case \"room.player-command\":\n return this.searchRoom(message.data)?.emit(\"player-command\", { ...message.data , sender: message.sender });\n case \"room.message\":\n return this.searchRoom(message.data)?.emit(\"message\", message.data);\n case \"global.command\":\n return this.emit(\"command\", { ...message.data , sender: message.sender });\n default:\n throw new Error('unknown message type.');\n }\n } catch (error) {\n cb?.(error as Error);\n }\n });\n\n this.on('player', (player, online) => {\n this.messageInstance?.send({ type: online ? 'player.login' : 'player.logout', data: player });\n });\n\n this.on('players', (players) => {\n this.messageInstance?.send({ type: 'player.list', data: players });\n });\n\n this.on('room', (room) => {\n this.messageInstance?.send({ type: 'room.create', data: room });\n });\n\n this.on('room-player', (room) => {\n this.messageInstance?.send({ type: 'room.update', data: room });\n });\n\n this.on('rooms', (rooms) => {\n this.messageInstance?.send({ type: 'room.list', data: rooms });\n });\n\n this.on('command', (data) => {\n this.messageInstance?.send({ type: 'global.command', data });\n });\n\n return this;\n }\n\n searchPlayer(player: string): Player | undefined;\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions): Player | undefined;\n\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((target) => target.id === playerId);\n }\n\n searchRoom(room: string): Room | undefined;\n searchRoom(room: Partial<IRoomOptions>): Room | undefined;\n\n searchRoom(room: Partial<IRoomOptions> | string) {\n const roomId = typeof room === \"string\" ? room : room.id;\n return this.rooms.find((target) => target.id === roomId);\n }\n\n createRoom(sender: IPlayer, options: IRoomOptions) {\n if (!options.name) {\n throw new Error('missing room id or name.');\n }\n const roomInstance = this.searchRoom(options);\n if (roomInstance) {\n throw new Error('room already exists.');\n }\n\n if (this.rooms.some(r => r.players.some(p => p.id === sender.id))) {\n throw new Error('you are already in a room.');\n }\n\n const room = new Room(options);\n room.setSender((type, message) => {\n this.messageInstance?.send({ type: `room.${type}`, data: message, sender: room });\n });\n \n this.emit(\"room\", room);\n this.rooms.push(room);\n\n this.joinPlayer(sender, { roomId: room.id, ...sender }, true);\n return room;\n }\n\n startRoom(sender: IPlayer, room: IRoom) {\n const roomInstance = this.searchRoom(room);\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n roomInstance.start();\n\n return this.emit(\"room-player\", roomInstance);\n }\n\n closeRoom(sender: IPlayer, room: IRoom) {\n const roomIndex = this.rooms.findIndex((r) => r.id === room.id);\n const roomInstance = this.rooms[roomIndex];\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n\n if (roomInstance.players.length && !roomInstance.players.some(p => p.id === sender.id && p.isCreator)) {\n throw new Error('only room creator can close the room.');\n }\n\n room = this.rooms.splice(roomIndex, 1)[0];\n\n this.emit(\"rooms\", this.rooms);\n roomInstance.emit('close');\n return room;\n }\n\n kickPlayer(sender: IPlayer, data: { roomId: string, playerId: string }) {\n const room = this.searchRoom(data.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const senderInRoom = room.searchPlayer(sender);\n if (!senderInRoom || !senderInRoom.isCreator) {\n throw new Error('permission denied.');\n }\n\n const targetPlayer = room.players.find(p => p.id === data.playerId);\n if (!targetPlayer) {\n throw new Error('player not found in room.');\n }\n\n const roomPlayer = room.kickPlayer(targetPlayer);\n if (roomPlayer) this.emit(\"room-player\", room);\n return roomPlayer;\n }\n\n transferOwner(sender: IPlayer, data: { roomId: string, playerId: string }) {\n const room = this.searchRoom(data.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const senderInRoom = room.searchPlayer(sender);\n if (!senderInRoom || !senderInRoom.isCreator) {\n throw new Error('permission denied.');\n }\n\n const targetPlayer = room.players.find(p => p.id === data.playerId);\n if (!targetPlayer) {\n throw new Error('player not found in room.');\n }\n\n if (targetPlayer.id === sender.id) {\n return;\n }\n\n senderInRoom.isCreator = false;\n targetPlayer.isCreator = true;\n\n this.emit(\"room-player\", room);\n return room;\n }\n\n loginPlayer (player: PlayerOptions, cb?: (data: { player: Player }) => void): Player {\n let playerInstance = this.searchPlayer(player);\n if (!playerInstance) {\n playerInstance = new Player(player);\n playerInstance.setSender((type, message) => {\n this.messageInstance?.send({ type: `player.${type}`, data: message, sender: playerInstance });\n });\n this.players.push(playerInstance);\n this.emit(\"player\", playerInstance, true);\n }\n \n playerInstance.emit(\"status\", PlayerStatus.online);\n cb?.({ player: playerInstance });\n return playerInstance;\n }\n\n joinPlayer(sender: IPlayer, player: IRoomPlayerOptions, isCreator: boolean = false) {\n let playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n playerInstance = this.loginPlayer(sender);\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.addPlayer(playerInstance, isCreator);\n if (!roomPlayer) {\n throw new Error('room is full.');\n }\n\n this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n leavePlayer(sender: IPlayer, player: IRoomPlayerOptions) {\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const playerInstance = room.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not in room.');\n }\n\n const roomPlayer = room.kickPlayer(playerInstance);\n\n if (roomPlayer) this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n readyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = true;\n\n if (room.isReady) {\n room.emit(\"all-ready\", room.players);\n }\n\n playerInstance.emit(\"status\", PlayerStatus.ready);\n\n room.emit(\"player-ready\", { ...player, ...roomPlayer });\n\n return this;\n }\n \n unReadyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = false;\n playerInstance.emit(\"status\", PlayerStatus.unready);\n room.emit(\"player-unready\", roomPlayer);\n\n return this;\n }\n\n removePlayer(sender: IPlayer) {\n const playerIndex = this.players.findIndex((p) => p.id === sender.id);\n const player = this.players[playerIndex];\n if (playerIndex > -1) {\n this.players.splice(playerIndex, 1)[0];\n this.emit(\"player\", player, false);\n if (this.rooms.some(r => r.searchPlayer(player))) {\n setTimeout(() => {\n if (this.players.some(p => p.id === sender.id)) return; // player is online\n this.rooms.filter(r => r.searchPlayer(player)).forEach(r => {\n this.leavePlayer(sender, { ...sender, roomId: r.id });\n });\n }, 5 * 60 * 1000); // 5 minutes later\n }\n }\n return player;\n }\n}\n\nexport * from \"./models/message\";\nexport * from \"./models/room\";\nexport * from \"./models/player\";\nexport * from \"./events\";"],"mappings":"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"}
|
package/src/index.d.cts
CHANGED
|
@@ -305,6 +305,7 @@ declare class Room extends EventEmitter$1 implements IRoom {
|
|
|
305
305
|
minSize,
|
|
306
306
|
attrs
|
|
307
307
|
}: IRoomOptions);
|
|
308
|
+
setCreator(player: Player): this;
|
|
308
309
|
addPlayer(player: Player, isCreator?: boolean): RoomPlayer | undefined;
|
|
309
310
|
kickPlayer(playerId: string): RoomPlayer;
|
|
310
311
|
kickPlayer(player: IPlayer): RoomPlayer;
|
|
@@ -336,6 +337,14 @@ declare class Tiaoom extends EventEmitter {
|
|
|
336
337
|
createRoom(sender: IPlayer, options: IRoomOptions): Room;
|
|
337
338
|
startRoom(sender: IPlayer, room: IRoom): boolean;
|
|
338
339
|
closeRoom(sender: IPlayer, room: IRoom): IRoom;
|
|
340
|
+
kickPlayer(sender: IPlayer, data: {
|
|
341
|
+
roomId: string;
|
|
342
|
+
playerId: string;
|
|
343
|
+
}): RoomPlayer;
|
|
344
|
+
transferOwner(sender: IPlayer, data: {
|
|
345
|
+
roomId: string;
|
|
346
|
+
playerId: string;
|
|
347
|
+
}): Room | undefined;
|
|
339
348
|
loginPlayer(player: PlayerOptions, cb?: (data: {
|
|
340
349
|
player: Player;
|
|
341
350
|
}) => void): Player;
|
package/src/index.d.mts
CHANGED
|
@@ -305,6 +305,7 @@ declare class Room extends EventEmitter$1 implements IRoom {
|
|
|
305
305
|
minSize,
|
|
306
306
|
attrs
|
|
307
307
|
}: IRoomOptions);
|
|
308
|
+
setCreator(player: Player): this;
|
|
308
309
|
addPlayer(player: Player, isCreator?: boolean): RoomPlayer | undefined;
|
|
309
310
|
kickPlayer(playerId: string): RoomPlayer;
|
|
310
311
|
kickPlayer(player: IPlayer): RoomPlayer;
|
|
@@ -336,6 +337,14 @@ declare class Tiaoom extends EventEmitter {
|
|
|
336
337
|
createRoom(sender: IPlayer, options: IRoomOptions): Room;
|
|
337
338
|
startRoom(sender: IPlayer, room: IRoom): boolean;
|
|
338
339
|
closeRoom(sender: IPlayer, room: IRoom): IRoom;
|
|
340
|
+
kickPlayer(sender: IPlayer, data: {
|
|
341
|
+
roomId: string;
|
|
342
|
+
playerId: string;
|
|
343
|
+
}): RoomPlayer;
|
|
344
|
+
transferOwner(sender: IPlayer, data: {
|
|
345
|
+
roomId: string;
|
|
346
|
+
playerId: string;
|
|
347
|
+
}): Room | undefined;
|
|
339
348
|
loginPlayer(player: PlayerOptions, cb?: (data: {
|
|
340
349
|
player: Player;
|
|
341
350
|
}) => void): Player;
|
package/src/index.mjs
CHANGED
|
@@ -159,6 +159,17 @@ var Room = class extends EventEmitter$1 {
|
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
+
setCreator(player) {
|
|
163
|
+
const roomPlayer = this.searchPlayer(player);
|
|
164
|
+
if (roomPlayer) {
|
|
165
|
+
this.players.forEach((p) => {
|
|
166
|
+
p.isCreator = false;
|
|
167
|
+
});
|
|
168
|
+
roomPlayer.isCreator = true;
|
|
169
|
+
this.emit("update", this);
|
|
170
|
+
}
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
162
173
|
addPlayer(player, isCreator = false) {
|
|
163
174
|
if (this.players.some((p) => p.id == player.id)) return;
|
|
164
175
|
let roomPlayer = this.searchPlayer(player);
|
|
@@ -271,6 +282,8 @@ var Tiaoom = class extends EventEmitter {
|
|
|
271
282
|
case "player.leave": return this.leavePlayer(message.sender, message.data);
|
|
272
283
|
case "room.get": return cb === null || cb === void 0 ? void 0 : cb(null, this.searchRoom(message.data));
|
|
273
284
|
case "room.start": return this.startRoom(message.sender, message.data);
|
|
285
|
+
case "room.kick": return this.kickPlayer(message.sender, message.data);
|
|
286
|
+
case "room.transfer": return this.transferOwner(message.sender, message.data);
|
|
274
287
|
case "room.close": return this.closeRoom(message.sender, message.data);
|
|
275
288
|
case "player.login": return this.loginPlayer(message.data);
|
|
276
289
|
case "player.logout": return this.removePlayer(message.data);
|
|
@@ -384,6 +397,30 @@ var Tiaoom = class extends EventEmitter {
|
|
|
384
397
|
roomInstance.emit("close");
|
|
385
398
|
return room;
|
|
386
399
|
}
|
|
400
|
+
kickPlayer(sender, data) {
|
|
401
|
+
const room = this.searchRoom(data.roomId);
|
|
402
|
+
if (!room) throw new Error("room not found.");
|
|
403
|
+
const senderInRoom = room.searchPlayer(sender);
|
|
404
|
+
if (!senderInRoom || !senderInRoom.isCreator) throw new Error("permission denied.");
|
|
405
|
+
const targetPlayer = room.players.find((p) => p.id === data.playerId);
|
|
406
|
+
if (!targetPlayer) throw new Error("player not found in room.");
|
|
407
|
+
const roomPlayer = room.kickPlayer(targetPlayer);
|
|
408
|
+
if (roomPlayer) this.emit("room-player", room);
|
|
409
|
+
return roomPlayer;
|
|
410
|
+
}
|
|
411
|
+
transferOwner(sender, data) {
|
|
412
|
+
const room = this.searchRoom(data.roomId);
|
|
413
|
+
if (!room) throw new Error("room not found.");
|
|
414
|
+
const senderInRoom = room.searchPlayer(sender);
|
|
415
|
+
if (!senderInRoom || !senderInRoom.isCreator) throw new Error("permission denied.");
|
|
416
|
+
const targetPlayer = room.players.find((p) => p.id === data.playerId);
|
|
417
|
+
if (!targetPlayer) throw new Error("player not found in room.");
|
|
418
|
+
if (targetPlayer.id === sender.id) return;
|
|
419
|
+
senderInRoom.isCreator = false;
|
|
420
|
+
targetPlayer.isCreator = true;
|
|
421
|
+
this.emit("room-player", room);
|
|
422
|
+
return room;
|
|
423
|
+
}
|
|
387
424
|
loginPlayer(player, cb) {
|
|
388
425
|
let playerInstance = this.searchPlayer(player);
|
|
389
426
|
if (!playerInstance) {
|
package/src/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["EventEmitter","EventEmitter","player","room"],"sources":["../lib/models/player.ts","../lib/models/room.ts","../lib/models/message.ts","../lib/index.ts"],"sourcesContent":["import { PlayerEvents } from \"@lib/events/player\";\nimport EventEmitter from \"events\";\n\nexport interface PlayerOptions {\n id: string;\n name: string;\n attributes?: any;\n sender?: (type: string, ...message: any) => void;\n}\n\nexport enum PlayerStatus {\n ready = 'ready',\n unready = 'unready',\n online = 'online',\n playing = 'playing',\n}\n\nexport interface IPlayer extends PlayerOptions {\n status: PlayerStatus;\n}\n\nexport class Player extends EventEmitter implements IPlayer {\n on<K extends keyof PlayerEvents>(event: K, listener: PlayerEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof PlayerEvents>(event: K, ...args: Parameters<PlayerEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n \n id: string = \"\";\n name: string = \"\";\n attributes?: any;\n status: PlayerStatus = PlayerStatus.online;\n sender?: (type: string, ...message: any) => void;\n\n constructor({ id = new Date().getTime().toString(), name = '', attributes, sender }: PlayerOptions) {\n super();\n this.id = id;\n this.name = name;\n this.attributes = attributes;\n this.sender = sender;\n\n this.on('status', (status: PlayerStatus) => {\n this.status = status;\n });\n \n const events: Array<keyof PlayerEvents> = ['command', 'message', 'join', 'leave', 'status'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n }); \n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n attributes: this.attributes,\n status: this.status,\n };\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}","import { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./player\";\nimport EventEmitter from \"events\";\nimport { RoomEvents } from \"@lib/events\";\n\nexport interface IRoomOptions {\n /**\n * 房间号\n */\n id?: string, \n /**\n * 房间名称\n */\n name?: string,\n /**\n * 房间容量\n */\n size?: number, \n /**\n * 最小容量\n */\n minSize?: number,\n /**\n * 其他属性\n */\n attrs?: Record<string, any>,\n}\n\nexport enum PlayerRole {\n player = 'player',\n watcher = 'watcher',\n}\n\nexport enum RoomStatus {\n waiting = 'waiting',\n ready = 'ready',\n playing = 'playing',\n}\n\nexport interface IRoom extends IRoomOptions {\n players: RoomPlayer[];\n}\n\nexport interface IRoomPlayerOptions extends PlayerOptions {\n roomId?: string;\n}\nexport interface IRoomPlayer extends IRoomPlayerOptions, IPlayer {\n isReady: boolean;\n role: PlayerRole;\n isCreator: boolean;\n}\n\nexport class RoomPlayer extends Player implements IRoomPlayer {\n isReady: boolean = false;\n role: PlayerRole = PlayerRole.player;\n isCreator: boolean = false;\n roomId?: string;\n\n constructor(player: IPlayer | Player, role: PlayerRole = PlayerRole.player) {\n super(player);\n this.role = role;\n if (player instanceof Player && player.sender) super.setSender(player.sender);\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n role: this.role,\n isReady: this.isReady,\n isCreator: this.isCreator,\n };\n }\n}\n\nexport class Room extends EventEmitter implements IRoom {\n on<K extends keyof RoomEvents>(event: K, listener: RoomEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof RoomEvents>(event: K, ...args: Parameters<RoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n id: string; // room id\n size: number = 10; // room size\n name: string = ''; // room name\n minSize: number = 2; // room min size\n attrs?: Record<string, any>; // other attributes\n players: RoomPlayer[] = []; // player list\n\n get validPlayers() {\n return this.players.filter((player) => player.role === PlayerRole.player);\n }\n\n get watchers() {\n return this.players.filter((player) => player.role === PlayerRole.watcher);\n }\n\n private sender?: (type: string, ...message: any) => void;\n\n get isReady(): boolean {\n return this.players.length >= this.minSize\n && this.players.every((target) => target.isReady || target.role === PlayerRole.watcher); // is all player ready\n }\n\n get status(): RoomStatus {\n if (!this.isReady) return RoomStatus.waiting;\n if (this.players.findIndex((target) => target.status === PlayerStatus.playing) != -1) return RoomStatus.playing;\n return RoomStatus.ready;\n }\n\n get isPlaying(): boolean {\n return this.status === RoomStatus.playing;\n }\n\n // is room full\n get isFull(): boolean {\n return this.validPlayers.length == this.size;\n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n size: this.size || 10,\n minSize: this.minSize,\n status: this.status,\n players: this.players.map((player) => player.toJSON()),\n attrs: this.attrs,\n }\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n constructor({\n id = new Date().getTime().toString(), name = '', size = 10, minSize = 2, attrs\n }: IRoomOptions) {\n super();\n this.id = id;\n this.name = name;\n this.size = size;\n this.minSize = minSize;\n this.attrs = attrs;\n \n const events: Array<keyof RoomEvents> = ['message', 'command', 'start', 'end', 'close', 'error', 'all-ready', 'player-unready', 'player-ready', 'join', 'leave'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n });\n }\n\n addPlayer(player: Player, isCreator: boolean = false) {\n if (this.players.some((p) => p.id == player.id)) return;\n let roomPlayer = this.searchPlayer(player);\n if (!roomPlayer) {\n roomPlayer = new RoomPlayer(player, this.isFull || this.isPlaying ? PlayerRole.watcher : PlayerRole.player);\n roomPlayer.isCreator = isCreator;\n roomPlayer.roomId = this.id;\n this.players.push(roomPlayer);\n this.emit(\"join\", { roomId: this.id, ...roomPlayer });\n }\n return roomPlayer;\n }\n\n kickPlayer(playerId: string): RoomPlayer;\n kickPlayer(player: IPlayer): RoomPlayer;\n\n kickPlayer(player: IPlayer | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n const index = this.players.findIndex((p) => p.id == playerId);\n const roomPlayer = this.players[index];\n if (index > -1) {\n this.emit(\"leave\", { roomId: this.id, ...roomPlayer});\n this.players.splice(index, 1);\n if (roomPlayer.isCreator && this.players.length > 0) {\n this.players[0].isCreator = true;\n this.emit(\"update\", this);\n }\n }\n return roomPlayer;\n }\n\n searchPlayer(playerId: string): RoomPlayer | undefined;\n searchPlayer(playerId: IPlayer): RoomPlayer | undefined;\n\n searchPlayer(player: string | IPlayer) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((player) => player.id == playerId);\n }\n\n start() {\n if (!this.isReady) {\n throw new Error('room is not ready.');\n }\n if (this.status === RoomStatus.playing) {\n throw new Error('room is already started.');\n }\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.playing);\n });\n this.emit(\"update\", this);\n return this.emit(\"start\", this);\n }\n\n end() {\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.unready);\n });\n this.emit(\"update\", this);\n return this.emit(\"end\", this);\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}\n","import EventEmitter from \"events\";\nimport { IPlayer, PlayerOptions } from \"./player\";\nimport { IRoom, IRoomPlayer, IRoomOptions } from \"./room\";\nimport { MessageEvents } from \"@lib/events/message\";\n\nexport enum MessageTypes {\n RoomList = \"room.list\",\n RoomCreate = \"room.create\",\n RoomReady = \"room.ready\",\n RoomStart = \"room.start\",\n RoomEnd = \"room.end\",\n RoomClose = \"room.close\",\n RoomAllReady = \"room.allready\",\n RoomCommand = \"room.command\",\n RoomMessage = \"room.message\",\n PlayerOffline = \"player.offline\",\n PlayerList = \"player.list\",\n PlayerLogin = \"player.login\",\n PlayerLogout = \"player.logout\",\n PlayerJoin = \"player.join\",\n PlayerLeave = \"player.leave\",\n PlayerReady = \"player.ready\",\n PlayerUnready = \"player.unready\",\n PlayerCommand = \"player.command\",\n}\n\nexport interface MessagePackage {\n type: MessageTypes | string;\n data?: PlayerOptions | IRoomOptions | IPlayer | IRoom | IRoomPlayer | any;\n sender?: IPlayer | IRoom | IRoomPlayer;\n}\n\nexport interface Message extends EventEmitter {\n on<K extends keyof MessageEvents>(event: K, listener: MessageEvents[K]): this;\n emit<K extends keyof MessageEvents>(event: K, ...args: Parameters<MessageEvents[K]>): boolean;\n close(): void;\n send(message: MessagePackage): void;\n}\n","import { EventEmitter } from \"events\";\nimport { TiaoomEvents } from \"./events\";\nimport { Message } from \"./models/message\";\nimport { IRoom, IRoomPlayer, Room, IRoomOptions, IRoomPlayerOptions } from \"./models/room\";\nimport { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./models/player\";\n\nexport interface ITiaoomOptions {\n socket: Message;\n}\n\nexport class Tiaoom extends EventEmitter {\n rooms: Room[] = []; // room list\n players: Player[] = []; // player list\n messageInstance?: Message;\n\n constructor({ socket }: ITiaoomOptions) {\n super();\n this.messageInstance = socket;\n }\n\n on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n super.on(event, listener);\n return this\n }\n\n emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n run() {\n this.messageInstance?.on(\"message\", (message: any, cb?: (err: Error | null, data?: any) => any) => {\n try {\n switch (message.type) {\n case \"room.list\":\n return cb?.(null, this.rooms);\n case \"player.list\":\n return cb?.(null, this.players);\n case \"room.create\":\n return this.createRoom(message.sender, message.data);\n case \"player.join\":\n return this.joinPlayer(message.sender, message.data);\n case \"player.leave\":\n return this.leavePlayer(message.sender, message.data);\n case \"room.get\":\n return cb?.(null, this.searchRoom(message.data));\n case \"room.start\":\n return this.startRoom(message.sender, message.data);\n case \"room.close\":\n return this.closeRoom(message.sender, message.data);\n case \"player.login\":\n return this.loginPlayer(message.data);\n case \"player.logout\":\n return this.removePlayer(message.data);\n case \"player.ready\":\n return this.readyPlayer(message.sender, message.data);\n case \"player.unready\":\n return this.unReadyPlayer(message.sender, message.data);\n case \"room.player-command\":\n return this.searchRoom(message.data)?.emit(\"player-command\", { ...message.data , sender: message.sender });\n case \"room.message\":\n return this.searchRoom(message.data)?.emit(\"message\", message.data);\n case \"global.command\":\n return this.emit(\"command\", { ...message.data , sender: message.sender });\n default:\n throw new Error('unknown message type.');\n }\n } catch (error) {\n cb?.(error as Error);\n }\n });\n\n this.on('player', (player, online) => {\n this.messageInstance?.send({ type: online ? 'player.login' : 'player.logout', data: player });\n });\n\n this.on('players', (players) => {\n this.messageInstance?.send({ type: 'player.list', data: players });\n });\n\n this.on('room', (room) => {\n this.messageInstance?.send({ type: 'room.create', data: room });\n });\n\n this.on('room-player', (room) => {\n this.messageInstance?.send({ type: 'room.update', data: room });\n });\n\n this.on('rooms', (rooms) => {\n this.messageInstance?.send({ type: 'room.list', data: rooms });\n });\n\n this.on('command', (data) => {\n this.messageInstance?.send({ type: 'global.command', data });\n });\n\n return this;\n }\n\n searchPlayer(player: string): Player | undefined;\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions): Player | undefined;\n\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((target) => target.id === playerId);\n }\n\n searchRoom(room: string): Room | undefined;\n searchRoom(room: Partial<IRoomOptions>): Room | undefined;\n\n searchRoom(room: Partial<IRoomOptions> | string) {\n const roomId = typeof room === \"string\" ? room : room.id;\n return this.rooms.find((target) => target.id === roomId);\n }\n\n createRoom(sender: IPlayer, options: IRoomOptions) {\n if (!options.name) {\n throw new Error('missing room id or name.');\n }\n const roomInstance = this.searchRoom(options);\n if (roomInstance) {\n throw new Error('room already exists.');\n }\n\n if (this.rooms.some(r => r.players.some(p => p.id === sender.id))) {\n throw new Error('you are already in a room.');\n }\n\n const room = new Room(options);\n room.setSender((type, message) => {\n this.messageInstance?.send({ type: `room.${type}`, data: message, sender: room });\n });\n \n this.emit(\"room\", room);\n this.rooms.push(room);\n\n this.joinPlayer(sender, { roomId: room.id, ...sender }, true);\n return room;\n }\n\n startRoom(sender: IPlayer, room: IRoom) {\n const roomInstance = this.searchRoom(room);\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n roomInstance.start();\n\n return this.emit(\"room-player\", roomInstance);\n }\n\n closeRoom(sender: IPlayer, room: IRoom) {\n const roomIndex = this.rooms.findIndex((r) => r.id === room.id);\n const roomInstance = this.rooms[roomIndex];\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n\n if (roomInstance.players.length && !roomInstance.players.some(p => p.id === sender.id && p.isCreator)) {\n throw new Error('only room creator can close the room.');\n }\n\n room = this.rooms.splice(roomIndex, 1)[0];\n\n this.emit(\"rooms\", this.rooms);\n roomInstance.emit('close');\n return room;\n }\n\n loginPlayer (player: PlayerOptions, cb?: (data: { player: Player }) => void): Player {\n let playerInstance = this.searchPlayer(player);\n if (!playerInstance) {\n playerInstance = new Player(player);\n playerInstance.setSender((type, message) => {\n this.messageInstance?.send({ type: `player.${type}`, data: message, sender: playerInstance });\n });\n this.players.push(playerInstance);\n this.emit(\"player\", playerInstance, true);\n }\n \n playerInstance.emit(\"status\", PlayerStatus.online);\n cb?.({ player: playerInstance });\n return playerInstance;\n }\n\n joinPlayer(sender: IPlayer, player: IRoomPlayerOptions, isCreator: boolean = false) {\n let playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n playerInstance = this.loginPlayer(sender);\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.addPlayer(playerInstance, isCreator);\n if (!roomPlayer) {\n throw new Error('room is full.');\n }\n\n this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n leavePlayer(sender: IPlayer, player: IRoomPlayerOptions) {\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const playerInstance = room.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not in room.');\n }\n\n const roomPlayer = room.kickPlayer(playerInstance);\n\n if (roomPlayer) this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n readyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = true;\n\n if (room.isReady) {\n room.emit(\"all-ready\", room.players);\n }\n\n playerInstance.emit(\"status\", PlayerStatus.ready);\n\n room.emit(\"player-ready\", { ...player, ...roomPlayer });\n\n return this;\n }\n \n unReadyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = false;\n playerInstance.emit(\"status\", PlayerStatus.unready);\n room.emit(\"player-unready\", roomPlayer);\n\n return this;\n }\n\n removePlayer(sender: IPlayer) {\n const playerIndex = this.players.findIndex((p) => p.id === sender.id);\n const player = this.players[playerIndex];\n if (playerIndex > -1) {\n this.players.splice(playerIndex, 1)[0];\n this.emit(\"player\", player, false);\n if (this.rooms.some(r => r.searchPlayer(player))) {\n setTimeout(() => {\n if (this.players.some(p => p.id === sender.id)) return; // player is online\n this.rooms.filter(r => r.searchPlayer(player)).forEach(r => {\n this.leavePlayer(sender, { ...sender, roomId: r.id });\n });\n }, 5 * 60 * 1000); // 5 minutes later\n }\n }\n return player;\n }\n}\n\nexport * from \"./models/message\";\nexport * from \"./models/room\";\nexport * from \"./models/player\";\nexport * from \"./events\";"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["EventEmitter","EventEmitter","player","room"],"sources":["../lib/models/player.ts","../lib/models/room.ts","../lib/models/message.ts","../lib/index.ts"],"sourcesContent":["import { PlayerEvents } from \"@lib/events/player\";\nimport EventEmitter from \"events\";\n\nexport interface PlayerOptions {\n id: string;\n name: string;\n attributes?: any;\n sender?: (type: string, ...message: any) => void;\n}\n\nexport enum PlayerStatus {\n ready = 'ready',\n unready = 'unready',\n online = 'online',\n playing = 'playing',\n}\n\nexport interface IPlayer extends PlayerOptions {\n status: PlayerStatus;\n}\n\nexport class Player extends EventEmitter implements IPlayer {\n on<K extends keyof PlayerEvents>(event: K, listener: PlayerEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof PlayerEvents>(event: K, ...args: Parameters<PlayerEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n \n id: string = \"\";\n name: string = \"\";\n attributes?: any;\n status: PlayerStatus = PlayerStatus.online;\n sender?: (type: string, ...message: any) => void;\n\n constructor({ id = new Date().getTime().toString(), name = '', attributes, sender }: PlayerOptions) {\n super();\n this.id = id;\n this.name = name;\n this.attributes = attributes;\n this.sender = sender;\n\n this.on('status', (status: PlayerStatus) => {\n this.status = status;\n });\n \n const events: Array<keyof PlayerEvents> = ['command', 'message', 'join', 'leave', 'status'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n }); \n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n attributes: this.attributes,\n status: this.status,\n };\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}","import { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./player\";\nimport EventEmitter from \"events\";\nimport { RoomEvents } from \"@lib/events\";\n\nexport interface IRoomOptions {\n /**\n * 房间号\n */\n id?: string, \n /**\n * 房间名称\n */\n name?: string,\n /**\n * 房间容量\n */\n size?: number, \n /**\n * 最小容量\n */\n minSize?: number,\n /**\n * 其他属性\n */\n attrs?: Record<string, any>,\n}\n\nexport enum PlayerRole {\n player = 'player',\n watcher = 'watcher',\n}\n\nexport enum RoomStatus {\n waiting = 'waiting',\n ready = 'ready',\n playing = 'playing',\n}\n\nexport interface IRoom extends IRoomOptions {\n players: RoomPlayer[];\n}\n\nexport interface IRoomPlayerOptions extends PlayerOptions {\n roomId?: string;\n}\nexport interface IRoomPlayer extends IRoomPlayerOptions, IPlayer {\n isReady: boolean;\n role: PlayerRole;\n isCreator: boolean;\n}\n\nexport class RoomPlayer extends Player implements IRoomPlayer {\n isReady: boolean = false;\n role: PlayerRole = PlayerRole.player;\n isCreator: boolean = false;\n roomId?: string;\n\n constructor(player: IPlayer | Player, role: PlayerRole = PlayerRole.player) {\n super(player);\n this.role = role;\n if (player instanceof Player && player.sender) super.setSender(player.sender);\n }\n\n toJSON() {\n return {\n ...super.toJSON(),\n role: this.role,\n isReady: this.isReady,\n isCreator: this.isCreator,\n };\n }\n}\n\nexport class Room extends EventEmitter implements IRoom {\n on<K extends keyof RoomEvents>(event: K, listener: RoomEvents[K]): this {\n return super.on(event, listener);\n }\n\n emit<K extends keyof RoomEvents>(event: K, ...args: Parameters<RoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n id: string; // room id\n size: number = 10; // room size\n name: string = ''; // room name\n minSize: number = 2; // room min size\n attrs?: Record<string, any>; // other attributes\n players: RoomPlayer[] = []; // player list\n\n get validPlayers() {\n return this.players.filter((player) => player.role === PlayerRole.player);\n }\n\n get watchers() {\n return this.players.filter((player) => player.role === PlayerRole.watcher);\n }\n\n private sender?: (type: string, ...message: any) => void;\n\n get isReady(): boolean {\n return this.players.length >= this.minSize\n && this.players.every((target) => target.isReady || target.role === PlayerRole.watcher); // is all player ready\n }\n\n get status(): RoomStatus {\n if (!this.isReady) return RoomStatus.waiting;\n if (this.players.findIndex((target) => target.status === PlayerStatus.playing) != -1) return RoomStatus.playing;\n return RoomStatus.ready;\n }\n\n get isPlaying(): boolean {\n return this.status === RoomStatus.playing;\n }\n\n // is room full\n get isFull(): boolean {\n return this.validPlayers.length == this.size;\n }\n\n toJSON() {\n return {\n id: this.id,\n name: this.name,\n size: this.size || 10,\n minSize: this.minSize,\n status: this.status,\n players: this.players.map((player) => player.toJSON()),\n attrs: this.attrs,\n }\n }\n\n toString() {\n return JSON.stringify(this.toJSON());\n }\n\n constructor({\n id = new Date().getTime().toString(), name = '', size = 10, minSize = 2, attrs\n }: IRoomOptions) {\n super();\n this.id = id;\n this.name = name;\n this.size = size;\n this.minSize = minSize;\n this.attrs = attrs;\n \n const events: Array<keyof RoomEvents> = ['message', 'command', 'start', 'end', 'close', 'error', 'all-ready', 'player-unready', 'player-ready', 'join', 'leave'];\n events.forEach((event) => {\n this.on(event, (...data: any) => {\n this.sender?.(event, ...data);\n });\n });\n }\n\n setCreator(player: Player) {\n const roomPlayer = this.searchPlayer(player);\n if (roomPlayer) {\n this.players.forEach((p) => {\n p.isCreator = false;\n });\n roomPlayer.isCreator = true;\n this.emit(\"update\", this);\n }\n return this;\n }\n\n addPlayer(player: Player, isCreator: boolean = false) {\n if (this.players.some((p) => p.id == player.id)) return;\n let roomPlayer = this.searchPlayer(player);\n if (!roomPlayer) {\n roomPlayer = new RoomPlayer(player, this.isFull || this.isPlaying ? PlayerRole.watcher : PlayerRole.player);\n roomPlayer.isCreator = isCreator;\n roomPlayer.roomId = this.id;\n this.players.push(roomPlayer);\n this.emit(\"join\", { roomId: this.id, ...roomPlayer });\n }\n return roomPlayer;\n }\n\n kickPlayer(playerId: string): RoomPlayer;\n kickPlayer(player: IPlayer): RoomPlayer;\n\n kickPlayer(player: IPlayer | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n const index = this.players.findIndex((p) => p.id == playerId);\n const roomPlayer = this.players[index];\n if (index > -1) {\n this.emit(\"leave\", { roomId: this.id, ...roomPlayer});\n this.players.splice(index, 1);\n if (roomPlayer.isCreator && this.players.length > 0) {\n this.players[0].isCreator = true;\n this.emit(\"update\", this);\n }\n }\n return roomPlayer;\n }\n\n searchPlayer(playerId: string): RoomPlayer | undefined;\n searchPlayer(playerId: IPlayer): RoomPlayer | undefined;\n\n searchPlayer(player: string | IPlayer) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((player) => player.id == playerId);\n }\n\n start() {\n if (!this.isReady) {\n throw new Error('room is not ready.');\n }\n if (this.status === RoomStatus.playing) {\n throw new Error('room is already started.');\n }\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.playing);\n });\n this.emit(\"update\", this);\n return this.emit(\"start\", this);\n }\n\n end() {\n this.players.forEach((player) => {\n if (player.role != PlayerRole.player) return;\n player.emit('status', PlayerStatus.unready);\n });\n this.emit(\"update\", this);\n return this.emit(\"end\", this);\n }\n\n setSender(sender: (type: string, ...message: any) => void) {\n this.sender = sender;\n return this;\n }\n}\n","import EventEmitter from \"events\";\nimport { IPlayer, PlayerOptions } from \"./player\";\nimport { IRoom, IRoomPlayer, IRoomOptions } from \"./room\";\nimport { MessageEvents } from \"@lib/events/message\";\n\nexport enum MessageTypes {\n RoomList = \"room.list\",\n RoomCreate = \"room.create\",\n RoomReady = \"room.ready\",\n RoomStart = \"room.start\",\n RoomEnd = \"room.end\",\n RoomClose = \"room.close\",\n RoomAllReady = \"room.allready\",\n RoomCommand = \"room.command\",\n RoomMessage = \"room.message\",\n PlayerOffline = \"player.offline\",\n PlayerList = \"player.list\",\n PlayerLogin = \"player.login\",\n PlayerLogout = \"player.logout\",\n PlayerJoin = \"player.join\",\n PlayerLeave = \"player.leave\",\n PlayerReady = \"player.ready\",\n PlayerUnready = \"player.unready\",\n PlayerCommand = \"player.command\",\n}\n\nexport interface MessagePackage {\n type: MessageTypes | string;\n data?: PlayerOptions | IRoomOptions | IPlayer | IRoom | IRoomPlayer | any;\n sender?: IPlayer | IRoom | IRoomPlayer;\n}\n\nexport interface Message extends EventEmitter {\n on<K extends keyof MessageEvents>(event: K, listener: MessageEvents[K]): this;\n emit<K extends keyof MessageEvents>(event: K, ...args: Parameters<MessageEvents[K]>): boolean;\n close(): void;\n send(message: MessagePackage): void;\n}\n","import { EventEmitter } from \"events\";\nimport { TiaoomEvents } from \"./events\";\nimport { Message } from \"./models/message\";\nimport { IRoom, IRoomPlayer, Room, IRoomOptions, IRoomPlayerOptions } from \"./models/room\";\nimport { IPlayer, Player, PlayerOptions, PlayerStatus } from \"./models/player\";\n\nexport interface ITiaoomOptions {\n socket: Message;\n}\n\nexport class Tiaoom extends EventEmitter {\n rooms: Room[] = []; // room list\n players: Player[] = []; // player list\n messageInstance?: Message;\n\n constructor({ socket }: ITiaoomOptions) {\n super();\n this.messageInstance = socket;\n }\n\n on<K extends keyof TiaoomEvents>(event: K, listener: TiaoomEvents[K]): this {\n super.on(event, listener);\n return this\n }\n\n emit<K extends keyof TiaoomEvents>(event: K, ...args: Parameters<TiaoomEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n\n run() {\n this.messageInstance?.on(\"message\", (message: any, cb?: (err: Error | null, data?: any) => any) => {\n try {\n switch (message.type) {\n case \"room.list\":\n return cb?.(null, this.rooms);\n case \"player.list\":\n return cb?.(null, this.players);\n case \"room.create\":\n return this.createRoom(message.sender, message.data);\n case \"player.join\":\n return this.joinPlayer(message.sender, message.data);\n case \"player.leave\":\n return this.leavePlayer(message.sender, message.data);\n case \"room.get\":\n return cb?.(null, this.searchRoom(message.data));\n case \"room.start\":\n return this.startRoom(message.sender, message.data);\n case \"room.kick\":\n return this.kickPlayer(message.sender, message.data);\n case \"room.transfer\":\n return this.transferOwner(message.sender, message.data);\n case \"room.close\":\n return this.closeRoom(message.sender, message.data);\n case \"player.login\":\n return this.loginPlayer(message.data);\n case \"player.logout\":\n return this.removePlayer(message.data);\n case \"player.ready\":\n return this.readyPlayer(message.sender, message.data);\n case \"player.unready\":\n return this.unReadyPlayer(message.sender, message.data);\n case \"room.player-command\":\n return this.searchRoom(message.data)?.emit(\"player-command\", { ...message.data , sender: message.sender });\n case \"room.message\":\n return this.searchRoom(message.data)?.emit(\"message\", message.data);\n case \"global.command\":\n return this.emit(\"command\", { ...message.data , sender: message.sender });\n default:\n throw new Error('unknown message type.');\n }\n } catch (error) {\n cb?.(error as Error);\n }\n });\n\n this.on('player', (player, online) => {\n this.messageInstance?.send({ type: online ? 'player.login' : 'player.logout', data: player });\n });\n\n this.on('players', (players) => {\n this.messageInstance?.send({ type: 'player.list', data: players });\n });\n\n this.on('room', (room) => {\n this.messageInstance?.send({ type: 'room.create', data: room });\n });\n\n this.on('room-player', (room) => {\n this.messageInstance?.send({ type: 'room.update', data: room });\n });\n\n this.on('rooms', (rooms) => {\n this.messageInstance?.send({ type: 'room.list', data: rooms });\n });\n\n this.on('command', (data) => {\n this.messageInstance?.send({ type: 'global.command', data });\n });\n\n return this;\n }\n\n searchPlayer(player: string): Player | undefined;\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions): Player | undefined;\n\n searchPlayer(player: PlayerOptions | IRoomPlayerOptions | string) {\n const playerId = typeof player === \"string\" ? player : player.id;\n return this.players.find((target) => target.id === playerId);\n }\n\n searchRoom(room: string): Room | undefined;\n searchRoom(room: Partial<IRoomOptions>): Room | undefined;\n\n searchRoom(room: Partial<IRoomOptions> | string) {\n const roomId = typeof room === \"string\" ? room : room.id;\n return this.rooms.find((target) => target.id === roomId);\n }\n\n createRoom(sender: IPlayer, options: IRoomOptions) {\n if (!options.name) {\n throw new Error('missing room id or name.');\n }\n const roomInstance = this.searchRoom(options);\n if (roomInstance) {\n throw new Error('room already exists.');\n }\n\n if (this.rooms.some(r => r.players.some(p => p.id === sender.id))) {\n throw new Error('you are already in a room.');\n }\n\n const room = new Room(options);\n room.setSender((type, message) => {\n this.messageInstance?.send({ type: `room.${type}`, data: message, sender: room });\n });\n \n this.emit(\"room\", room);\n this.rooms.push(room);\n\n this.joinPlayer(sender, { roomId: room.id, ...sender }, true);\n return room;\n }\n\n startRoom(sender: IPlayer, room: IRoom) {\n const roomInstance = this.searchRoom(room);\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n roomInstance.start();\n\n return this.emit(\"room-player\", roomInstance);\n }\n\n closeRoom(sender: IPlayer, room: IRoom) {\n const roomIndex = this.rooms.findIndex((r) => r.id === room.id);\n const roomInstance = this.rooms[roomIndex];\n if (!roomInstance) {\n throw new Error('room not found.');\n }\n\n if (roomInstance.players.length && !roomInstance.players.some(p => p.id === sender.id && p.isCreator)) {\n throw new Error('only room creator can close the room.');\n }\n\n room = this.rooms.splice(roomIndex, 1)[0];\n\n this.emit(\"rooms\", this.rooms);\n roomInstance.emit('close');\n return room;\n }\n\n kickPlayer(sender: IPlayer, data: { roomId: string, playerId: string }) {\n const room = this.searchRoom(data.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const senderInRoom = room.searchPlayer(sender);\n if (!senderInRoom || !senderInRoom.isCreator) {\n throw new Error('permission denied.');\n }\n\n const targetPlayer = room.players.find(p => p.id === data.playerId);\n if (!targetPlayer) {\n throw new Error('player not found in room.');\n }\n\n const roomPlayer = room.kickPlayer(targetPlayer);\n if (roomPlayer) this.emit(\"room-player\", room);\n return roomPlayer;\n }\n\n transferOwner(sender: IPlayer, data: { roomId: string, playerId: string }) {\n const room = this.searchRoom(data.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const senderInRoom = room.searchPlayer(sender);\n if (!senderInRoom || !senderInRoom.isCreator) {\n throw new Error('permission denied.');\n }\n\n const targetPlayer = room.players.find(p => p.id === data.playerId);\n if (!targetPlayer) {\n throw new Error('player not found in room.');\n }\n\n if (targetPlayer.id === sender.id) {\n return;\n }\n\n senderInRoom.isCreator = false;\n targetPlayer.isCreator = true;\n\n this.emit(\"room-player\", room);\n return room;\n }\n\n loginPlayer (player: PlayerOptions, cb?: (data: { player: Player }) => void): Player {\n let playerInstance = this.searchPlayer(player);\n if (!playerInstance) {\n playerInstance = new Player(player);\n playerInstance.setSender((type, message) => {\n this.messageInstance?.send({ type: `player.${type}`, data: message, sender: playerInstance });\n });\n this.players.push(playerInstance);\n this.emit(\"player\", playerInstance, true);\n }\n \n playerInstance.emit(\"status\", PlayerStatus.online);\n cb?.({ player: playerInstance });\n return playerInstance;\n }\n\n joinPlayer(sender: IPlayer, player: IRoomPlayerOptions, isCreator: boolean = false) {\n let playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n playerInstance = this.loginPlayer(sender);\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.addPlayer(playerInstance, isCreator);\n if (!roomPlayer) {\n throw new Error('room is full.');\n }\n\n this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n leavePlayer(sender: IPlayer, player: IRoomPlayerOptions) {\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const playerInstance = room.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not in room.');\n }\n\n const roomPlayer = room.kickPlayer(playerInstance);\n\n if (roomPlayer) this.emit(\"room-player\", room);\n\n return roomPlayer;\n }\n\n readyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = true;\n\n if (room.isReady) {\n room.emit(\"all-ready\", room.players);\n }\n\n playerInstance.emit(\"status\", PlayerStatus.ready);\n\n room.emit(\"player-ready\", { ...player, ...roomPlayer });\n\n return this;\n }\n \n unReadyPlayer(sender: IPlayer, player: IRoomPlayer) {\n const playerInstance = this.searchPlayer(sender);\n if (!playerInstance) {\n throw new Error('player not found.');\n }\n\n if (!player.roomId) {\n throw new Error('missing room id.');\n }\n\n const room = this.rooms.find((room) => room.id === player.roomId);\n if (!room) {\n throw new Error('room not found.');\n }\n\n const roomPlayer = room.searchPlayer(playerInstance);\n \n if (!roomPlayer) {\n throw new Error('player not in room.');\n }\n\n roomPlayer.isReady = false;\n playerInstance.emit(\"status\", PlayerStatus.unready);\n room.emit(\"player-unready\", roomPlayer);\n\n return this;\n }\n\n removePlayer(sender: IPlayer) {\n const playerIndex = this.players.findIndex((p) => p.id === sender.id);\n const player = this.players[playerIndex];\n if (playerIndex > -1) {\n this.players.splice(playerIndex, 1)[0];\n this.emit(\"player\", player, false);\n if (this.rooms.some(r => r.searchPlayer(player))) {\n setTimeout(() => {\n if (this.players.some(p => p.id === sender.id)) return; // player is online\n this.rooms.filter(r => r.searchPlayer(player)).forEach(r => {\n this.leavePlayer(sender, { ...sender, roomId: r.id });\n });\n }, 5 * 60 * 1000); // 5 minutes later\n }\n }\n return player;\n }\n}\n\nexport * from \"./models/message\";\nexport * from \"./models/room\";\nexport * from \"./models/player\";\nexport * from \"./events\";"],"mappings":"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"}
|