重构代码, 增加一些注释

This commit is contained in:
zhl 2021-02-22 17:53:48 +08:00
parent 3bdfeaec64
commit ff5cce11da
5 changed files with 450 additions and 423 deletions

View File

@ -1,84 +1,83 @@
import * as jetpack from "fs-jetpack";
import {singleton} from "./Singleton";
import {GameEnv} from "../cfg/GameEnv";
import {BaseConst} from "../constants/BaseConst";
import {error} from "./Debug";
import * as jetpack from 'fs-jetpack'
import { GameEnv } from '../cfg/GameEnv'
import { BaseConst } from '../constants/BaseConst'
import { error } from './Debug'
const $cfg = new Map();
const jsonPath = 'config';
export var DataParser = (function (){
const parsers: { [index: string]: ConfigDataParser } = {};
const $cfg = new Map()
const jsonPath = 'config'
export var DataParser = (function () {
const parsers: { [index: string]: ConfigDataParser } = {}
return {
regParser,
regCommonParser(key: string, CfgCreator: { new (): Cfg }, idkey = "id") {
regParser(key, (data: any[]): any => {
if (!data) return;
let dict = new Map();
for (let i = 0, len = data.length; i < len; i++) {
let obj = data[i];
if (!obj[idkey]) {
error(`配置${key}的数据有误,唯一标识 ${idkey} 值为0或者没有${idkey}`);
continue;
}
let to = new CfgCreator();
to.decode(obj);
if (dict.has(to.id)) {
error(`配置${key}的数据有误,唯一标识 id 有重复值:${to.id}`)
process.abort();
}
dict.set(to.id, to);
}
return dict;
});
},
loadAll() {
let fileArr = jetpack.list(jsonPath);
for (let f of fileArr) {
let key = f.replace('_tbl.json', '');
let parser = parsers[key];
let json = jetpack.read(`${jsonPath}/${f}`, 'json');
if (parser && json){
if (Array.isArray(json)) {
let data = parser(json);
if (data) { // 支持一些void的情况
$cfg.set(key, data);
}
} else {
$cfg.set(key, json);
}
}
return {
regParser,
regCommonParser(key: string, CfgCreator: { new(): Cfg }, idkey = 'id') {
regParser(key, (data: any[]): any => {
if (!data) return
let dict = new Map()
for (let i = 0, len = data.length; i < len; i++) {
let obj = data[i]
if (!obj[idkey]) {
error(`配置${ key }的数据有误,唯一标识 ${ idkey } 值为0或者没有${ idkey }`)
continue
}
let to = new CfgCreator()
to.decode(obj)
if (dict.has(to.id)) {
error(`配置${ key }的数据有误,唯一标识 id 有重复值:${ to.id }`)
process.abort()
}
dict.set(to.id, to)
}
return dict
})
},
loadAll() {
let fileArr = jetpack.list(jsonPath)
for (let f of fileArr) {
let key = f.replace('_tbl.json', '')
let parser = parsers[key]
let json = jetpack.read(`${ jsonPath }/${ f }`, 'json')
if (parser && json) {
if (Array.isArray(json)) {
let data = parser(json)
if (data) { // 支持一些void的情况
$cfg.set(key, data)
}
new GameEnv().init($cfg.get(BaseConst.COMPOUND));
Object.assign(global, {
$cfg: $cfg
})
},
} else {
$cfg.set(key, json)
}
}
}
new GameEnv().init($cfg.get(BaseConst.COMPOUND))
Object.assign(global, {
$cfg: $cfg
})
}
/**
*
* @param key
* @param parser
*/
function regParser(key: string, parser: ConfigDataParser) {
parsers[key] = parser;
}
})();
}
/**
*
* @param key
* @param parser
*/
function regParser(key: string, parser: ConfigDataParser) {
parsers[key] = parser
}
})()
/**
*
*/
export interface ConfigDataParser {
(data: any): any;
(data: any): any;
}
export interface Cfg
{
/**
*
* @param {*} data
* @param {*} [local]
*/
decode?: { (local?: any):void };
id?: number;
export interface Cfg {
/**
*
* @param {*} data
* @param {*} [local]
*/
decode?: { (local?: any): void };
id?: number;
}

515
src/global.d.ts vendored
View File

@ -1,299 +1,308 @@
import {IMsg} from "./message/IMsg";
import {Client, Room} from "colyseus";
import {PetInfo, PetInfoMsg} from "./message/PetInfo";
import {BattleHandler} from "./rooms/logic/Handler/BattleHandler";
import {SkillInfoMsg} from "./message/SkillInfo";
import {PartResultMsg} from "./message/PartResult";
import {RemovePetMsg} from "./message/RemovePetMsg";
import {Dispatcher} from "@colyseus/command";
import {Delayed} from "@gamestdio/timer/lib/Delayed";
import {Player} from "./rooms/schema/Player";
import {RobotClient} from "./robot/RobotClient";
import { IMsg } from './message/IMsg'
import { Client } from 'colyseus'
import { PetInfo, PetInfoMsg } from './message/PetInfo'
import { BattleHandler } from './rooms/logic/Handler/BattleHandler'
import { SkillInfoMsg } from './message/SkillInfo'
import { PartResultMsg } from './message/PartResult'
import { RemovePetMsg } from './message/RemovePetMsg'
import { Dispatcher } from '@colyseus/command'
import { Delayed } from '@gamestdio/timer/lib/Delayed'
import { Player } from './rooms/schema/Player'
import { RobotClient } from './robot/RobotClient'
export {};
export {}
declare global {
namespace NodeJS {
interface Global {
NODE_ENV: string
ROOT_PATH: string
$cfg: any
isProd: boolean
}
namespace NodeJS {
interface Global {
NODE_ENV: string
ROOT_PATH: string
$cfg: any
isProd: boolean
}
}
}
/**
* GeneralRoom
*/
declare module "colyseus" {
interface Room {
battleMan: BattleHandler;
dispatcher: Dispatcher;
mainClock: Delayed;
robotCount: number;
match: string | undefined ;
score: number;
/**
* sessionId获取client
* @param player id或者玩家的对象
*/
getClient(player: string | Player): Client;
declare module 'colyseus' {
interface Room {
battleMan: BattleHandler;
dispatcher: Dispatcher;
mainClock: Delayed;
robotCount: number;
match: string | undefined;
score: number;
/**
* room的client数量
*/
clientCount(): number;
// >>>>>>>>> Begin of extend send message <<<<<<<<<<<<<
/**
* 广
* @param data
* @param options
*/
bUserJoin(data?: any, options?: any): void;
/**
* sessionId获取client
* @param player id或者玩家的对象
*/
getClient(player: string | Player): Client;
/**
* 广
* @param data
*/
bUserLeft(data?: any): void;
/**
* room的client数量
*/
clientCount(): number;
/**
*
* @param client
* @param data
*/
sSelectHero(client: Client, data?: any):void;
// >>>>>>>>> Begin of extend send message <<<<<<<<<<<<<
/**
* 广
* @param data
* @param options
*/
bUserJoin(data?: any, options?: any): void;
/**
* 广
* @param data
*/
bSelectHero(data?: any):void;
/**
* 广
* @param data
*/
bUserLeft(data?: any): void;
/**
*
* @param client
* @param data
*/
sDrawCard(client: Client, data?: any):void;
/**
*
* @param client
* @param data
*/
sSelectHero(client: Client, data?: any): void;
/**
* 广
* @param data
*/
bSelectHero(data?: any): void;
/**
*
* @param client
* @param data
*/
sDrawCard(client: Client, data?: any): void;
/**
*
* @param data
*/
bAddPet(data?: PetInfoMsg): void;
/**
*
* @param data
*/
bAddPet(data?: PetInfoMsg): void;
/**
*
* @param data
*/
bCastSkill(data?: SkillInfoMsg): void;
/**
*
* @param data
*/
bCastSkill(data?: SkillInfoMsg): void;
/**
* 广
* @param data
* @param options
*/
bStealCard(data?: any, options?: any):void;
/**
* 广
* @param data
* @param options
*/
bStealCard(data?: any, options?: any): void;
/**
*
* @param data
*/
sStealCard(data?: any):void;
/**
*
* @param data
*/
sStealCard(data?: any): void;
/**
* 广
* @param data
* @param options
*/
bDrawCard(data?: any, options?: any):void;
/**
* 广
* @param data
* @param options
*/
bDrawCard(data?: any, options?: any): void;
/**
* 广
* @param data
* @param options
*/
bRemoveCard(data?: any, options?: any):void;
/**
* 广
* @param data
* @param options
*/
bRemoveCard(data?: any, options?: any): void;
/**
*
* @param data
* @param options
*/
bRemovePet(data?: RemovePetMsg, options?: any): void;
/**
* 广
* @param data
* @param options
*/
bPartResult(data?: PartResultMsg, options?: any): void;
/**
*
* @param data
* @param options
*/
bRemovePet(data?: RemovePetMsg, options?: any): void;
/**
* 广
* @param data
* @param options
*/
bGameResult(data?: any, options?: any): void;
/**
* 广
* @param data
* @param options
*/
bPartResult(data?: PartResultMsg, options?: any): void;
/**
*
* @param client
* @param data
*/
sChangeCard(client: Client, data?: any):void;
/**
* 广
* @param data
* @param options
*/
bGameResult(data?: any, options?: any): void;
/**
*
* @param player
* @param data
*/
sNeedChangePet(player: string | Player, data?: any): void;
/**
*
* @param client
* @param data
*/
sChangeCard(client: Client, data?: any): void;
/**
*
* @param client
* @param data
*/
sMsgQueue(client: Client, data: IMsg[]): void;
/**
*
* @param player
* @param data
*/
sNeedChangePet(player: string | Player, data?: any): void;
/**
*
* @param client
* @param data
*/
sMsgQueue(client: Client, data: IMsg[]): void;
/**
* 广
* :
* let datas:IMsg[] = [];
* datas.push({errcode: 0, type: '消息类型', data: {pid: 1}});
* this.room.bMsgQueue(datas);
* @param datas
* @param options
*/
bMsgQueue(datas: IMsg[], options?: any): void;
/**
* 广
* :
* let datas:IMsg[] = [];
* datas.push({errcode: 0, type: '消息类型', data: {pid: 1}});
* this.room.bMsgQueue(datas);
* @param datas
* @param options
*/
bMsgQueue(datas: IMsg[], options?: any): void;
send(client: Client, type: string, data?: any): void;
send(client: Client, type: string, data?: any): void;
// >>>>>>>>> End of extend send message <<<<<<<<<<<<<
// >>>>>>>>> End of extend send message <<<<<<<<<<<<<
// >>>>>>>>> Begin of extend functions <<<<<<<<<<<<<
// >>>>>>>>> Begin of extend functions <<<<<<<<<<<<<
/**
* , 广
* @param srcplayer
* @param dstplayer
* @param count
*/
drawCardFromPlayer(srcplayer: string, dstplayer: string, count: number) :number;
/**
* , 广
* @param srcplayer
* @param dstplayer
* @param count
*/
drawCardFromPlayer(srcplayer: string, dstplayer: string, count: number): number;
/**
* , 广
* @param dstplayer
* @param count
* @param fromplayer
*/
giveUpCard(dstplayer: string, count: number, fromplayer?: string): number;
/**
* , 广
* @param dstplayer
* @param count
* @param fromplayer
*/
giveUpCard(dstplayer: string, count: number, fromplayer?: string): number;
/**
* , 广
* @param dstplayer
* @param count , max_count至少一个不为0
* @param max_count , count和max_count都不为0, Math.min(count, (max_count - ))
* @param source 0: 正常抽卡, 1: 技能, 2: gm命令抽的卡
* @param fromplayer
* @param extData
*/
addCard(dstplayer: string, count: number, max_count: number, source?: number, fromplayer?: string, extData?: {}): number;
/**
* , 广
* @param dstplayer
* @param count , max_count至少一个不为0
* @param max_count , count和max_count都不为0, Math.min(count, (max_count - ))
* @param source 0: 正常抽卡, 1: 技能, 2: gm命令抽的卡
* @param fromplayer
* @param extData
*/
addCard(dstplayer: string, count: number, max_count: number, source?: number, fromplayer?: string, extData?: {}): number;
/**
*
* @param dstplayer
* @param hp
* @param reason
* @param fromplayer
*/
updateHp(dstplayer: string, hp: number, reason?: string, fromplayer?: string): number;
/**
*
* @param dstplayer
* @param hp
* @param reason
* @param fromplayer
*/
updateHp(dstplayer: string, hp: number, reason?: string, fromplayer?: string): number;
/**
*
* @param datas
* @param fromplayer
*/
updatePet(datas: PetInfo[], fromplayer?: string): void;
/**
* ,
* @param datas
* @param fromplayer
*/
updatePetStat(datas: PetInfo[], fromplayer?: string): void;
/**
*
* @param datas
* @param fromplayer
*/
updatePet(datas: PetInfo[], fromplayer?: string): void;
/**
* room.mainClock设定任务
* mainClock任何时候只有一个可执行的任务
* @param millisecond
* @param handler
* @param name
*/
beginSchedule(millisecond: number, handler: Function, name: string): void;
/**
* ,
* @param datas
* @param fromplayer
*/
updatePetStat(datas: PetInfo[], fromplayer?: string): void;
/**
* room.mainClock的任务
* mainClock任何时候只有一个可执行的任务
*
* @param name
*/
stopSchedule(name: string): number;
/**
* room.mainClock增加n秒
* @param name
* @param millisecond
* @param reason
*/
addScheduleTime(millisecond: number, reason?: string, name?: string, ): void;
/**
* room.mainClock设定任务
* mainClock任何时候只有一个可执行的任务
* @param millisecond
* @param handler
* @param name
*/
beginSchedule(millisecond: number, handler: Function, name: string): void;
/**
* n张指定效果id的卡
* @param effectId
* @param count
* @param player
* @param fromplayer
*/
generateCard({player, count, effectId, fromplayer, options}
: {player: string | Player,
count: number,
effectId: number,
fromplayer?: string | Player,
options?: any}): number;
/**
*
* @param playerId
*/
addRobot(playerId?: string):void;
/**
* room.mainClock的任务
* mainClock任何时候只有一个可执行的任务
*
* @param name
*/
stopSchedule(name: string): number;
/**
*
* @param sessionId
*/
addAssistClient(sessionId: string): void;
/**
* session的辅助机器人
* @param sessionId
*/
getAssistClient(sessionId: string): RobotClient;
/**
* room.mainClock增加n秒
* @param name
* @param millisecond
* @param reason
*/
addScheduleTime(millisecond: number, reason?: string, name?: string): void;
/**
*
* @param srcPlayer
*/
getOppositePlayer(srcPlayer: string|Player): Player;
/**
* n张指定效果id的卡
* @param effectId
* @param count
* @param player
* @param fromplayer
*/
generateCard({ player, count, effectId, fromplayer, options }
: {
player: string | Player,
count: number,
effectId: number,
fromplayer?: string | Player,
options?: any
}): number;
/**
* index获取玩家
* @param {number} idx
* @return {Player}
*/
getPlayerByIdx(idx: number): Player;
}
/**
*
* @param playerId
*/
addRobot(playerId?: string): void;
/**
*
* @param sessionId
*/
addAssistClient(sessionId: string): void;
/**
* session的辅助机器人
* @param sessionId
*/
getAssistClient(sessionId: string): RobotClient;
/**
*
* @param srcPlayer
*/
getOppositePlayer(srcPlayer: string | Player): Player;
/**
* index获取玩家
* @param {number} idx
* @return {Player}
*/
getPlayerByIdx(idx: number): Player;
}
}

View File

@ -4,7 +4,6 @@ import cors from 'cors'
import { RedisPresence, Server } from 'colyseus'
import { monitor } from '@colyseus/monitor'
import rateLimit from 'express-rate-limit'
// import socialRoutes from "@colyseus/social/express"
import { GeneralRoom } from './rooms/GeneralRoom'
import { initData } from './common/GConfig'
import { Config } from './cfg/Config'

View File

@ -2,7 +2,7 @@ import { Client, generateId, matchMaker, Room, ServerError } from 'colyseus'
import { BaseConst } from '../constants/BaseConst'
import { IncomingMessage } from 'http'
import { checkMatchTicket } from '../common/WebApi'
import { error, matchlog } from '../common/Debug'
import { matchlog } from '../common/Debug'
import { retry } from 'colyseus/lib/Utils'
import { RoomListingData } from 'colyseus/lib/matchmaker/drivers/Driver'
@ -30,15 +30,12 @@ interface ClientStat {
export class RankedLobbyRoom extends Room {
/**
* If `allowUnmatchedGroups` is true, players inside an unmatched group (that
* did not reached `numClientsToMatch`, and `maxWaitingTime` has been
* reached) will be matched together. Your room should fill the remaining
* spots with "bots" on this case.
* true, maxWaitingTime,
*/
allowUnmatchedGroups: boolean = true
/**
* Evaluate groups for each client at interval
*
*/
evaluateGroupsInterval = 1000
@ -48,12 +45,12 @@ export class RankedLobbyRoom extends Room {
groups: MatchmakingGroup[] = []
/**
* name of the room to create
*
*/
roomToCreate = 'general_room'
/**
*
* , ,
*/
maxWaitingTime = 15 * 1000
/**
@ -62,28 +59,34 @@ export class RankedLobbyRoom extends Room {
*/
groupAddOneTime = 10 * 1000
/**
* after this time, try to fit this client with a not-so-compatible group
*/
maxWaitingTimeForPriority?: number = 10 * 1000
/**
* number of players on each match
*/
numClientsToMatch = 4
// /**
// * after a group is ready, clients have this amount of milliseconds to confirm
// * connection to the created room
// */
// cancelConfirmationAfter = 5000;
/**
* rank and group cache per-player
*/
stats: ClientStat[] = []
/**
*
* @type {number}
*/
rank_mpa = 0.2
/**
*
* @type {number}
*/
fair_ir = 1.2
/**
*
* @type {number}
*/
step_ir = 1.3
/**
* id
* @type {string}
*/
matchid = '100001'
async onAuth(client: Client, options: any, request: IncomingMessage) {
@ -94,7 +97,7 @@ export class RankedLobbyRoom extends Room {
try {
await checkMatchTicket(accountid, this.matchid)
} catch (err) {
let code = isNaN(err.message) ? 9: parseInt(err.message)
let code = isNaN(err.message) ? 9 : parseInt(err.message)
throw new ServerError(code, 'not enough ticket')
}
return true
@ -410,7 +413,7 @@ export class RankedLobbyRoom extends Room {
Object.assign(options, matchData)
data.client.send('match_success', options)
const mdata = data.options
matchlog(`${mdata.accountid}:${mdata.score}:${mdata.rank}:${data.seat}:${client.waitingTime}`)
matchlog(`${ mdata.accountid }:${ mdata.score }:${ mdata.rank }:${ data.seat }:${ client.waitingTime }`)
}
}))

View File

@ -1,83 +1,100 @@
import {Command} from "@colyseus/command";
import {CardGameState} from "../schema/CardGameState";
import {Client} from "colyseus";
import {TurnEndCommand} from "./TurnEndCommand";
import {GameEnv} from "../../cfg/GameEnv";
import gameUtil from "../../utils/game.util";
import { Command } from '@colyseus/command'
import { CardGameState } from '../schema/CardGameState'
import { Client } from 'colyseus'
import { TurnEndCommand } from './TurnEndCommand'
import { GameEnv } from '../../cfg/GameEnv'
import gameUtil from '../../utils/game.util'
/**
*
*/
export class SelectPetCommand extends Command<CardGameState, {client: Client,
cardId: number,
playerId: string,
pos: number,
effCards: number[],
oldpos: number
}> {
async execute({client, cardId, playerId, pos, effCards, oldpos} = this.payload) {
let sessionId = client.sessionId;
let player = this.state.players.get(sessionId);
let ap = 0;
let moreAp = 0;
let count = 0;
let targetCard;
let effectRate = this.room.battleMan.getTransEffCardRate(player);
// 检查效果卡, 并从玩家手牌中移除
let eff_cnt = 0; // 效果卡数量
let dbpt_cnt = 0; // 点数翻倍卡数量
let transCount = 0;
for (let eCardId of effCards) {
if (!player.cards.has(eCardId + '')) {
continue;
}
let card = player.cards.get(eCardId + '').clone();
player.cardQueue.push(card);
if (card.type === 3) {
dbpt_cnt ++;
} else if (card.type === 2){
eff_cnt ++;
} else {
transCount ++;
}
}
gameUtil.deleteCardFromPlayer(player, effCards);
if (effectRate && transCount) {
eff_cnt += (transCount / effectRate | 0);
}
for (let card of this.state.cards.values()) {
ap += card.number;
count ++;
if (count === 3) {
moreAp += new GameEnv().baseAddScore;
} else if (count > 3) {
moreAp += new GameEnv().extraAddScore;
}
if (card.id == cardId) {
targetCard = card;
}
}
if (!targetCard) {
return;
}
//停止选随从计时, 并更新player.extraTime;
let elapsedTime = this.room.stopSchedule('select_pet');
if (elapsedTime >= 0) {
let count = elapsedTime - new GameEnv().playerActTime * 1000;
let newCount = player.extraTime - Math.min(count, 0);
player.extraTime = Math.max(newCount, 0);
}
let dstplayer = this.state.players.get(playerId);
let dstpet;
if (dstplayer && pos != undefined) {
dstpet = dstplayer.pets.get(pos+'');
}
let cardpoint = moreAp + ap;
let data = {srcplayer: player, card: targetCard.effect, cardpoint, eff_cnt, dstplayer, dstpet, dbpt_cnt, oldpos}
let time = this.room.battleMan.useCard(data);
await this.delay(time);
return [new TurnEndCommand()];
export class SelectPetCommand extends Command<CardGameState, {
client: Client,
cardId: number,
playerId: string,
pos: number,
effCards: number[],
oldpos: number
}> {
async execute({
client,
cardId,
playerId,
pos,
effCards,
oldpos
} = this.payload) {
let sessionId = client.sessionId
let player = this.state.players.get(sessionId)
let ap = 0
let moreAp = 0
let count = 0
let targetCard
let effectRate = this.room.battleMan.getTransEffCardRate(player)
// 检查效果卡, 并从玩家手牌中移除
let eff_cnt = 0 // 效果卡数量
let dbpt_cnt = 0 // 点数翻倍卡数量
let transCount = 0
for (let eCardId of effCards) {
if (!player.cards.has(eCardId + '')) {
continue
}
let card = player.cards.get(eCardId + '').clone()
player.cardQueue.push(card)
if (card.type === 3) {
dbpt_cnt++
} else if (card.type === 2) {
eff_cnt++
} else {
transCount++
}
}
gameUtil.deleteCardFromPlayer(player, effCards)
if (effectRate && transCount) {
eff_cnt += (transCount / effectRate | 0)
}
for (let card of this.state.cards.values()) {
ap += card.number
count++
if (count === 3) {
moreAp += new GameEnv().baseAddScore
} else if (count > 3) {
moreAp += new GameEnv().extraAddScore
}
if (card.id == cardId) {
targetCard = card
}
}
if (!targetCard) {
return
}
//停止选随从计时, 并更新player.extraTime;
let elapsedTime = this.room.stopSchedule('select_pet')
if (elapsedTime >= 0) {
let count = elapsedTime - new GameEnv().playerActTime * 1000
let newCount = player.extraTime - Math.min(count, 0)
player.extraTime = Math.max(newCount, 0)
}
let dstplayer = this.state.players.get(playerId)
let dstpet
if (dstplayer && pos != undefined) {
dstpet = dstplayer.pets.get(pos + '')
}
let cardpoint = moreAp + ap
let data = {
srcplayer: player,
card: targetCard.effect,
cardpoint,
eff_cnt,
dstplayer,
dstpet,
dbpt_cnt,
oldpos
}
let time = this.room.battleMan.useCard(data)
await this.delay(time)
return [new TurnEndCommand()]
}
}