import { Application, ChannelService, BackendSession, pinus } from "pinus"; import { GUILD_ACTIVITY_TYPE, STATUS, REDIS_KEY, GUILD_POINT_WAYS, CITY_STATUS } from "../../../consts"; import { resResult } from "../../../pubUtils/util"; import { getGuildActivityStatus, getCityActivityObj, getCityStatus as pubGetCityStatus, getCities, getCityActivityRank, sendSingleCityActEndMsg, getMedianCe } from "../../../services/guildActivityService"; import { GuildActivityCityModel } from "../../../db/GuildActivityCity"; import { gameData } from "../../../pubUtils/data"; import { UserGuildActivityRecModel } from "../../../db/UserGuildActivityRec"; import { leaveCityChannel, addRoleToCityChannel, getCityChannelSid } from "../../../services/chatService"; import { UserGuildModel } from "../../../db/UserGuild"; import { GuildActivityRecordModel } from "../../../db/GuildActivityRec"; import { nowSeconds, getBeforeSeconds } from "../../../pubUtils/timeUtil"; import { getGoldObject } from "../../../pubUtils/itemUtils"; import { GUILDACTIVITY } from "../../../pubUtils/dicParam"; import { handleCost } from "../../../services/rewardService"; import { getRankScore, getCityKeyName, getGuildKeyName, setUserGuildActivityRank, setRank } from "../../../services/redisService"; import { RoleModel, RoleType } from "../../../db/Role"; import { RankParam, GuildRankParam } from "../../../domain/rank"; import { GuildModel } from "../../../db/Guild"; import { addActive } from "../../../services/guildService"; export default function (app: Application) { return new CityActivityHandler(app); } export class CityActivityHandler { channelService: ChannelService; constructor(private app: Application) { this.channelService = app.get('channelService'); } private aid = GUILD_ACTIVITY_TYPE.CITY_ACTIVITY; // 诸侯混战id // 进入诸侯混战 async getCityActivity(msg: {}, session: BackendSession) { // const roleId = session.get('roleId'); // const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); let statusResult = getGuildActivityStatus(this.aid); if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); const dbCities = await GuildActivityCityModel.getAllCities(serverId); let cities = getCities(guildCode, dbCities); return resResult(STATUS.SUCCESS, { ...statusResult, cities }); } // 获取单个城池状态 async getCityStatus(msg: { cityId: number }, session: BackendSession) { const roleId = session.get('roleId'); const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); let sid = session.get('sid'); const { cityId } = msg; let statusResult = getGuildActivityStatus(this.aid); if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); let dicCity = gameData.cityActivity.get(cityId); if(!dicCity) return resResult(STATUS.DIC_DATA_NOT_FOUND); let obj = getCityActivityObj(); let gateHp = obj.getGateHpAndInc(serverId, cityId, dicCity.hp); let myGuildActivityRec = await UserGuildActivityRecModel.findByRoleId(roleId, this.aid); let challengeTime = 0; if(myGuildActivityRec) { challengeTime = myGuildActivityRec.challengeTime; } const dbCities = await GuildActivityCityModel.getAllCities(serverId); let cityStatus = pubGetCityStatus(guildCode, cityId, dicCity, dbCities); if(cityStatus == CITY_STATUS.DECLARED) { obj.pushGuild(guildCode, serverId, cityId); } let historyCity = obj.getHistoryCity(roleId); if(historyCity) { await leaveCityChannel(roleId, sid, historyCity); } await addRoleToCityChannel(roleId, sid, cityId); obj.setHistoryCity(roleId, cityId); let ranks = await getCityActivityRank(guildCode, serverId, cityId, roleId, roleName); return resResult(STATUS.SUCCESS, { cityId, ...statusResult, cityStatus, gateHp, challengeTime, ...ranks }); } // 宣战 async declareCity(msg: { cityId: number }, session: BackendSession) { // const roleId = session.get('roleId'); // const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); //TODO 权限校验&时间校验 let { cityId } = msg; let dicCity = gameData.cityActivity.get(cityId); if(dicCity.preCity.length > 0) return resResult(STATUS.CAN_NOT_DECLARE); let checkResult = await GuildActivityCityModel.checkDeclartion(serverId, guildCode); if(!!checkResult) return resResult(STATUS.HAS_DECLARED); let curCity = await GuildActivityCityModel.getCity(serverId, cityId); if(curCity && curCity.guardGuildCode) { return resResult(STATUS.CITY_IS_GUARD); } let rec = await GuildActivityCityModel.declare(serverId, cityId, guildCode); let chatSid = await getCityChannelSid(guildCode); pinus.app.rpc.chat.guildRemote.sendGuildCityDeclare.toServer(chatSid, cityId, guildCode, rec.declareCount); let obj = getCityActivityObj(); obj.pushGuild(guildCode, serverId, cityId); const dbCities = await GuildActivityCityModel.getAllCities(serverId); let cities = getCities(guildCode, dbCities); return resResult(STATUS.SUCCESS, { cities }); } // 开始挑战 async checkBattle(msg: {cityId: number, costGold: boolean, heroes: number[]}, session: BackendSession) { let { cityId, costGold, heroes } = msg; if(!heroes || heroes.length <= 0) return resResult(STATUS.WRONG_PARMS); const roleId = session.get('roleId'); const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); const sid = session.get('sid'); if(!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); let checkResult = await GuildActivityCityModel.checkDeclartion(serverId, guildCode); if(!checkResult) return resResult(STATUS.HAS_NOT_DECLARED); let obj = getCityActivityObj(); const dicCity = gameData.cityActivity.get(cityId); let gateHp = obj.getGateHpAndInc(serverId, cityId, dicCity.hp); if(gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO); let statusResult = getGuildActivityStatus(this.aid); if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); // TODO 测试完成后去掉这条判断 // if(!statusResult.isOpen) return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN); let userGuild = await UserGuildModel.getMyGuild(roleId, 'job'); let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid); if(!guildActivityRec) return resResult(STATUS.INTERNAL_ERR); let { code: sourceCode } = guildActivityRec; let myGuildActivityRec = await UserGuildActivityRecModel.getRecord(roleId, roleName, guildCode, serverId, sourceCode, this.aid); if(costGold) { let goldObj = getGoldObject(GUILDACTIVITY.CITYACTIVITY_CD_COST); const costRes = await handleCost(roleId, sid, [goldObj]); if (!costRes) { return resResult(STATUS.BATTLE_GOLD_NOT_ENOUGH); } } else { if(myGuildActivityRec.challengeTime > nowSeconds()) { return resResult(STATUS.CHALLENGE_TIME_NOT_REACH); } } myGuildActivityRec = await UserGuildActivityRecModel.incChallengeCnt(myGuildActivityRec.code, heroes); let { code } = myGuildActivityRec; // 更新公会参与的玩家 obj.pushMembers(guildCode, roleId, userGuild.job); // // 返回当前军团总军功 let guildScore = await getRankScore(getCityKeyName(REDIS_KEY.CITY_ACTIVITY, cityId), serverId, guildCode); const dbCities = await GuildActivityCityModel.getAllCities(serverId); let cityStatus = pubGetCityStatus(guildCode, cityId, dicCity, dbCities); // 前一天中位数战力 let medianCe = await getMedianCe(serverId); return resResult(STATUS.SUCCESS, { code, cityId, cityStatus, ...statusResult, gateHp, guildScore, myScore: 0, medianCe }); } // 上报城门受到伤害 async hitGate(msg: { cityId: number, code: string, damage: number, hid: number, round: number }, session: BackendSession) { const roleId = session.get('roleId'); const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); const sid = session.get('sid'); let { cityId, code, damage, hid, round } = msg; if(!damage || damage < 0) return resResult(STATUS.WRONG_PARMS); const dicCity = gameData.cityActivity.get(cityId); let obj = getCityActivityObj(); let gateHp = obj.getGateHpAndInc(serverId, cityId, dicCity.hp); if(gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO); let statusResult = getGuildActivityStatus(this.aid); if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); // TODO 测试完成后去掉这条判断 // if(!statusResult.isOpen) return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN); let pushResult = await UserGuildActivityRecModel.pushCityRecord(code, { round, hid, damage }); if(!pushResult) return resResult(STATUS.WRONG_PARMS); // 更新redis数据 let role = await RoleModel.findByRoleId(roleId); let { lv, vLv, head, frame, spine, title } = role; let userParam = new RankParam(roleName, lv, vLv, head, frame, spine, title); let myScore = await setUserGuildActivityRank(REDIS_KEY.USER_CITY_ACTIVITY, guildCode, serverId, roleId, damage, Date.now(), userParam); let guild = await GuildModel.findByCode(guildCode, serverId); let leader = guild.leader; let params = new GuildRankParam(guild.icon, guild.name, guild.lv, leader); let guildScore = await setRank(getCityKeyName(REDIS_KEY.CITY_ACTIVITY, cityId), serverId, guild.code, damage, Date.now(), params, true); gateHp = obj.getGateHpAndInc(serverId, cityId, dicCity.hp, -1 * damage); if(gateHp <= 0) { // 推送 停止活动并结算奖励 await sendSingleCityActEndMsg(cityId, serverId); } // 推送 城门血量 let chatSid = await getCityChannelSid(cityId); pinus.app.rpc.chat.guildRemote.pushCityGateHp.toServer(chatSid, cityId, gateHp); return resResult(STATUS.SUCCESS, { code, ...statusResult, guildScore, myScore, gateHp }) } // 结束挑战 async battleEnd(msg: { cityId: number, code: string, isSuccess: boolean }, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let guildCode = session.get('guildCode'); let serverId = session.get('serverId'); let { cityId, code, isSuccess } = msg; let obj = getCityActivityObj(); let statusResult = getGuildActivityStatus(this.aid); if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); let dicCity = gameData.cityActivity.get(cityId); if(!dicCity) return resResult(STATUS.DIC_DATA_NOT_FOUND); // 更新userGuildActivityRecord let challengeTime = getBeforeSeconds(-1 * GUILDACTIVITY.CITYACTIVITY_CHALLENGE_CD); let myGuildActivityRec = await UserGuildActivityRecModel.updateInfo(code, { isSuccess, isCompleted: true, cityId, challengeTime }); if(!myGuildActivityRec) return resResult(STATUS.INTERNAL_ERR); // 发放活跃 await addActive(roleId, serverId, GUILD_POINT_WAYS.ACTIVITY); //获得活跃值 // 返回当前军团总军功 let guildScore = await getRankScore(getCityKeyName(REDIS_KEY.CITY_ACTIVITY, cityId), serverId, guildCode); let myScore = await getRankScore(getGuildKeyName(REDIS_KEY.USER_CITY_ACTIVITY, guildCode), serverId, roleId, true); let gateHp = obj.getGateHpAndInc(serverId, cityId, dicCity.hp); return resResult(STATUS.SUCCESS, { isSuccess, code, ...statusResult, guildScore, myScore, gateHp, challengeTime: myGuildActivityRec.challengeTime }); } }