diff --git a/package.json b/package.json index 4374bea..1d01420 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@colyseus/proxy": "^0.12.2", "@colyseus/social": "^0.10.9", "axios": "^0.21.0", + "body-parser": "^1.19.0", "colyseus": "^0.14.0", "cors": "^2.8.5", "debug": "^4.3.1", diff --git a/src/api/apiRouter.ts b/src/api/apiRouter.ts index 268d031..46a9e63 100644 --- a/src/api/apiRouter.ts +++ b/src/api/apiRouter.ts @@ -14,14 +14,14 @@ export function getAPI (opts: Partial) { const message = UNAVAILABLE_ROOM_ERROR.replace("$roomId", roomId); console.error(message); res.status(500); - res.json({ message }); + res.json({ errcode: 1, message }); } }); - api.get("/room/call", async (req: express.Request, res: express.Response) => { - const roomId = req.query.roomId as string; - const method = req.query.method as string; - const args = JSON.parse(req.query.args as string); + api.post("/room/call", async (req: express.Request, res: express.Response) => { + const roomId = req.body.roomId as string; + const method = req.body.method as string; + const args = JSON.parse(req.body.args as string); try { const data = await matchMaker.remoteRoomCall(roomId, method, args); @@ -30,14 +30,14 @@ export function getAPI (opts: Partial) { const message = UNAVAILABLE_ROOM_ERROR.replace("$roomId", roomId); console.error(e); res.status(500); - res.json({ message }); + res.json({ errcode: 1, message }); } }); - api.get("/broadcast", async (req: express.Request, res: express.Response) => { - const roomId = req.query.roomId as string; - const type = req.query.type as string; - const msg = req.query.msg as string; + api.post("/broadcast", async (req: express.Request, res: express.Response) => { + const roomId = req.body.roomId as string; + const type = req.body.type as string; + const msg = req.body.msg as string; const method = 'broadcast' const paramArr = [type, msg] @@ -48,7 +48,7 @@ export function getAPI (opts: Partial) { const message = UNAVAILABLE_ROOM_ERROR.replace("$roomId", roomId); console.error(e); res.status(500); - res.json({ message }); + res.json({ errcode: 1, message }); } }); diff --git a/src/constants/GameStateConst.ts b/src/constants/GameStateConst.ts new file mode 100644 index 0000000..1353248 --- /dev/null +++ b/src/constants/GameStateConst.ts @@ -0,0 +1,12 @@ +export class GameStateConst { + + // 等待玩家加入 + public static readonly STATE_WAIT_JOIN = 0; + // 等待玩家准备 + public static readonly STATE_WAIT_PREPARE = 1; + // 游戏进行中 + public static readonly STATE_GAMING = 2; + + // 游戏结束 + public static readonly STATE_GAME_OVER = 9; +} diff --git a/src/index.ts b/src/index.ts index a45027b..3863aa3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ import { MongooseDriver } from 'colyseus/lib/matchmaker/drivers/MongooseDriver' import { RedisClient } from './redis/RedisClient' import { PuzzleMathRoom } from './rooms/PuzzleMathRoom' import { zApis } from './api/api' +import bodyParser from 'body-parser' require('./common/Extend') @@ -22,6 +23,12 @@ const app = express() app.use(cors()) app.use(express.json()) +app.use(bodyParser.json({limit: '500mb'})); +app.use(bodyParser.urlencoded({ + limit: '500mb', + parameterLimit: 50000, + extended: true, +})); initData() global.isProd = isProd const server = http.createServer(app) diff --git a/src/rooms/PuzzleMathRoom.ts b/src/rooms/PuzzleMathRoom.ts index 48eb9b2..d09e497 100644 --- a/src/rooms/PuzzleMathRoom.ts +++ b/src/rooms/PuzzleMathRoom.ts @@ -3,6 +3,9 @@ import { Dispatcher } from '@colyseus/command' import { IncomingMessage } from 'http' import { debugRoom, msgLog } from '../common/Debug' import { OnJoinCommand } from './commands/OnJoinCommand' +import { Player } from './schema/Player' +import { BeginGameCommand } from './commands/BeginGameCommand' +import { PuzzleGameState } from './schema/PuzzleGameState' export class PuzzleMathRoom extends Room { @@ -14,6 +17,8 @@ export class PuzzleMathRoom extends Room { return true } onCreate(options: any) { + let cs = new PuzzleGameState() + this.setState(cs) this.onMessage('*', (client, type, message) => { msgLog(client.sessionId, 'sent', type, JSON.stringify(message)) @@ -33,7 +38,56 @@ export class PuzzleMathRoom extends Room { this.dispatcher.stop() } - adminMsg(str: string) { - console.log(`receive admin msg: ${str}`); + /** + * 获取指定player的client实例, 如果玩家已掉线, 则获取该玩家的assist client + * @param {string | Player} player + * @return {Client} + */ + getRemoteClient(player: string | Player): Client { + let result: Client + if (typeof player == 'string') { + result = this.clients.find(client => client.sessionId == player) + } else { + result = this.clients.find(client => client.sessionId == player.id) + } + + return result + } + + /** + * 发送私信给玩家 + * @param {string} clientId + * @param {string} type + * @param {string} msg + */ + smsg(clientId: string, type: string, msg: string) { + msgLog(`sendMsg to: ${clientId}, type: ${type}, msg: ${msg}`); + const client = this.getRemoteClient(clientId) + if (client) { + client.send(type, msg); + } + } + + /** + * 加入当前房间的client数量 + * @return {number} + */ + get clientCount(): number { + return this.clients.length + } + + /** + * 开始游戏 + */ + beginGame() { + console.log(`admin send begin game cmd`) + this.dispatcher.dispatch(new BeginGameCommand() ) + } + + /** + * 游戏结束 + */ + endGame() { + } } diff --git a/src/rooms/commands/BeginGameCommand.ts b/src/rooms/commands/BeginGameCommand.ts new file mode 100644 index 0000000..ec1822c --- /dev/null +++ b/src/rooms/commands/BeginGameCommand.ts @@ -0,0 +1,13 @@ +import { Command } from '@colyseus/command' +import { PuzzleGameState } from '../schema/PuzzleGameState' +import { GameStateConst } from '../../constants/GameStateConst' + +/** + * 开始游戏 + */ +export class BeginGameCommand extends Command { + async execute() { + this.state.updateGameState(GameStateConst.STATE_GAMING) + this.room.broadcast('begingame', {}) + } +} diff --git a/src/rooms/commands/OnJoinCommand.ts b/src/rooms/commands/OnJoinCommand.ts index 069940d..95f25af 100644 --- a/src/rooms/commands/OnJoinCommand.ts +++ b/src/rooms/commands/OnJoinCommand.ts @@ -1,12 +1,14 @@ import { Command } from '@colyseus/command' import { PuzzleGameState } from '../schema/PuzzleGameState' import { Client } from 'colyseus' +import { Player } from '../schema/Player' export class OnJoinCommand extends Command { async execute({ client, accountId} = this.payload) { - + let player = new Player(client.id, accountId) + this.state.players.set(client.sessionId, player) } } diff --git a/src/rooms/schema/Player.ts b/src/rooms/schema/Player.ts new file mode 100644 index 0000000..5ab3591 --- /dev/null +++ b/src/rooms/schema/Player.ts @@ -0,0 +1,22 @@ +import { Schema, type } from '@colyseus/schema' + +export class Player extends Schema { + @type('string') + id: string + + accountId: string + + @type('number') + score: number + + @type('number') + rank: number + + team: number + + constructor(id: string, accountId: string) { + super() + this.id = id + this.accountId = accountId + } +} diff --git a/src/rooms/schema/PuzzleGameState.ts b/src/rooms/schema/PuzzleGameState.ts index 2b456ef..5ced0f5 100644 --- a/src/rooms/schema/PuzzleGameState.ts +++ b/src/rooms/schema/PuzzleGameState.ts @@ -1,5 +1,25 @@ import { MapSchema, Schema, type } from '@colyseus/schema' +import { GameStateConst } from '../../constants/GameStateConst' +import { Player } from './Player' export class PuzzleGameState extends Schema { + @type('number') + gameState: number = GameStateConst.STATE_WAIT_JOIN + @type({ map: Player }) + players = new MapSchema() + + /** + * 轮次 + */ + @type('number') + round: number + + + + updateGameState(val: number) { + let preVal = this.gameState + this.gameState = val + this.$listeners?.gameState?.invoke(val, preVal) + } }