diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index f281b6c87..4eff0a9c6 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -17,10 +17,12 @@ import { checkBattleHeroesByHid } from '../../../services/normalBattleService'; import { Rank } from '../../../services/rankService'; import { updateUserInfo } from '../../../services/redisService'; import { checkTaskWithHero, checkTask, checkTaskWithArgs, checkActivityTask } from '../../../services/taskService'; -import { getGoldObject, getCoinObject, createHeroesWhenInit } from '../../../pubUtils/itemUtils'; +import { getGoldObject, getCoinObject } from '../../../pubUtils/itemUtils'; import { RScriptRecordModel } from '../../../db/RScriptRecord'; import { checkPvp } from '../../../services/pvpService'; import { SkinModel, SkinUpdate } from '../../../db/Skin'; +import { CreateHeroes } from '../../../pubUtils/roleUtil'; +import { Figure } from '../../../domain/dbGeneral'; export default function (app: Application) { new HandlerService(app, {}); @@ -32,6 +34,7 @@ export class RoleHandler { } async initRole(msg: { roleName: string }, session: BackendSession) { + console.log('******** initRole start', Date.now()); let roleId = session.get('roleId'); let serverId = session.get('serverId'); let sid: string = session.get('sid'); @@ -45,9 +48,14 @@ export class RoleHandler { if (checkName) return resResult(STATUS.NAME_HAS_USED); console.log('****** createHeroes before', Date.now()) - let initInfos: { role: RoleUpdate, heroes: HeroUpdate[], skins: SkinUpdate[]} = await this.app.rpc.role.roleRemote.getInitRoleInfos.toServer(this.app.getServerId()); + let initInfos: { role: RoleUpdate, heroes: HeroUpdate[], skins: SkinUpdate[], figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }} + = await this.app.rpc.role.roleRemote.getInitRoleInfos.toServer(this.app.getServerId()); role = await RoleModel.updateRoleInfo(roleId, {...initInfos.role, roleName, hasInit: true}); - let { heroes } = await createHeroesWhenInit(roleId, roleName, serverId, initInfos.heroes, initInfos.skins); + let createHero = new CreateHeroes(roleId, roleName, serverId, funcs); + await createHero.createWithInitInfo(initInfos.heroes, initInfos.skins, initInfos.figureInfo); + await createHero.pushMessage(pinus, sid); + await createHero.updateRedisRank(Rank); + let heroes = createHero.getResultHeroes(); console.log('****** createHeroes after', Date.now()) session.set('roleName', roleName); diff --git a/game-server/app/servers/role/remote/roleRemote.ts b/game-server/app/servers/role/remote/roleRemote.ts index 517e9c8cd..25d2ff33b 100644 --- a/game-server/app/servers/role/remote/roleRemote.ts +++ b/game-server/app/servers/role/remote/roleRemote.ts @@ -6,6 +6,7 @@ import { RoleUpdate } from '../../../db/Role'; import { SkinUpdate } from '../../../db/Skin'; import { getInitRoleInfo } from '../../../pubUtils/roleUtil'; import { DEFAULT_HEROES } from '../../../consts'; +import { Figure } from '../../../domain/dbGeneral'; export default function (app: Application) { new HandlerService(app, {}); return new RoleRemote(app); @@ -22,10 +23,11 @@ export class RoleRemote { private initHeroes: Map = new Map(); // hid => hero private initRole: RoleUpdate = {}; private initSkins: Map = new Map(); // hid => skin + private figureInfo: {heads: Figure[], frames: Figure[], spines: Figure[]}; public setInitRole() { let result = getInitRoleInfo(); - let { role, heroes, skins } = result; + let { role, heroes, skins, figureInfo } = result; for(let hero of heroes) { this.initHeroes.set(hero.hid, hero); } @@ -33,13 +35,15 @@ export class RoleRemote { this.initSkins.set(skin.hid, skin); } this.initRole = role; + this.figureInfo = figureInfo; } public getInitRoleInfos() { return { heroes: this.getInitHeroes(), skins: this.getInitSkins(), - role: this.initRole + role: this.initRole, + figureInfo: this.figureInfo }; } @@ -60,7 +64,10 @@ export class RoleRemote { } public getInitHeroById(hid: number) { - return this.initHeroes.get(hid) + return { + heroInfo: this.initHeroes.get(hid), + skinInfo: this.initSkins.get(hid) + } } diff --git a/game-server/app/services/rankService.ts b/game-server/app/services/rankService.ts index 30e9a9af2..77eed673c 100644 --- a/game-server/app/services/rankService.ts +++ b/game-server/app/services/rankService.ts @@ -773,7 +773,6 @@ export class Rank { * @param serverId 分服 */ export async function setRankRedisFromDb(type: string, args?: { serverId?: number }) { - if (type == REDIS_KEY.TOWER_RANK) { let serverId = args.serverId; let ranks = await RoleModel.getRank('tower', serverId, ROLE_SELECT.RANK); diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index 199a452f9..4ea5d1ef9 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -7,11 +7,11 @@ import { pushCalPlayerCe, pushCalAllHeroCe, calPlayerCeAndSave } from './playerC import { ItemModel, ItemType } from '../db/Item'; import { STATUS } from '../consts/statusCode'; import { pinus } from 'pinus'; -import { addEquips, addBags, addSkin, addFigure, unlockFigure as pubUnlockFigure, createHeroes as pubCreateHeroes, transPiece, getGoldObject, getCoinObject, getApObject } from '../pubUtils/itemUtils'; +import { addEquips, addBags, addSkin, addFigure, unlockFigure as pubUnlockFigure, transPiece, getGoldObject, getCoinObject, getApObject } from '../pubUtils/itemUtils'; import { ItemInter, RewardInter, } from '../pubUtils/interface'; import { gameData } from '../pubUtils/data'; import { uniq } from 'underscore'; -import { HeroModel, HeroType } from '../db/Hero'; +import { HeroModel, HeroType, HeroUpdate } from '../db/Hero'; import { Figure } from '../domain/dbGeneral'; import { Rank } from './rankService'; import { checkActivityTask, checkTaskWithHero, pushActivityUpdate, pushTaskUpdate } from './taskService'; @@ -21,6 +21,8 @@ import { errlogger } from '../util/logger'; import { BAG } from '../pubUtils/dicParam'; import { sendMailByContent } from './mailService'; import { calEquipSeids } from '../pubUtils/playerCe'; +import { CreateHeroes } from '../pubUtils/roleUtil'; +import { SkinUpdate } from '../db/Skin'; export class CheckMeterial { private roleId: string; @@ -439,15 +441,15 @@ export async function createHeroes(roleId: string, roleName: string, sid: string let hids = heroInfo.map(cur => cur.hid); let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId); - - let newHeroInfo: CreateHeroParam[] = [], pieces: ItemInter[] = []; + let infos: Map = new Map(), pieces: ItemInter[] = []; for (let h of heroInfo) { let heroCount = h.count || 1; if (userHeroesMap.has(h.hid)) { let { pieceId, count } = transPiece(h.hid); pieces.push({ id: pieceId, count: count * heroCount }); } else { - newHeroInfo.push(h) + let initInfo = await pinus.app.rpc.role.roleRemote.getInitHeroById.toServer(pinus.app.getServerId(), h.hid); + infos.set(h.hid, initInfo); userHeroesMap.set(h.hid, null); if (heroCount > 1) { let { pieceId, count } = transPiece(h.hid); @@ -457,25 +459,12 @@ export async function createHeroes(roleId: string, roleName: string, sid: string } let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = []; - if (newHeroInfo.length > 0) { - - console.log('****** pubCreateHeroes before', Date.now()) - let { heroes, role, figureInfo, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage } = await pubCreateHeroes(roleId, roleName, serverId, newHeroInfo, funcs); - - console.log('****** pubCreateHeroes after', Date.now()) - let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId }); - await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role); - - await pushFigureUpdate(roleId, sid, figureInfo); - - // await pushCalAllHeroCe(roleId, sid, calAllHeroResult); - for (let calHeroResult of calHeroResults) { - await pushCalPlayerCe(roleId, sid, calHeroResult); - } - - pushTaskUpdate(roleId, sid, null, taskPushMessage); - pushActivityUpdate(roleId, sid, null, activityTaskPushMessage); - resultHeroes = heroes; + if (infos.size > 0) { + let createHero = new CreateHeroes(roleId, roleName, serverId, funcs); + await createHero.createWithHeroInfo(infos); + await createHero.pushMessage(pinus, sid); + await createHero.updateRedisRank(Rank); + resultHeroes = createHero.getResultHeroes(); } if (pieces.length > 0) { diff --git a/gm-server/app/service/Utils.ts b/gm-server/app/service/Utils.ts index 588b81fde..b20921e25 100644 --- a/gm-server/app/service/Utils.ts +++ b/gm-server/app/service/Utils.ts @@ -1,11 +1,42 @@ import { Service } from 'egg'; import * as pubUtils from '@pubUtils/util'; +import { HeroUpdate } from '@db/Hero'; +import { SkinUpdate } from '@db/Skin'; +import { getInitRoleInfo } from '@pubUtils/roleUtil'; const csprng = require('csprng'); /** * Utils Service */ export default class Utils extends Service { + + constructor(args) { + super(args); + + this.setInitRole(); + } + + private initHeroes: Map = new Map(); // hid => hero + private initSkins: Map = new Map(); // hid => skin + + public setInitRole() { + let result = getInitRoleInfo(); + let { heroes, skins } = result; + for(let hero of heroes) { + this.initHeroes.set(hero.hid, hero); + } + for(let skin of skins) { + this.initSkins.set(skin.hid, skin); + } + } + + public getInitHeroById(hid: number) { + return { + heroInfo: this.initHeroes.get(hid), + skinInfo: this.initSkins.get(hid) + } + } + /** * 生成 len 长度的随机字符串 * @param len 长度 diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 9db6611f2..559b97355 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -23,7 +23,7 @@ import Counter from '@db/Counter'; import { STATUS, HERO_SYSTEM_TYPE } from '@consts'; import { ITID, COUNTER } from '@consts'; import { ItemModel } from '@db/Item'; -import { gameData, getHeroExpByLv, getExpByLv } from '@pubUtils/data'; +import { gameData, getExpByLv } from '@pubUtils/data'; import { calPlayerCeAndSave, calculatetopLineup, calEquipSeids } from '@pubUtils/playerCe'; import { SchoolModel } from '@db/School'; import { AttributeCal } from '@domain/roleField/attribute'; @@ -32,9 +32,10 @@ import { isString } from 'underscore'; import { FriendShipModel } from '@db/FriendShip'; import { FriendApplyModel } from '@db/FriendApply'; import { FriendRelationModel } from '@db/FriendRelation'; -import { createHero as pubCreateHero, addSkin, addEquips, addBags } from '@pubUtils/itemUtils'; +import { addSkin, addEquips, addBags } from '@pubUtils/itemUtils'; import { GiftCodeModel } from '@db/GiftCode'; import { GiftCodeDetailModel } from '@db/GiftCodeDetail'; +import { CreateHeroes } from '@pubUtils/roleUtil'; // import { resResult } from '@pubUtils/util'; // import * as fs from 'fs'; @@ -240,38 +241,32 @@ export default class GMUsers extends Service { public async createHero(uids: Array, _hid: string, _hlv: string) { const { ctx } = this; - console.log('gm createHero', uids, _hid, _hlv); - let hlv = parseInt(_hlv); - if (isNaN(hlv)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS); - let hids = (_hid as string).split('&').map(cur => parseInt(cur)); - for (let hid of hids) { - if (isNaN(hid)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS); - } - - let heroInfos = new Array(); - for (let roleId of uids) { - let role = await RoleModel.findByRoleId(roleId); - if (role) { - for (let hid of hids) { - let hero = await HeroModel.findByHidAndRole(hid, roleId); - if (hero) continue; - let dicHero = gameData.hero.get(hid); - if (!dicHero) continue; - const heroInfo = { - roleId, roleName: role.roleName, hid, serverId: role.serverId, - lv: hlv, exp: getHeroExpByLv(hlv - 1) || 0 - } - heroInfos.push(heroInfo); - } - } else { - return ctx.service.utils.resResult(STATUS.GM_CREATE_ERROR, null, '未找到角色' + roleId) - } - } - try { - for (let heroInfo of heroInfos) { - await pubCreateHero(heroInfo.roleId, heroInfo.roleName, heroInfo.serverId, heroInfo); + console.log('gm createHero', uids, _hid, _hlv); + let hlv = parseInt(_hlv); + if (isNaN(hlv)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS); + let hids = (_hid as string).split('&').map(cur => parseInt(cur)); + for (let hid of hids) { + if (isNaN(hid)) return ctx.service.utils.resResult(STATUS.WRONG_PARMS); } + + for (let roleId of uids) { + let role = await RoleModel.findByRoleId(roleId); + if (role) { + let heroInfos = new Map(); + for (let hid of hids) { + let heroInfo = ctx.service.utils.getInitHeroById(hid); + heroInfos.set(hid, {...heroInfo}); + } + + let createHero = new CreateHeroes(roleId, role.roleName, role.serverId); + await createHero.createWithHeroInfo(heroInfos); + + } else { + return ctx.service.utils.resResult(STATUS.GM_CREATE_ERROR, null, '未找到角色' + roleId) + } + } + return ctx.service.utils.resResult(STATUS.SUCCESS, { uids }); } catch (e) { console.error(e.stack) diff --git a/shared/db/Role.ts b/shared/db/Role.ts index 6193b6d00..4c2921dfd 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -728,7 +728,7 @@ export const RoleModel = getModelForClass(Role); export interface RoleType extends Pick, keyof Role> { }; export type RoleUpdate = Partial; // 将所有字段变成可选项 -export type RoleInc = Partial, 'heroNum' | 'blockCnt' | 'friendCnt' | 'gold' | 'coin'>>; +export type RoleInc = Partial, 'heroNum' | 'blockCnt' | 'friendCnt' | 'gold' | 'coin' | 'ce'>>; // 初始化 function getInitialTeraph() { diff --git a/shared/db/Skin.ts b/shared/db/Skin.ts index d5663cfaf..a500de023 100644 --- a/shared/db/Skin.ts +++ b/shared/db/Skin.ts @@ -34,7 +34,7 @@ export default class Skin extends BaseModel { const items: SkinType[] = await SkinModel.insertMany(insertInfos); return items; } - + public static async increaseSkin(roleId: string, id: number, info: { roleId: string, roleName: string, id: number, skinName: string, hid: number }, lean = true) { const doc = new SkinModel(); const setOnInsert = Object.assign(doc.toJSON(), info); diff --git a/shared/domain/roleField/calCe.ts b/shared/domain/roleField/calCe.ts index b7e42bb04..9eb206ee0 100644 --- a/shared/domain/roleField/calCe.ts +++ b/shared/domain/roleField/calCe.ts @@ -196,7 +196,7 @@ export class CalHeroCe { } // 添加技能增加的被动属性 -function addSeidEffect(this: CalRoleCe, seidList: number[]) { +function addSeidEffect(this: CalRoleCe|CalHeroCe, seidList: number[]) { console.log('******addSeidEffect',this, seidList) // console.log('addSeidList', addSeidList.join()) diff --git a/shared/pubUtils/itemUtils.ts b/shared/pubUtils/itemUtils.ts index b093c506d..397e8e1bc 100644 --- a/shared/pubUtils/itemUtils.ts +++ b/shared/pubUtils/itemUtils.ts @@ -1,6 +1,6 @@ -import { HeroModel, HeroType, HeroUpdate } from '../db/Hero'; +import { HeroModel, HeroType, } from '../db/Hero'; import { ItemModel } from '../db/Item'; import { EquipModel, RandSe, Holes, RandMain, equipUpdate } from './../db/Equip'; import { gameData, getQuenchByQualityAndGrade, getQuenchGradeByValue } from './data'; @@ -10,12 +10,11 @@ import { getRandValueByMinMax, getRandEelm } from './util'; import { findWhere } from 'underscore'; import { RoleModel, RoleType, } from '../db/Role'; import { Figure } from '../domain/dbGeneral'; -import { getTimeFun, nowSeconds } from './timeUtil'; -import { calPlayerCeAndSave, reCalAllHeroCe } from './playerCe'; -import { accomplishTask, checkTask, checkTaskWithEquip, checkTaskWithHeroes } from './taskUtil'; +import { getTimeFun } from './timeUtil'; +import { reCalAllHeroCe } from './playerCe'; +import { checkTaskWithEquip } from './taskUtil'; // import { checkTask, checkTaskWithHeroes, checkTaskWithEquip, accomplishTask } from './taskUtil'; -import { CreateHeroParam } from '../domain/roleField/hero'; -import { SkinModel, SkinType, SkinUpdate, } from '../db/Skin'; +import { SkinModel, } from '../db/Skin'; import { TaskListReturn } from '../domain/roleField/task'; /** @@ -185,16 +184,14 @@ export function getFriendPointObject(count: number) { export function getHonourObject(count: number) { return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.HONOUR), count }; } + /** - * 解锁头像/相框 - * @param roleId 玩家id + * 返回 解锁头像/相框 * @param conditions 解锁条件 * @param role 如果已查询过role表就直接可以使用 */ -export async function unlockFigure(roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }[], role?: RoleType) { - if (!role || !role.heads || !role.frames) { - role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); - } + export function unlockFigureWithoutSave(conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }[], role: RoleType) { + let { heads, frames, spines } = role; let figureInfo = { heads: new Array
(), frames: new Array
(), spines: new Array
() }; for (let { type, paramHid, paramFavourLv, paramSkinId } of conditions) { @@ -235,6 +232,20 @@ export async function unlockFigure(roleId: string, conditions: { type: number, p } } + return { figureInfo, heads, frames, spines }; +} + +/** + * 解锁头像/相框 + * @param roleId 玩家id + * @param conditions 解锁条件 + * @param role 如果已查询过role表就直接可以使用 + */ +export async function unlockFigure(roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }[], role?: RoleType) { + if (!role || !role.heads || !role.frames) { + role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); + } + let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role); role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines }); return figureInfo; } @@ -314,108 +325,17 @@ function unlockSingleFigure(dbFigures: Figure[], id: number, unlockDirect = fals return figure } -async function getSkinsOfThisHero(roleId: string, roleName: string, hid: number, initialSkin: number, allSkins?: SkinType[]) { - if(!allSkins) allSkins = await SkinModel.findbyRoleAndHid(roleId, hid); - let skin = await increaseSkin(roleId, roleName, initialSkin); - if(skin) allSkins.push(skin); - let skins: { id: number, skin: string, enable: boolean }[] = []; - for(let skin of allSkins) { - skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initialSkin }); - } +// async function getSkinsOfThisHero(roleId: string, roleName: string, hid: number, initialSkin: number, allSkins?: SkinType[]) { +// if(!allSkins) allSkins = await SkinModel.findbyRoleAndHid(roleId, hid); +// let skin = await increaseSkin(roleId, roleName, initialSkin); +// if(skin) allSkins.push(skin); +// let skins: { id: number, skin: string, enable: boolean }[] = []; +// for(let skin of allSkins) { +// skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initialSkin }); +// } - return skins -} - -/** - * 创建武将 - * @param roleId 玩家id - * @param roleName 玩家名 - * @param serverId 服务器id - * @param {CreateHeroParam} heroInfo 创建武将所需信息 - * @param funcs 玩家开启了的功能,主要用于任务 - */ -export async function createHero(roleId: string, roleName: string, serverId: number, heroInfo: CreateHeroParam, funcs?: number[]) { - let { role, figureInfo, heroes, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage } = await createHeroes(roleId, roleName, serverId, [heroInfo], funcs) - return { hero: heroes[0], role, figureInfo, calHeroResult: calHeroResults[0], calAllHeroResult, taskPushMessage, activityTaskPushMessage } -} - -export async function createHeroes(roleId: string, roleName: string, serverId: number, heroInfos: CreateHeroParam[], funcs?: number[]) { - - let heroNum = 0; - let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); - let heroes: HeroType[] = [], calHeroResults = [], calAllHeroResult = undefined; - let figureInfos:{ heads: Figure[], frames: Figure[], spines: Figure[] }[] = []; - - for (let heroInfo of heroInfos) { - let dicHero = gameData.hero.get(heroInfo.hid); - let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = dicHero; - - let info = { roleId, roleName, serverId, quality, star, job, hName }; - - let skins = await getSkinsOfThisHero(roleId, roleName, heroInfo.hid, initialSkin); - - let curHero = await HeroModel.createHero(Object.assign(info, heroInfo, { skins })); - - // 计算初始战力 - let calHeroResult = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.INIT, roleId, curHero, {}); - calHeroResults.push(calHeroResult); - heroes.push(calHeroResult.hero); - conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid }); - heroNum++; - } - figureInfos.push(await unlockFigure(roleId, conditions)); // 解锁头像 - - let role = await RoleModel.incRoleInfo(roleId, { heroNum }, { heroNumUpdatedAt: nowSeconds() }); - // 任务 - console.log('****** checkTask before', Date.now()) - let m1 = await checkTask(roleId, TASK_TYPE.HERO_NUM, heroNum, true, {}, funcs); - let m2 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY, heroes, funcs); - let m3 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, heroes, funcs); - let m4 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_LV, heroes, funcs); - let taskPushMessage = m1.concat(m2, m3, m4); - console.log('****** checkTask after', Date.now()) - //成长任务 - console.log('****** accomplishTask before', Date.now()) - let mm1 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_NUM, heroNum) - let mm2 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_QUALITY, heroNum, { heroes }) - console.log('****** accomplishTask after', Date.now()) - let activityTaskPushMessage = mm1.concat(mm2); - console.log(funcs); - return { role, figureInfo: combineFigureInfo(figureInfos), heroes, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage } -} - - -export async function createHeroesWhenInit(roleId: string, roleName: string, serverId: number, heroInfos: HeroUpdate[], skinInfos: SkinUpdate[], funcs?: number[]) { - - let heroNum = 0; - let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); - let figureInfos:{ heads: Figure[], frames: Figure[], spines: Figure[] }[] = []; - - for (let heroInfo of heroInfos) { - conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid }); - heroNum++; - } - figureInfos.push(await unlockFigure(roleId, conditions)); // 解锁头像 - let heroes = await HeroModel.insertHeroes(roleId, roleName, serverId, heroInfos); - await SkinModel.insertSkins(roleId, roleName, skinInfos); - - // 任务 - console.log('****** checkTask before', Date.now()) - let m1 = await checkTask(roleId, TASK_TYPE.HERO_NUM, heroNum, true, {}, funcs); - let m2 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY, heroes, funcs); - let m3 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, heroes, funcs); - let m4 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_LV, heroes, funcs); - let taskPushMessage = m1.concat(m2, m3, m4); - console.log('****** checkTask after', Date.now()) - //成长任务 - console.log('****** accomplishTask before', Date.now()) - let mm1 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_NUM, heroNum) - let mm2 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_QUALITY, heroNum, { heroes }) - console.log('****** accomplishTask after', Date.now()) - let activityTaskPushMessage = mm1.concat(mm2); - console.log(funcs); - return { figureInfo: combineFigureInfo(figureInfos), heroes, taskPushMessage, activityTaskPushMessage } -} +// return skins +// } export function combineFigureInfo(figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[]) { let figureInfo = { heads: new Array
(), frames: new Array
(), spines: new Array
() }; diff --git a/shared/pubUtils/roleUtil.ts b/shared/pubUtils/roleUtil.ts index 9e05858dd..107969bf0 100644 --- a/shared/pubUtils/roleUtil.ts +++ b/shared/pubUtils/roleUtil.ts @@ -1,21 +1,32 @@ -import { DEFAULT_HERO_LV, LINEUP_NUM } from "../consts"; +import { DEFAULT_HERO_LV, FIGURE_UNLOCK_CONDITION, LINEUP_NUM, REDIS_KEY, STATUS, TASK_TYPE } from "../consts"; import { SkinModel } from "../db/Skin"; -import { DEFAULT_COIN, DEFAULT_GOLD, DEFAULT_HEROES, DEFAULT_LV, HERO_SYSTEM_TYPE } from "../consts"; -import { HeroModel, HeroUpdate } from "../db/Hero"; -import { RoleModel, RoleUpdate } from "../db/Role"; +import { DEFAULT_HEROES, DEFAULT_LV, HERO_SYSTEM_TYPE } from "../consts"; +import { HeroModel, HeroType, HeroUpdate } from "../db/Hero"; +import { RoleModel, RoleType, RoleUpdate } from "../db/Role"; import { SkinUpdate } from "../db/Skin"; -import { TopHero } from "../domain/dbGeneral"; +import { Figure, TopHero } from "../domain/dbGeneral"; import { CalHeroCe, CalRoleCe } from "../domain/roleField/calCe"; import { gameData, getHeroExpByLv } from "../pubUtils/data"; +import { accomplishTask, checkTask, checkTaskWithHeroes } from './taskUtil'; +import { combineFigureInfo, unlockFigure, unlockFigureWithoutSave } from './itemUtils'; +import { TaskListReturn } from "../domain/roleField/task"; +import { nowSeconds } from "./timeUtil"; +import { reduceCe, resResult } from "./util"; +import { calculatetopLineup, calPlayerCeAndSave } from "./playerCe"; +import { GuildModel, GuildType } from "../db/Guild"; +import { PvpDefenseModel } from "../db/PvpDefense"; +import { CreateHeroParam } from "../domain/roleField/hero"; // 储存在内存中的初始数据 export function getInitRoleInfo() { - let topLineup: TopHero[] = [], topLineupCe = 0, allCe = 0, initHeroes: HeroUpdate[] = [], initSkins: SkinUpdate[] = [], heroNum = 0; + let topLineup: TopHero[] = [], topLineupCe = 0, allCe = 0, + heroes: HeroUpdate[] = [], initHeroes: HeroUpdate[] = [], initSkins: SkinUpdate[] = [], heroNum = 0, + conditions: {type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = []; let role = new RoleModel(); let calRoleCe = new CalRoleCe(role); let roleAttr = calRoleCe.cal(HERO_SYSTEM_TYPE.INIT); - for(let hid of DEFAULT_HEROES) { + for(let { actorId: hid } of gameData.recruit) { let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = gameData.hero.get(hid); // 皮肤 let skin = new SkinModel(); @@ -28,10 +39,17 @@ export function getInitRoleInfo() { let calHeroCe = new CalHeroCe(hid, heroInfo); let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.INIT); let ce = calHeroCe.getCalculatedCe(roleAttr); - allCe += ce; - initHeroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce }); - heroNum++; + heroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce }); + // 更新role表 + if(DEFAULT_HEROES.includes(hid)) { + // 头像 + conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid }); + allCe += ce; + heroNum++; + initHeroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce }); + } } + let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role); // 最强阵容 initHeroes.sort((a, b) => { return b.ce - a.ce }); for(let i = 0; i < LINEUP_NUM; i++) { @@ -42,8 +60,222 @@ export function getInitRoleInfo() { } } - let initRole: RoleUpdate = { topLineupCe, topLineup, attr: roleAttr, ce: allCe, lv: DEFAULT_LV, gold: DEFAULT_GOLD, coin: DEFAULT_COIN, heroNum, heroNumUpdatedAt: Date.now() }; + let initRole: RoleUpdate = { topLineupCe, topLineup, attr: roleAttr, ce: allCe, lv: DEFAULT_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0, heroNum, heroNumUpdatedAt: Date.now(), heads, frames, spines }; return { - role: initRole, heroes: initHeroes, skins: initSkins + role: initRole, heroes, skins: initSkins, figureInfo + } +} + +export class UpdateHeroes { + roleId: string; + roleName: string; + serverId: number; + funcs: number[] = []; + incHeroNum: number = 0; + incRoleCe: number = 0; + pushHeroes: {hid: number, incHeroCe: number, ce: number}[] = []; + roleUpdate: RoleUpdate; + role: RoleType; + guild: GuildType; + + constructor(roleId: string, roleName: string, serverId: number, funcs?: number[]) { + this.roleId = roleId; + this.roleName = roleName; + this.serverId = serverId; + if(funcs) this.funcs = funcs; + } + + public setRole(role: RoleType) { + this.role = role; + } + + public async getRole() { + if(!this.role) { + this.role = await RoleModel.findByRoleId(this.roleId); + } + return this.role; + } + + public addRoleUpdateParam(param: RoleUpdate) { + this.roleUpdate = {...this.roleUpdate, ...param}; + } + + public async updateDbCe(isCreate: boolean, heroInfo: HeroUpdate, originCe = 0) { + let role = await this.getRole(); + if(isCreate) this.incHeroNum ++; + if(heroInfo != originCe) this.incRoleCe += heroInfo.ce - originCe; + this.addRoleUpdateParam(await calculatetopLineup(role, heroInfo.hid, heroInfo.ce, heroInfo._id )); + this.pushHeroes.push({ hid: heroInfo.hid, incHeroCe: heroInfo.ce - originCe, ce: heroInfo.ce }); + } + + // 更新战力相关的各个表 + public async saveCeToDb() { + let role = await this.getRole(); + // 更新role表 + this.role = await RoleModel.updateRoleInfo(this.roleId, { + heroNum: this.incHeroNum + role.heroNum, ce: this.incRoleCe + role.ce, heroNumUpdatedAt: nowSeconds(), ...this.roleUpdate + }); + + // 更新guild表 + if(role.hasGuild) { + this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe); // 公会更新战力 + } + for(let { hid, incHeroCe } of this.pushHeroes) { + await PvpDefenseModel.updateCe(this.roleId, hid, incHeroCe); // 更新pvp防守阵战力 + } + } + + public async updateRedisRank(Rank: any) { + let role = await this.getRole(); + let { serverId, roleId, pushHeroes } = this; + // 更新军团信息 + if(this.guild) { + let r = new Rank(REDIS_KEY.GUILD_INFO, { code: this.guild.code }); + await r.generParamAndSet(REDIS_KEY.GUILD_INFO, { roleId }, { role }); + } + // 武将数量 + if(this.incHeroNum > 0) { + let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId }); + await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role); + } + + // 最强阵容 + let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId }); + await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role); + + // 最强武将 + for(let { hid, ce } of pushHeroes) { + let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId }); + await r2.setRankWithHeroInfo(roleId, hid, ce, 0); + + let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid }); + await r4.setRankWithHeroInfo(roleId, hid, ce, 0); + } + + // 总战力 + let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }); + await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role); + + // 更新最强五人阵容信息 + let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId }); + await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role }); + } + + public async pushMessage(pinus: any, sid: string) { + let role = await this.getRole(); + let uids = [{ uid: this.roleId, sid }]; + pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe: reduceCe(role.topLineupCe) }), uids); + } + +} + +export class CreateHeroes extends UpdateHeroes { + private resultHeroes: HeroType[] = []; + private heroNum = 0; + // 推送信息 + private taskPushMessage: TaskListReturn[] = []; + private activityTaskPushMessage = []; + private figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[] = []; + + // web-server和gm-server里面创建 + public async calWithParam(heroInfos: CreateHeroParam[]) { + let heroNum = 0; + let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); + + for (let heroInfo of heroInfos) { + let dicHero = gameData.hero.get(heroInfo.hid); + let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = dicHero; + let info = { roleId: this.roleId, roleName: this.roleName, serverId: this.serverId, quality, star, job, hName }; + let skin = new SkinModel(); + let dicFashion = gameData.fashion.get(initialSkin); + let skins = await this.getSkinsOfThisHero(heroInfo.hid, { ...skin.toJSON(), id: initialSkin, hid: heroInfo.hid, skinName: dicFashion.name }); + let curHero = await HeroModel.createHero(Object.assign(info, heroInfo, { skins })); + + // 计算初始战力 + await calPlayerCeAndSave(HERO_SYSTEM_TYPE.INIT, this.roleId, curHero, {}); + conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid }); + heroNum++; + } + this.figureInfos.push(await unlockFigure(this.roleId, conditions)); // 解锁头像 + + await RoleModel.incRoleInfo(this.roleId, { heroNum }, { heroNumUpdatedAt: nowSeconds() }); + await this.clearTask(); + } + + private async getSkinsOfThisHero(hid: number, initSkinInfo: SkinUpdate) { + let allSkins = await SkinModel.findbyRoleAndHid(this.roleId, hid); + let skin = await SkinModel.insertSkins(this.roleId, this.roleName, [initSkinInfo]); + if(skin) allSkins.push(...skin); + let skins: { id: number, skin: string, enable: boolean }[] = []; + for(let skin of allSkins) { + skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initSkinInfo.id }); + } + return skins + } + + // game-server里面创建武将 + public async createWithHeroInfo(infos: Map) { + let role = await this.getRole(); + // 数据处理 + let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); // 解锁头像条件 + let initHeroInfos: HeroUpdate[] = []; + for (let [ hid, { heroInfo, skinInfo }] of infos) { + conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid }); + this.updateDbCe(true, heroInfo); + // 皮肤使用初始加载进内存的数据 + let skins = await this.getSkinsOfThisHero(hid, skinInfo); + initHeroInfos.push({ ...heroInfo, skins }); + } + // 武将使用初始加载数据插入 + this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, initHeroInfos); + // 头像解锁 + let { figureInfo, frames, heads, spines } = unlockFigureWithoutSave(conditions, role); + this.figureInfos.push(figureInfo); + this.addRoleUpdateParam({ frames, heads, spines }); + // 更新战力 + await this.saveCeToDb(); + await this.clearTask(); + } + + // 创建初始账号时候的初始 + public async createWithInitInfo(heroeInfos: HeroUpdate[], skinInfos: SkinUpdate[], figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }) { + this.figureInfos.push(figureInfo); + for(let heroInfo of heroeInfos) this.updateDbCe(true, heroInfo); + this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, heroeInfos); + await SkinModel.insertSkins(this.roleId, this.roleName, skinInfos); + await this.clearTask(); + } + + private async clearTask() { + // 任务 + console.log('****** checkTask before', Date.now()) + let m1 = await checkTask(this.roleId, TASK_TYPE.HERO_NUM, this.heroNum, true, {}, this.funcs); + let m2 = await checkTaskWithHeroes(this.roleId, TASK_TYPE.HERO_QUALITY, this.resultHeroes, this.funcs); + let m3 = await checkTaskWithHeroes(this.roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, this.resultHeroes, this.funcs); + let m4 = await checkTaskWithHeroes(this.roleId, TASK_TYPE.HERO_LV, this.resultHeroes, this.funcs); + this.taskPushMessage.push(...m1, ...m2, ...m3, ...m4); + console.log('****** checkTask after', Date.now()) + //成长任务 + console.log('****** accomplishTask before', Date.now()) + let mm1 = await accomplishTask(this.serverId, this.roleId, TASK_TYPE.HERO_NUM, this.heroNum) + let mm2 = await accomplishTask(this.serverId, this.roleId, TASK_TYPE.HERO_QUALITY, this.heroNum, { heroes: this.resultHeroes }) + console.log('****** accomplishTask after', Date.now()) + this.activityTaskPushMessage.push(...mm1, ...mm2); + } + + public async pushMessage(pinus: any, sid: string) { + let role = await this.getRole(); + let uids = [{ uid: this.roleId, sid }]; + pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe: reduceCe(role.topLineupCe) }), uids); + pinus.app.get('channelService').pushMessageByUids('onTaskUpdate', resResult(STATUS.SUCCESS, this.taskPushMessage), uids); + pinus.app.get('channelService').pushMessageByUids('onActivityUpdate', resResult(STATUS.SUCCESS, this.activityTaskPushMessage), uids); + let figureInfo = combineFigureInfo(this.figureInfos); + if (!!figureInfo && (figureInfo.heads.length > 0 || figureInfo.frames.length > 0 || figureInfo.spines.length > 0)) { + pinus.app.get('channelService').pushMessageByUids('onHeadChange', resResult(STATUS.SUCCESS, { ...figureInfo }), uids); + } + } + + public getResultHeroes() { + return this.resultHeroes; } } \ No newline at end of file