From 4d5428f37bcabe71571d7909273efb54e3da1b80 Mon Sep 17 00:00:00 2001 From: mamengke01 <794347210@qq.com> Date: Wed, 9 Dec 2020 14:50:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A6=E5=B0=86=E5=85=BB=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/heroHandler.ts | 48 +- shared/consts/statusCode.ts | 3 + shared/db/Hero.ts | 261 ++++--- shared/db/Role.ts | 661 +++++++++--------- shared/pubUtils/gamedata.ts | 9 + 5 files changed, 540 insertions(+), 442 deletions(-) diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 77dd6205f..a4a64eda2 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -1,8 +1,10 @@ import {Application, BackendSession, createTcpMailBox, ChannelService} from 'pinus'; import { handleCost } from '../../../services/rewardService'; +import { calPlayerCeAndSave } from '../../../services/playerCeService'; import { resResult } from '../../../pubUtils/util'; import { STATUS } from '../../../consts/statusCode'; - +import {HeroModel} from '../../../db/Hero'; +import { getJobInfoById, getMaxGradeByjobClass , updateHeroInfo} from '../../../pubUtils/gamedata'; export default function(app: Application) { return new HeroHandler(app); } @@ -74,5 +76,49 @@ export class HeroHandler { // 升品,满品3级 // handleCost } + //训练 TODO + async heroJobTrain (msg: {hid:number}, session: BackendSession) { + let roleId = session.get('roleId'); + let { hid } = msg; + let hero = await HeroModel.findByHidAndRole(hid, roleId); + if (!hero) + return resResult(STATUS.WRONG_PARMS); + let heroJob = getJobInfoById(hero.job); + if (hero.jobStage >= 6) + return resResult(STATUS.HERO_JOB_STAGE_REACH_MAX_STAGE); + if (hero.job >= getMaxGradeByjobClass(heroJob.job_class)) + return resResult(STATUS.HERO_JOB_REACH_MAX_STAGE); + //消耗物品TODO + + hero.jobStage = hero.jobStage ++; + //重算战力并下发 + let sid: string = session.get('sid'); + let heros = await calPlayerCeAndSave(sid, roleId, [hero]); + return resResult(STATUS.SUCCESS, { hid : heros[0].hid, job : heros[0].job, jobStage : heros[0].jobStage}); + } + //进阶 TODO + async heroJobStageUp() { + + } + + //激活羁绊 TODO + async heroConectionActivate() { + + } + + //赠送(包括一键赠送)TODO + async heroGiveFavor() { + + } + + //购买时装 + async buyHeroSkin() { + + } + + //穿带时装 + async heroWearSkin() { + + } } diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 5aeb9a414..aa71e3621 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -112,6 +112,8 @@ export const STATUS = { DUNGEON_REFRESH_TIMES_LACK: { code: 20701, simStr: '购买次数不足' }, DUNGEON_TIMES_LACK: { code: 20701, simStr: '挑战次数不足' }, // 养成相关状态 30000 - 39999 + HERO_JOB_REACH_MAX_STAGE: {code: 30001, simStr: '武将已达到最大的职业阶级'}, + HERO_JOB_STAGE_REACH_MAX_STAGE: {code: 30001, simStr: '武将已训练到最大阶段'}, // 社交相关状态 40000 - 49999 // 运营模块相关状态 50000 - 59999 // GM后台相关状态 60000 - 69999 @@ -129,4 +131,5 @@ export const STATUS = { GM_PVP_DEFENSE_NOT_FOUND: { code: 60012, simStr: '该玩家未保存防守阵' }, GM_PVP_DEFENSE_HERO_NOT_FOUND: { code: 60013, simStr: '该守阵没有该武将' }, GM_JSON_FORMAT_ERR: { code: 60005, simStr: 'json格式错误' } + } diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index 68129e6b2..e6b0795ac 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -6,140 +6,171 @@ import { updateCe } from '../pubUtils/util'; /** * 英雄表 */ +interface heroUpdate { + exp?: number; + lv?: number; + ce?: number; + star?: number; + starStage?: number; + fire?: number; + fireStage?: number; + quality?: number; + job?:number; + jobStage?:number; + favour?:number; + favourLv?:number; + skins?: [{ + id: number; + enable: boolean; + }]; + conections?: [{ + id: number; + name: string; + valid: boolean; + }]; + _id?:number; +} @index({ roleId: 1, hid: 1 }) @index({ roleId: 1, seqId: 1 }) export default class Hero extends BaseModel { - @prop({ required: true }) - roleId: string; // 角色 id - @prop({ required: true }) - roleName: string; // 角色名称 - @prop({ required: true }) - serverId: number; // 区服 id + @prop({ required: true }) + roleId: string; // 角色 id + @prop({ required: true }) + roleName: string; // 角色名称 + @prop({ required: true }) + serverId: number; // 区服 id - @prop({ required: true }) - hid: number; // 武将 id - @prop({ required: true }) - hName: string; // 武将名 - @prop({ required: true }) - seqId: number; // 武将表自增 id + @prop({ required: true }) + hid: number; // 武将 id + @prop({ required: true }) + hName: string; // 武将名 + @prop({ required: true }) + seqId: number; // 武将表自增 id - @prop({ required: true, default: 0 }) - exp: number; // 经验值 - @prop({ required: true, default: 1 }) - lv: number; // 武将等级 - @prop({ required: true, default: 0 }) - ce: number; // 武将战力 - @prop({ required: true, default: 0 }) - historyCe: number; // 武将历史最高战力 + @prop({ required: true, default: 0 }) + exp: number; // 经验值 + @prop({ required: true, default: 1 }) + lv: number; // 武将等级 + @prop({ required: true, default: 0 }) + ce: number; // 武将战力 + @prop({ required: true, default: 0 }) + historyCe: number; // 武将历史最高战力 - @prop({ required: true, default: 1 }) - star: number; // 星级 - @prop({ required: true, default: 0 }) - starStage: number; // 星级六维阶段 - @prop({ required: true, default: 0 }) - fire: number; // 觉醒, 彩星 - @prop({ required: true, default: 0 }) - fireStage: number; // 觉醒六维阶段 - - @prop({ required: true, default: 0 }) - quality: number; // 品质 + @prop({ required: true, default: 1 }) + star: number; // 星级 + @prop({ required: true, default: 0 }) + starStage: number; // 星级六维阶段 + @prop({ required: true, default: 0 }) + fire: number; // 觉醒, 彩星 + @prop({ required: true, default: 0 }) + fireStage: number; // 觉醒六维阶段 + + @prop({ required: true, default: 0 }) + quality: number; // 品质 - @prop({ required: true, default: 0 }) - job: number; // 职业 - @prop({ required: true, default: 0 }) - jobStage: number; // 职阶 + @prop({ required: true, default: 0 }) + job: number; // 职业 + @prop({ required: true, default: 0 }) + jobStage: number; // 职阶 - @prop({ required: true, default: 0 }) - favour: number; // 好感度 - @prop({ required: true, default: 1 }) - favourLv: number; // 好感等级 - @prop({ required: true, default: [] }) - conections: [{ // 羁绊 - id: number; // 羁绊编号 - name: string; // 羁绊名称 - valid: boolean; // 是否开启 - }]; - @prop({ required: true, default: [] }) - skins: [{ // 皮肤 - id: number; // id - enable: boolean; // 是否装备 - }] + @prop({ required: true, default: 0 }) + favour: number; // 好感度 + @prop({ required: true, default: 1 }) + favourLv: number; // 好感等级 + @prop({ required: true, default: [] }) + conections: [{ // 羁绊 + id: number; // 羁绊编号 + name: string; // 羁绊名称 + valid: boolean; // 是否开启 + }]; + @prop({ required: true, default: [] }) + skins: [{ // 皮肤 + id: number; // id + enable: boolean; // 是否装备 + }] - @prop({ ref: Equip, type: mongoose.Schema.Types.ObjectId }) - equips: Ref[]; // 武将装备引用数组 + @prop({ ref: Equip, type: mongoose.Schema.Types.ObjectId }) + equips: Ref[]; // 武将装备引用数组 - public static async findByRole(roleId: string, lean = true) { - const heros = await HeroModel.find({ roleId }).populate('equips').lean(lean); - return heros || []; - } - - public static async findBySeqIdRange(seqIds: Array, roleId: string, lean = true) { - const hero = await HeroModel.find({ seqId: {$in: seqIds}, roleId }).lean(lean); - return hero; - } - public static async findBySeqIdAndRole(seqId: number, roleId: string, lean = true) { - const hero = await HeroModel.findOne({ seqId, roleId }).lean(lean); - return hero; - } - public static async findByHidAndRole(hid: number, roleId: string, lean = true) { - const hero = await HeroModel.findOne({ hid, roleId }).lean(lean); - return hero; - } - - public static async addEquip(roleId: string, hid: number, equipId: string, lean = true) { - const hero = await HeroModel.findOneAndUpdate({ roleId, hid }, {$push: {equips: equipId}}, {new: true}).lean(lean); - if (hero) { - await Equip.putOn(hero.hid, equipId); - await updateCe(roleId, hero ) + public static async findByRole(roleId: string, lean = true) { + const heros = await HeroModel.find({ roleId }).populate('equips').lean(lean); + return heros || []; } - return hero; - } - public static async createHero(heroInfo: {roleId: string, roleName: string, hid: number, star: number, hName: string, seqId: number, lv?:number, ce: number}, lean = true) { - const doc = new HeroModel(); - const update = Object.assign(doc.toJSON(), heroInfo); - delete update._id; - const hero = await HeroModel.findOneAndUpdate({roleId: heroInfo.roleId, hid: heroInfo.hid}, update, {upsert: true, new: true}).lean(lean); - await updateCe(heroInfo.roleId, hero); - return hero; - } + public static async findBySeqIdRange(seqIds: Array, roleId: string, lean = true) { + const hero = await HeroModel.find({ seqId: {$in: seqIds}, roleId }).lean(lean); + return hero; + } + public static async findBySeqIdAndRole(seqId: number, roleId: string, lean = true) { + const hero = await HeroModel.findOne({ seqId, roleId }).lean(lean); + return hero; + } + public static async findByHidAndRole(hid: number, roleId: string, lean = true) { + const hero = await HeroModel.findOne({ hid, roleId }).lean(lean); + return hero; + } - public static async sumTopHeroCe(roleId: string, num: number) { - let ce = await HeroModel.aggregate([ - { $match : { roleId } }, - { $sort: {historyCe: -1} }, - { $limit: num }, - { $group: { _id: null, historyCe: { $sum: '$historyCe' } } } - ]); - return ce.length > 0?ce[0].historyCe:0; - } + public static async addEquip(roleId: string, hid: number, equipId: string, lean = true) { + const hero = await HeroModel.findOneAndUpdate({ roleId, hid }, {$push: {equips: equipId}}, {new: true}).lean(lean); + if (hero) { + await Equip.putOn(hero.hid, equipId); + await updateCe(roleId, hero ) + } + return hero; + } - public static async sumHeroCe(roleId: string) { - let ce = await HeroModel.aggregate([ - { $match : { roleId } }, - { $group: { _id: null, ce: { $sum: '$ce' } } } - ]); - return ce.length > 0?ce[0].ce:0; - } + public static async createHero(heroInfo: {roleId: string, roleName: string, hid: number, star: number, hName: string, seqId: number, lv?:number, ce: number}, lean = true) { + const doc = new HeroModel(); + const update = Object.assign(doc.toJSON(), heroInfo); + delete update._id; + const hero = await HeroModel.findOneAndUpdate({roleId: heroInfo.roleId, hid: heroInfo.hid}, update, {upsert: true, new: true}).lean(lean); + await updateCe(heroInfo.roleId, hero); + return hero; + } - public static async getTopHero(roleId: string, num: number, lean = true) { - const heroes = await HeroModel.find({roleId}).limit(num).sort({ce: -1}).lean(lean); - return heroes; - } + public static async sumTopHeroCe(roleId: string, num: number) { + let ce = await HeroModel.aggregate([ + { $match : { roleId } }, + { $sort: {historyCe: -1} }, + { $limit: num }, + { $group: { _id: null, historyCe: { $sum: '$historyCe' } } } + ]); + return ce.length > 0?ce[0].historyCe:0; + } - public static async updateCe(roleId: string, hid: number, ce: number, oldCe: number, historyCe: number, lean = true) { - let distance = ce - oldCe; - let historyDistance = ce > historyCe ?ce - historyCe: 0; - let result = await HeroModel.findOneAndUpdate({roleId, hid}, {$inc:{ce: distance, historyCe: historyDistance}}).lean(lean); - return result||{}; - } + public static async sumHeroCe(roleId: string) { + let ce = await HeroModel.aggregate([ + { $match : { roleId } }, + { $group: { _id: null, ce: { $sum: '$ce' } } } + ]); + return ce.length > 0?ce[0].ce:0; + } - public static async deleteAccount(roleId: string, lean = true) { - let result = await HeroModel.deleteMany({roleId}).lean(lean); - return result||{}; - } + public static async getTopHero(roleId: string, num: number, lean = true) { + const heroes = await HeroModel.find({roleId}).limit(num).sort({ce: -1}).lean(lean); + return heroes; + } + + public static async updateCe(roleId: string, hid: number, ce: number, oldCe: number, historyCe: number, lean = true) { + let distance = ce - oldCe; + let historyDistance = ce > historyCe ?ce - historyCe: 0; + let result = await HeroModel.findOneAndUpdate({roleId, hid}, {$inc:{ce: distance, historyCe: historyDistance}}).lean(lean); + return result||{}; + } + + public static async deleteAccount(roleId: string, lean = true) { + let result = await HeroModel.deleteMany({roleId}).lean(lean); + return result||{}; + } + + public static async updateHeroInfo(roleId: string, hid:number, heroUpdate:heroUpdate, lean = true) { + delete heroUpdate._id; + let result = await HeroModel.findOneAndUpdate({roleId, hid}, {$set:heroUpdate}).lean(lean); + return result||{}; + } } export const HeroModel = getModelForClass(Hero); + \ No newline at end of file diff --git a/shared/db/Role.ts b/shared/db/Role.ts index e5f882a73..88daf74cd 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -4,7 +4,10 @@ import { index, getModelForClass, prop } from '@typegoose/typegoose'; import User from './User'; import { shouldRefresh } from '../pubUtils/util'; import { HeroModel } from './Hero'; - +interface roleUpdate { + ce?: number; + _id?:number; +} class TopHero { @prop({ required: true }) hid: number; // 武将id @@ -28,358 +31,364 @@ class DungeonHero { // @index({ userInfo.uid: 1, serverId: 1 }) export default class Role extends BaseModel { - @prop({ required: true }) - userInfo: User; + @prop({ required: true }) + userInfo: User; - @prop({ required: true }) - seqId: number; + @prop({ required: true }) + seqId: number; - @prop({ required: true }) - roleId: string; // 角色 id,生成编码 - @prop({ required: true }) - roleName: string; // 角色名 - @prop({ required: true }) - serverType: string; // 服务器类型 - @prop({ required: true }) - serverId: number; // 区服 id - @prop({ required: true, default: false }) - blocked: boolean; // 是否屏蔽 - @prop({ required: true }) - code: string; // 邀请码 - @prop({ required: true, default: 19 }) - headHid: number; // 头像所用武将 Id,默认赵云 - @prop({ required: true, default: 19 }) - sHid: number; // 形象所用武将 Id,默认赵云 + @prop({ required: true }) + roleId: string; // 角色 id,生成编码 + @prop({ required: true }) + roleName: string; // 角色名 + @prop({ required: true }) + serverType: string; // 服务器类型 + @prop({ required: true }) + serverId: number; // 区服 id + @prop({ required: true, default: false }) + blocked: boolean; // 是否屏蔽 + @prop({ required: true }) + code: string; // 邀请码 + @prop({ required: true, default: 19 }) + headHid: number; // 头像所用武将 Id,默认赵云 + @prop({ required: true, default: 19 }) + sHid: number; // 形象所用武将 Id,默认赵云 - @prop({ required: true, default: 0 }) - exp: number; // 经验值 - @prop({ required: true, default: 1 }) - lv: number; // 主公等级 - @prop({ required: true, default: 0 }) - ce: number; // 总战力 - @prop({ required: true, default: 0 }) - topFiveCe: number; // 最强5人战力 - @prop({ required: true, type: TopHero, default: [] }) - topFive: Array; // 总战力 - @prop({ required: true, default: 100 }) - tili: number; // 体力值 + @prop({ required: true, default: 0 }) + exp: number; // 经验值 + @prop({ required: true, default: 1 }) + lv: number; // 主公等级 + @prop({ required: true, default: 0 }) + ce: number; // 总战力 + @prop({ required: true, default: 0 }) + topFiveCe: number; // 最强5人战力 + @prop({ required: true, type: TopHero, default: [] }) + topFive: Array; // 总战力 + @prop({ required: true, default: 100 }) + tili: number; // 体力值 - @prop({ required: true, default: 0 }) - vLv: number; // VIP 等级 - @prop({ required: true, default: 100 }) - gold: number; // 总金币 - @prop({ required: true, default: 0 }) - paidGold: number; // 支付所得金币 - @prop({ required: true, default: 100 }) - giftGold: number; // 赠送所得金币 - @prop({ required: true, default: 0 }) - totalPay: number; // 总支付金额 - @prop({ required: true, default: 0 }) - totalBuy: number; // 总金币购买 - @prop({ required: true, default: 0 }) - totalCost: number; // 金币总花费 - @prop({ required: true, default: [] }) - payRecord: [{ // 支付记录 - id: string; // 购买项 product id - cnt: number; // 购买次数 - }]; + @prop({ required: true, default: 0 }) + vLv: number; // VIP 等级 + @prop({ required: true, default: 100 }) + gold: number; // 总金币 + @prop({ required: true, default: 0 }) + paidGold: number; // 支付所得金币 + @prop({ required: true, default: 100 }) + giftGold: number; // 赠送所得金币 + @prop({ required: true, default: 0 }) + totalPay: number; // 总支付金额 + @prop({ required: true, default: 0 }) + totalBuy: number; // 总金币购买 + @prop({ required: true, default: 0 }) + totalCost: number; // 金币总花费 + @prop({ required: true, default: [] }) + payRecord: [{ // 支付记录 + id: string; // 购买项 product id + cnt: number; // 购买次数 + }]; - @prop({ required: true, default: 0 }) - coin: number; // 总铜钱 - @prop({ required: true, default: 0 }) - frdCnt: number; // 情谊点 + @prop({ required: true, default: 0 }) + coin: number; // 总铜钱 + @prop({ required: true, default: 0 }) + frdCnt: number; // 情谊点 - @prop({ required: true, default: [] }) - souls: [{ // 将魂 - id: number; // 武将 id - count: number; // 数量 - }]; - @prop({ required: true, default: [] }) - pieces: [{ // 装备碎片 - id: number; // 装备 id - count: number; // 数量 - }]; - @prop({ required: true, default: [] }) - jewels: [{ // 珠宝 - id: number; // 待定,也可能是 type + lv - count: number; // 数量 - }]; + @prop({ required: true, default: [] }) + souls: [{ // 将魂 + id: number; // 武将 id + count: number; // 数量 + }]; + @prop({ required: true, default: [] }) + pieces: [{ // 装备碎片 + id: number; // 装备 id + count: number; // 数量 + }]; + @prop({ required: true, default: [] }) + jewels: [{ // 珠宝 + id: number; // 待定,也可能是 type + lv + count: number; // 数量 + }]; - @prop({ required: true, default: [] }) - warStar: [{ // 关卡星级 - id: number; // 关卡 id - warType: number; // 关卡类型 - star: number; // 星级 - }]; + @prop({ required: true, default: [] }) + warStar: [{ // 关卡星级 + id: number; // 关卡 id + warType: number; // 关卡类型 + star: number; // 星级 + }]; - @prop({ required: true, default: 1 }) - loginCnt: number; // 登录次数 - @prop({ required: true }) - createTime: Date; // 创建时间 - @prop({ required: true }) - loginTime: Date; // 更新 / 登录时间 + @prop({ required: true, default: 1 }) + loginCnt: number; // 登录次数 + @prop({ required: true }) + createTime: Date; // 创建时间 + @prop({ required: true }) + loginTime: Date; // 更新 / 登录时间 - @prop({ required: true, type: Number, default: [] }) - funcs: Array; // 开启了的功能 + @prop({ required: true, type: Number, default: [] }) + funcs: Array; // 开启了的功能 - // 天梯相关 - @prop({ required: true, default: 1 }) - towerLv: number; // 天梯当前层数 - @prop({ required: true, default: new Date() }) - towerUpTime: Date; // 天梯爬到这一层的时间 + // 天梯相关 + @prop({ required: true, default: 1 }) + towerLv: number; // 天梯当前层数 + @prop({ required: true, default: new Date() }) + towerUpTime: Date; // 天梯爬到这一层的时间 - @prop({ required: true, default: HANG_UP_CONSTS.MAX_SPD_UP_CNT}) - hangUpSpdUpCnt: number; // 挂机加速次数 - @prop({ required: true, default: new Date()}) - lastSpdUpTime: Date; // 最后一次挂机加速时间 + @prop({ required: true, default: HANG_UP_CONSTS.MAX_SPD_UP_CNT}) + hangUpSpdUpCnt: number; // 挂机加速次数 + @prop({ required: true, default: new Date()}) + lastSpdUpTime: Date; // 最后一次挂机加速时间 - @prop({ required: true, default: 0}) - towerTaskCnt: number; // 刷新派遣任务的次数,向上累加,每天8个 - @prop({ required: false}) - towerTaskRefTime: Date; // 刷新派遣任务的时间 - @prop({ required: true, default: 0}) - towerTaskReCnt: number; // 刷新派遣任务刷新次数 + @prop({ required: true, default: 0}) + towerTaskCnt: number; // 刷新派遣任务的次数,向上累加,每天8个 + @prop({ required: false}) + towerTaskRefTime: Date; // 刷新派遣任务的时间 + @prop({ required: true, default: 0}) + towerTaskReCnt: number; // 刷新派遣任务刷新次数 - // 奇遇事件相关 - @prop({ required: true, default: 0 }) - eventStatus: number; // 奇遇开启状态, 0-未开启 1-开启了第一场事件 2-完全开启 + // 奇遇事件相关 + @prop({ required: true, default: 0 }) + eventStatus: number; // 奇遇开启状态, 0-未开启 1-开启了第一场事件 2-完全开启 - // 远征相关 - @prop({ required: true, default: 0 }) - expeditionPoint: number; // 远征点数 - @prop({ required: true, default: 0 }) - expeditionResetCnt: number; // 远征重置次数 - @prop({ required: true, default: new Date() }) - expeditionResetRefTime: Date; // 远征重置次数刷新时间 + // 远征相关 + @prop({ required: true, default: 0 }) + expeditionPoint: number; // 远征点数 + @prop({ required: true, default: 0 }) + expeditionResetCnt: number; // 远征重置次数 + @prop({ required: true, default: new Date() }) + expeditionResetRefTime: Date; // 远征重置次数刷新时间 - // 秘境相关 - @prop({ required: true, default: 0 }) - dungeonCnt: number; // 秘境挑战次数 - @prop({ required: true, default: 0 }) - dungeonBuyCnt: number; // 秘境购买次数 - @prop({ required: true, default: new Date() }) - dungeonRefTime: Date; // 秘境刷新时间 - @prop({ required: true, type: DungeonHero, default: [] }) - dungeonHeroes: Array; // 秘境首通使用的武将 - - public static async findByUid(uid: number, serverId: number, lean = true) { - const role = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); - return role; - } - - public static async findByRoleId(roleId: string, lean = true) { - const role = await RoleModel.findOne({ roleId }).lean(lean); - return role; - } - - public static async createRole(uid: number, serverId: number, roleInfo: {roleId: string; roleName: string; seqId: number; code: string}, lean = true) { - const user = await User.findUserByUid(uid); - if (!user) return null; - const doc = new RoleModel(); - const update = Object.assign(doc.toJSON(), roleInfo, { userInfo: user, serverType: user.serverType, serverId }); - const role = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, update, { upsert: true, new: true }).lean(lean); - return role; - } - - public static async findRoleByField(field: string, value?: Array, lean = true) { - let searchObj = {}; - if(field != 'all') { - searchObj[field] = { - $in: value - }; - } - //.select('uid tel username') - const user = await RoleModel.find(searchObj).lean(lean); - return user; - } - - - public static async setEventStatus(roleId: string, eventStatus: number, lean = true) { - await RoleModel.findOneAndUpdate({ roleId }, { eventStatus }, {new: true}).lean(lean); - } - - public static async towerLvUp(roleId: string, lean = true) { - let role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerLv: 1}, towerUpTime: new Date()}, {new: true}).lean(lean); - return role; - } - - public static async hangUpSpdUp(roleId: string, cnt: number, curTime: Date, lean = true) { - if (cnt < 0) return null; - - const result = await RoleModel.findOne({roleId}).lean(lean); - const lastSpdUpTime = result?.lastSpdUpTime; - let role = null; - if (!lastSpdUpTime || (shouldRefresh(lastSpdUpTime, curTime, HANG_UP_CONSTS.REFRESH_TIME, 1) && cnt <= HANG_UP_CONSTS.MAX_SPD_UP_CNT)) { - role = await RoleModel.findOneAndUpdate({roleId}, {hangUpSpdUpCnt: HANG_UP_CONSTS.MAX_SPD_UP_CNT - cnt, lastSpdUpTime: curTime}, {new: true}).lean(lean); - } else { - role = await RoleModel.findOneAndUpdate({roleId, hangUpSpdUpCnt: {$gte: cnt}}, {$inc: {hangUpSpdUpCnt: -cnt}, lastSpdUpTime: curTime}, {new: true}).lean(lean); - } - return role; - } - - public static async increaseExpeditionPoint(roleId: string, point: number, lean = true) { - let role = await RoleModel.findOneAndUpdate({roleId}, {$inc: { expeditionPoint: point }}, {new: true}).lean(lean); - return role; - } - - public static async levelup(roleId: string, lv: number, exp: number, lean = true) { - let role = await RoleModel.findOneAndUpdate({roleId}, {$set: { exp, lv }}, {new: true}).lean(lean); - return role; - } - - public static async deleteAccount(roleId: string, lean = true) { - let result = await RoleModel.deleteMany({roleId}).lean(lean); - return result||{}; - } + // 秘境相关 + @prop({ required: true, default: 0 }) + dungeonCnt: number; // 秘境挑战次数 + @prop({ required: true, default: 0 }) + dungeonBuyCnt: number; // 秘境购买次数 + @prop({ required: true, default: new Date() }) + dungeonRefTime: Date; // 秘境刷新时间 + @prop({ required: true, type: DungeonHero, default: [] }) + dungeonHeroes: Array; // 秘境首通使用的武将 - public static async addCoin(roleId: string, cnt: number, lean = true) { - let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: {coin: cnt} }, { "new": true, "upsert": true}).lean(lean); - return result; - } - - public static async addGoldFree(roleId: string, cnt: number, lean = true) { - let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: { gold: cnt, giftGold: cnt } }, { "new": true, "upsert": true}).lean(lean); - return result; - } - - public static async costCoin(roleId: string, cnt: number, lean = true) { - let result = await RoleModel.findOneAndUpdate({roleId, coin: {$gte: cnt}}, { $inc: { coin: -cnt } }, { "new": true}).lean(lean); - return result; - } - - public static async costGold(roleId: string, cnt: number, lean = true) { - let result = await RoleModel.findOneAndUpdate({roleId, gold: {$gte: cnt}}, { $inc: { gold: -cnt, totalCost: cnt } }, { "new": true}).lean(lean); - return result; - } - - public static async pushWarStar(roleId: string, battleId: number, warType: number, star: number, lean = true) { - let result = await RoleModel.findOneAndUpdate({roleId}, { $addToSet: { warStar: {id: battleId, warType, star }} }, { "new": true, "upsert": true}).lean(lean); - return result; - } - - public static async updateWarStar(roleId: string, battleId: number, star: number, lean = true) { - let result = await RoleModel.findOneAndUpdate( - {roleId, 'warStar.id': battleId}, - { $set: { 'warStar.$.star': star } }, - { "new": true, "upsert": true} - ).lean(lean); - return result; - } - - // 重置派遣次数 - public static async resetTowerCnt(roleId: string, curTime: Date, lean = true) { - const role = await RoleModel.findOneAndUpdate({roleId}, {towerTaskCnt: 0, towerTaskRefTime: curTime, towerTaskReCnt: 0}, {new: true}).lean(lean); - return role; - } - // 刷新派遣任务次数增长 - public static async increaseTowerCnt(roleId: string, num: number, lean = true) { - const role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerTaskCnt: num}}, {new: true}).lean(lean); - return role; - } - // 派遣任务增加刷新次数 - public static async increaseTowerRefCnt(roleId: string, num: number, lean = true) { - const role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerTaskReCnt: num}}, {new: true}).lean(lean); - return role; - } - - // 刷新远征重置次数 - public static async increaseExpeditionResetCnt(roleId: string, needRefresh: boolean, curTime: Date, lean = true) { - - let role = null; - if (needRefresh) { - role = await RoleModel.findOneAndUpdate({roleId}, {expeditionResetCnt: 1, expeditionResetRefTime: curTime}, {new: true}).lean(lean); - } else { - role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {expeditionResetCnt: 1}}, {new: true}).lean(lean); + public static async findByUid(uid: number, serverId: number, lean = true) { + const role = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); + return role; } - return role; - } - - // 购买次数 - public static async buyCnt(roleId: string, needRefresh: boolean, inc: number, curTime: Date, lean = true) { console.log('&*&*&*&*&') - - let role = null; - if (needRefresh) { - role = await RoleModel.findOneAndUpdate({roleId}, {dungeonCnt: 0, dungeonRefTime: curTime, dungeonBuyCnt: inc}, {new: true}).lean(lean); - } else { - role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {dungeonBuyCnt: inc}}, {new: true}).lean(lean); + public static async findByRoleId(roleId: string, lean = true) { + const role = await RoleModel.findOne({ roleId }).lean(lean); + return role; } - return role; - } - // 增加次数 - public static async increaseDungeonCnt(roleId: string, needRefresh: boolean, inc: number, curTime: Date, lean = true) { - let role = null; - if (needRefresh) { - role = await RoleModel.findOneAndUpdate({roleId}, {dungeonCnt: inc, dungeonRefTime: curTime, dungeonBuyCnt: 0}, {new: true}).lean(lean); - } else { - role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {dungeonCnt: inc}}, {new: true}).lean(lean); + public static async createRole(uid: number, serverId: number, roleInfo: {roleId: string; roleName: string; seqId: number; code: string}, lean = true) { + const user = await User.findUserByUid(uid); + if (!user) return null; + const doc = new RoleModel(); + const update = Object.assign(doc.toJSON(), roleInfo, { userInfo: user, serverType: user.serverType, serverId }); + const role = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, update, { upsert: true, new: true }).lean(lean); + return role; } - return role; - } - // 获取排行榜 - public static async getRank(type: string, serverId: number, fields: Array, page = 1, limit = 100, lean = true) { - let sortBy = {}; - if(type == 'tower') { - sortBy['towerLv'] = -1; - sortBy['towerUpTime'] = 1; - } - const ranks = await RoleModel.find({serverId}).select(fields.join(' ')).sort(sortBy).limit(limit).skip((page - 1) * limit).lean(lean); - return ranks; - } - - public static async updateSumCe(roleId: string, hid: number, ce: number, oldCe: number, lean = true) { - - let role = await RoleModel.findByRoleId(roleId); - let topFive = role?.topFive||new Array(); - let distance = ce - oldCe; - - topFive.sort((a, b) => {return b.ce - a.ce}); // 0-5,最大-最小 - let index = topFive.findIndex(cur => cur.hid == hid); - if(index == -1) { // 不在最强列表 - if(topFive.length < 5) { // 不满5人 - topFive.push({hid, ce}); - } else if(topFive.length == 5){ - if(ce > topFive[topFive.length - 1].ce) { // 跻身最强5人 - topFive.pop(); - topFive.push({hid, ce}); + public static async findRoleByField(field: string, value?: Array, lean = true) { + let searchObj = {}; + if(field != 'all') { + searchObj[field] = { + $in: value + }; } - } else { - topFive.splice(5, topFive.length - 5); - } - } else { // 原来就是最强5人 - if(ce < topFive[topFive.length - 1].ce) { // 滑出最强 - let heroes = await HeroModel.getTopHero(roleId, 5); - topFive = heroes.map(cur => {return {hid: cur.hid, ce: cur.ce}}); - } else { - topFive[index].ce = ce; - } + //.select('uid tel username') + const user = await RoleModel.find(searchObj).lean(lean); + return user; } - - let topFiveCe = topFive.reduce((pre, cur) => { - return pre + cur.ce - }, 0); - await RoleModel.findOneAndUpdate({roleId}, { topFive, topFiveCe, $inc: {ce: distance} }).lean(lean); - } - // 保存秘境首通队伍 - public static async saveDungeonHero(roleId: string, battleId: number, heroes: Array, isSuccess: boolean) { - if(isSuccess) { - const role = await Role.findByRoleId(roleId); - let dungeonHeroes = role && role.dungeonHeroes; - let hasHero = dungeonHeroes&&dungeonHeroes.find(cur => cur.battleId == battleId); - if(!dungeonHeroes || !hasHero) { - await RoleModel.findOneAndUpdate({roleId}, {$push:{dungeonHeroes: {battleId, heroes}}}) - } + + public static async setEventStatus(roleId: string, eventStatus: number, lean = true) { + await RoleModel.findOneAndUpdate({ roleId }, { eventStatus }, {new: true}).lean(lean); + } + + public static async towerLvUp(roleId: string, lean = true) { + let role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerLv: 1}, towerUpTime: new Date()}, {new: true}).lean(lean); + return role; } - } - // 保存开启功能 - public static async pushFuncs(roleId: string, funcs: Array, lean = true) { - const recs = await RoleModel.findOneAndUpdate({roleId}, {$push: {funcs: {$each: funcs}}}, {new: true}).lean(lean); - return recs - } + public static async hangUpSpdUp(roleId: string, cnt: number, curTime: Date, lean = true) { + if (cnt < 0) return null; + + const result = await RoleModel.findOne({roleId}).lean(lean); + const lastSpdUpTime = result?.lastSpdUpTime; + let role = null; + if (!lastSpdUpTime || (shouldRefresh(lastSpdUpTime, curTime, HANG_UP_CONSTS.REFRESH_TIME, 1) && cnt <= HANG_UP_CONSTS.MAX_SPD_UP_CNT)) { + role = await RoleModel.findOneAndUpdate({roleId}, {hangUpSpdUpCnt: HANG_UP_CONSTS.MAX_SPD_UP_CNT - cnt, lastSpdUpTime: curTime}, {new: true}).lean(lean); + } else { + role = await RoleModel.findOneAndUpdate({roleId, hangUpSpdUpCnt: {$gte: cnt}}, {$inc: {hangUpSpdUpCnt: -cnt}, lastSpdUpTime: curTime}, {new: true}).lean(lean); + } + return role; + } + + public static async increaseExpeditionPoint(roleId: string, point: number, lean = true) { + let role = await RoleModel.findOneAndUpdate({roleId}, {$inc: { expeditionPoint: point }}, {new: true}).lean(lean); + return role; + } + + public static async levelup(roleId: string, lv: number, exp: number, lean = true) { + let role = await RoleModel.findOneAndUpdate({roleId}, {$set: { exp, lv }}, {new: true}).lean(lean); + return role; + } + + public static async deleteAccount(roleId: string, lean = true) { + let result = await RoleModel.deleteMany({roleId}).lean(lean); + return result||{}; + } + + public static async addCoin(roleId: string, cnt: number, lean = true) { + let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: {coin: cnt} }, { "new": true, "upsert": true}).lean(lean); + return result; + } + + public static async addGoldFree(roleId: string, cnt: number, lean = true) { + let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: { gold: cnt, giftGold: cnt } }, { "new": true, "upsert": true}).lean(lean); + return result; + } + + public static async costCoin(roleId: string, cnt: number, lean = true) { + let result = await RoleModel.findOneAndUpdate({roleId, coin: {$gte: cnt}}, { $inc: { coin: -cnt } }, { "new": true}).lean(lean); + return result; + } + + public static async costGold(roleId: string, cnt: number, lean = true) { + let result = await RoleModel.findOneAndUpdate({roleId, gold: {$gte: cnt}}, { $inc: { gold: -cnt, totalCost: cnt } }, { "new": true}).lean(lean); + return result; + } + + public static async pushWarStar(roleId: string, battleId: number, warType: number, star: number, lean = true) { + let result = await RoleModel.findOneAndUpdate({roleId}, { $addToSet: { warStar: {id: battleId, warType, star }} }, { "new": true, "upsert": true}).lean(lean); + return result; + } + + public static async updateWarStar(roleId: string, battleId: number, star: number, lean = true) { + let result = await RoleModel.findOneAndUpdate( + {roleId, 'warStar.id': battleId}, + { $set: { 'warStar.$.star': star } }, + { "new": true, "upsert": true} + ).lean(lean); + return result; + } + + // 重置派遣次数 + public static async resetTowerCnt(roleId: string, curTime: Date, lean = true) { + const role = await RoleModel.findOneAndUpdate({roleId}, {towerTaskCnt: 0, towerTaskRefTime: curTime, towerTaskReCnt: 0}, {new: true}).lean(lean); + return role; + } + // 刷新派遣任务次数增长 + public static async increaseTowerCnt(roleId: string, num: number, lean = true) { + const role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerTaskCnt: num}}, {new: true}).lean(lean); + return role; + } + // 派遣任务增加刷新次数 + public static async increaseTowerRefCnt(roleId: string, num: number, lean = true) { + const role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerTaskReCnt: num}}, {new: true}).lean(lean); + return role; + } + + // 刷新远征重置次数 + public static async increaseExpeditionResetCnt(roleId: string, needRefresh: boolean, curTime: Date, lean = true) { + + let role = null; + if (needRefresh) { + role = await RoleModel.findOneAndUpdate({roleId}, {expeditionResetCnt: 1, expeditionResetRefTime: curTime}, {new: true}).lean(lean); + } else { + role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {expeditionResetCnt: 1}}, {new: true}).lean(lean); + } + return role; + } + + + // 购买次数 + public static async buyCnt(roleId: string, needRefresh: boolean, inc: number, curTime: Date, lean = true) { console.log('&*&*&*&*&') + + let role = null; + if (needRefresh) { + role = await RoleModel.findOneAndUpdate({roleId}, {dungeonCnt: 0, dungeonRefTime: curTime, dungeonBuyCnt: inc}, {new: true}).lean(lean); + } else { + role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {dungeonBuyCnt: inc}}, {new: true}).lean(lean); + } + return role; + } + + // 增加次数 + public static async increaseDungeonCnt(roleId: string, needRefresh: boolean, inc: number, curTime: Date, lean = true) { + let role = null; + if (needRefresh) { + role = await RoleModel.findOneAndUpdate({roleId}, {dungeonCnt: inc, dungeonRefTime: curTime, dungeonBuyCnt: 0}, {new: true}).lean(lean); + } else { + role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {dungeonCnt: inc}}, {new: true}).lean(lean); + } + return role; + } + + // 获取排行榜 + public static async getRank(type: string, serverId: number, fields: Array, page = 1, limit = 100, lean = true) { + let sortBy = {}; + if(type == 'tower') { + sortBy['towerLv'] = -1; + sortBy['towerUpTime'] = 1; + } + const ranks = await RoleModel.find({serverId}).select(fields.join(' ')).sort(sortBy).limit(limit).skip((page - 1) * limit).lean(lean); + return ranks; + } + + public static async updateSumCe(roleId: string, hid: number, ce: number, oldCe: number, lean = true) { + + let role = await RoleModel.findByRoleId(roleId); + let topFive = role?.topFive||new Array(); + let distance = ce - oldCe; + + topFive.sort((a, b) => {return b.ce - a.ce}); // 0-5,最大-最小 + let index = topFive.findIndex(cur => cur.hid == hid); + if(index == -1) { // 不在最强列表 + if(topFive.length < 5) { // 不满5人 + topFive.push({hid, ce}); + } else if(topFive.length == 5){ + if(ce > topFive[topFive.length - 1].ce) { // 跻身最强5人 + topFive.pop(); + topFive.push({hid, ce}); + } + } else { + topFive.splice(5, topFive.length - 5); + } + } else { // 原来就是最强5人 + if(ce < topFive[topFive.length - 1].ce) { // 滑出最强 + let heroes = await HeroModel.getTopHero(roleId, 5); + topFive = heroes.map(cur => {return {hid: cur.hid, ce: cur.ce}}); + } else { + topFive[index].ce = ce; + } + } + + let topFiveCe = topFive.reduce((pre, cur) => { + return pre + cur.ce + }, 0); + await RoleModel.findOneAndUpdate({roleId}, { topFive, topFiveCe, $inc: {ce: distance} }).lean(lean); + } + + // 保存秘境首通队伍 + public static async saveDungeonHero(roleId: string, battleId: number, heroes: Array, isSuccess: boolean) { + if(isSuccess) { + const role = await Role.findByRoleId(roleId); + let dungeonHeroes = role && role.dungeonHeroes; + let hasHero = dungeonHeroes&&dungeonHeroes.find(cur => cur.battleId == battleId); + if(!dungeonHeroes || !hasHero) { + await RoleModel.findOneAndUpdate({roleId}, {$push:{dungeonHeroes: {battleId, heroes}}}) + } + } + } + + // 保存开启功能 + public static async pushFuncs(roleId: string, funcs: Array, lean = true) { + const recs = await RoleModel.findOneAndUpdate({roleId}, {$push: {funcs: {$each: funcs}}}, {new: true}).lean(lean); + return recs + } + + public static async updateRoleInfo(roleId: string, roleUpdate:roleUpdate, lean = true) { + delete roleUpdate._id; + let result = await HeroModel.findOneAndUpdate({roleId}, {$set:roleUpdate}).lean(lean); + return result||{}; + } } export const RoleModel = getModelForClass(Role); diff --git a/shared/pubUtils/gamedata.ts b/shared/pubUtils/gamedata.ts index 01ab5ab20..6a8b50fab 100644 --- a/shared/pubUtils/gamedata.ts +++ b/shared/pubUtils/gamedata.ts @@ -11,6 +11,7 @@ const towerInfos = new Map(); const towerTaskInfos = new Map(); const heroInfos = new Map(); const jobInfos = new Map(); +const jobClassMaxGrades = new Map(); const levelInfos = new Map(); const starRatioInfo = new Map(); const heroSkillInfo = new Map() @@ -96,6 +97,10 @@ function parseJobData() { jobsData.forEach(elem => { if (elem && elem.jobid) { jobInfos.set(elem.jobid, elem); + let maxLevel = jobClassMaxGrades.get(elem.job_class)||0; + if (maxLevel < elem.grade) { + jobClassMaxGrades.set(elem.job_class, elem.grade); + } } }); } @@ -311,6 +316,10 @@ export function getJobInfoById(jid: number) { const jobInfo = jobInfos.get(jid); return jobInfo; } +export function getMaxGradeByjobClass(jobClass: number) { + const maxGrade = jobClassMaxGrades.get(jobClass); + return maxGrade; +} export function getLvByExp(exp: number) { let curLv = 0;