166 lines
5.8 KiB
TypeScript
166 lines
5.8 KiB
TypeScript
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";
|
|
|
|
|
|
export class GeneralRoom extends Room {
|
|
dispatcher = new Dispatcher(this);
|
|
maxClients = 4;
|
|
clientMap = new Map();
|
|
battleMan = new BattleHandler();
|
|
// 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家
|
|
mainClock: Delayed;
|
|
async onAuth (client:Client, options: any, request: IncomingMessage) {
|
|
console.log(options);
|
|
// TODO: 验证用户信息
|
|
// client.auth.accountId = options.accountId;
|
|
// client.auth.sessionId = options.sessionId;
|
|
return true;
|
|
}
|
|
onCreate (options: any) {
|
|
let cs = new CardGameState();
|
|
this.setState(cs);
|
|
this.battleMan.init(cs, this);
|
|
this.clock.start();
|
|
this.state.gameSate = 0;
|
|
this.onMessage("play_ready_c2s", (client, message) => {
|
|
msgLog('play_ready from ', client.sessionId, message);
|
|
this.dispatcher.dispatch(new PlayReadyCommand(), {client});
|
|
});
|
|
this.onMessage("change_card_c2s", (client, message) => {
|
|
msgLog('change_card from ', client.sessionId, message);
|
|
this.dispatcher.dispatch(new ChangeCardCommand(), {client, cards: message.cards});
|
|
});
|
|
this.onMessage("discard_card_c2s", (client, message) => {
|
|
msgLog('discard_card from ', client.sessionId, message);
|
|
this.dispatcher.dispatch(new DiscardCommand(), {client, cards: message.cards, dtype: 0});
|
|
});
|
|
this.onMessage("eat_card_c2s", (client, message) => {
|
|
msgLog('eat_card from ', client.sessionId, 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, message);
|
|
this.dispatcher.dispatch(new GiveUpCommand(), {client});
|
|
});
|
|
|
|
this.onMessage("select_pet_c2s", (client, message) => {
|
|
msgLog('select_pet from ', client.sessionId, message);
|
|
this.dispatcher.dispatch(new SelectPetCommand(), {client, cardId: message.card, playerId: message.player, pos: message.pos, effCards: message.effCards });
|
|
});
|
|
|
|
this.onMessage("select_hero_c2s", (client, message) => {
|
|
msgLog('select_hero from ', client.sessionId, message);
|
|
this.dispatcher.dispatch(new SelectHeroCommand(), {client, heroId: message.heroId});
|
|
});
|
|
|
|
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, message);
|
|
});
|
|
|
|
}
|
|
|
|
onJoin (client: Client, options: any) {
|
|
let data = {
|
|
client: client
|
|
};
|
|
this.dispatcher.dispatch(new OnJoinCommand(), data);
|
|
this.clientMap.set(client.sessionId, client);
|
|
}
|
|
//TODO: 掉线逻辑
|
|
async onLeave (client: Client, consented: boolean) {
|
|
// this.state.players.get(client.sessionId).state = PlayerStateConst.PLAYER_OFFLINE;
|
|
//
|
|
// try {
|
|
// if (consented) {
|
|
// throw new Error("consented leave");
|
|
// }
|
|
// await this.allowReconnection(client, 60);
|
|
// this.state.players.get(client.sessionId).state = PlayerStateConst.PLAYER_NORMAL;
|
|
//
|
|
// } catch (e) {
|
|
// this.state.players.delete(client.sessionId);
|
|
// }
|
|
}
|
|
|
|
onDispose() {
|
|
this.dispatcher.stop();
|
|
}
|
|
|
|
getClient(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 );
|
|
}
|
|
if (!result) {
|
|
error(`无法获取id为: ${typeof player == 'string' ? player : player.id} 的客户端`)
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 给room.mainClock设定任务
|
|
* mainClock任何时候只有一个可执行的任务
|
|
* @param millisecond
|
|
* @param handler
|
|
* @param name
|
|
*/
|
|
beginSchedule(millisecond: number, handler: Function, name: string): void {
|
|
debugRoom(`begin schedule: `, name, millisecond / 1000);
|
|
if (this.mainClock?.active) {
|
|
error(`当前已存在进行中的mainClock: ${this.mainClock['args']}`);
|
|
}
|
|
this.mainClock = this.clock.setTimeout(handler, millisecond , name);
|
|
}
|
|
|
|
/**
|
|
* 取消当前room.mainClock的任务
|
|
* mainClock任何时候只有一个可执行的任务
|
|
*/
|
|
stopSchedule(): number {
|
|
debugRoom(`manual stop schedule: ${this.mainClock['args']}`);
|
|
if (!this.mainClock.active) {
|
|
return -1;
|
|
} else {
|
|
let time = this.mainClock.elapsedTime;
|
|
this.mainClock.clear();
|
|
return time;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 给room的mainClock增加n秒
|
|
* @param millisecond
|
|
* @param reason
|
|
*/
|
|
addScheduleTime(millisecond: number, reason?: string): void {
|
|
debugRoom(`add schedule for ${this.mainClock['args']}, time: ${millisecond/1000}`);
|
|
if (this.mainClock?.active) {
|
|
this.mainClock.time += millisecond ;
|
|
debugRoom(`schedule remain: ${(this.mainClock.time - this.mainClock.elapsedTime)/1000}`);
|
|
}
|
|
}
|
|
|
|
}
|