import { GameRecord } from '../models/GameRecord' import BaseController from '../common/base.controller' import { role, router } from '../decorators/router' import { RecordInfo, User } from '../models/User' import { error } from '../common/Debug' import { timeBeforeDay } from '../utils/time.util' import { BaseConst } from '../constants/BaseConst' import { MatchCfg } from '../cfg/parsers/MatchCfg' import ItemCtrl from '../logic/ItemCtrl' import { ItemInfo } from '../logic/ItemDef' import { BagItem } from '../models/BagItem' import { setGameEnd, updateRank } from '../service/rank' import { ZError } from '../common/ZError' import { ActRecord } from '../models/ActRecord' export default class RecordController extends BaseController { @role('anon') @router('post /api/:accountid/records') async recordList(req: any) { let { accountid } = req.params let records = await GameRecord.find({ 'players.accountid': accountid }) let results: any = [] for (let record of records) { results.push(record.toJSON()) } return results } @role('anon') @router('post /svr/record/save') async upload(req: any) { let record = new GameRecord(req.params) await record.save() if (!record.matchid) { return {} } let cfg: MatchCfg = global.$cfg.get(BaseConst.MATCH).get(parseInt(record.matchid)) if (!cfg) { error(`match cfg not found: ${record.matchid}`) } const fc = global.$cfg.get(BaseConst.FORMULA) const scores = [ fc.get(70043).number, fc.get(70046).number, fc.get(70044).number, fc.get(70045).number, fc.get(70047).number, fc.get(70048).number ] let seasonData: any = {} let itemData: any = {} for (let player of record.players) { if (player.accountid.startsWith('robot')) { continue } let user = await User.findById(player.accountid) if (!user) { error(`save game record, account not found: ${ player.accountid }`) continue } await setGameEnd(player.accountid) if (!player.escape) { user.season_score = Math.max((user.season_score + player.scoreChange) | 0, fc.get(70002).number) await updateRank(user._id, user.season_score) } if (!user.season_data) { user.season_data = new Map() } /** * begin of 将赛季排位记录放入season_records, 方便计算10胜 */ if (!player.escape) { let data = new RecordInfo() data.time = Date.now() if (player.team == record.winner) { data.status = 2 } else if (record.winner == -1) { data.status = 1 } else { data.status = 0 } user.season_records.push(data) let records = user.season_records while (records.length > 10) { records.pop() } let smallTime = timeBeforeDay(30) for (let r of records) { if (r.time < smallTime) { records.removeEx(r) } } } /** * end of 将赛季排位记录放入season_records, 方便计算10胜 */ /** * begin of 处理比赛统计信息 */ let subType = '' if (!player.escape) { if (record.winner == player.team) { user.season_data.inc('win', 1) subType += 'win' } else { user.season_data.inc('loss', 1) subType += 'loss' } let statData = player.statdata let honorp = 0 for (let key in statData) { let numKey = +key if (numKey >= scores.length) { continue } // @ts-ignore let val = Number(statData[key]) honorp += val * scores[numKey] if (numKey == 4 || numKey == 5) { user.season_data.inc(key + '_total', val) } else { user.season_data.inc(key + '_total', val * scores[numKey]) } if (user.season_data.has(key + '')) { user.season_data.set(key + '', Math.max(user.season_data.get(key + ''), val)) } else { user.season_data.set(key + '', val) } } user.season_data.inc('honor_ap', honorp) user.season_data.inc('mvp_ap', player.mvpscore) } /** * end of 处理比赛统计信息 */ await user.save() seasonData[player.playerid] = user.season_data /** * 获取胜利失败的物品 */ let items: ItemInfo[] = [] if (cfg && !player.escape) { if (record.winner == player.team && cfg.winget) { items = ItemCtrl.getItemsByInfo(cfg.winget); } else if (record.winner !== player.team && cfg.failget) { items = ItemCtrl.getItemsByInfo(cfg.failget); } await BagItem.addItems(player.accountid, items, 'game_' + subType, record.id) } itemData[player.playerid] = items } return {seasonData, itemData} } @router('post /api/:accountid/gamereward') async doubleReward(req: any) { let { accountid, roomid } = req.params let day = (new Date(0)).format('yyyy-MM-dd', true) let arecord = (await ActRecord.findOrCreate({ accountid, actid: roomid, day })).doc if (arecord.count > 0) { throw new ZError(12, 'already goted') } arecord.count += 1 let records = await GameRecord.find({'players.accountid': accountid, roomid}) if (!records || records.length == 0) { throw new ZError(10, 'record not found') } let record = records[0] if (!record.matchid) { throw new ZError(11, 'current game mode has no double reward') } let isWin = false for (let pdata of record.players) { if (pdata.accountid == accountid) { if (pdata.team == record.winner) { isWin = true } break } } let cfg: MatchCfg = global.$cfg.get(BaseConst.MATCH).get(parseInt(record.matchid)) if (!cfg) { error(`match cfg not found: ${record.matchid}`) } /** * 获取胜利失败的物品 */ let items: ItemInfo[] = [] if (isWin) { items = ItemCtrl.getItemsByInfo(cfg.winget); } else { items = ItemCtrl.getItemsByInfo(cfg.failget); } await BagItem.addItems(accountid, items, 'double_reward', roomid) await arecord.save() return items } }