diff --git a/game-server/app.ts b/game-server/app.ts index 27abeb93d..73cce71b0 100644 --- a/game-server/app.ts +++ b/game-server/app.ts @@ -1,4 +1,4 @@ -import { COM_TEAM_STATUS } from './app/consts/consts'; +import { COM_TEAM_STATUS } from './app/consts'; import { createTcpAcceptor, createTcpMailBox, diff --git a/game-server/app/servers/battle/handler/comBattleHandler.ts b/game-server/app/servers/battle/handler/comBattleHandler.ts index 1cc089a48..ab39ff774 100644 --- a/game-server/app/servers/battle/handler/comBattleHandler.ts +++ b/game-server/app/servers/battle/handler/comBattleHandler.ts @@ -552,7 +552,7 @@ export class ComBattleHandler { } const now = Date.now(); // 当前时间戳 - let apJson = await setAp(now, roleId, -1 * warInfo.cost); // 扣除体力 + let apJson = await setAp(now, roleId, sid, -1 * warInfo.cost); // 扣除体力 if(!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } diff --git a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts index c1f8ace6a..9b225a3ae 100644 --- a/game-server/app/servers/battle/handler/expeditionBattleHandler.ts +++ b/game-server/app/servers/battle/handler/expeditionBattleHandler.ts @@ -235,7 +235,7 @@ export class ExpeditionBattleHandler { } const now = Date.now(); // 当前时间戳 - let apJson = await setAp(now, roleId, -1 * warInfo.cost); // 扣除体力 + let apJson = await setAp(now, roleId, sid, -1 * warInfo.cost); // 扣除体力 if(!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index 351263411..5ec78913e 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -184,7 +184,7 @@ export class NormalBattleHandler { } const now = Date.now(); // 当前时间戳 - let apJson = await setAp(now, roleId, -1 * warInfo.cost); // 扣除体力 + let apJson = await setAp(now, roleId, sid, -1 * warInfo.cost); // 扣除体力 if(!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } @@ -301,7 +301,7 @@ export class NormalBattleHandler { warInfo['cost'] = 0; } const now = Date.now(); // 当前时间戳 - let apJson = await setAp(now, roleId, -1 * warInfo.cost * count); // 扣除体力 + let apJson = await setAp(now, roleId, sid, -1 * warInfo.cost * count); // 扣除体力 if(!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } diff --git a/game-server/app/servers/chat/handler/chatHandler.ts b/game-server/app/servers/chat/handler/chatHandler.ts index d0f6688e8..8306c0c25 100644 --- a/game-server/app/servers/chat/handler/chatHandler.ts +++ b/game-server/app/servers/chat/handler/chatHandler.ts @@ -1,9 +1,10 @@ -import { CHANNEL_PREFIX, MSG_SOURCE } from './../../../consts/constModules/chatConst'; +import { CHANNEL_PREFIX, MSG_SOURCE, CHANNEL_TYPE } from './../../../consts/constModules/chatConst'; import {Application, BackendSession} from 'pinus'; import { resResult } from '../../../pubUtils/util'; -import { DEFAULT_MSG_PER_PAGE, STATUS } from '../../../consts'; +import { DEFAULT_MSG_PER_PAGE, STATUS, TASK_TYPE } from '../../../consts'; import { createAccuseData, createGroupMsg, createPrivateMsg, getPrivateMessages, pushGroupMsgToRoom, pushMsgToRole, updatePrivateMsgReadInfo, recentPrivateChatInfos } from '../../../services/chatService'; import { getSimpleRoleInfo } from '../../../services/roleService'; +import { checkTaskWithArgs } from '../../../services/taskService'; export default function(app: Application) { @@ -86,6 +87,7 @@ export class ChatHandler { const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); + const sid = session.get('guildCode'); let channelId = ''; if (channel === CHANNEL_PREFIX.WORLD) channelId = `${serverId}`; if (channel === CHANNEL_PREFIX.GUILD) channelId = guildCode; @@ -93,6 +95,8 @@ export class ChatHandler { const msgData = await createGroupMsg(roleId, roleName, channel, channelId, type, MSG_SOURCE.ROLE_SEND_TEXT, content, targetRoleId, targetMsgCode); if (!msgData) return resResult(STATUS.WRONG_PARMS); await pushGroupMsgToRoom(msgData); + // 任务 + await checkTaskWithArgs(roleId, sid, TASK_TYPE.CHAT, [ CHANNEL_TYPE.get(channel) ]); return resResult(STATUS.SUCCESS); } @@ -106,9 +110,13 @@ export class ChatHandler { const { type, content, targetRoleId, targetMsgCode } = msg; const roleId = session.get('roleId'); const roleName = session.get('roleName'); + const sid = session.get('sid'); const msgData = await createPrivateMsg(roleId, roleName, type, MSG_SOURCE.ROLE_SEND_TEXT, content, targetRoleId, targetMsgCode); await pushMsgToRole(msgData); if (!msgData) return resResult(STATUS.WRONG_PARMS); + + // 任务 + await checkTaskWithArgs(roleId, sid, TASK_TYPE.CHAT, [ CHANNEL_TYPE.get('private') ]); return resResult(STATUS.SUCCESS, msgData); } diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index bd8f8688e..c1ed84073 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -7,7 +7,7 @@ import { Application } from 'pinus'; import {FrontendSession} from 'pinus'; import { HeroModel } from './../../../db/Hero'; import { resResult } from '../../../pubUtils/util'; -import { COM_BTL_QUALITY, ROLE_SELECT, HERO_SELECT, GUILD_SELECT, USER_GUILD_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY } from '../../../consts'; +import { COM_BTL_QUALITY, ROLE_SELECT, HERO_SELECT, GUILD_SELECT, USER_GUILD_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY, TASK_TYPE } from '../../../consts'; import { getAp } from '../../../services/actionPointService'; import { ItemModel } from '../../../db/Item'; import { chackFunOpenWhenLogin } from '../../../services/funcSwitchService'; @@ -22,6 +22,7 @@ import { getMails } from '../../../services/mailService'; import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGuildChannel, leaveSysChannel, leaveWorldChannel, recentGuildMsgs, recentPrivateChatInfos, recentSysMsgs, recentWorldMsgs } from '../../../services/chatService'; import { reportOneOnline } from '../../../services/timeTaskService'; import { Rank } from '../../../services/rankService'; +import { checkTaskWithRole } from '../../../services/taskService'; export default function (app: Application) { return new EntryHandler(app); } @@ -46,7 +47,7 @@ export class EntryHandler { return resResult(STATUS.TOKEN_ERR); } - let role = await RoleModel.findByUid(user.uid, serverId, ROLE_SELECT.ENTRY, true); + let role = await RoleModel.findByUidAndSetTime(user.uid, serverId, ROLE_SELECT.ENTRY, true); if (!role) { return resResult(STATUS.ROLE_NOT_FOUND); } @@ -110,6 +111,10 @@ export class EntryHandler { let r2 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }); r2.setRankWithRoleInfo(role.roleId, role.lv, role.updatedAt.getTime(), role); + // 任务 + checkTaskWithRole(role.roleId, self.app.get('serverId'), TASK_TYPE.LOGIN_SUM, role); + checkTaskWithRole(role.roleId, self.app.get('serverId'), TASK_TYPE.LOGIN_SERIES, role); + role['heros'] = heros; role['equips'] = equips; role['consumeGoods'] = items; diff --git a/game-server/app/servers/role/handler/equipHandler.ts b/game-server/app/servers/role/handler/equipHandler.ts index 23ed7cf99..8b8ccef2b 100644 --- a/game-server/app/servers/role/handler/equipHandler.ts +++ b/game-server/app/servers/role/handler/equipHandler.ts @@ -1,5 +1,5 @@ import { Application, BackendSession } from "pinus"; -import { STATUS, EQUIP_STRENGTHEN_TYPE, CURRENCY_BY_TYPE, CURRENCY_TYPE, HERO_SYSTEM_TYPE, CONSUME_TYPE, HERO_GROW_MAX, MSG_SOURCE, JEWEL_PUSH_LV } from "../../../consts"; +import { STATUS, EQUIP_STRENGTHEN_TYPE, CURRENCY_BY_TYPE, CURRENCY_TYPE, HERO_SYSTEM_TYPE, CONSUME_TYPE, HERO_GROW_MAX, MSG_SOURCE, JEWEL_PUSH_LV, TASK_TYPE } from "../../../consts"; import { ItemInter } from "../../../pubUtils/interface"; import { resResult, parseGoodStr, getRandValueByMinMax, getRandEelm } from "../../../pubUtils/util"; @@ -15,6 +15,7 @@ import { changeEquip, dressEquip, checkMaterialEnough, takeOffEquipAndCalPlayerC import { indexOf, findIndex } from 'underscore'; import { pushEquipRefineSucMsg, pushNormalEquipMsg, pushNormalItemMsg } from "../../../services/chatService"; +import { checkTaskWithHero, checkTaskWithEquip, checkTask, checkTaskWithArgs } from "../../../services/taskService"; export default function (app: Application) { return new EquipHandler(app); @@ -97,6 +98,7 @@ export class EquipHandler { if (!hero) return resResult(STATUS.HERO_NOT_FIND); let { ePlace, lv: playerLv } = hero; // 装备栏 + let oldLvs = ePlace.map(cur => cur.lv); let strengthenArr = new Array(); if (type == EQUIP_STRENGTHEN_TYPE.SINGLE || type == EQUIP_STRENGTHEN_TYPE.SINGLE_QUICK) { // 单装备强化 strengthenArr = ePlace.filter(cur => cur.id == ePlaceId && cur.equip); @@ -146,6 +148,10 @@ export class EquipHandler { hero.ePlace = ePlace; await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_BASE, sid, roleId, hero, { ePlace }); + + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.EQUIP_STRENGTHEN, hero, oldLvs); + const curHero = { hid, ePlace: strengthenArr @@ -165,6 +171,7 @@ export class EquipHandler { if (!hero) return resResult(STATUS.HERO_NOT_FIND); let { ePlace, lv: playerLv } = hero; // 装备栏 + let oldLvs = ePlace.map(cur => cur.lv); let strengthenArr = ePlace.filter(cur => cur.equip); if (strengthenArr.length <= 0) { @@ -205,6 +212,10 @@ export class EquipHandler { hero.ePlace = ePlace; await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP_BASE, sid, roleId, hero, { ePlace }); + + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.EQUIP_STRENGTHEN, hero, oldLvs); + const curHero = { hid, ePlace: strengthenArr @@ -279,6 +290,7 @@ export class EquipHandler { if (isSuccess) { let curEquip = equip; pushEquipRefineSucMsg(roleId, roleName, serverId, curEplace, curEquip?curEquip.quality: 0); + await checkTask(roleId, sid, TASK_TYPE.EQUIP_REFINE, 1, true, {}); } return resResult(STATUS.SUCCESS, { isSuccess, curHero }); } @@ -396,6 +408,7 @@ export class EquipHandler { const hero = await HeroModel.findByHidAndRoleWithEquip(hid, roleId); await calPlayerCeAndSave(HERO_SYSTEM_TYPE.RESTRENGTHEN, sid, roleId, hero, {}, [ePlaceId, ...removeSeidList]); + await checkTask(roleId, sid, TASK_TYPE.EQUIP_RESTRENGTHEN, 1, true, {}); return resResult(STATUS.SUCCESS,{curEquip}); } @@ -452,7 +465,7 @@ export class EquipHandler { if (index < 0) return resResult(STATUS.WRONG_PARMS); let equipOffInfo = hero.ePlace[index].equip; - let curEquip = await changeEquip(roleId, sid, equipOffInfo, equip.hid, id, eid); + let curEquip = await changeEquip(roleId, sid, equipOffInfo, equip.hid, id, equip); if (!!curEquip) curEquips.push(curEquip); curEquip = await dressEquip(roleId, sid, hero, equip); @@ -502,6 +515,8 @@ export class EquipHandler { let consumes: Array<{ id: number, count: number }> = []; let goods: Array<{ id: number, count: number }> = []; let equip = await EquipModel.getEquip(eid); + let oldJewelCount = equip.holes.filter(cur => cur.jewel > 0).length; + let { itid } = getGoodById(equip.id); let {equipJewel} = ITID.get(itid); let jewelInfo = getGoodById(jewel); @@ -528,6 +543,12 @@ export class EquipHandler { let hero = await HeroModel.findByHidAndRole(equip.hid, roleId); await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_ON, sid, roleId, hero, {}, [jewel, oldJewel]); } + + // 任务 + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_JEWEL, equip, [oldJewelCount]); + await checkTaskWithArgs(roleId, sid, TASK_TYPE.EQUIP_JEWEL_STAGE, [jewel, oldJewel]); + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_JEWEL_SUM, equip, [oldJewelCount]); + return resResult(STATUS.SUCCESS, { curEquip: { seqId: eid, holes: equip.holes } }); } @@ -567,6 +588,7 @@ export class EquipHandler { let sid: string = session.get('sid'); let goods: Array<{ id: number, count: number }> = []; let equip = await EquipModel.getEquip(eid); + let oldJewelCount = equip.holes.filter(cur => cur.jewel > 0).length; let index = findIndex(equip.holes, { id }); if (index > 0) return resResult(STATUS.EQUIP_HOLE_NOT_FIND); @@ -581,6 +603,11 @@ export class EquipHandler { let hero = await HeroModel.findByHidAndRole(equip.hid, roleId); await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_OFF, sid, roleId, hero, {}, [jewel]); } + + // 任务 + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_JEWEL, equip, [oldJewelCount]); + await checkTaskWithArgs(roleId, sid, TASK_TYPE.EQUIP_JEWEL_STAGE, [0, jewel]); + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_JEWEL_SUM, equip, [oldJewelCount]); return resResult(STATUS.SUCCESS, { curEquip: { seqId: eid, holes: equip.holes } }); } @@ -646,22 +673,24 @@ export class EquipHandler { let goodInfo = getGoodById(jewel); let good = ITID.get(goodInfo.itid); let needUpdate = false; - let oldJewel; + let oldJewel: number; let consumes: Array<{id: number, count: number, ratio?: number}> = []; - if (good.type != CONSUME_TYPE.JEWEL) + if (good.type != CONSUME_TYPE.JEWEL || !eid || eid < 0) return resResult(STATUS.WRONG_PARMS); - let equip; - if (!!eid) {//合成并穿戴 - equip = await EquipModel.getEquip(eid); - let index = findIndex(equip.holes,{id}); - //装备上该位置有穿戴该宝石,且在合成的材料中 - if (!!equip.holes[index] && equip.holes[index].jewel == goodInfo.composeMaterial[0].id) { - oldJewel = equip.holes[index].jewel; - equip.holes[index].jewel = jewel;//合成后的新宝石穿戴到装备上 - needUpdate = true; - consumes.push({id: goodInfo.composeMaterial[0].id, count: 1, ratio: 1});//ratio:1表示可以释放掉一颗宝石 - } + let equip = await EquipModel.getEquip(eid); + if(!equip) return resResult(STATUS.EQUIP_NOT_FIND); + + let oldJewelCount = equip.holes.filter(cur => cur.jewel > 0).length; + + let index = findIndex(equip.holes,{id}); + //装备上该位置有穿戴该宝石,且在合成的材料中 + if (!!equip.holes[index] && equip.holes[index].jewel == goodInfo.composeMaterial[0].id) { + oldJewel = equip.holes[index].jewel; + equip.holes[index].jewel = jewel;//合成后的新宝石穿戴到装备上 + needUpdate = true; + consumes.push({id: goodInfo.composeMaterial[0].id, count: 1, ratio: 1});//ratio:1表示可以释放掉一颗宝石 } + consumes = consumes.concat(goodInfo.composeMaterial); if (goodInfo.specialMaterial.count) { consumes.push({id: goodInfo.specialMaterial.ids[0], count: goodInfo.specialMaterial.count}) @@ -677,11 +706,17 @@ export class EquipHandler { let result = {}; if (needUpdate) { //穿戴宝石 - await EquipModel.updateEquipInfo(eid, { holes: equip.holes }); + equip = await EquipModel.updateEquipInfo(eid, { holes: equip.holes }); if (!!equip.hid) { let hero = await HeroModel.findByHidAndRole(equip.hid, roleId); await calPlayerCeAndSave(HERO_SYSTEM_TYPE.JEWEL_ON, sid, roleId, hero, {}, [jewel, oldJewel]); } + + // 任务 + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_JEWEL, equip, [oldJewelCount]); + await checkTaskWithArgs(roleId, sid, TASK_TYPE.EQUIP_JEWEL_STAGE, [jewel, oldJewel]); + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_JEWEL_SUM, equip, [oldJewelCount]); + return resResult(STATUS.SUCCESS, { curEquip: { seqId: eid, holes: equip.holes } }); } else { result = await addItems(roleId, roleName, sid, [{ id: jewel, count: count }]); diff --git a/game-server/app/servers/role/handler/friendHandler.ts b/game-server/app/servers/role/handler/friendHandler.ts index 4102b3d56..270a34b4f 100644 --- a/game-server/app/servers/role/handler/friendHandler.ts +++ b/game-server/app/servers/role/handler/friendHandler.ts @@ -1,7 +1,7 @@ import { Application, BackendSession, ChannelService } from "pinus"; import { resResult, getRandEelm, getResStr, shouldRefresh, getRefTime, sortArrRandom } from "../../../pubUtils/util"; -import { STATUS, ROLE_SELECT, FRIEND_DROP_TYPE, FRIEND_RELATION_TYPE, POPULATE_TYPE, BLOCK_OPEATE, CONSUME_TYPE, ITID, HERO_SELECT, EQUIP_SELECT, REDIS_KEY, MSG_SOURCE, MSG_TYPE } from "../../../consts"; -import { RoleModel, RoleType } from "../../../db/Role"; +import { STATUS, ROLE_SELECT, FRIEND_DROP_TYPE, FRIEND_RELATION_TYPE, POPULATE_TYPE, BLOCK_OPEATE, CONSUME_TYPE, ITID, HERO_SELECT, EQUIP_SELECT, REDIS_KEY, MSG_SOURCE, MSG_TYPE, TASK_TYPE } from "../../../consts"; +import Role, { RoleModel, RoleType } from "../../../db/Role"; import { getBeforeHourSeconds } from "../../../pubUtils/timeUtil"; import { FriendApplyModel } from "../../../db/FriendApply"; import { FriendApplyParams, FriendListParam, FriendRecommendParams, BlackListParam, FriendValueListParam } from "../../../domain/roleField/friend"; @@ -22,6 +22,7 @@ import { FRIEND } from "../../../pubUtils/dicParam"; import { PlayerDetail, PlayerDetailHero } from "../../../domain/battleField/guild"; import { createPrivateMsg, pushMsgToRole, pushPresent } from "../../../services/chatService"; import { Rank } from "../../../services/rankService"; +import { checkTaskWithRole, checkTaskWithRoles, checkTask } from "../../../services/taskService"; export default function (app: Application) { @@ -200,10 +201,12 @@ export class FriendHandler { // (一键)同意/拒绝申请 public async handleApply(msg: { applyCodeList: string[], isPass: boolean }, session: BackendSession) { let roleId: string = session.get('roleId'); + let sid: string = session.get('sid'); let { applyCodeList, isPass } = msg; let role = await RoleModel.findByRoleId(roleId); + let roles = new Array(); let friendCnt = role.friendCnt; let myFriendRelation = await FriendRelationModel.findFriendByRole(roleId, POPULATE_TYPE.NOT); @@ -230,6 +233,7 @@ export class FriendHandler { let friend = apply.friend; str = await increaseFrdCnt(role, friend, friendCnt); if(str != '') continue; + roles.push(friend); // 创建friendShip let friendShip = await FriendShipModel.createFriendShip([roleId, friend.roleId]); @@ -257,7 +261,10 @@ export class FriendHandler { } await FriendApplyModel.deleteApply(resultApplyCodeList); - await RoleModel.increaseFriendApplyCnt(roleId, -1 * resultApplyCodeList.length, 50); + role = await RoleModel.increaseFriendApplyCnt(roleId, -1 * resultApplyCodeList.length, 50); + roles.push(role); + // 任务 + await checkTaskWithRoles(roleId, sid, TASK_TYPE.FRIEND_NUM, roles); // 特殊处理:如果他点一键同意,有很多人,这个单独的人就不做这个额外的提示,直接把他好友申请删掉就好 if(str == getResStr(STATUS.FRIEND_HAS_ADD) && resultApplyCodeList.length > 1) str = ''; @@ -363,9 +370,11 @@ export class FriendHandler { // 拉黑/移除 public async setBlackList(msg: { roleId: string, type: number }, session: BackendSession) { let roleId: string = session.get('roleId'); + let sid: string = session.get('sid'); let { roleId: hisRoleId, type } = msg; let role = await RoleModel.findByRoleId(roleId); + let friend: RoleType; let str = '', list = new Array(), frdRoleIds = new Array(), blackRoleIds = new Array(); if(type == BLOCK_OPEATE.ADD) { // 拉黑 @@ -382,15 +391,12 @@ export class FriendHandler { if(!role) { return resResult(STATUS.FRIEND_BLACK_MAX) } - await RoleModel.increaseFriendCnt(hisRoleId, curFriend? -1: 0); // 对方好友减少 + friend = await RoleModel.increaseFriendCnt(hisRoleId, curFriend? -1: 0); // 对方好友减少 - let friend: RoleType, friendShip: FriendShipType; + let friendShip: FriendShipType; if(!!curFriend) { await FriendShipModel.clearValue([roleId, hisRoleId]); - friend = curFriend.role; friendShip = curFriend.friendShip; - } else { - friend = await RoleModel.findByRoleId(hisRoleId); } await FriendRelationModel.moveFromFriend(hisRoleId, role, friendShip, false, !!curFriend); //从对方好友删除 @@ -422,12 +428,11 @@ export class FriendHandler { if(!role) { return resResult(STATUS.FRIEND_NOT_FOUND) } - await RoleModel.increaseFriendCnt(hisRoleId, -1); // 对方好友减少 + friend = await RoleModel.increaseFriendCnt(hisRoleId, -1); // 对方好友减少 - let friend: RoleType, friendShip: FriendShipType; + let friendShip: FriendShipType; await FriendShipModel.clearValue([roleId, hisRoleId]); - friend = curFriend.role; friendShip = curFriend.friendShip; await FriendRelationModel.moveFromFriend(hisRoleId, role, friendShip, false, !!curFriend); //从对方好友删除 @@ -452,8 +457,8 @@ export class FriendHandler { if(type == BLOCK_OPEATE.REMOVE_AND_APPLY) { // 申请好友 - let applyResult = await RoleModel.increaseFriendApplyCnt(hisRoleId, 1, FRIEND.FRIEND_MANAGE_APPLICATION); - if(!applyResult) { + friend = await RoleModel.increaseFriendApplyCnt(hisRoleId, 1, FRIEND.FRIEND_MANAGE_APPLICATION); + if(!friend) { str = getResStr(STATUS.FRIEND_HIS_APPLY_MAX); } else { await FriendApplyModel.createApply(hisRoleId, role); @@ -467,6 +472,9 @@ export class FriendHandler { let { friendCnt = 0, blockCnt = 0 } = role; + // 任务 + await checkTaskWithRoles(roleId, sid, TASK_TYPE.FRIEND_NUM, [role, friend]); + return resResult(STATUS.SUCCESS, { frdRoleIds, blackRoleIds, isSuccess: str == '', @@ -480,6 +488,7 @@ export class FriendHandler { public async sendHeart(msg: { roleId: string }, session: BackendSession) { let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); + let sid: string = session.get('sid'); let { roleId: hisRoleId } = msg; @@ -533,6 +542,8 @@ export class FriendHandler { // 更新情谊值 frdPointRec = await FriendPointModel.updateSendCntToday(roleId, roleName, todaySendInc, max, FRIEND_DROP_TYPE.SEND_GIFT); + // 任务 + await checkTask(roleId, sid, TASK_TYPE.FRIEND_SEND_HEART, todaySendInc, true, {}); return resResult(STATUS.SUCCESS, { todaySendCnt, list diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index f3d968af3..d61e4a551 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -4,7 +4,7 @@ import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeServ import { resResult, returnHeroCeRatio, deepCopy } from '../../../pubUtils/util'; import { STATUS } from '../../../consts/statusCode'; import { HeroModel, Connect } from '../../../db/Hero'; -import {CURRENCY_BY_TYPE, CURRENCY_TYPE, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE, ABI_STAGE, DEBUG_MAGIC_WORD, HERO_INITIAL_QUALITY, REDIS_KEY} from '../../../consts'; +import {CURRENCY_BY_TYPE, CURRENCY_TYPE, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE, ABI_STAGE, DEBUG_MAGIC_WORD, HERO_INITIAL_QUALITY, REDIS_KEY, TASK_TYPE} from '../../../consts'; import { RoleModel } from '../../../db/Role'; import { ItemModel } from '../../../db/Item'; import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, getHeroLvByExp, getMaxGradeByjobClass, getJobByGradeAndClass, getFriendShipById, getFavourLvByExp } from '../../../pubUtils/data'; @@ -16,6 +16,7 @@ import { PvpDefenseModel } from '../../../db/PvpDefense'; import { Attribute } from '../../../domain/roleField/attribute'; import { nowSeconds } from '../../../pubUtils/timeUtil'; import { Rank } from '../../../services/rankService'; +import { checkTaskWithHero, checkTask } from '../../../services/taskService'; export default function(app: Application) { return new HeroHandler(app); @@ -205,6 +206,10 @@ export class HeroHandler { } hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.LVUP, sid, roleId, hero, update); + + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_LV, hero); + const curHero = { hid, lv : hero.lv, exp : hero.exp } @@ -248,7 +253,13 @@ export class HeroHandler { } hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAR, sid, roleId, hero, update); - if(isUpStar) await calAllHeroCe(HERO_SYSTEM_TYPE.STAR, sid, roleId, {}, [hid, isUpStar?1:0]); // 升星可能影响到百家学院全局加成 + if(isUpStar) { + await calAllHeroCe(HERO_SYSTEM_TYPE.STAR, sid, roleId, {}, [hid, isUpStar?1:0]); // 升星可能影响到百家学院全局加成 + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_STAR_UP, hero); + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_QUALITY_STAR_UP, hero); + } + const curHero = { hid, star : hero.star, @@ -298,6 +309,9 @@ export class HeroHandler { }); await calAllHeroCe(HERO_SYSTEM_TYPE.QUALITY, sid, roleId, {}, [hid, 0]); // 升品可能影响到百家学院全局加成 + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_QUALITY_UP, hero); + const curHero = { hid, quality : hero.quality @@ -352,8 +366,13 @@ export class HeroHandler { } hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, hero, update); - if(isUpStar) await calAllHeroCe(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, {}, [hid, isUpStar?1:0]); // 升星可能影响到百家学院全局加成 - + if(isUpStar) { + await calAllHeroCe(HERO_SYSTEM_TYPE.COLORSTAR, sid, roleId, {}, [hid, isUpStar?1:0]); // 升星可能影响到百家学院全局加成 + ; + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_STAR_UP, hero); + await checkTask(roleId, sid, TASK_TYPE.HERO_WAKE_UP, 1, true, {}); + } const curHero = { hid, star : hero.star, @@ -395,6 +414,10 @@ export class HeroHandler { hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.TRAIN, sid, roleId, hero, { jobStage: hero.jobStage + 1 }); + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_TRAIN, hero); + await checkTask(roleId, sid, TASK_TYPE.HERO_TRAIN_SUM, 1, true, {}); + return resResult(STATUS.SUCCESS, { curHero: {hid : hero.hid, job : hero.job, jobStage: hero.jobStage}}); } @@ -424,6 +447,9 @@ export class HeroHandler { jobStage: 0 } hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.STAGEUP, sid, roleId, hero, update); + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_STAGE_UP, hero); + return resResult(STATUS.SUCCESS, { curHero: {hid : hero.hid, job : hero.job, jobStage : hero.jobStage}}); } @@ -438,22 +464,19 @@ export class HeroHandler { if (!hero) return resResult(STATUS.HERO_NOT_FIND); let heroConnections: Connect[] = deepCopy(hero.connections); - let flag = true; - let level = 1; - for (let conection of heroConnections) { - if (conection.shipId == shipId ) { - if (conection.level >= shipHidAndLevel.level) { - return resResult(STATUS.HERO_CONECTION_IS_MAX_LEVEL); - } else { - flag = false; - conection.level++; - level = conection.level; - } - } - } - if (!!flag) { - heroConnections.push({shipId, level}); + + let curConnect = heroConnections.find(cur => cur.shipId == shipId); + if(!curConnect) { + curConnect = {shipId, level: 0}; + heroConnections.push(curConnect); } + if (curConnect.level >= shipHidAndLevel.level) { + return resResult(STATUS.HERO_CONECTION_IS_MAX_LEVEL); + } + + curConnect.level++; + let level = curConnect.level; + let friendShip = getFriendShipById(shipId, level); if (hero.star < friendShip.level) return resResult(STATUS.NOT_REACH_UNLOCK_LEVEL); @@ -473,6 +496,9 @@ export class HeroHandler { } //重算战力并下发 hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.CONNECT, sid, roleId, hero, { connections: heroConnections }, [shipId]); + + // 任务 + await checkTask(roleId, sid, TASK_TYPE.HERO_CONNECT, 1, true, { connectLv: level }) return resResult(STATUS.SUCCESS, { curHero: {hid : hero.hid, connections : hero.connections}}); } @@ -538,11 +564,14 @@ export class HeroHandler { } //重算战力并下发 - if (oldLv != hero.favourLv) { + if (oldLv != newLv) { await unlockFigure(sid, roleId, [{type: FIGURE_UNLOCK_CONDITION.HERO_FAVOR, paramHid: hero.hid, paramFavourLv: hero.favourLv }]); hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.FAVOUR, sid, roleId, hero, { favour: newExp, favourLv: newLv }, [oldLv]); + + // 任务 + await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, hero); } else { hero = await HeroModel.updateHeroInfo(roleId, hero.hid, { favour: newExp, favourLv: newLv }); } diff --git a/game-server/app/servers/role/handler/roleHandler.ts b/game-server/app/servers/role/handler/roleHandler.ts index 55d49be26..03c0a84b1 100644 --- a/game-server/app/servers/role/handler/roleHandler.ts +++ b/game-server/app/servers/role/handler/roleHandler.ts @@ -12,10 +12,11 @@ import { SclResultInter, SclPosInter } from '../../../pubUtils/interface'; import { SchoolModel } from '../../../db/School'; import { checkTeraphMaterialEnough } from '../../../services/roleService' import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService'; -import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT, REDIS_KEY } from '../../../consts'; +import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT, REDIS_KEY, TASK_TYPE } from '../../../consts'; import { checkBattleHeroesByHid } from '../../../services/normalBattleService'; import { Rank } from '../../../services/rankService'; import { updateUserInfo } from '../../../services/redisService'; +import { checkTaskWithHero, checkTask, checkTaskWithArgs } from '../../../services/taskService'; export default function(app: Application) { return new RoleHandler(app); @@ -99,6 +100,10 @@ export class RoleHandler { let update = { title: title + 1 } role = await calAllHeroCe(HERO_SYSTEM_TYPE.TITLE, sid, roleId, update); + + // 任务 + await checkTask(roleId, sid, TASK_TYPE.ROLE_TITLE, role.title, false, {}); + return resResult(STATUS.SUCCESS, { roleId, title: role.title }); } @@ -137,6 +142,10 @@ export class RoleHandler { return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); role = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH, sid, roleId, { teraphs }, [id]); + + // 任务 + await checkTask(roleId, sid, TASK_TYPE.ROLE_TERAPH_STRENGTHEN, count, true, {}); + return resResult(STATUS.SUCCESS, { roleId, teraphs: role.teraphs }); } @@ -258,6 +267,9 @@ export class RoleHandler { await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { hid, isOpen }) await calAllHeroCe(HERO_SYSTEM_TYPE.SCHOOL, sid, roleId, {}, [schoolId, hid, preHid]); + // 任务 + await checkTaskWithArgs(roleId, sid, TASK_TYPE.ROLE_SCHOOL_UNLOCK, [ hid, preHid ]); + return resResult(STATUS.SUCCESS, { schoolId, positionId, hid, preHid, isOpen }); @@ -292,6 +304,9 @@ export class RoleHandler { curSchool = await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { isOpen: true }) + // 任务 + await checkTask(roleId, sid, TASK_TYPE.ROLE_SCHOOL_UNLOCK, 1, true, {}); + return resResult(STATUS.SUCCESS, { schoolId, positionId, hid: curSchool.hid, isOpen: curSchool.isOpen }); @@ -347,6 +362,10 @@ export class RoleHandler { let hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.SCROLL, sid, roleId, curHero, update); // 更新单个武将战力 calAllHeroCe(HERO_SYSTEM_TYPE.SCROLL, sid, roleId, {}, [hid]); // 全局增加战力 + // 任务 + if(favourLv != hero.favourLv) await checkTaskWithHero(roleId, sid, TASK_TYPE.HERO_FAVOUR_LV, hero); + if(!scrollActive) await checkTask(roleId, sid, TASK_TYPE.ROLE_SCROLL_ACTIVE, 1, true, {}); + return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, diff --git a/game-server/app/services/actionPointService.ts b/game-server/app/services/actionPointService.ts index dbf45dc88..f988542a8 100644 --- a/game-server/app/services/actionPointService.ts +++ b/game-server/app/services/actionPointService.ts @@ -3,7 +3,8 @@ */ import { ActionPointModel } from '../db/ActionPoint'; -import { ACTION_POIN } from '../consts'; +import { ACTION_POIN, TASK_TYPE } from '../consts'; +import { checkTask } from './taskService'; export async function getAp(now: number, roleId: string) { let dataAp = await ActionPointModel.getAp(roleId); @@ -29,7 +30,7 @@ export async function getAp(now: number, roleId: string) { } } -export async function setAp(now: number, roleId: string, changeAp: number) { +export async function setAp(now: number, roleId: string, sid: string, changeAp: number) { let ApResult = await getAp(now, roleId); let { ap, maxAp, refTime, apRemainTime, isOver } = ApResult; // 更新ap ap += changeAp; @@ -41,5 +42,9 @@ export async function setAp(now: number, roleId: string, changeAp: number) { await ActionPointModel.saveAp(roleId, ap, refTime); if(isOver && ap < maxAp) apRemainTime = Math.floor(ACTION_POIN.PER / 1000); // 特殊处理 + + if(changeAp < 0) { + await checkTask(roleId, sid, TASK_TYPE.BATTLE_COST_AP, -1 * changeAp, true, {}); + } return {ap, maxAp, refTime, apRemainTime} } diff --git a/game-server/app/services/comBattleService.ts b/game-server/app/services/comBattleService.ts index f8da7d69f..c1fde85f3 100644 --- a/game-server/app/services/comBattleService.ts +++ b/game-server/app/services/comBattleService.ts @@ -1,6 +1,6 @@ import { MemComBtlTeam } from './../domain/battleField/ComBattleTeamField'; import { ItemModel } from './../db/Item'; -import { IT_TYPE } from './../consts/consts'; +import { IT_TYPE } from './../consts'; import { COM_BTL_QUALITY } from './../consts/constModules/itemConst'; import { FriendRelationModel } from './../db/FriendRelation'; import { RoleModel, RoleType } from './../db/Role'; diff --git a/game-server/app/services/equipService.ts b/game-server/app/services/equipService.ts index 8e4b1495c..f2e5cf46d 100644 --- a/game-server/app/services/equipService.ts +++ b/game-server/app/services/equipService.ts @@ -3,10 +3,11 @@ import { EquipModel } from "../db/Equip"; import { HeroModel, EPlace, HeroType } from "../db/Hero"; import { getHeroJob, getGoodById, gameData, getJewelById, getHeroEquipByClassId } from "../pubUtils/data"; import { calPlayerCeAndSave } from "./playerCeService"; -import { HERO_SYSTEM_TYPE } from "../consts"; +import { HERO_SYSTEM_TYPE, TASK_TYPE } from "../consts"; import { EquipType } from "../db/Equip"; import { calEquipSeids } from '../pubUtils/playerCe'; import { indexOf, findIndex } from 'underscore'; +import { checkTask, checkTaskWithHero, checkTaskWithEquip } from './taskService'; /** * 校验前端传入的消耗数量是否准确,并返回消耗的道具并加上特殊材料needConsumes * @param consumes @@ -44,40 +45,42 @@ export function checkMaterialEnough(consumes:Array<{id: number, count: number}>, return needConsumes; } /** - * 将装备卸载下来,并坚持是否有替换装备的武将,若有则替换 - * @param roleId + * 将装备卸载下来,并检查是否有替换装备的武将,若有则替换 + * 武将A(装备A)&武将B(装备B) ==> 武将A(装备B)&武将B(装备A) + * @param roleId 玩家id * @param sid - * @param equip - * @param hid - * @param id - * @param seqId + * @param equip 目标武将要卸下的装备,装备A + * @param hid 要装上的装备备原来装备着的武将id, 武将B + * @param id 装备类型 + * @param seqId 要装上的装备的唯一id 装备B */ -export async function changeEquip(roleId: string, sid: string, equip: EquipType, hid: number, id: number, seqId: number) { - let hero; +export async function changeEquip(roleId: string, sid: string, equipA: EquipType, hid: number, id: number, equipB: EquipType) { + let heroB: HeroType; if (!!hid) //需要卸下或者替换的武将 - hero = await HeroModel.findByHidAndRoleWithEquip(hid, roleId);//需要替换的武将 - if (!!equip) {//需要卸下的装备 - if (!!hero) { - let goodInfo = getGoodById(equip.id); - if (goodInfo.lvLimited > hero.lv) { - let res = await takeOffEquip(equip.seqId);//不能替换,卸载装备不算战力 + heroB = await HeroModel.findByHidAndRoleWithEquip(hid, roleId);//需要替换的武将 + + if (!!equipA) {//需要卸下的装备 + if (!!heroB) { + let goodInfo = getGoodById(equipA.id); + if (goodInfo.lvLimited > heroB.lv) { + let res = await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id);//卸下装备并重算战力 return res; } let { jobid } = gameData.hero.get(hid); let { job_class } = getHeroJob(jobid); let { classId } = getHeroEquipByClassId(goodInfo.itid); if (indexOf(classId, job_class) < 0) { - let res = await takeOffEquip(equip.seqId);//不能替换,卸载装备不算战力 + let res = await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id);//卸下装备并重算战力 return res; } - let res = await dressEquip(roleId, sid, hero, equip);//替换给武将,并计算战力 + let res = await dressEquip(roleId, sid, heroB, equipA);//替换给武将,并计算战力 return res; } else { - let res = await takeOffEquip(equip.seqId);//不能替换,卸载装备不算战力 + let res = await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id);//卸下装备并重算战力 return res; } - } else if (!!hero) {//从穿戴装备的武将上卸下装备 - await takeOffEquipAndCalPlayerCe(roleId, sid, hero, equip, id);//卸下装备并重算战力 + } else if (!!heroB) {//从穿戴装备的武将上卸下装备 + await takeOffEquipAndCalPlayerCe(roleId, sid, heroB, equipB, id);//卸下装备并重算战力 } } /** @@ -93,6 +96,12 @@ export async function takeOffEquipAndCalPlayerCe(roleId: string, sid: string, he hero = await HeroModel.removeEquip(roleId, hero.hid, id, equip._id); await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, args); + + // 任务 + await checkTask(roleId, sid, TASK_TYPE.EQUIP_SUM, 1, true, {}); + await checkTaskWithHero(roleId, sid, TASK_TYPE.EQUIP_BY_HERO, hero, [1]); + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_QUALITY, equip, [1]); + return { seqId: equip.seqId, hid: 0}; } /** @@ -107,13 +116,11 @@ export async function dressEquip(roleId: string, sid: string, hero:HeroType, equ hero = await HeroModel.addEquip(roleId, hero.hid, equip.ePlaceId, equip._id); await calPlayerCeAndSave(HERO_SYSTEM_TYPE.EQUIP, sid, roleId, hero, {}, args); + + // 任务 + await checkTask(roleId, sid, TASK_TYPE.EQUIP_SUM, -1, true, {}); + await checkTaskWithHero(roleId, sid, TASK_TYPE.EQUIP_BY_HERO, hero, [-1]); + await checkTaskWithEquip(roleId, sid, TASK_TYPE.EQUIP_QUALITY, equip, [-1]); + return { seqId: equip.seqId, hid: hero.hid }; -} -/** - * 修改装备未穿戴状态,不计算战力 - * @param seqId - */ -async function takeOffEquip(seqId: number) { - await EquipModel.updateEquipInfo(seqId, { hid: 0 }); - return { seqId, hid: 0}; } \ No newline at end of file diff --git a/game-server/app/services/friendService.ts b/game-server/app/services/friendService.ts index 042c0a71d..ecffaeb58 100644 --- a/game-server/app/services/friendService.ts +++ b/game-server/app/services/friendService.ts @@ -31,6 +31,7 @@ export async function increaseFrdCnt(role1: RoleType, role2: RoleType, originalF return getResStr(STATUS.FRIEND_THEY_CNT_MAX); } originalFriendCnt = incMyFrdCnt.friendCnt; + role1 = incMyFrdCnt; role2 = incHisFrdCnt; return ''; } diff --git a/game-server/app/services/normalBattleService.ts b/game-server/app/services/normalBattleService.ts index 3197b3c94..02f5cda41 100644 --- a/game-server/app/services/normalBattleService.ts +++ b/game-server/app/services/normalBattleService.ts @@ -4,10 +4,11 @@ import Role, { RoleModel } from '../db/Role' import { getLvByExp, getExpByLv, gameData } from '../pubUtils/data'; import { updateUserInfo } from './redisService'; import { switchOnFunc } from './funcSwitchService'; -import { FUNC_OPT_TYPE } from '../consts'; +import { FUNC_OPT_TYPE, TASK_TYPE } from '../consts'; import { BackendSession } from 'pinus'; import { REDIS_KEY } from '../consts'; import { Rank } from './rankService'; +import { checkTask } from './taskService'; export async function roleLevelup(roleId: string, kingExp: number, session: BackendSession) { let role = await RoleModel.findByRoleId(roleId); @@ -29,6 +30,9 @@ export async function roleLevelup(roleId: string, kingExp: number, session: Back let r = new Rank(REDIS_KEY.USER_LV, { serverId: role.serverId }); await r.setRankWithRoleInfo(roleId, newLv, Date.now(), role); + + // 任务 + await checkTask(roleId, session.get('sid'), TASK_TYPE.ROLE_LV, newLv, false, {}); } let actordata = []; for(let i = lv; i <= newLv; i++) { diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index f0098aefd..c34688796 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -143,6 +143,8 @@ export async function matchPlayerByRank(seasonNum: number, oppPlayers: OppPlayer oppRank ++; } } + } else if(myRank == 0){ + return false } else { if(pos == 1 || pos == 2) { // 刷新我前一名 oppRank = myRank - 1; diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index d27b318ae..cc44303f3 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -15,6 +15,7 @@ import { uniq, indexOf, findIndex } from 'underscore'; import { HeroModel } from '../db/Hero'; import { Figure } from '../domain/dbGeneral'; import { Rank } from './rankService'; +import { pushTaskUpdate } from './taskService'; export async function handleFixedReward(roleId: string, roleName: string, sid: string, rewardStr: string, multi: number) { let reward = parseGoodStr(rewardStr); @@ -114,22 +115,25 @@ export async function addItems(roleId: string, roleName: string, sid: string, go let figures: Array = []; let uids = [{uid: roleId, sid}]; sortItems(goods, bags, skins, figures, currencysMap, equips, showItems); - let equipInfos = []; + let equipInfos = [], taskPushMessage = []; for (let equip of equips) { - let equipInfo = await addEquips(roleId, roleName, equip); + let { equipInfo, pushMessage } = await addEquips(roleId, roleName, equip); showItems.push({seqId: equipInfo.seqId, id: equip.id, count: 1}); equipInfos.push(equipInfo); + taskPushMessage.concat(pushMessage); } //装备推送 if (!!equipInfos.length) pinus.app.get('channelService').pushMessageByUids('onEquipAdd', resResult(STATUS.SUCCESS, {equipInfos}), uids); + pushTaskUpdate(roleId, sid, taskPushMessage); + //货币推送 if (!!Object.keys(currencysMap).length) { let role = await RoleModel.findByRoleId(roleId); for (let key in currencysMap) { if (key == 'ap') { - let {ap} = await setAp(Date.now(), roleId, currencysMap[key]); + let {ap} = await setAp(Date.now(), roleId, sid, currencysMap[key]); currencysMap.ap = ap; } else { currencysMap[key] += role[key]; @@ -301,7 +305,7 @@ export async function pushFigureUpdate(roleId: string, sid: string, figureInfo: } export async function createHero(roleId: string, sid: string, serverId: number, heroInfo) { - let { hero, role, figureInfo, calHeroResult, calAllHeroResult } = await pubCreateHero(roleId, heroInfo); + let { hero, role, figureInfo, calHeroResult, calAllHeroResult, taskPushMessage } = await pubCreateHero(roleId, heroInfo); let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId }); await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role); @@ -311,5 +315,7 @@ export async function createHero(roleId: string, sid: string, serverId: number, hero = await pushCalPlayerCe(roleId, sid, calHeroResult); await pushCalAllHeroCe(roleId, sid, calAllHeroResult); + pushTaskUpdate(roleId, sid, taskPushMessage); + return hero; } \ No newline at end of file diff --git a/game-server/app/services/roleService.ts b/game-server/app/services/roleService.ts index 67902e3ed..760249109 100644 --- a/game-server/app/services/roleService.ts +++ b/game-server/app/services/roleService.ts @@ -1,7 +1,7 @@ import { ChannelUser } from './../domain/ChannelUser'; import { Channel } from 'pinus'; import { getRandNum, getRandomArr } from '../pubUtils/util'; -import { TERAPH_RANDOM } from "../consts/consts"; +import { TERAPH_RANDOM } from "../consts"; import { indexOf } from 'underscore'; import { DicTeraph } from '../pubUtils/dictionary/DicTeraph'; import { Teraph, RoleModel } from '../db/Role'; diff --git a/game-server/app/services/sysChatService.ts b/game-server/app/services/sysChatService.ts index 23f0b95f9..741326f06 100644 --- a/game-server/app/services/sysChatService.ts +++ b/game-server/app/services/sysChatService.ts @@ -37,7 +37,7 @@ export async function pushHeroStarMax(roleId: string, roleName: string, serverId } export async function pushHeroWakeUp(roleId: string, roleName: string, serverId: number | string, heroInfo: Partial) { - await pushNormalHeroInfoBySource(roleId, roleName, serverId, MSG_SOURCE.HERO_WAKEUP, heroInfo); + await pushNormalHeroInfoBySource(roleId, roleName, serverId, MSG_SOURCE.HERO_WAKE_UP, heroInfo); } diff --git a/game-server/app/services/taskService.ts b/game-server/app/services/taskService.ts new file mode 100644 index 000000000..9c02c5e41 --- /dev/null +++ b/game-server/app/services/taskService.ts @@ -0,0 +1,51 @@ +import * as taskUtil from '../pubUtils/taskUtil'; +import { RoleType } from '../db/Role'; +import { pinus } from 'pinus'; +import { resResult } from '../pubUtils/util'; +import { STATUS } from '../consts'; +import { TaskParam } from '../domain/roleField/task'; +import { HeroType } from '../db/Hero'; +import { EquipType } from '../db/Equip'; +import { getRoleOnlineInfo } from './redisService'; + +export async function checkTaskWithRoles(roleId: string, sid: string, taskType: number, roles: RoleType[]) { + for(let role of roles) { + await checkTaskWithRole(role.roleId, role.roleId == roleId? sid: null, taskType, role); + } +} + +export async function checkTaskWithRole(roleId: string, sid: string, taskType: number, role: RoleType) { + let pushMessage = await taskUtil.checkTaskWithRole(roleId, taskType, role); + pushTaskUpdate(roleId, sid, pushMessage); +} + +export async function checkTaskWithHero(roleId: string, sid: string, taskType: number, hero: HeroType, args?: number[]) { + let pushMessage = await taskUtil.checkTaskWithHero(roleId, taskType, hero, args); + pushTaskUpdate(roleId, sid, pushMessage); +} + +export async function checkTaskWithEquip(roleId: string, sid: string, taskType: number, equip: EquipType, args?: number[]) { + let pushMessage = await taskUtil.checkTaskWithEquip(roleId, taskType, equip, args); + pushTaskUpdate(roleId, sid, pushMessage); +} + +export async function checkTaskWithArgs(roleId: string, sid: string, taskType: number, args: number[]) { + let pushMessage = await taskUtil.checkTaskWithArgs(roleId, taskType, args); + pushTaskUpdate(roleId, sid, pushMessage); +} + +export async function checkTask(roleId: string, sid: string, taskType: number, count: number, isInc: boolean, param: TaskParam) { + let pushMessage = await taskUtil.checkTask(roleId, taskType, count, isInc, param); + pushTaskUpdate(roleId, sid, pushMessage); +} + +export async function pushTaskUpdate(roleId: string, sid: string, pushMessage: {type: number, id: number, count: number, received: boolean}[]) { + if(!sid) { + let onlineUser = await getRoleOnlineInfo(roleId); + sid = onlineUser.sid; + } + if(!!sid) { + let uids = [{uid: roleId, sid}]; + pinus.app.get('channelService').pushMessageByUids('onTaskUpdate', resResult(STATUS.SUCCESS, pushMessage), uids); + } +} \ No newline at end of file diff --git a/shared/consts/constModules/chatConst.ts b/shared/consts/constModules/chatConst.ts index 2037c5f0b..06a34ad25 100644 --- a/shared/consts/constModules/chatConst.ts +++ b/shared/consts/constModules/chatConst.ts @@ -21,6 +21,14 @@ export const CHANNEL_PREFIX = { CITY: 'city', // 军团活动,诸侯混战,按城池分channel } +export const CHANNEL_TYPE = new Map([ + [ CHANNEL_PREFIX.SYS, 1 ], + [ CHANNEL_PREFIX.WORLD, 2 ], + [ CHANNEL_PREFIX.GUILD, 3 ], + [ CHANNEL_PREFIX.TEAM, 4 ], + [ 'private', 5 ], +]); + // 消息来源 export const MSG_SOURCE = { ROLE_SEND_TEXT: 0, @@ -42,7 +50,7 @@ export const MSG_SOURCE = { MYSTERY_FIRST_SUC: 16, VESTIGE_FIRST_SUC: 17, TEAM_INVITE: 18, - HERO_WAKEUP: 19, + HERO_WAKE_UP: 19, EQUIP_REFRESH_BEST: 20, ACQUIRE_RARE_GOODS: 21, GROUP_SEND_GIFT: 22, diff --git a/shared/consts/constModules/itemConst.ts b/shared/consts/constModules/itemConst.ts index dc99c1259..c4044573e 100644 --- a/shared/consts/constModules/itemConst.ts +++ b/shared/consts/constModules/itemConst.ts @@ -265,4 +265,17 @@ export enum FIGURE_UNLOCK_CONDITION { GET_HERO = 1, // 获取武将 HERO_FAVOR = 2, // 武将好感度达到 GET_SKIN = 3, // 获得时装 -} \ No newline at end of file +} + +// 神像随机属性数量 +export const TERAPH_RANDOM = { + MIN: 2, + MAX: 4 +} + +// 道具特殊属性,如藏宝图等 +export const SPECIAL_ATTR = { + WAR_ID: 1, + TREASURE_ID: 2, + TREASURE_TYPE: 3 + } \ No newline at end of file diff --git a/shared/consts/constModules/selectConst.ts b/shared/consts/constModules/selectConst.ts index ca163b27f..6a39f7af1 100644 --- a/shared/consts/constModules/selectConst.ts +++ b/shared/consts/constModules/selectConst.ts @@ -1,7 +1,7 @@ export enum ROLE_SELECT { // 初始登录数据 - ENTRY = 'serverId userInfo.uid userInfo.tel userInfo.serverType ce topLineup topLineupCe teraphs roleId roleName tili lv exp gold coin vLv title hasGuild funcs eventStatus heads head frames frame spines spine guildCode frdCnt showLineup updatedAt heroNum heroNumUpdatedAt', + ENTRY = 'serverId userInfo.uid userInfo.tel userInfo.serverType ce topLineup topLineupCe teraphs roleId roleName tili lv exp gold coin vLv title hasGuild funcs eventStatus heads head frames frame spines spine guildCode frdCnt showLineup updatedAt heroNum heroNumUpdatedAt loginTime', // 玩家列表显示基础数据 SHOW_SIMPLE = 'roleId roleName ce head frame spine lv title job quitTime loginTime vLv guildName serverId userInfo.serverType', // 显示申请需要的信息 diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index bbe593416..d5173d23b 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -16,6 +16,8 @@ export const ADULT_AGE = 18; export const GUEST_MAX_TIME = 60 * 60; // 游客体验时间 export const GUEST_DAY = 15; // 同一设备15天内不得重复体验游客模式 +export const REFRESH_TIME = 5; // 统一一天刷新时间 + export const COUNTER = { UID: { name: 'uid', def: 1 }, GMUID: { name: 'gmuid', def: 1 }, @@ -461,7 +463,10 @@ export const FILENAME = { DIC_SHOP: 'dic_zyz_shop', DIC_SHOP_LIST: 'dic_zyz_shopList', DIC_RANK: 'dic_zyz_rankingType', - DIC_RANK_REWARD: 'dic_zyz_rankingReward' + DIC_RANK_REWARD: 'dic_zyz_rankingReward', + DIC_MAIN_TASK: 'dic_zyz_mainTask', + DIC_DAILY_TASK: 'dic_zyz_dailyTask', + DIC_ACHIEVEMENT: 'dic_zyz_achievement' } export const WAR_RELATE_TABLES = [ @@ -560,4 +565,51 @@ export enum SHOP_REFRESH_TYPE { WEEKLY = 2, // 每周 MONTHLY = 3, // 每月 FOREVER = 4 // 不重置 +} + +// 任务的大类 +export enum TASK_FUN_TYPE { + MAIN = 1, // 主线 + DAILY = 2, // 每日 + ACHIEVEMENT = 3, // 成就 +} + +export enum TASK_TYPE { + LOGIN_SUM = 1, // 累计登录 + LOGIN_SERIES = 2, // 连续登录 + ROLE_LV = 3, // 主公等级 + GASHA = 4, // 招募 暂无 + HERO_NUM = 5, // 武将数量 + HERO_STAR_UP = 6, // 升星次数 + HERO_QUALITY = 7, // 拥有品质 + HERO_QUALITY_STAR_UP = 8, // 某品质升星 + HERO_LV = 9, // 武将升级 + HERO_TRAIN = 10, // 武将训练 + HERO_QUALITY_UP = 11, // 武将升品 + HERO_WAKE_UP = 12, // 武将觉醒 + HERO_TRAIN_SUM = 13, // 武将总训练次数 + HERO_STAGE_UP = 14, // 武将兵种进阶 + HERO_FAVOUR_LV = 15, // 武将好感度升级 + HERO_CONNECT = 16, // 激活武将羁绊 + ROLE_SCHOOL_UNLOCK = 17, // 百家学宫解锁 + ROLE_SCHOOL_PUT_HERO = 18, // 百家学宫放置武将 + ROLE_TITLE = 19, // 爵位 + ROLE_TERAPH_STRENGTHEN = 20, // 神像强化 + ROLE_SCROLL_ACTIVE = 21, // 名将谱激活 + EQUIP_SUM = 22, // 总装备数 + EQUIP_BY_HERO = 23, // 各武将装备数量 + EQUIP_QUALITY = 24, // 装备品质 + EQUIP_STRENGTHEN = 25, // 装备栏强化 + EQUIP_JEWEL = 26, // 多少装备镶嵌宝石 + EQUIP_COMPOSE_SUIT = 27, // 合成套装 + EQUIP_SUIT = 28, // 拥有套装 + ROLE_SIGN = 29, // 签到 暂无 + EQUIP_REFINE = 30, // 成功精炼 + EQUIP_RESTRENGTHEN = 31, // 洗炼 + EQUIP_JEWEL_STAGE = 32, // 镶嵌几阶宝石 + EQUIP_JEWEL_SUM = 33, // 总计镶嵌多少宝石 + FRIEND_NUM = 34, // 好友人数 + FRIEND_SEND_HEART = 35, // 赠送友情点 + CHAT = 36, // 发送消息 + BATTLE_COST_AP = 37, // 消耗体力 } \ No newline at end of file diff --git a/shared/consts/consts.ts b/shared/consts/consts.ts deleted file mode 100644 index f3a83cd3d..000000000 --- a/shared/consts/consts.ts +++ /dev/null @@ -1,420 +0,0 @@ -export const TURBO_CORE_URL = 'https://coresrv.tgamebox.cn'; -export const APP_ID = 'AXaXmIHPs9eONvzrBesD8aSKQNXYdALF'; -export const TURBO_PARM_SECRET = 'ipqw05du6ob4x130w89t31yrqd6xs005zzltcmg2zpqnvrjp1s'; - -export const ENCRYPT_IV = 'f7182j5f04e377ux'; -export const ENCRYPT_KEY = 'fiqaxijabbantusmprc234fj'; - -export const AUTH_SMS_CNT_PER_DAY = 8; - -export const COUNTER = { - UID: {name:'uid',def:1}, - GMUID: {name:'gmuid',def:1}, - API: {name:'api',def:1}, - GM_GROUP: {name:'gmgroup',def:1}, - HID: {name:'hid',def:10000}, - EID: {name:'eid',def:1}, - ROLE: {name:'role',def:1} -}; - -export const ACTION_POIN = { - MAX: 100000, - PER: 6 * 60 * 1000 -}; -//武将养成系统分类 -export const HERO_SYSTEM_TYPE = { - STAR: 1, - TRAIN: 5, - STAGEUP:6, - SKIN:7, - FAVOUR:8, - CONNECT:9 -}; - -export const BATTLE_REWARD_TYPE = { - FIX_REWARD: 1, - CONDITION_REWARD: 2, - RANDOM_REWARD: 3 -}; - -export const IT_TYPE = { - BLUEPRT: 28 -} - -export const GOOD_QUALITY = [1, 2, 3, 4, 5]; - -// 大类型,区分存到哪张表里 -export const GOOD_TYPE = { - EQUIP: 1, - CONSUMES: 2, - SCRIPT: 3 -}; - -// 存到消耗品表内显示的类型 -export const CONSUME_TYPE = { - CONSUME: 1, // 消耗品 - SOUL: 2, // 将魂 - BLUEPRT: 3, // 藏宝图 - POINT: 4, // 远征币等 - EXP: 5, // 经验书 - FAVOUR: 6, // 好感度道具 - SKIN: 7, // 好感度道具 - PIECE: 8, // 装备碎片 - JEWEL: 9,//宝石 -}; - -const itid_array = [ - { id: 1, name: '剑', goodType: GOOD_TYPE.EQUIP }, - { id: 2, name: '枪', goodType: GOOD_TYPE.EQUIP }, - { id: 3, name: '刀', goodType: GOOD_TYPE.EQUIP }, - { id: 4, name: '弓', goodType: GOOD_TYPE.EQUIP }, - { id: 5, name: '拳', goodType: GOOD_TYPE.EQUIP }, - { id: 6, name: '扇', goodType: GOOD_TYPE.EQUIP }, - { id: 7, name: '宝剑', goodType: GOOD_TYPE.EQUIP }, - { id: 8, name: '权杖', goodType: GOOD_TYPE.EQUIP }, - { id: 9, name: '头盔', goodType: GOOD_TYPE.EQUIP }, - { id: 10, name: '帽子', goodType: GOOD_TYPE.EQUIP }, - { id: 11, name: '头巾', goodType: GOOD_TYPE.EQUIP }, - { id: 12, name: '铠甲(衣)', goodType: GOOD_TYPE.EQUIP }, - { id: 13, name: '战袍(衣)', goodType: GOOD_TYPE.EQUIP }, - { id: 14, name: '法衣(衣)', goodType: GOOD_TYPE.EQUIP }, - { id: 15, name: '铠甲(裤)', goodType: GOOD_TYPE.EQUIP }, - { id: 16, name: '战袍(裤)', goodType: GOOD_TYPE.EQUIP }, - { id: 17, name: '法衣(裤)', goodType: GOOD_TYPE.EQUIP }, - { id: 18, name: '重靴', goodType: GOOD_TYPE.EQUIP }, - { id: 19, name: '战靴', goodType: GOOD_TYPE.EQUIP }, - { id: 20, name: '布鞋', goodType: GOOD_TYPE.EQUIP }, - { id: 21, name: '饰品', goodType: GOOD_TYPE.EQUIP }, - { id: 22, name: '消耗类物品(图纸类)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.CONSUME }, - { id: 35, name: '消耗类物品(经验书)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.EXP }, - { id: 36, name: '消耗类物品(好感道具)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.FAVOUR }, - { id: 23, name: '消耗类物品(材料类)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.CONSUME }, - { id: 24, name: '消耗类物品(宝箱类)', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.CONSUME }, - { id: 26, name: '武将碎片', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.SOUL }, - { id: 27, name: '货币', goodType: GOOD_TYPE.CONSUMES, isCurrency: true }, - { id: 28, name: '藏宝图', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.BLUEPRT }, - { id: 29, name: '礼器', goodType: GOOD_TYPE.EQUIP }, - { id: 30, name: '宝甲', goodType: GOOD_TYPE.EQUIP }, - { id: 31, name: '名驹', goodType: GOOD_TYPE.EQUIP }, - { id: 32, name: '典籍', goodType: GOOD_TYPE.EQUIP }, - { id: 33, name: '神兵', goodType: GOOD_TYPE.EQUIP }, - { id: 34, name: '代币', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.POINT }, - { id: 39, name: '时装', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.SKIN }, - { id: 41, name: '装备碎片', goodType: GOOD_TYPE.CONSUMES, type: CONSUME_TYPE.PIECE } -]; - -export const ITID = new Map(); -for(let obj of itid_array) { - ITID.set(obj.id, obj); -} - -export const CURRENCY_TYPE = { - GOLD: "gold", - COIN: "coin", - ACTION_POINT: "ap", - TREASURE_POINT: "treasurePoint", - EXPEDITION_POINT: "expeditionPoint", - DUNGEON_POINT: "dungeonPoint", - FRIEND_POINT: "friendPoint" -} - -const currencyArr = [ - { "gid": 31001, "name": "铜钱", "type": CURRENCY_TYPE.COIN }, - { "gid": 31002, "name": "元宝", "type": CURRENCY_TYPE.GOLD }, - { "gid": 31003, "name": "体力", "type": CURRENCY_TYPE.ACTION_POINT }, - { "gid": 40001, "name": "远征币", "type": CURRENCY_TYPE.EXPEDITION_POINT }, - { "gid": 40002, "name": "寻宝币", "type": CURRENCY_TYPE.TREASURE_POINT }, - { "gid": 40003, "name": "情谊点", "type": CURRENCY_TYPE.FRIEND_POINT }, - { "gid": 40004, "name": "秘境币", "type": CURRENCY_TYPE.DUNGEON_POINT }, -]; -export const CURRENCY = new Map(); -export const CURRENCY_BY_TYPE = new Map(); -for(let obj of currencyArr) { - CURRENCY.set(obj.gid, obj); - CURRENCY_BY_TYPE.set(obj.type, obj.gid); -} - -export function getCurNameById(gid) { - let currency = CURRENCY.get(gid); - if (!currency) { - return; - } - if (currency.type == CURRENCY_TYPE.COIN) { - return 'coin'; - } else if (currency.type == CURRENCY_TYPE.GOLD) { - return 'gold'; - } else if (currency.type == CURRENCY_TYPE.ACTION_POINT) { - return 'ap'; - } else if (currency.type == CURRENCY_TYPE.FRIEND_POINT) { - return 'frdCnt'; - } else if (currency.type == CURRENCY_TYPE.EXPEDITION_POINT) { - return 'expeditionPoint'; - } -} - -export const WAR_TYPE = { - NORMAL: 1, // 主线本 - VESTIGE: 2, // 遗迹本 - EVENT: 3, // 事件本 - DAILY: 4, // 每日 - EXPEDITION: 5, // 远征 - MYSTERY: 6, // 秘境 - WARLOARDS: 7, // 群雄 - TOWER: 8, // 天梯 - PVP: 9, // PVP - GUILD_TIMER: 10, // 军团定时副本 - GUILD_WEEKLY: 11, // 军团周副本 - MAIN_ELITE: 12, // 主线精英 - MYSTERY_ELITE: 13 // 秘境精英 -}; - -// 藏宝图掉落参数 -export const BLUEPRT_CONST = { - REFRESH_TIME: 5, // 每天几点刷新 - DAILY_CNT: 5, // 每天最多掉落多少张 - PER_AP: 15 // 每多少体力掉落1张藏宝图 -}; - -// 事件,是否开启保存随机记录方式 -export const EVENT_RANDOM_TYPE_ONE_OPEN = false; -// 奇遇事件每次刷新几个 -export const EVENT_REFRESH_NUM = 3; -// 奇遇事件开启等级 -export const EVENT_START_LV = 1; - -// 存于用户Role表,事件开启状态 -export const EVENT_STATUS = { - WAITING: 0, // 未开启 - STARTING: 1, // 初步触发,等到挑战完成 - OPEN: 2 // 开启 -}; - -// 奇遇事件状态 -export const EVENT_RECORD_STATUS = { - WAITING: 0, // 初始状态 - BATTLE_SUCCESS: 1, // 挑战成功,待领取成功奖励 - BATTLE_FAIL: 2, // 挑战失败,可领取失败奖励 - SUCCESS_RECEIVED: 3, // 领取成功奖励 - FAIL_RECEIVED: 4 // 领取了失败奖励 -}; - -// 奇遇事件类型 -export const EVENT_TYPE = { - BOX: 1, // 宝箱 - QUIZ: 2, // 答题 - BATTLE: 3 // 战斗 -}; - -export const EVENT_ANSWER_STATUS = { - WAITING: 0, - CORRECT: 1, - WRONG: 2 -}; - -export const EXPEDITION_WAR_RECORD_STATUS = { - HIDE: -1, - WAITING: 0, - SUCCESS: 1, - FAIL: 2 -}; - -export const EVENT_START_BATTLE = 101; - -export const HANG_UP_CONSTS = { - ENABLE_LV: 2, // 第几层开始可以挂机 - UNIT_TIME: 10 * 60 * 1000, // 每几分钟能有一次收益 - MAX_TIME: 24 * 60 * 60 * 1000, // 最多可储存24小时收益 - MAX_SPD_UP_CNT: 2, // 每天可以收取多少次 - REFRESH_TIME: 5, // 每天的几点刷新 - SPD_UP_REC_TIME: 6 * 60 * 60 * 1000 // 加速直接获得6小时收益 -} - -export const TOWER_TASK_CONST = { - REFRESH_TIME: 5, // 每天几点刷新 - RAND_CNT: 8, // 每次刷新多少个任务 - MAX_TASK_REF_CNT: 8, // 完成的派遣任务数最多多少个 - MAX_HEROES_NUM: 3, // 每个任务最大派遣武将数 - COST_GOLD: 50 // 每次刷新花费的元宝 -} - -export const DAILY_CONST = { - REFRESH_TIME: 5 // 每天加点刷新 -} - -export const DUNGEON_CONST = { - REFRESH_TIME: 5, // 每天加点刷新 - MAX_CNT: 10, // 最大挑战次数 - MAX_BUY_CNT: 10 // 最大购买次数 -} - -export const EXPEDITION_CONST = { - REFRESH_TIME: 5, // 重置次数刷新时间 - INCREASE_POINT: 1, // 远征每成功一次累计的点数 - RESET_CNT: 1 // 可以免费重置的次数 -} - -export const EVENT_QUIZ_NUM = 3; - -export const DEFAULT_HEROES = [19, 53, 55, 54, 13]; - -export const FIX_SMS_CODE_TELS = ['18855953630', '13911134885', '15167549151', '15618654010', '15167549151', '18342915387']; - -export const GONGSHI = { - "TOWER_HANG_UP_SPEED_COST": "50", - "TOWER_TASK_REF_COST": "200", - "DAILY_REFRESH_NUM_COST": "50*num" -}; - -/** - * 计算元宝和次数相关的系数 - * 公式: A * num + B - */ -export const GOLD_COST_RATIO = { - "TOWER_HANG_SPDUP": { "A": 0, "B": 50 }, // 天梯挂机加速花费 - "TOWER_TASK_REF": { "A": 0, "B": 50 }, // 天梯派遣刷新花费 - "DAILY_REF_NUM": { "A": 50, "B": 0 }, // 每日购买次数花费 - "DUNGRON_BUY_NUM": { "A": 0, "B": 50 } // 秘境购买次数花费 -} - -export const EXPRESSION = { - "CE": "1*hp+2*atk+2*matk+2*def+2*mdef+2*agi+2*luk+0*hit+0*cri+0*flee+0*antCri+0*damageIncrease+0*damageDecrease+0*defIngnore+0*bloodSuck" -} - -// 寻宝(共斗)相关 -export const COM_TEAM_STATUS = { - DEFAULT: 0, - FIGHTING: 1, - WIN: 2, - LOOSE: 3 -} - - -// 寻宝配置常量 -export const COM_BTL_CONST = { - ENABLE_LV: 1, // 功能开启等级 - ASSIST_DROP_RATE: 0.5, // 助战掉落占队长掉落的比例 - BLUEPRT_DROP_PER_AP: 10, // 藏宝图伪随机所需体力 - BTL_TIME_LMT: 10 * 60 * 1000, // 每局时长限制 - ROBOT_HURT_RAND_RATE: 0.05, // 每个机器人消耗 boss 血量百分比浮动范围 - FRDCNT_DROP: 10, // 每场情谊点掉落 - ROBOT_CE_RATIO: 0.2, // 机器人战力上下浮动百分比 - ASSIST_TIME: 60 * 1000, // 助战匹配机器人的等待时长 - CAP_TIME: 60 * 1000, // 队长匹配机器人的等待时长 - CAP_START_TIME: 60 * 1000, // 人齐后队长开始时长倒计时 - ROBOT_RND_LMT: 10, // 机器人输出伤害的回合数 - ROBOT_HURT_RATIO: 0.2, // 单个机器人输出总伤害占 boss 血量比重 - ROBOT_HURT_CH_RATIO: 0.1, // 机器人伤害上下浮动的比例 - ASSIST_REWARD_RATIO: 0.5, // 队员奖励比例 -} - -// 机器人名字随机 -export const COM_BATTLE_ROBOT_ID_NAME = [ - {robotRoleId: 'cd9h0iy8', robotRoleName: '徐埋农'}, - {robotRoleId: 'rtdgr4oz', robotRoleName: '简普瞳'}, - {robotRoleId: 'rv96unin', robotRoleName: '邛瑛'}, - {robotRoleId: 'b33u625l', robotRoleName: '嵇晁伊'}, - {robotRoleId: 'l6wopj9p', robotRoleName: '颜校'}, - {robotRoleId: '6wdqcumj', robotRoleName: '吉辉娇'} -]; - -export const REDIS_KEY = { - USER_INFO: "userInfo", // 玩家缓存信息 - TOWER_RANK: "towerRank", // 天梯排行榜 - COM_TEAM_SEARCH_PRE: 'comTeamSerQ', // 匹配中的玩家,按品质分 - PVP_RANK: 'pvpRank' -} - -export const FUNC_OPT_TYPE = { - LEVEL_UP: 1, - BATTLE_END: 2 -} - - -export const FUNCS_ID = { - EVENT: 1 -} - -export const FRIEND_DROP_TYPE = { - COM_BATTLE: 1 -} - -// 每日情谊点上限 -export const FRIEND_DROP_MAX = { - COM_BTL: 150 -} - - -// 武将上限 -export const HERO_GROW_MAX = { - STAR: 6, - COLORSTAR: 6, - QUALITY: 3 -} - -export const JOB_TYPE = { - PHYSIC: 1, - MAGIC: 2 -} - -export const TERAPH_RANDOM = { - MIN: 2, - MAX: 4 -} - -export const SPECIAL_ATTR = { - WAR_ID: 1, - TREASURE_ID: 2, - TREASURE_TYPE: 3 -} - -export const FILENAME = { - DIC_BLUEPRT_COMPOSE: 'dic_blueprt_compose', - DIC_BLUEPRT_POSSIBILITY: 'dic_blueprt_possibility', - DIC_EXPEDITION: 'dic_expedition', - DIC_EXPEDITION_POINT: 'dic_expedition_point', - DIC_FUNC_SWITCH: 'dic_func_switch', - DIC_GOODS: 'dic_goods', - DIC_CHAREXP: 'dic_zyz_charexp', - DIC_DAILY: 'dic_zyz_daily', - DIC_EVENT: 'dic_zyz_event', - DIC_FASHIONS: 'dic_zyz_fashions', - DIC_FRIEND_SHIP: 'dic_zyz_friend_ship', - DIC_FRIEND_SHIP_LEVEL: 'dic_zyz_friend_ship_level', - DIC_GACHA: 'dic_gacha', - DIC_GK_BRANCH: 'dic_zyz_gk_branch', - DIC_GK_DAILY: 'dic_zyz_gk_daily', - DIC_GK_DUNGEON: 'dic_zyz_gk_dungeon', - DIC_GK_DUNGEON_ELITE: 'dic_zyz_gk_dungeonElite', - DIC_GK_EVENT: 'dic_zyz_gk_event', - DIC_GK_EXPEDITION: 'dic_zyz_gk_expedition', - DIC_GK_MAIN: 'dic_zyz_gk_main', - DIC_GK_MAIN_ELITE: 'dic_zyz_gk_mainElite', - DIC_GK_TOWER: 'dic_zyz_gk_tower', - DIC_GK_TREASURE: 'dic_zyz_gk_Treasure', - DIC_HERO: 'dic_zyz_hero', - DIC_HERO_QUALITY_UP: 'dic_zyz_hero_quality_up', - DIC_HERO_STAR: 'dic_zyz_hero_star', - DIC_HERO_WAKE: 'dic_zyz_hero_wake', - DIC_HERO_SKILL: 'dic_zyz_heroskill', - DIC_JOB: 'dic_zyz_job', - DIC_KING_EXP: 'dic_zyz_kingexp', - DIC_CHAR_EXP: 'dic_zyz_charexp', - DIC_SE: 'dic_zyz_se', - DIC_TOWER_TASK: 'dic_zyz_search', - DIC_TOWER: 'dic_zyz_tower', - DIC_XUNBAO: 'dic_zyz_xunbao', - DIC_QUESTION: 'Questions', -} - -export const WAR_RELATE_TABLES = [ - FILENAME.DIC_GK_BRANCH, - FILENAME.DIC_GK_DAILY, - FILENAME.DIC_GK_DUNGEON, - FILENAME.DIC_GK_DUNGEON_ELITE, - FILENAME.DIC_GK_EVENT, - FILENAME.DIC_GK_EXPEDITION, - FILENAME.DIC_GK_MAIN, - FILENAME.DIC_GK_MAIN_ELITE, - FILENAME.DIC_GK_TOWER, - FILENAME.DIC_GK_TREASURE -] diff --git a/shared/db/Role.ts b/shared/db/Role.ts index a8ef8f067..f098ce0b7 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -295,9 +295,16 @@ export default class Role extends BaseModel { return role; } - public static async findByUid(uid: number, serverId: number, select?: string, getters = false) { + public static async findByUidAndSetTime(uid: number, serverId: number, select?: string, getters = false) { const curSec = nowSeconds(); - const role: RoleType = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, { loginTime: curSec, quitTime: curSec }, { new: true }).select(select).lean({ getters, virtuals: true }); + // 为了计算累计登录,此处查询new为false + const role: RoleType = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, { loginTime: curSec, quitTime: curSec }, { new: false }).select(select).lean({ getters, virtuals: true }); + return role; + } + + public static async findByUid(uid: number, serverId: number, select?: string, getters = false) { + const role: RoleType = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).select(select).lean({ getters, virtuals: true }); + return role; } diff --git a/shared/db/UserTaskRec.ts b/shared/db/UserTaskRec.ts new file mode 100644 index 000000000..8ffcc7216 --- /dev/null +++ b/shared/db/UserTaskRec.ts @@ -0,0 +1,52 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; +import { TASK_FUN_TYPE } from '../consts'; +import { genCode } from '../pubUtils/util'; + +/** + * 玩家购买商店记录表,每个商品一条,每次刷新新建一条 +**/ +@modelOptions({ schemaOptions: { id: false } }) +@index({ roleId: 1, itemId: 1 }) + +export default class UserTaskRec extends BaseModel { + @prop({ required: true }) + code: string; // 该记录唯一标识 + + @prop({ required: true }) + roleId: string; // 玩家id + + @prop({ required: true, enum: TASK_FUN_TYPE }) + type: number; // 任务类型 + + @prop({ required: true }) + id: number; // 任务id,任务表内id + + @prop({ required: true }) + taskType: number; // 行为类型 + + @prop({ required: true }) + group: number; // 行为类型下的分组 + + @prop({ required: true }) + count: number; // 达成次数 + + @prop({ required: true, default: false }) + received: boolean; // 是否已领取 + + public static async setTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) { + let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, type, group }, { $setOnInsert: { code: genCode(8), taskType, received: false }, $set: { count } }, { new: true, upsert: true }).lean(); + return rec; + } + + public static async incTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) { + + let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, type, group }, { $setOnInsert: { code: genCode(8), taskType, received: false }, $inc: { count } }, { new: true, upsert: true }).lean(); + return rec; + } +} + +export const UserTaskRecModel = getModelForClass(UserTaskRec); + +export interface UserTaskRecType extends Pick, keyof UserTaskRec> { } +export type UserTaskRecParam = Partial; diff --git a/shared/domain/battleField/guild.ts b/shared/domain/battleField/guild.ts index dcb7d8d35..f53bc2b10 100644 --- a/shared/domain/battleField/guild.ts +++ b/shared/domain/battleField/guild.ts @@ -1,7 +1,7 @@ import { PvpEnemies, PvpOtherHeroes, WarStar } from "../../domain/dbGeneral"; import { GuildType } from "../../db/Guild"; import { RoleType } from "../../db/Role"; -import { WAR_TYPE } from "../../consts/consts"; +import { WAR_TYPE } from "../../consts"; import { gameData } from "../../pubUtils/data"; import { EXTERIOR } from "../../pubUtils/dicParam"; diff --git a/shared/domain/roleField/task.ts b/shared/domain/roleField/task.ts new file mode 100644 index 000000000..e4ef0aeb7 --- /dev/null +++ b/shared/domain/roleField/task.ts @@ -0,0 +1,12 @@ +export class TaskParam { + star?: number; + quality?: number; + lv?: number; + count?: number; + favourLv?: number; + connectLv?: number; + isPutOn?: number; + oldLv?: number; + stage?: number; + chatType?: number; +} \ No newline at end of file diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index d26ce25c6..4da39b1db 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -18,7 +18,7 @@ import { dicTowerTask } from "./dictionary/DicTowerTask"; import { dicWar, dicWarPvp } from "./dictionary/DicWar"; import { dicWarJson } from "./dictionary/DicWarJson"; import { dicXunbao } from "./dictionary/DicXunbao"; -import { SPECIAL_ATTR } from "../consts/consts"; +import { SPECIAL_ATTR } from "../consts"; import { dicFashions } from "./dictionary/DicFashions"; import { friendShips, friendShipHidAandIds } from "./dictionary/DicFriendShip"; import { maxFriendShipLv, dicFriendShipLevelMap } from "./dictionary/DicFriendShipLevel"; @@ -73,6 +73,7 @@ import { dicShop, dicShopItem } from "./dictionary/DicShop"; import { dicShopList } from "./dictionary/DicShopList"; import { dicRank } from "./dictionary/DicRank"; import { dicRankReward } from "./dictionary/DicRankReward"; +import { dicTaskType, dicMainTask, dicDailyTask, dicAchievement } from "./dictionary/DicTask"; export const gameData = { blurprtCompose: dicBlueprtCompose, @@ -171,7 +172,11 @@ export const gameData = { shopList: dicShopList, dicMyHeroes: dicMyHeroes, rank: dicRank, - generalRankReward: dicRankReward + generalRankReward: dicRankReward, + taskType: dicTaskType, + mainTask: dicMainTask, + dailyTask: dicDailyTask, + achievement: dicAchievement }; // 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据 diff --git a/shared/pubUtils/dictionary/DicSuit.ts b/shared/pubUtils/dictionary/DicSuit.ts index 949281b90..3d1ea43d9 100644 --- a/shared/pubUtils/dictionary/DicSuit.ts +++ b/shared/pubUtils/dictionary/DicSuit.ts @@ -1,5 +1,5 @@ // 镇念塔表 -import { decodeArrayListStr, readJsonFile } from '../util' +import { decodeArrayListStr, readJsonFile, parseNumberList } from '../util' import { FILENAME } from '../../consts'; export interface DicSuit { @@ -11,7 +11,7 @@ export interface DicSuit { readonly totalCount: number; // 套装效果 readonly effect: Array<{ count: number, seid: number }>; - readonly tireInfo: Map; + readonly tireInfo: Array; } const str = readJsonFile(FILENAME.DIC_SUIT); @@ -21,7 +21,7 @@ export const dicSuit = new Map(); arr.forEach(o => { o.effect = parseSuitEffect(o.effect); - o.tireInfo = parseTireInfo(o.tireInfo); + o.tireInfo = parseNumberList(o.tireInfo); dicSuit.set(o.id, o); }); arr = undefined; @@ -37,13 +37,4 @@ function parseSuitEffect(str: string) { result.push({ count: parseInt(count), seid: parseFloat(seid) }); } return result -} - -function parseTireInfo(str: string) { - let result = new Map(); - let arrs = str.split('&'); - for (let arr of arrs) { - result.set(parseInt(arr), 1); - } - return result; } \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicTask.ts b/shared/pubUtils/dictionary/DicTask.ts new file mode 100644 index 000000000..db3f37aee --- /dev/null +++ b/shared/pubUtils/dictionary/DicTask.ts @@ -0,0 +1,132 @@ +// 任务 +import { RewardInter } from '../interface'; +import { readJsonFile, parseNumberList, parseGoodStr } from '../util'; +import { FILENAME, TASK_FUN_TYPE} from '../../consts'; +const _ = require('lodash'); + +type KeysEnum = { [P in keyof Required]: true }; + +interface DicTaskBase { + // id + readonly id: number; + // 任务类型 + readonly taskType: number; + // 类型下面的分组 + readonly group: number; + // 任务参数 + readonly taskParam: number[]; + // 条件 + readonly condition: number; +} + +const DicTaskKeys: KeysEnum = { + id: true, + taskType: true, + group: true, + taskParam: true, + condition: true +}; + +// 主线任务 +export interface DicMainTask extends DicTaskBase { + // 奖励 + readonly taskReward: RewardInter[]; + // 任务阶段 + readonly taskStage: number; +} + +const DicMainTaskKeys: KeysEnum = { + id: true, + taskType: true, + group: true, + taskParam: true, + condition: true, + taskStage: true, + taskReward: true +}; + +// 每日任务 +export interface DicDailyTask extends DicTaskBase { + // 奖励 + readonly taskReward: RewardInter[]; + // 活跃 + readonly point: number; + // 经验基数 + readonly exp: number; +} + +const DicDailyTaskKeys: KeysEnum = { + id: true, + taskType: true, + group: true, + taskParam: true, + condition: true, + taskReward: true, + point: true, + exp: true +}; + +// 成就 +export interface DicAchievement extends DicTaskBase { + // 奖励 + readonly taskReward: RewardInter[]; + // 活跃 + readonly point: number; +} + +const DicAchievementKeys: KeysEnum = { + id: true, + taskType: true, + group: true, + taskParam: true, + condition: true, + taskReward: true, + point: true +}; + +export type DicTask = DicTaskBase & { type: number }; + +export const dicMainTask = new Map(); // 主线任务 +export const dicDailyTask = new Map(); // 每日任务 +export const dicAchievement = new Map(); // 成就 + +export const dicTaskType = new Map(); + +const mainTask = readJsonFile(FILENAME.DIC_MAIN_TASK); +let arrMainTask = JSON.parse(mainTask); +arrMainTask.forEach(o => { + o.taskParam = parseNumberList(o.taskParam); + o.taskReward = parseGoodStr(o.taskReward); + dicMainTask.set(o.id, _.pick(o, Object.keys(DicMainTaskKeys))); + pushDicTaskType(o.taskType, TASK_FUN_TYPE.MAIN, o); +}); +arrMainTask = undefined; + +const dailyTask = readJsonFile(FILENAME.DIC_DAILY_TASK); +let arrDailyTask = JSON.parse(dailyTask); +arrDailyTask.forEach(o => { + o.taskParam = parseNumberList(o.taskParam); + o.taskReward = parseGoodStr(o.taskReward); + dicDailyTask.set(o.id, _.pick(o, Object.keys(DicDailyTaskKeys))); + pushDicTaskType(o.taskType, TASK_FUN_TYPE.DAILY, o); +}); +arrDailyTask = undefined; + +const achievement = readJsonFile(FILENAME.DIC_ACHIEVEMENT); +let arrAchievement = JSON.parse(achievement); +arrAchievement.forEach(o => { + o.taskParam = parseNumberList(o.taskParam); + o.taskReward = parseGoodStr(o.taskReward); + dicAchievement.set(o.id, _.pick(o, Object.keys(DicAchievementKeys))); + pushDicTaskType(o.taskType, TASK_FUN_TYPE.ACHIEVEMENT, o); +}); +arrAchievement = undefined; + +function pushDicTaskType(taskType: number, type: number, o: any) { + if(!dicTaskType.has(taskType)) { + dicTaskType.set(taskType, new Array()); + } + let newObj = _.pick(o, Object.keys(DicTaskKeys)); + newObj.type = type; + dicTaskType.get(taskType).push(newObj) +} \ No newline at end of file diff --git a/shared/pubUtils/itemUtils.ts b/shared/pubUtils/itemUtils.ts index 412629d99..bed2b50e8 100644 --- a/shared/pubUtils/itemUtils.ts +++ b/shared/pubUtils/itemUtils.ts @@ -5,7 +5,7 @@ import { ItemModel } from '../db/Item'; import { EquipModel, RandSe, Holes } from './../db/Equip'; import { BagInter, EquipInter } from './interface'; import { gameData } from './data'; -import { RANDOM_SE_COUNT, FIX_ATTRIBUTES_RAN, ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE } from '../consts'; +import { RANDOM_SE_COUNT, FIX_ATTRIBUTES_RAN, ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, TASK_TYPE } from '../consts'; import { getRandValueByMinMax, getRandEelm } from './util'; import { findWhere } from 'underscore'; @@ -13,6 +13,7 @@ import { RoleModel, RoleType } from '../db/Role'; import { Figure } from '../domain/dbGeneral'; import { getBeforeDaySeconds, nowSeconds } from './timeUtil'; import { calPlayerCeAndSave, reCalAllHeroCe } from './playerCe'; +import { checkTask, checkTaskWithHeroes, checkTaskWithEquip } from './taskUtil'; export async function addSkins(roleId: string, id: number) { let skinInfo = gameData.fashion.get(id); @@ -61,7 +62,11 @@ export async function addEquips(roleId: string, roleName: string, weapon: EquipI } const equip = await EquipModel.createEquip({roleId, roleName, id, name, quality, suitId, randRange, ePlaceId: type, randSe, holes, hid}); - return equip + + // 任务 + let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip); + + return { equipInfo: equip, pushMessage } } /** @@ -217,8 +222,8 @@ function unlockSingleFigure(dbFigures: Figure[], id: number, unlockDirect = fals } export async function createHero(roleId: string, heroInfo: HeroUpdate) { - let { role, figureInfo, heroes, calHeroResults, calAllHeroResults } = await createHeroes(roleId, [heroInfo]) - return { hero: heroes[0], role, figureInfo, calHeroResult: calHeroResults[0], calAllHeroResult: calAllHeroResults[0] } + let { role, figureInfo, heroes, calHeroResults, calAllHeroResults, taskPushMessage } = await createHeroes(roleId, [heroInfo]) + return { hero: heroes[0], role, figureInfo, calHeroResult: calHeroResults[0], calAllHeroResult: calAllHeroResults[0], taskPushMessage } } export async function createHeroes(roleId: string, heroInfos: HeroUpdate[]) { @@ -226,7 +231,7 @@ export async function createHeroes(roleId: string, heroInfos: HeroUpdate[]) { let heroNum = 0; let skinIds = new Array(); let conditions = new Array<{type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); - let heroes = [], calHeroResults = [], calAllHeroResults = []; + let heroes = [], calHeroResults = [], calAllHeroResults = []; for(let heroInfo of heroInfos) { let curHero = await HeroModel.createHero(heroInfo); heroes.push(curHero); @@ -243,5 +248,11 @@ export async function createHeroes(roleId: string, heroInfos: HeroUpdate[]) { let figureInfo = await unlockFigure(roleId, conditions); // 解锁头像 let role = await RoleModel.incRoleInfo(roleId, { heroNum }, { heroNumUpdatedAt: nowSeconds() }); - return { role, figureInfo, heroes, calHeroResults, calAllHeroResults } + // 任务 + let m1 = await checkTask(roleId, TASK_TYPE.HERO_NUM, heroNum, true, {}); + let m2 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY, heroes); + let m3 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, heroes); + let m4 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_LV, heroes); + let taskPushMessage = m1.concat(m2, m3, m4); + return { role, figureInfo, heroes, calHeroResults, calAllHeroResults, taskPushMessage } } \ No newline at end of file diff --git a/shared/pubUtils/taskUtil.ts b/shared/pubUtils/taskUtil.ts new file mode 100644 index 000000000..fa9fe0945 --- /dev/null +++ b/shared/pubUtils/taskUtil.ts @@ -0,0 +1,346 @@ +import { gameData } from './data'; +import { DicTask } from './dictionary/DicTask'; +import { TASK_TYPE, ABI_STAGE } from '../consts'; +import { UserTaskRecModel, UserTaskRecType } from '../db/UserTaskRec' +import { RoleType } from '../db/Role'; +import { TaskParam } from '../domain/roleField/task'; +import { getTodayZeroPoint } from './timeUtil'; +import { HeroType } from '../db/Hero'; +import { EquipType, EquipModel } from '../db/Equip'; + +export async function checkTaskWithRoles(taskType: number, roles: RoleType[]) { + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + for(let role of roles) { + let singlePush = await checkTaskWithRole(role.roleId, taskType, role); + pushMessage.concat(singlePush); + } + return pushMessage +} + +export async function checkTaskWithRole(roleId: string, taskType: number, role: RoleType) { + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + + if(taskType == TASK_TYPE.LOGIN_SUM) + { + let today = getTodayZeroPoint(); + if(today > role.loginTime) { + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } + } + else if (taskType == TASK_TYPE.LOGIN_SERIES) + { + let today = getTodayZeroPoint(); + if(today > role.loginTime) { + if(today - role.loginTime > 24 * 60 * 60 ) { + pushMessage = await checkTask(roleId, taskType, 1, false, {}); + } else { + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } + } + } + else if (taskType == TASK_TYPE.FRIEND_NUM) + { + let { friendCnt } = role; + pushMessage = await checkTask(roleId, taskType, friendCnt, false, {}); + } + + return pushMessage +} + + +export async function checkTaskWithHeroes(roleId: string, taskType: number, heroes: HeroType[]) { + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + for(let hero of heroes) { + let singlePush = await checkTaskWithHero(roleId, taskType, hero); + pushMessage.concat(singlePush); + } + return pushMessage +} + +export async function checkTaskWithHero(roleId: string, taskType: number, hero: HeroType, args?: number[]) { + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + if(taskType == TASK_TYPE.HERO_STAR_UP) + { + let dicHero = gameData.hero.get(hero.hid); + let starUp = hero.star - dicHero.initialStars; + if(hero.colorStar > 1) starUp += hero.colorStar - 1; + pushMessage = await checkTask(roleId, taskType, 1, true, { star: starUp }) + } + else if(taskType == TASK_TYPE.HERO_QUALITY) + { + let dicHero = gameData.hero.get(hero.hid); + pushMessage = await checkTask(roleId, taskType, 1, true, { quality: dicHero.quality }); + } + else if (taskType == TASK_TYPE.HERO_QUALITY_STAR_UP) + { + let dicHero = gameData.hero.get(hero.hid); + pushMessage = await checkTask(roleId, taskType, 1, true, { quality: dicHero.quality, star: hero.star }); + } + else if (taskType == TASK_TYPE.HERO_LV) + { + pushMessage = await checkTask(roleId, taskType, 1, true, { lv: hero.lv }); + } + else if (taskType == TASK_TYPE.HERO_TRAIN) + { + let dicHero = gameData.hero.get(hero.hid); + let initGrage = gameData.job.get(dicHero.jobid).grade; + let curGrade = gameData.job.get(hero.job).grade; + let count = (curGrade - initGrage) * (ABI_STAGE.END - ABI_STAGE.START) + (hero.jobStage - ABI_STAGE.START); // 训练次数 + pushMessage = await checkTask(roleId, taskType, 1, true, { count }); + } + else if (taskType == TASK_TYPE.HERO_QUALITY_UP) + { + let dicHero = gameData.hero.get(hero.hid); + if(hero.quality - dicHero.quality == 1) { // 每个武将升品算一次 + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } + } + else if (taskType == TASK_TYPE.HERO_STAGE_UP) + { + let dicHero = gameData.hero.get(hero.hid); + let initGrage = gameData.job.get(dicHero.jobid).grade; + let curGrade = gameData.job.get(hero.job).grade; + let count = curGrade - initGrage; // 进阶次数 + pushMessage = await checkTask(roleId, taskType, 1, true, { count }); + } + else if (taskType == TASK_TYPE.HERO_FAVOUR_LV) + { + pushMessage = await checkTask(roleId, taskType, 1, true, { favourLv: hero.favourLv }) + } + else if (taskType == TASK_TYPE.EQUIP_BY_HERO) + { + // arg[0] 1:穿上 -1:脱下 + let { ePlace } = hero; + let count = ePlace.filter(cur => cur.equip).length; + pushMessage = await checkTask(roleId, taskType, args[0], true, { count, isPutOn: args[0] }); + } + else if (taskType == TASK_TYPE.EQUIP_STRENGTHEN) + { + // args: 依次为原先的装备的强化等级 + let { ePlace } = hero; + let index = 0; + for(let { lv } of ePlace) { + let p = await checkTask(roleId, taskType, 1, true, { oldLv: args[index++], lv }); + pushMessage = pushMessage.concat(p); + } + } + + return pushMessage +} + + +export async function checkTaskWithEquip(roleId: string, taskType: number, equip: EquipType, args?: number[]) { + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + if(taskType == TASK_TYPE.EQUIP_QUALITY) + { + // args[0] 1:装上 -1:脱下 + let dicGood = gameData.goods.get(equip.id); + pushMessage = await checkTask(roleId, taskType, args[0], true, { quality: dicGood.quality }) + } + else if (taskType == TASK_TYPE.EQUIP_JEWEL) + { + // args[0] 原来镶嵌了多少宝石 + let { holes } = equip; + let jewelCount = holes.filter(cur => cur.jewel > 0).length; + if(jewelCount > 0 && args[0] <= 0) { // 原来没有,镶嵌上了 + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } else if (jewelCount <= 0 && args[0] > 0) { // 原来镶嵌着,现在没了 + pushMessage = await checkTask(roleId, taskType, -1, true, {}); + } + } + else if (taskType == TASK_TYPE.EQUIP_COMPOSE_SUIT) + { + let dicGood = gameData.goods.get(equip.id); + if(dicGood.suitId) { + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } + } + else if (taskType == TASK_TYPE.EQUIP_SUIT) + { + let dicGood = gameData.goods.get(equip.id); + if(dicGood.suitId) { + let suit = gameData.suit.get(dicGood.suitId); + let equips = await EquipModel.getEquipsByIds(roleId, suit.tireInfo); + let everyEquip = new Map(); + for(let equip of equips) { + if(everyEquip.has(equip.id)) { + everyEquip.set(equip.id, everyEquip.get(equip.id) + 1); + } else { + everyEquip.set(equip.id, 1); + } + } + let minCount = 0, curCount = 0; + for(let id of suit.tireInfo) { + let count = everyEquip.get(id)||0; + if(minCount > count) minCount = count; + if(id == equip.id) curCount = count; + } + if(curCount == minCount) { + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } + } + } + else if (taskType == TASK_TYPE.EQUIP_JEWEL_SUM) + { + // args[0] 原来镶嵌了多少宝石 + let { holes } = equip; + let jewelCount = holes.filter(cur => cur.jewel > 0).length; + pushMessage = await checkTask(roleId, taskType, jewelCount - args[0], true, {}); + } + return pushMessage +} + +export async function checkTaskWithArgs(roleId: string, taskType: number, args: number[]) { + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + + if(taskType == TASK_TYPE.ROLE_SCHOOL_PUT_HERO) + { + let [ hid, preHid ] = args; + if(hid > 0 && preHid <= 0) { // 放置 + pushMessage = await checkTask(roleId, taskType, 1, true, {}); + } else if (hid <= 0 && preHid > 0) { // 卸下 + pushMessage = await checkTask(roleId, taskType, -1, true, {}); + } + } + else if (taskType == TASK_TYPE.EQUIP_JEWEL_STAGE) + { + // args 装上的, 卸下的 + let [putOnJewel, putOffJewel] = args; + if(putOnJewel > 0) { + let dicGood = gameData.goods.get(putOnJewel); + let push = await checkTask(roleId, taskType, 1, true, { stage: dicGood.lvLimited }); + pushMessage.concat(push); + } + if(putOffJewel > 0) { + let dicGood = gameData.goods.get(putOffJewel); + let push = await checkTask(roleId, taskType, -1, true, { stage: dicGood.lvLimited }); + pushMessage.concat(push); + } + } + else if (taskType == TASK_TYPE.CHAT) + { + // args[0] 聊天type 1-系统 2-世界 3-军团 4-组队 5-私聊 + pushMessage = await checkTask(roleId, taskType, 1, true, { chatType: args[0] }) + } + + return pushMessage +} + +// 根据taskType判断有哪些任务需要check的 +export async function checkTask(roleId: string, taskType: number, count: number, isInc: boolean, param: TaskParam) { + let tasks = gameData.taskType.get(taskType); + let pushMessage = new Array<{type: number, id: number, count: number, received: boolean}>(); + let groups = new Map(); + for(let dicTask of tasks) { + if(!groups.has(dicTask.group)) { + groups.set(dicTask.group, { task0: dicTask, tasks: new Array() }); + } + groups.get(dicTask.group).tasks.push(dicTask); + } + + for(let [ group, { task0, tasks } ] of groups) { + let rec = await checkTaskRec(roleId, group, task0, count, isInc, param); + if(rec) { + for(let dicTask of tasks) { + if(checkRecResult(rec, dicTask.condition)) { + pushMessage.push({ type: dicTask.type, id: dicTask.id, count: rec.count, received: rec.received }); + } + } + } + } + return pushMessage; +} + +// 检查各项任务是否达成,达成了就保存到数据库 +export async function checkTaskRec(roleId: string, group: number, dicTask: DicTask, count: number, isInc: boolean, param: TaskParam ) { + let { type, taskParam, taskType } = dicTask; + let isMatch = false; // 条件是否满足 + switch(taskType) { + case TASK_TYPE.LOGIN_SUM: + case TASK_TYPE.LOGIN_SERIES: + case TASK_TYPE.ROLE_LV: + case TASK_TYPE.GASHA: + case TASK_TYPE.HERO_NUM: + case TASK_TYPE.HERO_QUALITY_UP: + case TASK_TYPE.HERO_WAKE_UP: + case TASK_TYPE.HERO_TRAIN_SUM: + case TASK_TYPE.HERO_STAGE_UP: + case TASK_TYPE.ROLE_SCHOOL_UNLOCK: + case TASK_TYPE.ROLE_SCHOOL_PUT_HERO: + case TASK_TYPE.ROLE_TITLE: + case TASK_TYPE.ROLE_TERAPH_STRENGTHEN: + case TASK_TYPE.ROLE_SCROLL_ACTIVE: + case TASK_TYPE.EQUIP_SUM: + case TASK_TYPE.EQUIP_JEWEL: + case TASK_TYPE.EQUIP_COMPOSE_SUIT: + case TASK_TYPE.EQUIP_SUIT: + case TASK_TYPE.EQUIP_RESTRENGTHEN: + case TASK_TYPE.EQUIP_REFINE: + case TASK_TYPE.EQUIP_JEWEL_SUM: + case TASK_TYPE.FRIEND_NUM: + case TASK_TYPE.FRIEND_SEND_HEART: + isMatch = true; + break; + case TASK_TYPE.HERO_STAR_UP: + isMatch = taskParam[1] == param.star; + break; + case TASK_TYPE.HERO_QUALITY: + case TASK_TYPE.EQUIP_QUALITY: + isMatch = taskParam[1] == param.quality; + break; + case TASK_TYPE.HERO_QUALITY_STAR_UP: + isMatch = taskParam[1] == param.quality && taskParam[2] == param.star; + break; + case TASK_TYPE.HERO_LV: + isMatch = taskParam[1] == param.lv; + break; + case TASK_TYPE.HERO_TRAIN: + isMatch = taskParam[1] == param.count; + break; + case TASK_TYPE.HERO_FAVOUR_LV: + isMatch = taskParam[1] == param.favourLv; + break; + case TASK_TYPE.HERO_CONNECT: + isMatch = taskParam[1] == param.connectLv; + break; + case TASK_TYPE.EQUIP_BY_HERO: + if(param.isPutOn && param.count == taskParam[1]) { // 装上之后达到 +1 + isMatch = true; + } else if (!param.isPutOn && param.count < taskParam[1]) { // 脱下后不能达到 -1 + isMatch = true; + } + break; + case TASK_TYPE.EQUIP_STRENGTHEN: + isMatch = param.oldLv < taskParam[1] && param.lv >= taskParam[1]; + break; + case TASK_TYPE.EQUIP_JEWEL_STAGE: + isMatch = param.stage == taskParam[1]; + break; + case TASK_TYPE.CHAT: + isMatch = param.chatType == 0 || param.chatType == taskParam[0]; + break; + + } + console.log('****isMatch', isMatch, type, taskType, group, count) + + if(isMatch) { + if(isInc) { + let rec = await UserTaskRecModel.incTaskRec(roleId, type, taskType, group, count); + return rec; + } else { + let rec = await UserTaskRecModel.setTaskRec(roleId, type, taskType, group, count); + return rec; + } + } +} + +function checkRecResult(rec: UserTaskRecType, condition: number) { + if(!rec) return false; + if(rec.received) return false; + + if(rec.count >= condition) { + return rec + } else { + return false + } +} \ No newline at end of file diff --git a/shared/pubUtils/timeUtil.ts b/shared/pubUtils/timeUtil.ts index fed0acbeb..6bea91419 100644 --- a/shared/pubUtils/timeUtil.ts +++ b/shared/pubUtils/timeUtil.ts @@ -1,4 +1,4 @@ -import { TIME_FORMAT } from '../consts'; +import { TIME_FORMAT, REFRESH_TIME } from '../consts'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; @@ -13,7 +13,7 @@ export function nowSeconds() { return Math.floor(Date.now() / PER_SECOND ); } -export function getTodayZeroPoint(hour = 0) { +export function getTodayZeroPoint(hour = REFRESH_TIME) { var date = new Date(); date.setHours(hour); date.setMinutes(0); diff --git a/shared/resource/jsons/dic_zyz_achievement.json b/shared/resource/jsons/dic_zyz_achievement.json index 265eb9065..7c71080aa 100644 --- a/shared/resource/jsons/dic_zyz_achievement.json +++ b/shared/resource/jsons/dic_zyz_achievement.json @@ -1,148 +1,4 @@ [ - { - "id": 8, - "achieveTaskId": 8, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "20&", - "group": 1, - "achieveTaskName": "情深义重·壹", - "taskinfo": "累计签到20天", - "condition": 20, - "taskReward": 0, - "point": 10 - }, - { - "id": 9, - "achieveTaskId": 9, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "30&", - "group": 1, - "achieveTaskName": "情深义重·贰", - "taskinfo": "累计签到30天", - "condition": 30, - "taskReward": 0, - "point": 20 - }, - { - "id": 10, - "achieveTaskId": 10, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "50&", - "group": 1, - "achieveTaskName": "情深义重·叁", - "taskinfo": "累计签到50天", - "condition": 50, - "taskReward": 0, - "point": 30 - }, - { - "id": 11, - "achieveTaskId": 11, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "70&", - "group": 1, - "achieveTaskName": "情深义重·肆", - "taskinfo": "累计签到70天", - "condition": 70, - "taskReward": 0, - "point": 40 - }, - { - "id": 12, - "achieveTaskId": 12, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "90&", - "group": 1, - "achieveTaskName": "情深义重·伍", - "taskinfo": "累计签到90天", - "condition": 90, - "taskReward": 0, - "point": 50 - }, - { - "id": 13, - "achieveTaskId": 13, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "100&", - "group": 1, - "achieveTaskName": "情深义重·陆", - "taskinfo": "累计签到100天", - "condition": 100, - "taskReward": 0, - "point": 60 - }, - { - "id": 14, - "achieveTaskId": 14, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "120&", - "group": 1, - "achieveTaskName": "情深义重·柒", - "taskinfo": "累计签到120天", - "condition": 120, - "taskReward": 0, - "point": 70 - }, - { - "id": 15, - "achieveTaskId": 15, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "150&", - "group": 1, - "achieveTaskName": "情深义重·捌", - "taskinfo": "累计签到150天", - "condition": 150, - "taskReward": 0, - "point": 80 - }, - { - "id": 16, - "achieveTaskId": 16, - "tab": 1, - "tabName": "足迹", - "subTab": 1, - "subTabName": "登陆", - "taskType": 29, - "taskParam": "200&", - "group": 1, - "achieveTaskName": "情深义重·玖", - "taskinfo": "累计签到200天", - "condition": 200, - "taskReward": 0, - "point": 90 - }, { "id": 1, "achieveTaskId": 1, @@ -254,5 +110,149 @@ "condition": 15, "taskReward": 0, "point": 35 + }, + { + "id": 8, + "achieveTaskId": 8, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "20&", + "group": 1, + "achieveTaskName": "情深义重·壹", + "taskinfo": "累计登录20天", + "condition": 20, + "taskReward": 0, + "point": 10 + }, + { + "id": 9, + "achieveTaskId": 9, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "30&", + "group": 1, + "achieveTaskName": "情深义重·贰", + "taskinfo": "累计登录30天", + "condition": 30, + "taskReward": 0, + "point": 20 + }, + { + "id": 10, + "achieveTaskId": 10, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "50&", + "group": 1, + "achieveTaskName": "情深义重·叁", + "taskinfo": "累计登录50天", + "condition": 50, + "taskReward": 0, + "point": 30 + }, + { + "id": 11, + "achieveTaskId": 11, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "70&", + "group": 1, + "achieveTaskName": "情深义重·肆", + "taskinfo": "累计登录70天", + "condition": 70, + "taskReward": 0, + "point": 40 + }, + { + "id": 12, + "achieveTaskId": 12, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "90&", + "group": 1, + "achieveTaskName": "情深义重·伍", + "taskinfo": "累计登录90天", + "condition": 90, + "taskReward": 0, + "point": 50 + }, + { + "id": 13, + "achieveTaskId": 13, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "100&", + "group": 1, + "achieveTaskName": "情深义重·陆", + "taskinfo": "累计登录100天", + "condition": 100, + "taskReward": 0, + "point": 60 + }, + { + "id": 14, + "achieveTaskId": 14, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "120&", + "group": 1, + "achieveTaskName": "情深义重·柒", + "taskinfo": "累计登录120天", + "condition": 120, + "taskReward": 0, + "point": 70 + }, + { + "id": 15, + "achieveTaskId": 15, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "150&", + "group": 1, + "achieveTaskName": "情深义重·捌", + "taskinfo": "累计登录150天", + "condition": 150, + "taskReward": 0, + "point": 80 + }, + { + "id": 16, + "achieveTaskId": 16, + "tab": 1, + "tabName": "足迹", + "subTab": 1, + "subTabName": "登陆", + "taskType": 1, + "taskParam": "200&", + "group": 1, + "achieveTaskName": "情深义重·玖", + "taskinfo": "累计登录200天", + "condition": 200, + "taskReward": 0, + "point": 90 } ] \ No newline at end of file diff --git a/shared/resource/jsons/dic_zyz_chat_system.json b/shared/resource/jsons/dic_zyz_chat_system.json index 46fd67843..c35357817 100644 --- a/shared/resource/jsons/dic_zyz_chat_system.json +++ b/shared/resource/jsons/dic_zyz_chat_system.json @@ -153,7 +153,7 @@ }, { "id": 19, - "name": "HERO_WAKEUP", + "name": "HERO_WAKE_UP", "mean": "武将觉醒", "type": "1&", "template": "恭喜%d,成功将%d觉醒", diff --git a/web-server/app/service/Auth.ts b/web-server/app/service/Auth.ts index 4c1587548..0d6f459b9 100644 --- a/web-server/app/service/Auth.ts +++ b/web-server/app/service/Auth.ts @@ -1,5 +1,5 @@ -import { COUNTER, DEFAULT_LV, DEFAULT_ITEMS, ITID, DEFAULT_GOLD, DEFAULT_HERO_LV, DEFAULT_EQUIPS, DEFAULT_COIN, ADULT_AGE, GUEST_MAX_TIME } from '@consts'; +import { COUNTER, DEFAULT_LV, DEFAULT_ITEMS, ITID, DEFAULT_GOLD, DEFAULT_HERO_LV, DEFAULT_EQUIPS, DEFAULT_COIN, ADULT_AGE, GUEST_MAX_TIME, TASK_TYPE } from '@consts'; import { DEFAULT_HEROES } from '@consts'; import { HeroModel } from '@db/Hero'; import { RoleModel } from '@db/Role'; @@ -15,6 +15,7 @@ import { getAge } from '../pubUtils/timeUtil'; import { shouldRefresh, resResult } from '../pubUtils/util'; import { authenticate } from '../pubUtils/httpUtil'; import { createHeroes } from '../pubUtils/itemUtils'; +import { checkTask } from 'app/pubUtils/taskUtil'; /** * Test Service @@ -337,6 +338,9 @@ export default class Auth extends Service { await RoleModel.addGoldFree(roleId, DEFAULT_GOLD); await RoleModel.addCoin(roleId, DEFAULT_COIN); + // 任务 + await checkTask(roleId, TASK_TYPE.ROLE_LV, role.lv, false, {}); + return ctx.service.utils.resResult(STATUS.SUCCESS, { roleId: role.roleId }); } return ctx.service.utils.resResult(STATUS.ROLE_NOT_FOUND);