From 222b9c6e1225da8039f0a2f162a05b8d59ccac4e Mon Sep 17 00:00:00 2001 From: luying Date: Wed, 28 Oct 2020 19:29:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BF=9C=E5=BE=81=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E7=8E=A9=E5=AE=B6=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../battle/handler/expeditionBattleHandler.ts | 3 +- .../battle/handler/normalBattleHandler.ts | 5 +- game-server/app/services/expeditionService.ts | 49 ++++++-- gm-server/app/controller/users.ts | 25 +++- gm-server/app/router.ts | 6 + gm-server/app/service/users.ts | 109 +++++++++++++++++- gm-server/config/config.prod.ts | 6 + shared/consts/statusCode.ts | 5 +- shared/db/EventRecord.ts | 2 +- shared/db/PvpDefense.ts | 81 +++++++++++++ shared/resource/jsons/const.json | 18 +-- 11 files changed, 282 insertions(+), 27 deletions(-) create mode 100644 shared/db/PvpDefense.ts diff --git a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts index ff5bdbf92..0d26e40dc 100644 --- a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts +++ b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts @@ -77,6 +77,7 @@ export class ExpeditionBattleHandler { // 计算我方战斗力(最高五人) let myCe = await calculateSumCE(roleId, 1, { num: 5 }); + console.log(myCe); let enemyObj = { enemyFrom: 0, enemyId: '', @@ -88,7 +89,7 @@ export class ExpeditionBattleHandler { // 获取系数和步长 let {scale, range, lv} = await getCEScaleAndRange(roleId, curDicExpedition); // 优先匹配其他玩家 - let flag = await matchPlayers(scale, range, myCe, enemyObj); + let flag = await matchPlayers(roleId, scale, range, myCe, curDicExpedition.json, enemyObj); // 当数量不够时使用机器人匹配 if(!flag) { flag = await matchRobots(scale, myCe, curDicExpedition.ce, curDicExpedition.json, lv, enemyObj); diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index 810c47ca0..a3507ca80 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -3,7 +3,7 @@ import { BattleRecordModel } from '../../../db/BattleRecord'; import { BattleSweepRecordModel } from '../../../db/BattleSweepRecord'; import { getWarById, } from '../../../pubUtils/gamedata'; import { genCode } from '../../../pubUtils/util'; -import { WAR_TYPE } from '../../../consts/consts'; +import { WAR_TYPE, EVENT_STATUS } from '../../../consts/consts'; import { checkDaily, checkDailyAndIncrease } from '../../../services/dailyBattleService'; import { checkTowerWar, towerBattleEnd } from '../../../services/battleService'; import { WarReward } from '../../../services/warRewardService'; @@ -70,7 +70,8 @@ export class NormalBattleHandler { towerData = Object.assign(towerData, checkResult.data); } else if (warInfo.warType == WAR_TYPE.EVENT) { // 记录事件状态 - let checkResult = await checkEventBattle( roleId, session.get('eventStatus'), battleId, battleCode); + let eventStatus = session.get('eventStatus')||EVENT_STATUS.WAITING; + let checkResult = await checkEventBattle( roleId, eventStatus, battleId, battleCode); if(checkResult.status == -1) { return checkResult.resResult } diff --git a/game-server/app/services/expeditionService.ts b/game-server/app/services/expeditionService.ts index c4b6b6112..39a9106d9 100644 --- a/game-server/app/services/expeditionService.ts +++ b/game-server/app/services/expeditionService.ts @@ -1,20 +1,44 @@ import { ExpeditionPointModel } from '../db/ExpeditionPoint'; import { RoleModel } from '../db/Role'; +import { PvpDefenseModel } from '../db/PvpDefense'; import { getWarJsons, getGamedata } from '../pubUtils/gamedata'; -import { decodeStr } from '../pubUtils/util'; +import { decodeStr, resResult } from '../pubUtils/util'; import { WAR_JSON_ATTRIBUTE_TYPE } from '../consts/consts'; // 匹配玩家 -export async function matchPlayers(scale: number, range: number, myCe: number ,enemyObj: {enemyFrom: number, enemyId: string, enemies: Array }) { +export async function matchPlayers(roleId: string, scale: number, range: number, myCe: number, warJsonIndex:any, enemyObj: {enemyFrom: number, enemyId: string, enemies: Array }) { + let {json: dicWarJson } = getWarJsons(warJsonIndex); let min = myCe * scale * (1 - range/100); let max = myCe * scale * (1 + range/100); - console.log(min, max, enemyObj); - return false + let resultRange = await PvpDefenseModel.findByScale(roleId, min, max); + if(resultRange.length > 0) { + let index = Math.floor(Math.random() * resultRange.length); + let result = resultRange[index]; + let {roleId, heroes } = result; + + enemyObj.enemyFrom = 1; + enemyObj.enemyId = roleId; + + let heroIndex = 0; + for(let enemy of dicWarJson) { + if(enemy.relation == 2) { + let hero = heroes[heroIndex]; + if(hero) { + enemyObj.enemies.push({...enemy, ...hero}); + heroIndex ++; + } + } + } + + return true; + } else { + return false + } } // 匹配机器人 @@ -26,12 +50,14 @@ export async function matchRobots(scale: number, myCe: number, robotCe: number, let ratio = myCe / robotCe * scale; // 玩家战力/机器人初始战力*系数 for(let enemy of dicWarJson) { - let attribute = decodeWarJsonAttribute(enemy.attribute); // 格式:{'hp':1000, ...} - for(let value in attribute) { - attribute[value] *= ratio; - attribute[value] = Math.round(attribute[value]); + if(enemy.relation == 2) { + let attribute = decodeWarJsonAttribute(enemy.attribute); // 格式:{'hp':1000, ...} + for(let value in attribute) { + attribute[value] *= ratio; + attribute[value] = Math.round(attribute[value]); + } + enemyObj.enemies.push({...enemy, attribute, lv}); } - enemyObj.enemies.push({...enemy, attribute, lv}); } return true @@ -55,7 +81,10 @@ export async function getCEScaleAndRange(roleId: string, curDicExpedition: any) // 远征表属性解码 export function decodeWarJsonAttribute(attribute) { let arr = decodeStr('attribute', attribute); - let obj = {}; + let obj = {} + for(let key in WAR_JSON_ATTRIBUTE_TYPE) { + obj[WAR_JSON_ATTRIBUTE_TYPE[key]] = 0; // 初始化 + } for(let {id, value} of arr) { let field = WAR_JSON_ATTRIBUTE_TYPE[id]; if(field) { diff --git a/gm-server/app/controller/users.ts b/gm-server/app/controller/users.ts index 0010b32af..192ea3c16 100644 --- a/gm-server/app/controller/users.ts +++ b/gm-server/app/controller/users.ts @@ -30,7 +30,6 @@ export default class UserController extends Controller { public async createRoleData() { const { ctx } = this; - console.log(ctx.request.body) const { hid, hlv, eid, elv, ecount, ehid, itemid, itemcount, selectedRowKeys: uids, optType } = ctx.request.body; if(optType == 'hero') { ctx.body = await ctx.service.users.createHero(uids, hid, hlv); @@ -42,4 +41,28 @@ export default class UserController extends Controller { ctx.body = ctx.service.utils.resResult(STATUS.WRONG_PARMS); } } + + public async getPveDefense() { + const { ctx } = this; + const { roleId } = ctx.request.body; + ctx.body = await ctx.service.users.getPvpDefense(roleId); + } + + public async getHeroList() { + const { ctx } = this; + const { roleId } = ctx.request.body; + ctx.body = await ctx.service.users.getHeroList(roleId); + } + + public async saveHeroToDefense() { + const { ctx } = this; + const { roleId, roleName, hid } = ctx.request.body; + ctx.body = await ctx.service.users.saveHeroToDefense(roleId, roleName, hid); + } + + public async removeHeroFromDefense() { + const { ctx } = this; + const { roleId, hid } = ctx.request.body; + ctx.body = await ctx.service.users.removeHeroFromDefense(roleId, hid); + } } diff --git a/gm-server/app/router.ts b/gm-server/app/router.ts index f7d551a33..347f24434 100644 --- a/gm-server/app/router.ts +++ b/gm-server/app/router.ts @@ -28,5 +28,11 @@ export default (app: Application) => { router.post('/api/users/deleterole',tokenParser, controller.users.deleteRole); router.post('/api/users/getrolelist',tokenParser, controller.users.getrolelist); router.post('/api/users/createroledata',tokenParser, controller.users.createRoleData); + router.post('/api/users/getpvpdefense',tokenParser, controller.users.getPveDefense); + router.post('/api/users/getherolist',tokenParser, controller.users.getHeroList); + router.post('/api/users/saveherotodefense',tokenParser, controller.users.saveHeroToDefense); + router.post('/api/users/removeherofromdefense',tokenParser, controller.users.removeHeroFromDefense); + + }; diff --git a/gm-server/app/service/users.ts b/gm-server/app/service/users.ts index 6a3537adb..43a3f5909 100644 --- a/gm-server/app/service/users.ts +++ b/gm-server/app/service/users.ts @@ -1,6 +1,6 @@ import { UserModel } from '@db/User'; import { RoleModel } from '@db/Role'; -import { HeroModel } from '@db/Hero'; +import Hero, { HeroModel } from '@db/Hero'; import { EquipModel } from '@db/Equip'; import { CounterModel } from '@db/Counter'; import { ActionPointModel } from '@db/ActionPoint'; @@ -17,6 +17,7 @@ import { HangUpSpdUpRecModel } from '@db/HangUpSpdUpRec'; import { SearchRecordModel } from '@db/SearchRecord'; import { TowerRecordModel } from '@db/TowerRecord'; import { TowerTaskRecModel } from '@db/TowerTaskRec'; +import { PvpDefenseModel } from '@db/PvpDefense'; import { Service } from 'egg'; import Counter from '@db/Counter'; @@ -110,6 +111,7 @@ export default class GMUsers extends Service { await SearchRecordModel.deleteAccount(roleId); await TowerTaskRecModel.deleteAccount(roleId); await TowerRecordModel.deleteAccount(roleId); + await PvpDefenseModel.deleteAccount(roleId); return ctx.service.utils.resResult(STATUS.SUCCESS); } @@ -158,10 +160,13 @@ export default class GMUsers extends Service { let heroCount = await HeroModel.count({roleId: role.roleId}).lean(); let equipCount = await EquipModel.count({roleId: role.roleId}).lean(); let itemCount = (role.consumeGoods?role.consumeGoods.length: 0) + (role.souls?role.souls.length:0); + let defense = await PvpDefenseModel.findByRoleId(role.roleId); + let {roleId, roleName, serverId, lv, vLv, gold, coin} = role; let {uid, tel} = role.userInfo; result.push({ - key: roleId, roleId, roleName, serverId, lv, vLv, uid, tel, heroCount, equipCount, itemCount, gold, coin + key: roleId, roleId, roleName, serverId, lv, vLv, uid, tel, heroCount, equipCount, itemCount, gold, coin, + hasDefense: defense?'是':'否', defCe: defense?defense.ce:0 }); } return ctx.service.utils.resResult(STATUS.SUCCESS, { list: result }); @@ -284,4 +289,104 @@ export default class GMUsers extends Service { return ctx.service.utils.resResult(STATUS.SUCCESS, { uids }); } } + + public async getPvpDefense(roleId: string) { + const {ctx} = this; + let result = await PvpDefenseModel.findByRoleId(roleId); + return ctx.service.utils.resResult(STATUS.SUCCESS, { + hasDefense: !!result, defense: result + }) + } + + public async getHeroList(roleId: string) { + const {ctx} = this; + let herolist = await HeroModel.findByRole(roleId); + let defense = await PvpDefenseModel.findByRoleId(roleId); + + let result = Array(); + for(let hero of herolist) { + if(defense) { + let {heroes = []} = defense; + let curHero = heroes.find(cur => cur.actorId == hero.hid); + if(!curHero) { + result.push(hero); + } + } else{ + result.push(hero); + } + } + + return ctx.service.utils.resResult(STATUS.SUCCESS, { + heroes: result + }) + } + + public async saveHeroToDefense(roleId: string, roleName: string, hid: number) { + const {ctx} = this; + let hero = await HeroModel.findByHidAndRole(hid, roleId); + if(!hero) { + return ctx.service.utils.resResult(STATUS.GM_HERO_NOT_FOUND); + } + let { lv } = hero; + + let dicHero = ctx.service.utils.getHeroById(hid); + let { hp, hp_up, atk, atk_up, matk, matk_up, def, def_up, mdef, mdef_up } = dicHero; + + let ce = ctx.service.utils.calculateCE({hid, lv}); + let heroInfo = { + actorId: dicHero.heroId, + actorName: dicHero.name, + attribute: { + hp: hp + lv * hp_up, + atk: atk + lv * atk_up, + matk: matk + lv * matk_up, + def: def + lv * def_up, + mdef: mdef + lv * mdef_up, + agi: 0, + luk: 0, + speed: 0, + hit: 0, + cri: 0, + flee: 0, + antCri: 0, + damageIncrease: 0, + damageDecrease: 0, + defIgnore: 0, + bloodSuck: 0, + ap: 0 + }, + lv, + ce + }; + + let defense = await PvpDefenseModel.findByRoleId(roleId); + if(!defense) { + defense = await PvpDefenseModel.createPvpDefense({roleId, roleName, heroes: [heroInfo], ce}); + } else { + defense = await PvpDefenseModel.addHeroToDefense(roleId, heroInfo, ce); + } + return ctx.service.utils.resResult(STATUS.SUCCESS, { + defense + }); + } + + + public async removeHeroFromDefense(roleId: string, hid: number) { + const {ctx} = this; + + let defense = await PvpDefenseModel.findByRoleId(roleId); + if(!defense) { + return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_NOT_FOUND); + } + let {heroes} = defense; + let curHero = heroes.find(cur => cur.actorId == hid); + if(!curHero) { + return ctx.service.utils.resResult(STATUS.GM_PVP_DEFENSE_HERO_NOT_FOUND); + } + defense = await PvpDefenseModel.removeHeroFromDefense(roleId, hid, curHero.ce); + + return ctx.service.utils.resResult(STATUS.SUCCESS, { + defense + }); + } } diff --git a/gm-server/config/config.prod.ts b/gm-server/config/config.prod.ts index 56415cecc..e17868917 100644 --- a/gm-server/config/config.prod.ts +++ b/gm-server/config/config.prod.ts @@ -2,5 +2,11 @@ import { EggAppConfig, PowerPartial } from 'egg'; export default () => { const config: PowerPartial = {}; + + config.cluster = { + listen: { + port: 7500 + } + }; return config; }; diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index e738db4fa..e383fc79b 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -77,5 +77,8 @@ export const STATUS = { GM_DUPLICATE_API: { code: 60007, simStr: '该接口已存在' }, GM_DUPLICATE_GROUP: { code: 60008, simStr: '该用户组已存在' }, GM_CREATE_ERROR: { code: 60009, simStr: '创建失败' }, - GM_ROLE_NOT_FOUND: { code: 60010, simStr: '未找到该玩家' } + GM_ROLE_NOT_FOUND: { code: 60010, simStr: '未找到该玩家' }, + GM_HERO_NOT_FOUND: { code: 60011, simStr: '未找到武将' }, + GM_PVP_DEFENSE_NOT_FOUND: { code: 60012, simStr: '该玩家未保存防守阵' }, + GM_PVP_DEFENSE_HERO_NOT_FOUND: { code: 60013, simStr: '该守阵没有该武将' } } diff --git a/shared/db/EventRecord.ts b/shared/db/EventRecord.ts index 364e5e1ad..817376c51 100644 --- a/shared/db/EventRecord.ts +++ b/shared/db/EventRecord.ts @@ -86,7 +86,7 @@ export default class EventRecord extends BaseModel { } public static async setStatusByCode(roleId: string, eventCode: string, status: number , lean=true ) { - let result = await EventRecordModel.findOneAndUpdate({ roleId, eventCode }, {$set:{ status }}).lean(lean); + let result = await EventRecordModel.findOneAndUpdate({ roleId, eventCode }, {$set:{ status }}, {new: true, upsert: true}).lean(lean); return result; } diff --git a/shared/db/PvpDefense.ts b/shared/db/PvpDefense.ts new file mode 100644 index 000000000..28b8b3ff0 --- /dev/null +++ b/shared/db/PvpDefense.ts @@ -0,0 +1,81 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop } from '@typegoose/typegoose'; + +class Heroes { + @prop({ required: true }) + actorId: number; // 武将id + @prop({ required: true }) + actorName: string; // 武将名 + @prop({ required: true }) + attribute: {hp: number, atk: number, matk: number, def: number, mdef: number, agi: number, luk: number, speed: number, hit: number, cri: number, flee: number, antCri: number, damageIncrease: number, damageDecrease: number, defIgnore: number, bloodSuck: number, ap: number}; // 属性 + @prop({ required: true }) + lv: number; // 角色等级 + @prop({ required: true }) + ce: number; // 战斗力 + @prop({ required: false }) + skill: string; // 技能 + @prop({ required: false }) + seid: string; // 技能 + @prop({ required: false }) + star: number; // 角色星级 + } + + +@index({ roleId: 1 }) +@index({ ce: 1 }) +export default class PvpDefense extends BaseModel { + @prop({ required: true }) + roleId: string; // 角色 id + @prop({ required: true }) + roleName: string; // 角色名称 + + @prop({ required: true, type: Heroes, default: []}) + heroes: Array; + @prop({ required: true, default: 0}) + ce: number; + + + public static async findByRoleId(roleId: string, lean = true) { + const result = await PvpDefenseModel.findOne({ roleId }).lean(lean); + return result; + } + + public static async findByScale(roleId: string, min: number, max: number, lean = true) { + console.log(min, max); + const result = await PvpDefenseModel.find({ roleId: {$ne: roleId}, ce: { $lte: max, $gte: min } }).sort({updatedAt: -1}).limit(100).lean(lean); + return result; + } + + public static async createPvpDefense(params: {roleId: string, roleName: string, heroes: Array, ce: number}, lean=true) { + const doc = new PvpDefenseModel(); + const update = Object.assign(doc.toJSON(), params); + const defense = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, {upsert: true, new: true}).lean(lean); + return defense; + + } + + public static async addHeroToDefense(roleId: string, heroInfo: any, ce: number, lean=true) { + const defense = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, { + $inc: {ce}, + $push: { heroes: heroInfo } + }, {upsert: true, new: true}).lean(lean); + return defense; + + } + + public static async removeHeroFromDefense(roleId: string, hid: number, ce: number, lean=true) { + const defense = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, { + $inc: {ce: -1 * ce}, + $pull: { heroes: { actorId: hid }} + }, {upsert: true, new: true}).lean(lean); + return defense; + + } + + public static async deleteAccount(roleId: string, lean = true) { + let result = await PvpDefenseModel.deleteMany({roleId}).lean(lean); + return result||{}; + } +} + +export const PvpDefenseModel = getModelForClass(PvpDefense); diff --git a/shared/resource/jsons/const.json b/shared/resource/jsons/const.json index 219cc520c..db8b107dc 100644 --- a/shared/resource/jsons/const.json +++ b/shared/resource/jsons/const.json @@ -1,9 +1,9 @@ -[ - { - "IsTestService":true, - "OpenIosAliPay":false, - "GuideSwitch":true, - "GENERAL_EQUIPMENT_DEFAULT_LEVEL":7, - "ServiceSign":"guanfu" - } -] \ No newline at end of file +[ + { + "IsTestService":true, + "OpenIosAliPay":false, + "GuideSwitch":true, + "GENERAL_EQUIPMENT_DEFAULT_LEVEL":7, + "ServiceSign":"guanfu" + } + ] \ No newline at end of file