diff --git a/game-server/app/servers/battle/handler/ladderHandler.ts b/game-server/app/servers/battle/handler/ladderHandler.ts index 9c0c2444a..fa1370bf0 100644 --- a/game-server/app/servers/battle/handler/ladderHandler.ts +++ b/game-server/app/servers/battle/handler/ladderHandler.ts @@ -6,7 +6,7 @@ import { STATUS } from '../../../consts/statusCode'; import { arrToMap, resResult } from '../../../pubUtils/util'; import { getTimeFunM } from '../../../pubUtils/timeUtil'; import { LadderMatchModel, LadderUpdateInter } from '../../../db/LadderMatch'; -import { battleEndWhenChange, checkRank, generateInitRecInfo, generateOppPlayers, getBuyCntCost, getLadderData, getLadderEnemies, getLadderOppDetailData, getLadderOppStatus, getNumberArr, ladderBattleEndReward, refreshLadderDaily, refreshLadderEnemies, sendLadderDailyReward, uniqueArr } from '../../../services/ladderService'; +import { battleEndWhenChange, checkRank, generateInitRecInfo, generateOppPlayers, getBuyCntCost, getLadderData, getLadderEnemies, getLadderOppDetailData, getLadderOppStatus, getNumberArr, ladderBattleEndReward, pushLadderIconShow, refreshLadderDaily, refreshLadderEnemies, sendLadderDailyReward, uniqueArr } from '../../../services/ladderService'; import { LadderDataReturn, LadderDefense, LadderDefenseHero, LadderOppDetailReturn, LadderOppLineupReturn, LadderOppPlayerHeroInfo, LadderOppPlayerReturn } from '../../../domain/battleField/ladder'; import { LadderMatchRecModel } from '../../../db/LadderMatchRec'; import { HeroModel } from '../../../db/Hero'; @@ -234,6 +234,8 @@ export class LadderHandler { let { battleGoods = [], breakGoods = [] } = rewardResult||{}; await checkTaskInLadderEnd(serverId, roleId, sid, isSuccess, historyRank, atkLadderMatch.rank); + + if (isSuccess || !rec.defenseInfo?.isRobot) await pushLadderIconShow(rec.roleId2, true); return resResult(STATUS.SUCCESS, {...pick(result, ['rank', 'historyRank', 'challengeCnt','status', 'time', 'oppPlayers']), battleGoods, breakGoods}); } diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index 086651e60..3a8d34d32 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -159,6 +159,7 @@ export class EntryHandler { session.set('channel', user.channelInfo?.platformAppid||'pc'); session.set('isNewUser', user['isNewUser']||false); session.set('version', version); + session.set('quitTime', role.quitTime ? (role.quitTime * 1000) : Date.now()) session.push('userid', () => { }); session.push('sid', () => { }); session.push('roleId', () => { }); @@ -173,6 +174,8 @@ export class EntryHandler { session.push('channel', () => { }); session.push('version', () => { }); session.push('isNewUser', () => { }); + session.push('quitTime', () => { }) + assignServer(role.roleId, session); // console.log('#####', role.serverId, role.guildCode) diff --git a/game-server/app/servers/guild/handler/gvgFightHandler.ts b/game-server/app/servers/guild/handler/gvgFightHandler.ts index d127eabfd..22a3d76d0 100644 --- a/game-server/app/servers/guild/handler/gvgFightHandler.ts +++ b/game-server/app/servers/guild/handler/gvgFightHandler.ts @@ -19,7 +19,7 @@ import { GVG } from "../../../pubUtils/dicParam"; import { RewardInter, pvpEndParamInter } from "../../../pubUtils/interface"; import { parseGoodStr, resResult } from "../../../pubUtils/util"; import { isHeroHidden } from "../../../services/dataService"; -import { calBreakGoods, checkHeroIsUsedInOtherVestige, checkVestige, checkVestigeOppStatus, checkVestigeRank, generateAttackHeroInfo, generateAttackInfo, generateDefenseInfo, getDayKeyInfo, getMyVestigeRank, getOppDetailData, getOppPlayerByRanks, getVestigeRecStatus, getVestigeRank, getVestigeUsedHeroes, isRobot, refreshVestigeOppRanks, saveScoreToRank, updateMyVestigeRank, saveVestigeRankSchedule, calVestigeLeagueBoxRewards, checkFightTime, savePlayerRank } from "../../../services/gvg/gvgFightService"; +import { calBreakGoods, checkHeroIsUsedInOtherVestige, checkVestige, checkVestigeOppStatus, checkVestigeRank, generateAttackHeroInfo, generateAttackInfo, generateDefenseInfo, getDayKeyInfo, getMyVestigeRank, getOppDetailData, getOppPlayerByRanks, getVestigeRecStatus, getVestigeRank, getVestigeUsedHeroes, isRobot, refreshVestigeOppRanks, saveScoreToRank, updateMyVestigeRank, saveVestigeRankSchedule, calVestigeLeagueBoxRewards, checkFightTime, savePlayerRank, pushGvgFightIconShow } from "../../../services/gvg/gvgFightService"; import { addGVGReward, combinePushItem, handleGVGCost } from "../../../services/gvg/gvgItemService"; import { addGVGActive, getGVGActive } from "../../../services/gvg/gvgPrepareService"; import { addVestigeBattleEndRec } from "../../../services/gvg/gvgRecService"; @@ -378,6 +378,7 @@ export class GVGProduceHandler { await saveScoreToRank(rec); addVestigeBattleEndRec(rec); + if (isSuccess && !rec.defenseInfo?.isRobot) await pushGvgFightIconShow(rec.defenseRoleId, battleCode); return resResult(STATUS.SUCCESS, { vestigeId: rec.vestigeId, diff --git a/game-server/app/services/connectorService.ts b/game-server/app/services/connectorService.ts index 9c3c7ad9f..5c73eb246 100644 --- a/game-server/app/services/connectorService.ts +++ b/game-server/app/services/connectorService.ts @@ -6,9 +6,9 @@ import { recentGuildMsgs, recentLeagueMsgs, recentPrivateChatInfos, recentServer import { getCurTask, getPvpTask } from './task/taskService'; import { RoleModel, RoleType } from '../db/Role'; -import { Application, FrontendOrBackendSession, pinus, RpcClient } from 'pinus'; +import { Application, BackendSession, FrontendOrBackendSession, pinus, RpcClient } from 'pinus'; import { compareVersion, getRandEelmWithWeight, resResult } from '../pubUtils/util'; -import { STATUS, PUSH_BATCH, PUSH_INTERVAL, CONSUME_TYPE, HERO_SELECT, ENTERY_ROLE_PICK, JEWEL_SELECT, ITEM_SELECT, SKIN_SELECT, PUSH_ROUTE, ARTIFACT_SELECT, ACTIVITYITEM_SELECT, SNS_LINK_TYPE } from '../consts'; +import { STATUS, PUSH_BATCH, PUSH_INTERVAL, CONSUME_TYPE, HERO_SELECT, ENTERY_ROLE_PICK, JEWEL_SELECT, ITEM_SELECT, SKIN_SELECT, PUSH_ROUTE, ARTIFACT_SELECT, ACTIVITYITEM_SELECT, SNS_LINK_TYPE, VESTIGE_STATUS } from '../consts'; import { getAllShopList } from './shopService'; import { getGeneralRank, getRankFirstReward } from './rankService'; import { getFriendList, getApplyList } from './friendService'; @@ -17,7 +17,7 @@ import { getExpeditionStatus } from './expeditionService'; import { getTowerStatus, getHungupRewards, getTasks } from './battleService'; import { getAllAssistCnt, getCapExtraCnt, getComBtlLvByPlayerLv } from './battle/comBattleService'; import { getDungeonData } from './dungeonService'; -import { nowSeconds, getZeroPoint } from '../pubUtils/timeUtil'; +import { nowSeconds, getZeroPoint, getTimeFunM } from '../pubUtils/timeUtil'; import { getGachaList, getVisitedHeroList } from './activity/gachaService'; import { getSchoolList } from './roleService'; import { addRoleToGuildChannel } from './chatChannelService'; @@ -55,6 +55,10 @@ import { getHiddenData } from './memoryCache/hiddenData'; import { AuthorBookModel } from '../db/AuthorBook'; import { gameData } from '../pubUtils/data'; import { getRougeData } from './battle/rougeService'; +import { LadderMatchRecModel } from '../db/LadderMatchRec'; +import { GVGVestigeRecModel, GVGVestigeRecUpdate } from '../db/GVGVestigeRec'; +import { getVestigeRecStatus } from './gvg/gvgFightService'; +import { getRemoteRplPrefix } from '../pubUtils/battleUtils'; /** * init: 初始的时候是否推送 true-推 false-不推 @@ -91,6 +95,8 @@ const modules = [ { id: 27, type: 'ladder', init: false, refresh: true, guild: false }, { id: 28, type: 'hiddenData', init: true, refresh: true, guild: false }, { id: 29, type: 'rouge', init: true, refresh: true, guild: false }, + { id: 30, type: 'iconShow', init: true, refresh: true, guild: false }, + ] export async function pushData(hasInit: boolean, role: RoleType, session: FrontendOrBackendSession, pushType: 'entry' | 'refresh' = 'entry') { @@ -101,10 +107,10 @@ export async function pushData(hasInit: boolean, role: RoleType, session: Fronte pushEntryStart(roleId, sid); // 军团 const guildData = await getGuildEntryData(role, sid, session); - for(let { type, init, refresh, guild } of modules) { - if(!hasInit && !init) continue; - if(pushType == 'refresh' && !refresh) continue; - if(!guildData.hasGuild && guild) continue; + for (let { type, init, refresh, guild } of modules) { + if (!hasInit && !init) continue; + if (pushType == 'refresh' && !refresh) continue; + if (!guildData.hasGuild && guild) continue; let data = await getModuleData(type, { role, session }, guildData); if (data) { @@ -124,7 +130,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio const { roleId, serverId, roleName, guildCode } = role; let { hasGuild, guild, userGuild, guildResult } = guildData; switch (type) { - case 'role': + case 'role': let heros = await HeroModel.findByRole(role.roleId, [], HERO_SELECT.ENTRY, true); let jewels = await JewelModel.findbyRole(role.roleId, JEWEL_SELECT.ENTRY); let items = await ItemModel.findbyRole(role.roleId, ITEM_SELECT.ENTRY); @@ -138,7 +144,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio role['skins'] = skins; let apJson = await getAp(role.roleId, '', role.lv); role['apJson'] = apJson; - role['ipLocation'] = role.fixedIpLocation||role.ipLocation||'未知'; + role['ipLocation'] = role.fixedIpLocation || role.ipLocation || '未知'; role['artifacts'] = artifacts; role['activityItems'] = activityItems; role['authorBook'] = await getAuthorBook(role.roleId); @@ -147,7 +153,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio role.heads = role.heads.filter(cur => cur.status); role.frames = role.frames.filter(cur => cur.status); role.spines = role.spines.filter(cur => cur.status); - role['customerLink'] = link?.link||''; + role['customerLink'] = link?.link || ''; return pick(role, ENTERY_ROLE_PICK); case 'shop': // 商店 return await getAllShopList(roleId, serverId); @@ -186,7 +192,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio case 'train': if (hasGuild) { let trainInstance = await getGuildTrainInstance(roleId, guild, userGuild); - if(!trainInstance) return null; + if (!trainInstance) return null; let trainBoxRewards = await getTrainBoxRewardsResult(guildCode); return { trainInstance, trainBoxRewards } } @@ -208,7 +214,7 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio case 'task': let tasks = await getCurTask(role.roleId, session); let pvpTask = await getPvpTask(role.roleId); - return {...tasks, pvpTask} + return { ...tasks, pvpTask } case 'chat': const worldMsgs = await recentWorldMsgs(serverId); const sysMsgs = await recentSysMsgs(serverId); @@ -233,6 +239,8 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio return getHiddenData(); case 'rouge': return await getRougeData(role.roleId); + case 'iconShow': + return await getIconShow(role.roleId, session); default: return null; } @@ -332,7 +340,7 @@ async function getComBattleEntryData(role: RoleType, guildCode: string) { let refreshTime = nowSeconds() - INFO_WINDOW.TEAM_INFORMATION_TIME; const invitations = await ComBattleTeamModel.findInvitations(roleId, guildCode, minLv, maxLv, topLineupCe, refreshTime, 1); let capExtraCnt = await getCapExtraCnt(roleId); - return { assistCnt, blueprts, hasInvitation: invitations.length > 0, invitationTime: invitations.length > 0?invitations[0].inviteTime: 0, capExtraCnt } + return { assistCnt, blueprts, hasInvitation: invitations.length > 0, invitationTime: invitations.length > 0 ? invitations[0].inviteTime : 0, capExtraCnt } } export async function pushRefreshTime() { @@ -362,61 +370,61 @@ export async function assignServer(roleId: string, session: FrontendOrBackendSes let role = await _assignServer(roleId, 'role'); let order = await _assignServer(roleId, 'order'); let comBattle = await _assignServer(roleId, 'comBattle'); - if(activity) { + if (activity) { session.set('activityServer', activity); session.push('activityServer', () => { }); } - if(battle) { + if (battle) { session.set('battleServer', battle); session.push('battleServer', () => { }); } - if(chat) { + if (chat) { session.set('chatServer', chat); session.push('chatServer', () => { }); } - if(guild) { + if (guild) { session.set('guildServer', guild); session.push('guildServer', () => { }); } - if(role) { + if (role) { session.set('roleServer', role); session.push('roleServer', () => { }); } - if(order) { + if (order) { session.set('orderServer', order); session.push('orderServer', () => { }); } - if(comBattle) { + if (comBattle) { session.set('comBattleServer', comBattle); session.push('comBattleServer', () => { }); } - } catch(e) { + } catch (e) { console.log(e) } } async function _assignServer(roleId: string, serverType: string) { - let servers = pinus.app.getServersByType(serverType)||[]; - let sum = servers.reduce((pre, cur) => pre + (cur['num']||0), 0); + let servers = pinus.app.getServersByType(serverType) || []; + let sum = servers.reduce((pre, cur) => pre + (cur['num'] || 0), 0); let id = ''; - if(sum > 0) { - let serversWithWeight = servers.map(cur => ({...cur, weight: sum - (cur['num']||0)})); + if (sum > 0) { + let serversWithWeight = servers.map(cur => ({ ...cur, weight: sum - (cur['num'] || 0) })); let { dic: server } = getRandEelmWithWeight(serversWithWeight); id = server?.id; } - if(!id) { + if (!id) { id = (await dispatch(redisClient(), roleId, servers, serverType))?.id; } return id } export function incServerNum(sid: string, inc: number) { - if(!pinus.app.getServerById(sid)) return; - if(!pinus.app.getServerById(sid)['num']) { + if (!pinus.app.getServerById(sid)) return; + if (!pinus.app.getServerById(sid)['num']) { pinus.app.getServerById(sid)['num'] = 0; } pinus.app.getServerById(sid)['num'] += inc; - if(pinus.app.getServerById(sid)['num'] < 0) { + if (pinus.app.getServerById(sid)['num'] < 0) { pinus.app.getServerById(sid)['num'] = 0; } } @@ -443,9 +451,32 @@ export async function leaveServer(session: FrontendOrBackendSession) { async function getAuthorBook(roleId: string) { let result: { bookId: number, authors: { subId: number, star: number }[], progress: number, maxProgress: number }[] = []; let authorBooks = await AuthorBookModel.findByRoleId(roleId); - for(let [bookId, maxProgress] of gameData.authorBookMaxProgress) { + for (let [bookId, maxProgress] of gameData.authorBookMaxProgress) { let authorBook = authorBooks.find(cur => cur.bookId == bookId); - result.push({ bookId, authors: authorBook?.authors??[], progress: authorBook?.progress??0, maxProgress}); + result.push({ bookId, authors: authorBook?.authors ?? [], progress: authorBook?.progress ?? 0, maxProgress }); } return result +} + +async function getIconShow(roleId: string, session:FrontendOrBackendSession) { + let quitTime = session.get('quitTime'); + if (!roleId) return; + let ladderIconShow = await LadderMatchRecModel.findRecByRoleId(roleId, quitTime); + + let list = await GVGVestigeRecModel.findRecCurDay(roleId, Math.max(quitTime, getZeroPoint()*1000)); + let result: (GVGVestigeRecUpdate & { rplFileUrl: string })[] = []; + for (let rec of list) { + const { attackRoleId, battleCode, hasRpl, remoteUrl } = rec; + const rplFileUrl = battleCode && hasRpl ? remoteUrl : ''; + const obj = getVestigeRecStatus(rec); + if (obj.status == VESTIGE_STATUS.COMPLETE && result.length < 10) result.push({ ...rec, endTime: obj.time, rplFileUrl }); + } + let gvgFightRecs = { list: result, rplPrefixUrl: getRemoteRplPrefix(pinus.app.get('env')) }; + + return { ladderIconShow, gvgFightRecs } +} + +export async function pushIconShow(roleId: string, ladderIconShow?: boolean, gvgFightRecs?) { + if (!roleId) return; + sendMessageToUserWithSuc(roleId, PUSH_ROUTE.LADDER_OR_GVG_ICON_SHOW, { ladderIconShow, gvgFightRecs }); } \ No newline at end of file diff --git a/game-server/app/services/gvg/gvgFightService.ts b/game-server/app/services/gvg/gvgFightService.ts index 0707a78ee..c0c0135e5 100644 --- a/game-server/app/services/gvg/gvgFightService.ts +++ b/game-server/app/services/gvg/gvgFightService.ts @@ -10,7 +10,7 @@ import { GVGVestigeModel } from "../../db/GVGVestige"; import { GVGVestigeLeagueRankModel, GVGVestigeLeagueRankType } from "../../db/GVGVestigeLeagueRank"; import { GVGVestigeLockModel } from "../../db/GVGVestigeLock"; import { GVGVestigeRankModel, GVGVestigeRankType, GVGVestigeRankUpdate } from "../../db/GVGVestigeRank"; -import { GVGVestigeRecType } from "../../db/GVGVestigeRec"; +import { GVGVestigeRecModel, GVGVestigeRecType, GVGVestigeRecUpdate } from "../../db/GVGVestigeRec"; import { GVGVestigeSumRankModel, GVGVestigeSumRankType } from "../../db/GVGVestigeSumRank"; import { HeroModel, HeroType } from "../../db/Hero"; import { RoleModel } from "../../db/Role"; @@ -34,6 +34,9 @@ import { calFighterContribute } from "./gvgPrepareService"; import { addVestigeLeagueRankRec, addVestigeRankMessage } from "./gvgRecService"; import { getGroupKey, getGVGServerType, getPeriodByTime } from "./gvgService"; import { Combo } from "../../domain/battleField/pvp"; +import { getRemoteRplPrefix } from "../../pubUtils/battleUtils"; +import { pinus } from "pinus"; +import { pushIconShow } from "../connectorService"; let gvgFightTime = undefined; @@ -530,4 +533,16 @@ export function calVestigeLeagueBoxRewards(canReceiveRanks: { rank: number }[], return { leagueReward, rewards, boxPreview, canReceiveBox: canReceiveRanks.length > 0 || canReceivePlayerRanks.length > 0 } +} + +export async function pushGvgFightIconShow(roleId: string, battleCode: string) { + const rec = await GVGVestigeRecModel.findByBattleCode(battleCode); + let result: (GVGVestigeRecUpdate & { rplFileUrl: string })[] = []; + const { attackRoleId, hasRpl, remoteUrl } = rec; + const rplFileUrl = battleCode && hasRpl ? remoteUrl : ''; + const obj = getVestigeRecStatus(rec); + if (obj.status == VESTIGE_STATUS.COMPLETE) result.push({ ...rec, endTime: obj.time, rplFileUrl }); + let gvgFightRecs = { list: result, rplPrefixUrl: getRemoteRplPrefix(pinus.app.get('env')) }; + + await pushIconShow(roleId, false, gvgFightRecs) } \ No newline at end of file diff --git a/game-server/app/services/ladderService.ts b/game-server/app/services/ladderService.ts index ba2c9346b..0f5b2f2b1 100644 --- a/game-server/app/services/ladderService.ts +++ b/game-server/app/services/ladderService.ts @@ -10,6 +10,7 @@ import { gameData, getDicLadderMatchByMyRank, getLadderRankReward } from "../pub import { EXTERIOR, LADDER } from "../pubUtils/dicParam"; import { ItemInter, RewardInter } from "../pubUtils/interface"; import { getRandValueByMinMax, shouldRefresh } from "../pubUtils/util"; +import { pushIconShow } from "./connectorService"; import { sendMailByContent } from "./mailService"; import { getHeroesAttributes } from "./playerCeService"; import { sendMessageToUserWithSuc } from "./pushService"; @@ -440,3 +441,10 @@ export async function getLadderOppDetailData(rec: LadderMatchRecType) { } return result; } + +export async function pushLadderIconShow(roleId: string, ladderIconShow:boolean) { + console.log('-x-11111x--x-x-x-x-x-xx- roleId', roleId) + console.log('-x-x--x11111-x-x-x-x-xx- ladderIconShow', ladderIconShow) + if (!roleId) return; + await pushIconShow(roleId, ladderIconShow); +} \ No newline at end of file diff --git a/shared/consts/constModules/chatConst.ts b/shared/consts/constModules/chatConst.ts index 200171b33..838bf0b2d 100644 --- a/shared/consts/constModules/chatConst.ts +++ b/shared/consts/constModules/chatConst.ts @@ -214,5 +214,5 @@ export const PUSH_ROUTE = { GVG_REC_ADD: 'onGVGRecAdd', // 动态更新 ROUGE_COLLECT_UPDATE: 'onRougeCollectUpdate', // 更新图鉴 ROUGE_CHALLENGE_UPDATE: 'onRougeChallengeUpdate', //更新学宫挑战进度 - + LADDER_OR_GVG_ICON_SHOW: 'onLadderOrGvgIconShow', //名将擂台icon提示 } \ No newline at end of file diff --git a/shared/db/GVGVestigeRec.ts b/shared/db/GVGVestigeRec.ts index d35e55482..0c37bcf0c 100644 --- a/shared/db/GVGVestigeRec.ts +++ b/shared/db/GVGVestigeRec.ts @@ -127,6 +127,23 @@ export default class GVGVestigeRec extends BaseModel { }).select({ battleCode: 1, attackRoleId: 1, defenseRoleId: 1, _id: 0, endTime: 1, attackInfo: 1, defenseInfo: 1, hasRpl: 1, remoteUrl: 1 }).limit(1000).lean(); return recs; } + + public static async findRecCurDay(roleId: string, startMs:number) { + const pipeline = [ + { $match: {endTime: { $gt: startMs }, $or: [{ attackRoleId: roleId }, { defenseRoleId: roleId }]} }, + { $sort: { endTime: -1 } }, + // { $limit: 1000 }, + ]; + let result:GVGVestigeRecType[] = [] + const recs: GVGVestigeRecType[] = await GVGVestigeRecModel.aggregate(pipeline); + if (recs.length > 0) { + for(const obj of recs){ + if(obj.defenseRoleId == roleId && (!obj.defenseInfo.isSuccess)) result.push(obj); + } + } + + return result; + } } export const GVGVestigeRecModel = getModelForClass(GVGVestigeRec); diff --git a/shared/db/LadderMatchRec.ts b/shared/db/LadderMatchRec.ts index 797b0e19c..8d01f6476 100644 --- a/shared/db/LadderMatchRec.ts +++ b/shared/db/LadderMatchRec.ts @@ -41,12 +41,12 @@ export default class LadderMatchRec extends BaseModel { remoteUrl: string; // 录像地址 public static async findByRoleId(roleId: string, getters = false) { - const result: LadderMatchRecType = await LadderMatchRecModel.findOne({ roleId1: roleId }).lean({ getters}); + const result: LadderMatchRecType = await LadderMatchRecModel.findOne({ roleId1: roleId }).lean({ getters }); return result; } public static async findNotCompleteRecByRoleId(roleId: string, getters = false) { - const result: LadderMatchRecType = await LadderMatchRecModel.findOne({ roleId1: roleId, status: { $in: [ LADDER_STATUS.BATTLE, LADDER_STATUS.CHECK ] } }).lean({ getters}); + const result: LadderMatchRecType = await LadderMatchRecModel.findOne({ roleId1: roleId, status: { $in: [LADDER_STATUS.BATTLE, LADDER_STATUS.CHECK] } }).lean({ getters }); return result; } @@ -82,11 +82,11 @@ export default class LadderMatchRec extends BaseModel { public static async battleEnd(battleCode: string, isSuccess: boolean, endTime: number, atkNewRank?: number, defNewRank?: number) { let update: LadderMatchRecUpdate = { status: LADDER_STATUS.COMPLETE, endTime, timeout: false }; - if(isSuccess) { + if (isSuccess) { update['attackInfo.isSuccess'] = true; update['defenseInfo.isSuccess'] = false; } - if(atkNewRank != undefined && defNewRank != undefined) { + if (atkNewRank != undefined && defNewRank != undefined) { update['attackInfo.newRank'] = atkNewRank; update['attackInfo.oldRank'] = defNewRank; update['defenseInfo.newRank'] = defNewRank; @@ -98,10 +98,10 @@ export default class LadderMatchRec extends BaseModel { } public static async findRec(roleId: string) { - let recs: LadderMatchRecType[] = await LadderMatchRecModel.find({ - $or: [{roleId1: roleId}, { roleId2: roleId }], + let recs: LadderMatchRecType[] = await LadderMatchRecModel.find({ + $or: [{ roleId1: roleId }, { roleId2: roleId }], status: LADDER_STATUS.COMPLETE - }).select({ battleCode: 1, roleId1: 1, roleId2: 1, _id: -1, endTime: 1, attackInfo: 1, defenseInfo: 1, hasRpl: 1 }).limit(1000).lean(); + }).select({ battleCode: 1, roleId1: 1, roleId2: 1, _id: -1, endTime: 1, attackInfo: 1, defenseInfo: 1, hasRpl: 1 }).limit(1000).lean(); return recs; } @@ -116,30 +116,55 @@ export default class LadderMatchRec extends BaseModel { public static async findRecentRec(roleId: string, startMs: number) { let recs: LadderMatchRecType[] = await LadderMatchRecModel.find({ endTime: { $gt: startMs }, - $or: [{roleId1: roleId}, { roleId2: roleId }], + $or: [{ roleId1: roleId }, { roleId2: roleId }], status: LADDER_STATUS.COMPLETE - }).select({ battleCode: 1, roleId1: 1, roleId2: 1, _id: -1, endTime: 1, attackInfo: 1, defenseInfo: 1, hasRpl: 1, remoteUrl: 1 }).limit(1000).lean(); + }).select({ battleCode: 1, roleId1: 1, roleId2: 1, _id: -1, endTime: 1, attackInfo: 1, defenseInfo: 1, hasRpl: 1, remoteUrl: 1 }).limit(1000).lean(); return recs; } + /** + * 查找包含roleId最新一条记录 + * @param roleId + * @returns true--表示查到最新一条roleId作为守方失败 + */ + // public static async findOneRecByRoleId(roleId: string) { + // let recs: LadderMatchRecType = await LadderMatchRecModel.findOne({ $or: [{ roleId1: roleId }, { roleId2: roleId }], status: LADDER_STATUS.COMPLETE }).sort({ endTime: -1 }).limit(1).lean(); + // if (recs && recs.roleId2 == roleId && (!recs.defenseInfo.isSuccess)) return true; + // return false; + // } + public static async findRecByRoleId(roleId: string, quitTime: number) { + const pipeline = [ + { $match: { endTime: { $gt: quitTime }, $or: [{ roleId1: roleId }, { roleId2: roleId }], status: LADDER_STATUS.COMPLETE } }, + { $sort: { endTime: -1 } }, + // { $limit: 1 }, + { $project: { _id: 0, roleId2: 1, "defenseInfo.isSuccess": 1 } } + ]; + const recs: LadderMatchRecType[] = await LadderMatchRecModel.aggregate(pipeline); + for (let obj of recs) { + if (obj.roleId2 === roleId && !obj.defenseInfo.isSuccess) return true; + } + return false; + } + + public static async checkByRank(serverId: number, roleId2: string) { const result = await LadderMatchRecModel.exists({ serverId, roleId2, status: { $in: [LADDER_STATUS.BATTLE, LADDER_STATUS.CHECK] } }); return result; } public static async getUncompleteData() { - let recs = await LadderMatchRecModel.find({ + let recs = await LadderMatchRecModel.find({ $or: [ { status: LADDER_STATUS.CHECK }, { status: LADDER_STATUS.BATTLE } ] - }); + }); return recs; } public static async timeoutMany(battleCode: string[]) { - - await LadderMatchRecModel.updateMany({ + + await LadderMatchRecModel.updateMany({ battleCode: { $in: battleCode } }, { $set: { status: LADDER_STATUS.COMPLETE, timeout: true, endTime: Date.now() } });