feat(pvp): 巅峰演武战区化

This commit is contained in:
luying
2023-03-18 16:59:39 +08:00
parent da86251116
commit e52c7b5241
25 changed files with 341 additions and 191 deletions
+7
View File
@@ -1265,4 +1265,11 @@ export enum PVP_SEASON_STATUS {
START = 1, // 已开始
SUMMIT = 2, // 结算中
WAITING = 3, // 待新赛季
}
// 战区配置类型
export enum SERVER_GROUP_FUN_TYPE {
GVG = 1,
PVP = 2,
ARENA = 3,
}
-41
View File
@@ -1,41 +0,0 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
/**
* 服务器分战区
*/
@index({ time: -1, serverId: -1 })
export default class GVGServerGroup extends BaseModel {
@prop({ required: true, default: 1 })
serverId: number; // 服务器id
@prop({ required: true, default: 1 })
groupId: number; // 战区id
@prop({ required: true, default: 0 })
time: number; // 生效时间
public static async findByTime(time: number) {
const serverGroup: { serverId: number, groupId: number }[] = await GVGServerGroupModel.aggregate([
{ $match: { time: { $lte: time } } },
{ $sort: { time: -1 } },
{ $group: { _id: "$serverId", serverId: { $first: "$serverId" }, groupId: { $first: "$groupId" }, time: { $first: "$time" }} },
{ $sort: { _id: -1 } },
{ $project: { _id: 0, serverId: "$serverId", groupId: "$groupId", time: "$time" } }
]);
return serverGroup;
}
public static async updateByServerId(serverId: number, groupId: number, time: number) {
const result: GVGServerGroupType = await GVGServerGroupModel.findOneAndUpdate({ serverId, time }, { $set: { groupId } }, { new: true, upsert: true }).lean();
return result
}
}
export let GVGServerGroupModel = getModelForClass(GVGServerGroup);
export interface GVGServerGroupType extends Pick<DocumentType<GVGServerGroup>, keyof GVGServerGroup> {
id: number;
};
export type GVGServerGroupUpdate = Partial<GVGServerGroupType>; // 将所有字段变成可选项
+11 -19
View File
@@ -5,7 +5,7 @@ import { Defense, Attack, LineupCe, OppPlayer, HeroScore, } from '../domain/batt
import { PVP } from '../pubUtils/dicParam';
@index({ roleId: 1 })
@index({ score: 1 })
@index({ serverId: 1, score: 1 })
export default class PvpDefense extends BaseModel {
@prop({ required: true })
serverId: number; // 区 id
@@ -71,14 +71,6 @@ export default class PvpDefense extends BaseModel {
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }).lean({ getters});
return result;
}
public static async findByScale(roleId: string, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ roleId: { $ne: roleId }, defCe: { $lte: max, $gte: min } })
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.sort({ updatedAt: -1 }).limit(100).lean({ getters: true, virtuals: true });
return result;
}
public static async createPvpDefense(seasonNum: number, params: pvpUpdateInter) {
const doc = new PvpDefenseModel();
@@ -121,16 +113,16 @@ export default class PvpDefense extends BaseModel {
public static async findByRoleIdIncludeAll(roleId: string) {
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId })
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('role', 'serverId head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes warId buff')
.populate('oppBeforePlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes warId buff').lean({ getters: true, virtuals: true });
return result;
}
public static async findByTeamLv(seasonNum: number, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, hasDefense: true, 'defense.pLv': { $gte: min, $lte: max } })
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
public static async findByTeamLv(serverIds: number[], seasonNum: number, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ serverId: {$in: serverIds}, seasonNum, hasDefense: true, 'defense.pLv': { $gte: min, $lte: max } })
.populate('role', '_id serverId head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff')
.lean({ getters: true, virtuals: true });
@@ -141,14 +133,14 @@ export default class PvpDefense extends BaseModel {
const beforeData: PvpDefenseType[] = await PvpDefenseModel.find({
seasonNum, hasDefense: true, score: { $lt: score }
}).sort({ score: -1 }).limit(10)
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('role', '_id serverId head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff')
.lean({ getters: true, virtuals: true });
const afterData: PvpDefenseType[] = await PvpDefenseModel.find({
seasonNum, hasDefense: true, score: { $gt: score }
}).sort({ score: 1 }).limit(10)
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('role', '_id serverId head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff')
.lean({ getters: true, virtuals: true });
@@ -159,7 +151,7 @@ export default class PvpDefense extends BaseModel {
public static async updateInfoAndInclude(roleId: string, update: pvpUpdateInter) {
delete update._id;
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv title')
.populate('role', 'serverId head frame spine heads frames spines topLineupCe roleId roleName lv title')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff').lean({ getters: true, virtuals: true });
return result;
}
@@ -173,10 +165,10 @@ export default class PvpDefense extends BaseModel {
return result;
}
public static async getRank(seasonNum: number, page = 1, limit = 1000) {
public static async getRank(serverIds: number[], seasonNum: number, page = 1, limit = 1000) {
let sortBy = { score: -1, updatedAt: 1 };
const ranks: PvpDefenseType[] = await PvpDefenseModel.find({rankSeasonNum: seasonNum, score: { $gt: 0 }}).select('roleId role score updatedAt')
.populate('role', 'roleId roleName head frame spine heads frames spines title lv vLv updatedAt serverId')
const ranks: PvpDefenseType[] = await PvpDefenseModel.find({ serverId: {$in: serverIds}, rankSeasonNum: seasonNum, score: { $gt: 0 }}).select('serverId roleId role score updatedAt')
.populate('role', 'serverId roleId roleName head frame spine heads frames spines title lv vLv updatedAt')
.sort(sortBy).limit(limit).skip((page - 1) * limit).lean({ getters: true, virtuals: true });
return ranks;
}
+52
View File
@@ -0,0 +1,52 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { SERVER_GROUP_FUN_TYPE } from '../consts';
/**
* 服务器分战区
*/
@index({ serverId: -1 })
export default class ServerGroup extends BaseModel {
@prop({ required: true, default: 1 })
serverId: number; // 服务器id
@prop({ required: true, default: 1 })
groupId: number; // 战区id
@prop({ required: true, default: 0 })
gvgTime: number; // gvg生效时间
@prop({ required: true, default: 0 })
pvpTime: number; // pvp生效时间
@prop({ required: true, default: 0 })
arenaTime: number; // 3v3生效时间
public static async findByTime(time: number, type: number) {
let key = type == SERVER_GROUP_FUN_TYPE.GVG? 'gvgTime': (type == SERVER_GROUP_FUN_TYPE.PVP? 'pvpTime': 'arenaTime');
let match = {}, sort = {};
match[key] = { $lte: time, $gt: 0 };
sort[key] = -1;
const serverGroup: { serverId: number, groupId: number }[] = await ServerGroupModel.aggregate([
{ $match: match },
{ $sort: sort },
{ $group: { _id: "$serverId", groupId: { $first: "$groupId" }, time: { $first: `$${key}` }} },
{ $sort: { _id: -1 } },
{ $project: { _id: 0, serverId: "$_id", groupId: "$groupId", time: "$time" } }
]);
return serverGroup;
}
public static async updateByServerId(serverId: number, groupId: number, gvgTime: number, pvpTime: number) {
const result: ServerGroupType = await ServerGroupModel.findOneAndUpdate({ serverId, gvgTime, pvpTime }, { $set: { groupId } }, { new: true, upsert: true }).lean();
return result
}
}
export let ServerGroupModel = getModelForClass(ServerGroup);
export interface ServerGroupType extends Pick<DocumentType<ServerGroup>, keyof ServerGroup> {
id: number;
};
export type ServerGroupUpdate = Partial<ServerGroupType>; // 将所有字段变成可选项
+3 -1
View File
@@ -356,6 +356,7 @@ export class SimpleRoleRankParam {
export class KeyName {
key: string;
serverId?: number;
groupId?: number; // 战区
guildCode?: string;
cityId?: number;
hid?: number;
@@ -371,6 +372,7 @@ export class KeyName {
constructor(key: string, param: KeyNameParam) {
this.key = key;
if(param.serverId) this.serverId = param.serverId;
if(param.groupId) this.groupId = param.groupId;
if(param.guildCode) this.guildCode = param.guildCode;
if(param.cityId) this.cityId = param.cityId;
if(param.hid) this.hid = param.hid;
@@ -401,7 +403,7 @@ export class KeyName {
case REDIS_KEY.HERO_RANK:
return `${this.key}:${this.serverId}:${this.hid}`;
case REDIS_KEY.PVP_RANK:
return `${this.key}:${this.seasonNum}`;
return `${this.key}:${this.seasonNum}:${this.groupId}`;
case REDIS_KEY.GATE_ACTIVITY:
case REDIS_KEY.RACE_ACTIVITY:
return `${this.key}:${this.serverId}:${this.index}`;