From 7dd2c82a5013379e1d155d8d3f7257f86cf2f32a Mon Sep 17 00:00:00 2001 From: zhl Date: Mon, 1 Mar 2021 14:24:48 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cfg/RoomOptions.ts | 0 src/rooms/GeneralRoom.ts | 351 +++++++++++++++++++++------------------ 2 files changed, 191 insertions(+), 160 deletions(-) create mode 100644 src/cfg/RoomOptions.ts diff --git a/src/cfg/RoomOptions.ts b/src/cfg/RoomOptions.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/rooms/GeneralRoom.ts b/src/rooms/GeneralRoom.ts index e69e0f4..3343bdb 100644 --- a/src/rooms/GeneralRoom.ts +++ b/src/rooms/GeneralRoom.ts @@ -1,194 +1,223 @@ -import {Client, Room} from "colyseus"; -import {CardGameState} from "./schema/CardGameState"; -import {OnJoinCommand} from "./commands/OnJoinCommand"; -import {PlayReadyCommand} from "./commands/PlayReadyCommand"; -import {Dispatcher} from "@colyseus/command"; -import {DiscardCommand} from "./commands/DiscardCommand"; -import {SelectPetCommand} from "./commands/SelectPetCommand"; -import {ChangeCardCommand} from "./commands/ChangeCardCommand"; -import {SelectHeroCommand} from "./commands/SelectHeroCommand"; -import {EatCardCommand} from "./commands/EatCardCommand"; -import {GiveUpCommand} from "./commands/GiveUpCommand"; -import {BattleHandler} from "./logic/Handler/BattleHandler"; -import {debugRoom, error, msgLog} from "../common/Debug"; -import {Delayed} from "@gamestdio/timer/lib/Delayed"; -import {IncomingMessage} from "http"; -import {PlayerStateConst} from "../constants/PlayerStateConst"; -import {Player} from "./schema/Player"; -import {GMCommand} from "./commands/GMCommand"; -import {GameStateConst} from "../constants/GameStateConst"; -import {GameRestartCommand} from "./commands/GameRestartCommand"; -import {RobotClient} from "../robot/RobotClient"; -import {ChangePetCommand} from "./commands/ChangePetCommand"; -import {createRobot} from "../common/WebApi"; +import { Client, Room } from 'colyseus' +import { CardGameState } from './schema/CardGameState' +import { OnJoinCommand } from './commands/OnJoinCommand' +import { PlayReadyCommand } from './commands/PlayReadyCommand' +import { Dispatcher } from '@colyseus/command' +import { DiscardCommand } from './commands/DiscardCommand' +import { SelectPetCommand } from './commands/SelectPetCommand' +import { ChangeCardCommand } from './commands/ChangeCardCommand' +import { SelectHeroCommand } from './commands/SelectHeroCommand' +import { EatCardCommand } from './commands/EatCardCommand' +import { GiveUpCommand } from './commands/GiveUpCommand' +import { BattleHandler } from './logic/Handler/BattleHandler' +import { debugRoom, error, msgLog } from '../common/Debug' +import { Delayed } from '@gamestdio/timer/lib/Delayed' +import { IncomingMessage } from 'http' +import { Player } from './schema/Player' +import { GMCommand } from './commands/GMCommand' +import { GameStateConst } from '../constants/GameStateConst' +import { GameRestartCommand } from './commands/GameRestartCommand' +import { RobotClient } from '../robot/RobotClient' +import { ChangePetCommand } from './commands/ChangePetCommand' +import { createRobot } from '../common/WebApi' import { Service } from '../service/Service' export class GeneralRoom extends Room { - dispatcher = new Dispatcher(this); - maxClients = 4; - score = 0; - battleMan = new BattleHandler(); + dispatcher = new Dispatcher(this) + maxClients = 4 + score = 0 + battleMan = new BattleHandler() // 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家 - gameClock: Map = new Map(); + gameClock: Map = new Map() - assistMap: Map = new Map(); - match = ''; - robotCount = 0; + assistMap: Map = new Map() + match = '' + robotCount = 0 - async onAuth (client:Client, options: any, request: IncomingMessage) { - debugRoom(options); + async onAuth(client: Client, options: any, request: IncomingMessage) { + debugRoom(options) // TODO: 验证用户信息 // client.auth.accountId = options.accountId; // client.auth.sessionId = options.sessionId; - return true; + return true } - onCreate (options: any) { - let cs = new CardGameState(); + + onCreate(options: any) { + let cs = new CardGameState() if (options.clients) { this.maxClients = options.clients } - this.setState(cs); + this.setState(cs) if (options.mode) { - this.state.mode = +options.mode; + this.state.mode = +options.mode } - this.setPrivate(true); + this.setPrivate(true) if (options.count) { - this.robotCount = Math.min(Math.max(0, options.count), this.maxClients - 1); + this.robotCount = Math.min(Math.max(0, options.count), this.maxClients - 1) } - this.match = options.match; + this.match = options.match if (options.score) { - this.score = options.score; + this.score = options.score } - this.battleMan.init(cs, this); - this.clock.start(); - this.state.gameState = GameStateConst.STATE_WAIT_JOIN; - this.onMessage("play_ready_c2s", (client, message) => { - msgLog('play_ready from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new PlayReadyCommand(), {client}); - }); - this.onMessage("change_card_c2s", (client, message) => { - msgLog('change_card from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new ChangeCardCommand(), {client, cards: message.cards}); - }); - this.onMessage("discard_card_c2s", (client, message) => { - msgLog('discard_card from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new DiscardCommand(), {client, cards: message.cards, target: message.target, dtype: 0}); - }); - this.onMessage("eat_card_c2s", (client, message) => { - msgLog('eat_card from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new EatCardCommand(), {client, cards: message.cards, target: message.target}); - }); + this.battleMan.init(cs, this) + this.clock.start() + this.state.gameState = GameStateConst.STATE_WAIT_JOIN + this.onMessage('play_ready_c2s', (client, message) => { + msgLog('play_ready from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new PlayReadyCommand(), { client }) + }) + this.onMessage('change_card_c2s', (client, message) => { + msgLog('change_card from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new ChangeCardCommand(), { + client, + cards: message.cards + }) + }) + this.onMessage('discard_card_c2s', (client, message) => { + msgLog('discard_card from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new DiscardCommand(), { + client, + cards: message.cards, + target: message.target, + dtype: 0 + }) + }) + this.onMessage('eat_card_c2s', (client, message) => { + msgLog('eat_card from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new EatCardCommand(), { + client, + cards: message.cards, + target: message.target + }) + }) - this.onMessage("give_up_eat_c2s", (client, message) => { - msgLog('give_up_take from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new GiveUpCommand(), {client}); - }); + this.onMessage('give_up_eat_c2s', (client, message) => { + msgLog('give_up_take from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new GiveUpCommand(), { client }) + }) - this.onMessage("select_pet_c2s", (client, message) => { - msgLog('select_pet from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new SelectPetCommand(), {client, cardId: message.card, playerId: message.player, pos: message.pos, effCards: message.effCards, oldpos: message.oldPos }); - }); + this.onMessage('select_pet_c2s', (client, message) => { + msgLog('select_pet from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new SelectPetCommand(), { + client, + cardId: message.card, + playerId: message.player, + pos: message.pos, + effCards: message.effCards, + oldpos: message.oldPos + }) + }) - this.onMessage("select_hero_c2s", (client, message) => { - msgLog('select_hero from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new SelectHeroCommand(), {client, heroId: message.heroId, cardGroup: message.cardgroup}); - }); + this.onMessage('select_hero_c2s', (client, message) => { + msgLog('select_hero from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new SelectHeroCommand(), { + client, + heroId: message.heroId, + cardGroup: message.cardgroup + }) + }) - this.onMessage("gm", (client, message) => { - msgLog('gm command from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new GMCommand(), {client, message}); - }); + this.onMessage('gm', (client, message) => { + msgLog('gm command from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new GMCommand(), { client, message }) + }) - this.onMessage("restart_c2s", (client, message) => { - msgLog('restart game from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new GameRestartCommand(), {client}); - }); + this.onMessage('restart_c2s', (client, message) => { + msgLog('restart game from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new GameRestartCommand(), { client }) + }) - this.onMessage("change_pet_c2s", (client, message) => { - msgLog('change pet from ', client.sessionId, JSON.stringify(message)); - this.dispatcher.dispatch(new ChangePetCommand(), {client, pos: message.pos, petId: message.petId}); - }); + this.onMessage('change_pet_c2s', (client, message) => { + msgLog('change pet from ', client.sessionId, JSON.stringify(message)) + this.dispatcher.dispatch(new ChangePetCommand(), { + client, + pos: message.pos, + petId: message.petId + }) + }) /** * broadcast_c2s的消息, 原样广播出去 */ - this.onMessage("broadcast_c2s", (client, message) => { - msgLog('broadcast_c2s from ', client.sessionId, JSON.stringify(message)); - this.broadcast("broadcast_s2c", message, {except: client}); - }); + this.onMessage('broadcast_c2s', (client, message) => { + msgLog('broadcast_c2s from ', client.sessionId, JSON.stringify(message)) + this.broadcast('broadcast_s2c', message, { except: client }) + }) - this.onMessage("*", (client, type, message) => { + this.onMessage('*', (client, type, message) => { // // Triggers when any other type of message is sent, // excluding "action", which has its own specific handler defined above. // - msgLog(client.sessionId, "sent", type, JSON.stringify(message)); - }); + msgLog(client.sessionId, 'sent', type, JSON.stringify(message)) + }) } - onJoin (client: Client, options: any) { + + onJoin(client: Client, options: any) { let data = { client: client, accountId: options.accountid, seat: options.seat, - score: options.score, - }; - this.dispatcher.dispatch(new OnJoinCommand(), data); + score: options.score + } + this.dispatcher.dispatch(new OnJoinCommand(), data) } + //TODO: 掉线逻辑 - async onLeave (client: Client, consented: boolean) { + async onLeave(client: Client, consented: boolean) { if (this.state.gameState === GameStateConst.STATE_GAME_OVER || this.state.gameState === GameStateConst.STATE_WAIT_JOIN) { - this.state.players.delete(client.sessionId); + this.state.players.delete(client.sessionId) if (this.assistMap.has(client.sessionId)) { - this.assistMap.get(client.sessionId).leave(); - this.assistMap.delete(client.sessionId); + this.assistMap.get(client.sessionId).leave() + this.assistMap.delete(client.sessionId) } - this.bUserLeft(client.sessionId); + this.bUserLeft(client.sessionId) } else { - this.state.players.get(client.sessionId).online = false; - let assistClient = this.getAssistClient(client.sessionId); - assistClient.active = true; + this.state.players.get(client.sessionId).online = false + let assistClient = this.getAssistClient(client.sessionId) + assistClient.active = true try { if (consented) { - throw new Error("consented leave"); + throw new Error('consented leave') } else { - await this.allowReconnection(client, 10 * 60); - debugRoom(`${client.sessionId} 重连`); - assistClient.active = false; - this.state.players.get(client.sessionId).online = true; + await this.allowReconnection(client, 10 * 60) + debugRoom(`${ client.sessionId } 重连`) + assistClient.active = false + this.state.players.get(client.sessionId).online = true } } catch (e) { - debugRoom(`player realy level :${client.sessionId}, try add robot`); + debugRoom(`player realy level :${ client.sessionId }, try add robot`) // this.state.players.delete(client.sessionId); } } } onDispose() { - this.gameClock.clear(); - this.assistMap.clear(); - this.dispatcher.stop(); + this.gameClock.clear() + this.assistMap.clear() + this.dispatcher.stop() } getClient(player: string | Player): Client { - let result: Client; - let sessionId; + let result: Client + let sessionId if (typeof player == 'string') { - sessionId = player; - result = this.clients.find(client => client.sessionId == player ); + sessionId = player + result = this.clients.find(client => client.sessionId == player) } else { - sessionId = player.id; - result = this.clients.find(client => client.sessionId == player.id ); + sessionId = player.id + result = this.clients.find(client => client.sessionId == player.id) } if (!result) { - debugRoom(`无法获取id为: ${typeof player == 'string' ? player : player.id} 的客户端`); - result = this.getAssistClient(sessionId); - debugRoom(`启用辅助机器人, 当前机器人状态: ${(result as RobotClient).active}`) + debugRoom(`无法获取id为: ${ typeof player == 'string' ? player : player.id } 的客户端`) + result = this.getAssistClient(sessionId) + debugRoom(`启用辅助机器人, 当前机器人状态: ${ (result as RobotClient).active }`) } - return result; + return result } clientCount(): number { - return this.clients.length; + return this.clients.length } /** @@ -199,17 +228,17 @@ export class GeneralRoom extends Room { * @param name */ beginSchedule(millisecond: number, handler: Function, name: string): void { - debugRoom(`begin schedule: `, name, millisecond / 1000); + debugRoom(`begin schedule: `, name, millisecond / 1000) if (this.gameClock.has(name) && this.gameClock.get(name)?.active) { - error(`当前已存在进行中的gameClock: ${name}`); - this.gameClock.get(name).clear(); - this.gameClock.delete(name); + error(`当前已存在进行中的gameClock: ${ name }`) + this.gameClock.get(name).clear() + this.gameClock.delete(name) } - let self = this; + let self = this let timeOverFun = function () { - handler && handler(); + handler && handler() } - this.gameClock.set(name, this.clock.setTimeout(timeOverFun, millisecond , name)); + this.gameClock.set(name, this.clock.setTimeout(timeOverFun, millisecond, name)) } /** @@ -217,19 +246,19 @@ export class GeneralRoom extends Room { * gameClock任何时候只有一个可执行的任务 */ stopSchedule(name: string): number { - debugRoom(`manual stop schedule: ${name}`); + debugRoom(`manual stop schedule: ${ name }`) if (!this.gameClock.has(name)) { - return -1; + return -1 } else { let clock = this.gameClock.get(name) if (!clock.active) { - this.gameClock.delete(name); - return -1; + this.gameClock.delete(name) + return -1 } else { - let time = clock.elapsedTime; - clock.clear(); - this.gameClock.delete(name); - return time; + let time = clock.elapsedTime + clock.clear() + this.gameClock.delete(name) + return time } } @@ -242,25 +271,25 @@ export class GeneralRoom extends Room { * @param reason */ addScheduleTime(millisecond: number, reason?: string, name?: string): void { - let current; - let currentName = name; + let current + let currentName = name if (!name) { for (let [id, clock] of this.gameClock) { if (clock.active) { - current = clock; - currentName = id; - break; + current = clock + currentName = id + break } } } else { if (this.gameClock.has(name)) { - current = this.gameClock.get(name); + current = this.gameClock.get(name) } } - debugRoom(`add schedule for ${currentName}, time: ${millisecond/1000}, reason: ${reason}`); + debugRoom(`add schedule for ${ currentName }, time: ${ millisecond / 1000 }, reason: ${ reason }`) if (current) { - current.time += millisecond ; - debugRoom(`schedule for ${name} remain: ${(current.time - current.elapsedTime)/1000}`); + current.time += millisecond + debugRoom(`schedule for ${ name } remain: ${ (current.time - current.elapsedTime) / 1000 }`) } } @@ -271,42 +300,44 @@ export class GeneralRoom extends Room { room: this.roomId, sessionId: playerId } - await createRobot(data); + await createRobot(data) } addAssistClient(sessionId: string) { if (!this.assistMap.has(sessionId)) { - let client = new RobotClient(sessionId, this.state, this['onMessageHandlers']); - this.assistMap.set(sessionId, client); + let client = new RobotClient(sessionId, this.state, this['onMessageHandlers']) + this.assistMap.set(sessionId, client) } } getAssistClient(sessionId: string): RobotClient { - return this.assistMap.get(sessionId); + return this.assistMap.get(sessionId) } + getPlayerByIdx(idx: number) { for (let [, player] of this.state.players) { if (player.idx == idx) { - return player; + return player } } } + /** * 获取对位玩家 * @param srcPlayer */ getOppositePlayer(srcPlayer: string | Player): Player { - let playerId; + let playerId if (typeof srcPlayer === 'string') { - playerId = srcPlayer as string; + playerId = srcPlayer as string } else { - playerId = srcPlayer.id; + playerId = srcPlayer.id } if (!this.state.players.has(playerId)) { - return null; + return null } - let idx = this.state.players.get(playerId).idx; - let opposIdx = ((this.maxClients / 2 | 0) + idx) % this.maxClients; - return this.getPlayerByIdx(opposIdx); + let idx = this.state.players.get(playerId).idx + let opposIdx = ((this.maxClients / 2 | 0) + idx) % this.maxClients + return this.getPlayerByIdx(opposIdx) } }