feat(gvg): 开始挑战和结束挑战

This commit is contained in:
luying
2023-02-01 21:26:24 +08:00
parent b727249106
commit ddce23d7fd
12 changed files with 34095 additions and 179 deletions

View File

@@ -25,13 +25,13 @@ export default class GVGVestige extends BaseModel {
@prop({ required: true })
day: number; // 每天5点
public static async getVestigate(groupId: number) {
public static async getVestige(groupId: number) {
let day = getZeroPoint();
let result: GVGVestigeType = await GVGVestigeModel.findOne({ groupId, day }).lean();
return result;
}
public static async initTodayVestigate(groupId: number, type: number, vestiges: Vestige[]) {
public static async initTodayVestige(groupId: number, type: number, vestiges: Vestige[]) {
let day = getZeroPoint();
let result: GVGVestigeType = await GVGVestigeModel.findOneAndUpdate({ groupId, day }, { $setOnInsert: { type, vestiges } }, { new: true, upsert: true }).lean();
return result;

View File

@@ -23,24 +23,28 @@ export default class GVGVestigeLock extends BaseModel {
rank: number; // 排名
@prop({ required: true })
unlockTime: number; // 锁定到什么时候
unlockTime: number; // 锁定到什么时候,13位时间戳
@prop({ required: true })
attackRoleId: string; // 锁定到什么时候
attackRoleId: string; // 挑战玩家
@prop({ required: true })
defenseRoleId: string; // 锁定到什么时候
defenseRoleId: string; // 防守玩家
public static async chooseOppLock(groupId: number, vestigeId: number, rank: number, configId: number, attackRoleId: string, defenseRoleId: string ) {
return await this.lock(groupId, vestigeId, rank, configId, attackRoleId, defenseRoleId, nowSeconds() + GVG.GVG_VESTIGE_PREPARE_COUNTDOWN);
}
private static async lock(groupId: number, vestigeId: number, rank: number, configId: number, attackRoleId: string, defenseRoleId: string, unlockTime: number) {
let day = getZeroPoint();
await GVGVestigeLockModel.findOneAndUpdate({ day, groupId, vestigeId, rank }, { $setOnInsert: { configId, unlockTime: 0 } }, { upsert: true });
let result: GVGVestigeLockType = await GVGVestigeLockModel.findOneAndUpdate({
day, groupId, vestigeId, rank, unlockTime: { $lt: nowSeconds() }
}, { $set: { unlockTime, attackRoleId, defenseRoleId } }, { new: true }).lean();
day, groupId, vestigeId, rank, unlockTime: { $lt: Date.now() }
}, { $set: { unlockTime: Date.now() + GVG.GVG_VESTIGE_PREPARE_COUNTDOWN * 1000, attackRoleId, defenseRoleId } }, { new: true }).lean();
return result;
}
public static async checkBattleLock(groupId: number, vestigeId: number, rank: number, attackRoleId: string) {
let day = getZeroPoint();
let result: GVGVestigeLockType = await GVGVestigeLockModel.findOneAndUpdate({
day, groupId, vestigeId, rank, attackRoleId, unlockTime: { $gt: Date.now() }
}, { $set: { unlockTime: Date.now() + GVG.GVG_VESTIGE_BATTLE_COUNTDOWN * 1000 } }, { new: true }).lean();
return result;
}

View File

@@ -45,16 +45,13 @@ export default class GVGVestigeRank extends BaseModel {
@prop({ required: true, default: 0 })
historyRank: number; // 历史最高排名
@prop({ required: true, default: 0 })
locked: number; // 是否被挑战
@prop({ required: true, default: false })
hasAdjustLineup: boolean; // 是否调整过阵容
hasDefense: boolean; // 是否调整过阵容,首次挑战自动保存阵容
@prop({ required: true, type: Lineup, default: [] })
@prop({ required: true, type: Lineup, default: [], _id: false })
lineup: Lineup[]; // 阵容
@prop({ required: true, type: Number, default: [] })
@prop({ required: true, type: Number, default: [], _id: false })
oppRanks: number[]; // 对手的排名
@prop({ required: true, default: 0 })
@@ -86,6 +83,12 @@ export default class GVGVestigeRank extends BaseModel {
return result;
}
public static async updateByRoleId(vestigeId: number, roleId: string, update: GVGVestigeRankUpdate) {
let today = getZeroPoint();
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId }, { $set: update }, { new: true, upsert: true }).lean();
return result;
}
public static async findByRanks(groupId: number, vestigeId: number, ranks: number[]) {
let today = getZeroPoint();
let result: GVGVestigeRankType[] = await GVGVestigeRankModel.find({ day: today, vestigeId, groupId, rank: { $in: ranks } })
@@ -96,13 +99,45 @@ export default class GVGVestigeRank extends BaseModel {
public static async updateCe(roleId: string, hid: number, ce: number) {
let today = getZeroPoint();
await GVGVestigeRankModel.updateMany({ day: today, roleId, 'lineup.hid': hid }, { $set: { 'lineupCe.$.ce': ce } });
await GVGVestigeRankModel.updateMany({ day: today, hasDefense: true, roleId, 'lineup.hid': hid }, { $set: { 'lineupCe.$.ce': ce } });
}
public static async changeRank(isSuccess: boolean, attackInfo: { roleId: string }, defenseInfo: { isRobot: boolean, roleId: string, oldRank: number }): Promise<{ isChange: boolean, atkData?: GVGVestigeRankType, defData?: GVGVestigeRankType, endTime: number }> {
const session = await mongoose.connection.startSession();
session.startTransaction()
try {
let newAtkData: GVGVestigeRankType, newDefData: GVGVestigeRankType, isChange = false, endTime = Date.now();
if(defenseInfo.isRobot) {
let atkData = await GVGVestigeRankModel.findOne({ roleId: attackInfo.roleId }).lean();
if(isSuccess && atkData && (atkData.rank == 0 || atkData.rank > defenseInfo.oldRank)) {
newAtkData = await GVGVestigeRankModel.findOneAndUpdate({ roleId: attackInfo.roleId }, { $set: { rank: defenseInfo.oldRank, oldRank: atkData.rank } }, { new: true, session }).lean();
isChange = true;
endTime = Date.now();
} else {
newAtkData = atkData;
}
} else {
let atkData = await GVGVestigeRankModel.findOne({ roleId: attackInfo.roleId }).lean();
let defData = await GVGVestigeRankModel.findOne({ roleId: defenseInfo.roleId }).lean();
if(isSuccess && atkData && defData && (atkData.rank == 0 || atkData.rank > defData.rank)) {
newAtkData = await GVGVestigeRankModel.findOneAndUpdate({ roleId: attackInfo.roleId }, { $set: { rank: defData.rank, oldRank: atkData.rank } }, { new: true, session }).lean();
newDefData = await GVGVestigeRankModel.findOneAndUpdate({ roleId: defenseInfo.roleId }, { $set: { rank: atkData.rank, oldRank: defData.rank } }, { new: true, session }).lean();
isChange = true;
endTime = Date.now();
} else {
newAtkData = atkData;
newDefData = defData;
}
}
await session.commitTransaction()
return { isChange, atkData: newAtkData, defData: newDefData, endTime }
} finally {
session.endSession()
}
}
}
export const GVGVestigeRankModel = getModelForClass(GVGVestigeRank);
export interface GVGVestigeRankType extends Pick<DocumentType<GVGVestigeRank>, keyof GVGVestigeRank> {
id: number;
};
export interface GVGVestigeRankType extends Pick<DocumentType<GVGVestigeRank>, keyof GVGVestigeRank> {};
export type GVGVestigeRankUpdate = Partial<GVGVestigeRankType>; // 将所有字段变成可选项

View File

@@ -1,9 +1,8 @@
// 征战中原对手锁
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { OppPlayerInfo } from '../domain/gvgField/gvgDb';
import { OppPlayerInfo, OppPlayerHeroInfo } from '../domain/gvgField/gvgDb';
import { genCode } from '../pubUtils/util';
import { VESTIGE_STATUS } from '../consts';
class LeagueGood {
@prop({ required: true })
@@ -16,12 +15,16 @@ class LeagueGood {
count: number
}
@index({ battleCode: 1 })
@index({ day: 1, groupId: 1, vestigeId: 1, rank: 1 })
export default class GVGVestigeRec extends BaseModel {
@prop({ required: true })
battleCode: string; // 唯一code
@prop({ required: true })
warId: number; // 关卡id
@prop({ required: true })
attackRoleId: string; // 攻方玩家id
@@ -35,7 +38,7 @@ export default class GVGVestigeRec extends BaseModel {
vestigeId: number; // 遗迹id
@prop({ required: true })
status: number; // 1-出兵中 2-挑战中 3-挑战完毕 4-取消
cancel: boolean; // 是否取消
@prop({ required: true })
checkTime: number; // 开始出兵的时间13位时间戳
@@ -58,19 +61,50 @@ export default class GVGVestigeRec extends BaseModel {
@prop({ required: true, default: false })
hasRpl: boolean; // 是否存在对应录像
public static async createRec(configId: number, vestigeId: number, groupId: number, attackInfo: OppPlayerInfo, defenseInfo: OppPlayerInfo, leagueGoods: LeagueGood[]) {
public static async createRec(configId: number, vestigeId: number, groupId: number, warId: number, attackInfo: OppPlayerInfo, defenseInfo: OppPlayerInfo, leagueGoods: LeagueGood[]) {
const battleCode = genCode(10);
const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, {
$set: { configId, vestigeId, groupId, attackRoleId: attackInfo.roleId, defenseRoleId: defenseInfo.roleId, status: VESTIGE_STATUS.CHECK, checkTime: Date.now(), attackInfo, defenseInfo, leagueGoods }
$set: { configId, vestigeId, groupId, attackRoleId: attackInfo.roleId, defenseRoleId: defenseInfo.roleId, warId, checkTime: Date.now(), attackInfo, defenseInfo, leagueGoods }
}, { new: true, upsert: true }).lean();
return result;
}
public static async findByBattleCode(battleCode: string, select = '') {
const result: GVGVestigeRecType = await GVGVestigeRecModel.findOne({ battleCode }).select(select).lean();
return result;
}
public static async startBattle(battleCode: string, attackHeroes: OppPlayerHeroInfo[]) {
const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, {
$set: { battleTime: Date.now(), 'attackInfo.heroes': attackHeroes }
}, { new: true }).lean();
return result;
}
public static async battleEnd(battleCode: string, isSuccess: boolean, endTime: number, atkNewRank?: number, defNewRank?: number) {
let update: GVGVestigeRecUpdate = { endTime };
if(isSuccess) {
update['attackInfo.isSuccess'] = true;
update['defenseInfo.isSuccess'] = false;
}
if(atkNewRank != undefined && defNewRank != undefined) {
update['attackInfo.newRank'] = atkNewRank;
update['attackInfo.oldRank'] = defNewRank;
update['defenseInfo.newRank'] = defNewRank;
update['defenseInfo.oldRank'] = atkNewRank;
}
const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, { $set: update }, { new: true }).lean();
return result;
}
public static async giveup(roleId: string, battleCode: string) {
const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ attackRoleId: roleId, battleCode }, { $set: { cancel: true }}, { new: true }).lean();
return result;
}
}
export const GVGVestigeRecModel = getModelForClass(GVGVestigeRec);
export interface GVGVestigeRecType extends Pick<DocumentType<GVGVestigeRec>, keyof GVGVestigeRec> {
id: number;
};
export interface GVGVestigeRecType extends Pick<DocumentType<GVGVestigeRec>, keyof GVGVestigeRec> {};
export type GVGVestigeRecUpdate = Partial<GVGVestigeRecType>; // 将所有字段变成可选项