✨ feat(pvp): 巅峰演武战区化
This commit is contained in:
@@ -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,
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>; // 将所有字段变成可选项
|
||||
@@ -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}`;
|
||||
|
||||
Reference in New Issue
Block a user