Files
ZYZ/game-server/app/servers/role/handler/roleHandler.ts
2021-07-16 11:29:26 +08:00

530 lines
22 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { STATUS } from '../../../consts/statusCode';
import { RoleModel } from './../../../db/Role';
import { HeroModel } from '../../../db/Hero';
import { resResult, decodeIdCntArrayStr, parseGoodStr } from '../../../pubUtils/util';
import { Application, BackendSession, pinus, HandlerService, } from 'pinus';
import { handleCost, addItems, createHeroes } from '../../../services/rewardService';
import { getTitle, getTeraph, gameData, getScollByStar, getFriendLvByExp, getHeroExpByLv } from '../../../pubUtils/data';
import { SCHOOL, SCROLL, EXTERIOR, SCRIPT } from '../../../pubUtils/dicParam';
import { getAtrrNameById } from '../../../consts/constModules/abilityConst'
import { findIndex } from 'underscore';
import { SclResultInter, SclPosInter } from '../../../pubUtils/interface';
import { SchoolModel } from '../../../db/School';
import { checkTeraphMaterialEnough, getSchoolList } from '../../../services/roleService'
import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService';
import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT, REDIS_KEY, TASK_TYPE, DEFAULT_HEROES, DEFAULT_HERO_LV, DEFAULT_ITEMS, DEFAULT_EQUIPS, DEFAULT_GOLD, DEFAULT_COIN } from '../../../consts';
import { checkBattleHeroesByHid } from '../../../services/normalBattleService';
import { Rank } from '../../../services/rankService';
import { updateUserInfo } from '../../../services/redisService';
import { checkTaskWithHero, checkTask, checkTaskWithArgs, checkActivityTask } from '../../../services/taskService';
import { getGoldObject, getCoinObject } from '../../../pubUtils/itemUtils';
import { RScriptRecordModel } from '../../../db/RScriptRecord';
import { checkPvp } from '../../../services/pvpService';
import { pushData } from '../../../services/connectorService';
export default function (app: Application) {
new HandlerService(app, {});
return new RoleHandler(app);
}
export class RoleHandler {
constructor(private app: Application) {
}
async initRole(msg: { roleName: string }, session: BackendSession) {
let roleId = session.get('roleId');
let serverId = session.get('serverId');
let sid: string = session.get('sid');
let funcs: number[] = session.get('funcs');
let { roleName } = msg;
let role = await RoleModel.findByRoleId(roleId, 'roleName hasInit', true);
if (role.hasInit) return resResult(STATUS.ROLE_HAS_INIT);
let checkName = await RoleModel.checkName(roleName, serverId);
if (checkName) return resResult(STATUS.NAME_HAS_USED);
let heroInfos = [];
for (let hid of DEFAULT_HEROES) {
heroInfos.push({
hid, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0
});
}
let heroes = await createHeroes(roleId, roleName, sid, serverId, funcs, heroInfos);
session.set('roleName', roleName);
session.push('roleName', () => { });
let items = [].concat(DEFAULT_ITEMS, DEFAULT_EQUIPS, [getGoldObject(DEFAULT_GOLD)], [getCoinObject(DEFAULT_COIN)]);
await addItems(roleId, roleName, sid, items);
role = await RoleModel.updateRoleInfo(roleId, { hasInit: true, roleName }, true)
let battleId = SCRIPT.SCRIPT_BATTLE_ID;
let warInfo = gameData.war.get(battleId);
await RScriptRecordModel.setScript(roleId, battleId, warInfo.warType, 2, SCRIPT.SCRIPT_NAME);
await checkPvp(role);
return resResult(STATUS.SUCCESS, {
roleId, roleName, ...heroes
})
}
async getRoleInfo(msg: { targetRoleId: string }, session: BackendSession) {
let { targetRoleId } = msg;
let { roleId, roleName, head = EXTERIOR.EXTERIOR_FACE, frame = EXTERIOR.EXTERIOR_FACECASE, spine = EXTERIOR.EXTERIOR_APPEARANCE, ce = 0, topLineup, topLineupCe = 0 } = await RoleModel.findByRoleId(targetRoleId);
return resResult(STATUS.SUCCESS, { roleId, roleName, head, frame, spine, ce, topLineup, topLineupCe });
}
//爵位
async roleTitleLevelUp(msg: {}, session: BackendSession) {
let roleId = session.get('roleId');
let sid: string = session.get('sid');
const serverId = session.get('serverId');
let funcs: number[] = session.get('funcs');
let role = await RoleModel.findByRoleId(roleId);
let { title } = role;
let titleInfo = getTitle(title + 1);
if (!titleInfo)
return resResult(STATUS.DIC_DATA_NOT_FOUND)
if (titleInfo.lvLimited > role.lv)
return resResult(STATUS.COM_BATTLE_LV_NOT_ENOUGH)
let consumes = titleInfo.material;
let result = await handleCost(roleId, sid, consumes);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
let update = { title: title + 1 }
role = await calAllHeroCe(HERO_SYSTEM_TYPE.TITLE, sid, roleId, update);
// 任务
await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_TITLE, 1, false, { title });
//成长任务
await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.ROLE_TITLE, update.title)
return resResult(STATUS.SUCCESS, { roleId, title: role.title });
}
//神像强化
async roleTeraphStrengthen(msg: { id: number, count: number }, session: BackendSession) {
let { id, count } = msg;
let roleId = session.get('roleId');
let sid: string = session.get('sid');
let funcs: number[] = session.get('funcs');
let role = await RoleModel.findByRoleId(roleId);
let teraphs = role.teraphs;
let index = findIndex(teraphs, { id });
if (index < 0)
return resResult(STATUS.WRONG_PARMS);
let teraph = teraphs[index];
let dicTeraph = getTeraph(id, teraph.grade);
if (!dicTeraph)
return resResult(STATUS.DIC_DATA_NOT_FOUND);
let attrs = new Array<number>(); // 可以强化的属性
dicTeraph.mainAttrMax.forEach((max, id) => {
let attrName = getAtrrNameById(id);
if (teraph[attrName] < max) {
attrs.push(id);
}
});
if (!attrs.length)
return resResult(STATUS.ROLE_TERAPH_NOT_STRENGTHEN);
// 随机神像中的一条属性并检查道具是否足够以及更新teraph
let { consumes } = checkTeraphMaterialEnough(count, attrs, dicTeraph, teraph);
let result = await handleCost(roleId, sid, consumes);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
role = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH, sid, roleId, { teraphs }, [id]);
// 任务
await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_TERAPH_STRENGTHEN, count, true, {});
return resResult(STATUS.SUCCESS, { roleId, teraphs: role.teraphs });
}
//神像进阶
async roleTeraphQualityUp(msg: { id: number }, session: BackendSession) {
let { id } = msg;
let roleId = session.get('roleId');
let sid: string = session.get('sid');
const serverId = session.get('serverId');
let funcs: number[] = session.get('funcs');
let role = await RoleModel.findByRoleId(roleId);
let teraphs = role.teraphs;
let index = findIndex(teraphs, { id });
if (index < 0)
return resResult(STATUS.WRONG_PARMS);
let teraph = teraphs[index];
let teraphInfo = getTeraph(id, teraph.grade);
if (!teraphInfo)
return resResult(STATUS.DIC_DATA_NOT_FOUND)
for (let [attrId, val] of teraph.attr) {
if (val < teraphInfo.mainAttrMax.get(attrId))
return resResult(STATUS.ROLE_TERAPH_NOT_QUILITY);
teraph.attr.set(attrId, 0);
}
teraph.grade++;
let nextTeraphInfo = getTeraph(id, teraph.grade)
if (!nextTeraphInfo)
return resResult(STATUS.DIC_DATA_NOT_FOUND);
let consumes = teraphInfo.upGradeMaterial;
let result = await handleCost(roleId, sid, consumes);
if (!result)
return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
role = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH_UP, sid, roleId, { teraphs }, [id]);
// 神像进阶,进阶一次就触发一次礼包弹框
await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.ROLE_TERAPH_STAGE_UP, 1)
return resResult(STATUS.SUCCESS, { roleId, teraphs: role.teraphs });
}
// 获得百家学宫
async getSchoolList(msg: {}, session: BackendSession) {
let roleId = session.get('roleId');
let school = await getSchoolList(roleId);
return resResult(STATUS.SUCCESS, { school });
}
// 摆放/替换/卸下武将
async changeSchoolHero(msg: { schoolId: number, positionId: number, hid: number }, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let funcs: number[] = session.get('funcs');
const serverId = session.get('serverId');
let { schoolId, positionId, hid } = msg;
if (!gameData.school.has(schoolId)) {
return resResult(STATUS.DIC_DATA_NOT_FOUND);
}
const dicPosition = decodeIdCntArrayStr(SCHOOL.SCHOOL_POSITION, 1); // id(str) => isOpen
if (!dicPosition.has(positionId.toString())) {
return resResult(STATUS.DIC_DATA_NOT_FOUND);
}
let isOpen = !!dicPosition.get(positionId.toString()); // 该位置是否解锁
if (hid > 0) {
let findHero = await SchoolModel.findByHid(roleId, hid);
if (!!findHero) {
return resResult(STATUS.ROLE_SCHOOL_HERO_USED);
}
let curHero = await HeroModel.findByHidAndRole(hid, roleId);
if (!curHero) return resResult(STATUS.HERO_NOT_FIND);
}
let curSchool = await SchoolModel.findBySclAndPos(roleId, schoolId, positionId);
let preHid = 0; // 原先在该位置上的武将
if (curSchool) {
isOpen = curSchool.isOpen;
preHid = curSchool.hid;
}
if (!isOpen) {
return resResult(STATUS.ROLE_SCHOOL_POSITION_LOCKED);
}
await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { hid, isOpen })
await calAllHeroCe(HERO_SYSTEM_TYPE.SCHOOL, sid, roleId, {}, [schoolId, hid, preHid]);
// 任务
await checkTaskWithArgs(roleId, sid, funcs, TASK_TYPE.ROLE_SCHOOL_UNLOCK, [hid, preHid]);
if (hid > 0) {
//成长任务
await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.ROLE_SCHOOL_PUT_HERO, 1)
}
return resResult(STATUS.SUCCESS, {
schoolId, positionId, hid, preHid, isOpen
});
}
// 解锁位置
async unlockSchoolPosition(msg: { schoolId: number, positionId: number }, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let funcs: number[] = session.get('funcs');
let { schoolId, positionId } = msg;
if (!gameData.school.has(schoolId)) {
return resResult(STATUS.DIC_DATA_NOT_FOUND);
}
const dicPosition = decodeIdCntArrayStr(SCHOOL.SCHOOL_POSITION, 1); // id(str) => isOpen
if (!dicPosition.has(positionId.toString())) {
return resResult(STATUS.DIC_DATA_NOT_FOUND);
}
let isOpen = !!dicPosition.get(positionId.toString()); // 该位置是否解锁
if (isOpen) {
return resResult(STATUS.ROLE_SCHOOL_POSITION_UNLOCK_NOT_NEED);
}
let curSchool = await SchoolModel.findBySclAndPos(roleId, schoolId, positionId);
if (curSchool && curSchool.isOpen) {
return resResult(STATUS.ROLE_SCHOOL_POSITION_UNLOCK_NOT_NEED);
}
const cost = parseGoodStr(SCHOOL.SCHOOL_UNLOCK_COIN);
const costResult = await handleCost(roleId, sid, cost);
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
curSchool = await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { isOpen: true })
// 任务
await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_SCHOOL_UNLOCK, 1, true, {});
return resResult(STATUS.SUCCESS, {
schoolId, positionId, hid: curSchool.hid, isOpen: curSchool.isOpen
});
}
// 激活/升级名将谱
async activeHeroScroll(msg: { hid: number }, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let funcs: number[] = session.get('funcs');
let serverId: number = session.get('serverId');
let { hid } = msg;
let curHero = await HeroModel.findByHidAndRole(hid, roleId, 'hid star colorStar quality scrollId scrollActive scrollStar scrollColorStar scrollQuality favour favourLv connections attr ce');
if (!curHero) return resResult(STATUS.HERO_NOT_FIND);
let dicHero = gameData.hero.get(hid);
if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND);
let { star, colorStar, quality, scrollId, scrollActive, scrollStar, scrollColorStar, scrollQuality, favour, favourLv } = curHero;
let update = {
scrollActive, scrollId, scrollStar, scrollColorStar, scrollQuality, favour, favourLv
};
if (!scrollActive) { // 初次激活
update.scrollActive = true;
update.scrollStar = dicHero.initialStars;
update.scrollQuality = dicHero.quality;
update.scrollColorStar = 0;
// 获取一定好感度
let maxLv = gameData.maxFriendShipLv.max;
if (maxLv > favourLv) {
update.favour += SCROLL.SCROLL_ACTIVE_FAVOUR;
update.favourLv = getFriendLvByExp(update.favour);
}
await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.HERO_UNLOCK, 1, { dicHeroes: [dicHero] })
} else {
if (star > scrollStar) { // 可以升星
update.scrollStar++;
} else if (quality > scrollQuality) { // 可以升品
update.scrollQuality++;
} else if (colorStar > scrollColorStar) { // 可以升彩星
update.scrollColorStar++;
} else {
return resResult(STATUS.ROLE_SCROLL_REACH_MAX);
}
}
let dicHeroScroll = getScollByStar(dicHero.quality, update.scrollStar, update.scrollQuality, update.scrollColorStar);
update.scrollId = dicHeroScroll ? dicHeroScroll.id : 0;
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, funcs, TASK_TYPE.HERO_FAVOUR_LV, hero);
if (!scrollActive) await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_SCROLL_ACTIVE, 1, true, {});
return resResult(STATUS.SUCCESS, {
curHero: {
hid: hero.hid,
scrollActive: hero.scrollActive,
scrollId: hero.scrollId,
scrollStar: hero.scrollStar,
scrollColorStar: hero.scrollColorStar,
scrollQuality: hero.scrollQuality,
favour: hero.favour,
favourLv: hero.favourLv,
}
});
}
// 防沉迷调试用,推送窗口
async debugPlayerTime(msg: { type: number }, session: BackendSession) {
let { type } = msg;
let roleId = session.get('roleId');
let sid = session.get('sid');
if (type == 1) {
pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, {
isGuest: true,
guestTime: 60 * 60, // 游客已体验时间
hasAuthenticated: false, // 是否进行过实名认证
isAdult: false, // 是否已成年
todayPlayTime: 60 * 60, // 今天已游戏时长
type: 1
}), [{ uid: roleId, sid: sid }]);
} else if (type == 2) {
pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, {
isGuest: false,
guestTime: 0, // 游客已体验时间
hasAuthenticated: true, // 是否进行过实名认证
isAdult: false, // 是否已成年
todayPlayTime: 60 * 60, // 今天已游戏时长
type: 2
}), [{ uid: roleId, sid: sid }]);
} else if (type == 3) {
pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, {
isGuest: false,
guestTime: 0, // 游客已体验时间
hasAuthenticated: true, // 是否进行过实名认证
isAdult: false, // 是否已成年
todayPlayTime: 3 * 60 * 60, // 今天已游戏时长
type: 3
}), [{ uid: roleId, sid: sid }]);
} else if (type == 4) {
pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, {
isGuest: false,
guestTime: 0, // 游客已体验时间
hasAuthenticated: true, // 是否进行过实名认证
isAdult: false, // 是否已成年
todayPlayTime: 1.5 * 60 * 60, // 今天已游戏时长
type: 4
}), [{ uid: roleId, sid: sid }]);
}
return resResult(STATUS.SUCCESS);
}
// 保存展示阵容
async saveShowLineup(msg: { showLineup: number[] }, session: BackendSession) {
let { showLineup } = msg;
let roleId = session.get('roleId');
let serverId = session.get('serverId');
let checkHeroes = await checkBattleHeroesByHid(roleId, showLineup);
if (showLineup.length > 0 && !checkHeroes) return resResult(STATUS.BATTLE_HERO_NOT_FOUND);
if (showLineup.length > LINEUP_NUM) {
return resResult(STATUS.LINEUP_MAX);
}
let role = await RoleModel.updateRoleInfo(roleId, { showLineup });
let r = new Rank(REDIS_KEY.SHOW_LINEUP, {});
await r.generParamAndSet(REDIS_KEY.SHOW_LINEUP, { roleId }, { role });
return resResult(STATUS.SUCCESS, { showLineup: role.showLineup });
}
// 更换头像
async setHead(msg: { id: number }, session: BackendSession) {
let { id } = msg;
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS);
if (!role) return resResult(STATUS.ROLE_NOT_FOUND);
let { heads } = role;
let curHead = heads.find(cur => cur.id == id);
if (!curHead) return resResult(STATUS.HEAD_NOT_FOUND);
if (curHead.enable) return resResult(STATUS.HEAD_IS_WEARING);
if (!curHead.status) return resResult(STATUS.HEAD_IS_LOCKED);
let oldHead = heads.find(cur => cur.enable); // 穿戴中的头像
if (oldHead) {
oldHead.enable = false;
}
curHead.enable = true;
role = await RoleModel.updateRoleInfo(roleId, { heads });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'head', value: id }]);
return resResult(STATUS.SUCCESS, { heads: role.heads, head: role.head });
}
// 更换相框
async setFrame(msg: { id: number }, session: BackendSession) {
let { id } = msg;
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS);
if (!role) return resResult(STATUS.ROLE_NOT_FOUND);
let { frames } = role;
let curFrame = frames.find(cur => cur.id == id);
if (!curFrame) return resResult(STATUS.FRAME_NOT_FOUND);
if (curFrame.enable) return resResult(STATUS.FRAME_IS_WEARING);
if (!curFrame.status) return resResult(STATUS.FRAME_IS_LOCKED);
let oldHead = frames.find(cur => cur.enable); // 穿戴中的头像
if (oldHead) {
oldHead.enable = false;
}
curFrame.enable = true;
role = await RoleModel.updateRoleInfo(roleId, { frames });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'frame', value: id }]);
return resResult(STATUS.SUCCESS, { frames: role.frames, frame: role.frame });
}
// 更换形象
async setSpine(msg: { id: number }, session: BackendSession) {
let { id } = msg;
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS);
if (!role) return resResult(STATUS.ROLE_NOT_FOUND);
let { spines } = role;
let curSpine = spines.find(cur => cur.id == id);
if (!curSpine) return resResult(STATUS.SPINE_NOT_FOUND);
if (curSpine.enable) return resResult(STATUS.SPINE_IS_WEARING);
if (!curSpine.status) return resResult(STATUS.SPINE_IS_LOCKED);
let oldHead = spines.find(cur => cur.enable); // 穿戴中的头像
if (oldHead) {
oldHead.enable = false;
}
curSpine.enable = true;
role = await RoleModel.updateRoleInfo(roleId, { spines });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'spine', value: id }]);
return resResult(STATUS.SUCCESS, { spines: role.spines, spine: role.spine });
}
// 改名
async rename(msg: { roleName: string }, session: BackendSession) {
let { roleName } = msg;
let roleId = session.get('roleId');
let serverId = session.get('serverId');
let checkName = await RoleModel.checkName(roleName, serverId);
if (checkName) return resResult(STATUS.NAME_HAS_USED);
let role = await RoleModel.updateRoleInfo(roleId, { roleName });
session.set('roleName', role.roleName);
session.push('roleName', () => { });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'roleName', value: roleName }]);
return resResult(STATUS.SUCCESS, { roleName: role.roleName });
}
}