import { Application, ChannelService, BackendSession, pinus, HandlerService, } from "pinus"; import { GUILD_ACTIVITY_TYPE, STATUS, REDIS_KEY, CITY_STATUS, TASK_TYPE, ITEM_CHANGE_REASON, PUSH_ROUTE, GUILD_ACTIVITY_STATUS } from "../../../consts"; import { genCode, resResult } from "../../../pubUtils/util"; import { getGuildActivityStatus, getCityActivityObj, getCityStatus as pubGetCityStatus, getCities, getCityActivityRank, sendSingleCityActEndMsg, declareCity, autoDeclareMyCity, getGAIndexInPinus, getDeclareIndex, sendCityGuildRankToUser } from "../../../services/guildActivity/guildActivityService"; import { GuildActivityCityModel } from "../../../db/GuildActivityCity"; import { gameData } from "../../../pubUtils/data"; import { UserGuildActivityRecModel } from "../../../db/UserGuildActivityRec"; import { leaveCityChannel, addRoleToCityChannel } from "../../../services/chatService"; import { GuildActivityRecordModel } from "../../../db/GuildActivityRec"; import { nowSeconds, getTimeFun } from "../../../pubUtils/timeUtil"; import { GUILDACTIVITY } from "../../../pubUtils/dicParam"; import { getGoldObject, handleCost } from "../../../services/role/rewardService"; import { Rank } from "../../../services/rankService"; import { checkTask } from "../../../services/task/taskService"; import { guildInter } from "../../../pubUtils/interface"; import { dispatch } from "../../../pubUtils/dispatcher"; import { ServerRecordModel } from "../../../db/ServerRecords"; import { sendMessageToCityWithSuc } from "../../../services/pushService"; import { isDebugTime } from "../../../pubUtils/sdkUtil"; import { GuildActivityCityDeclareModel } from "../../../db/GuildActivityCityDeclare"; import { GuildModel } from "../../../db/Guild"; import { getHistoryCity, setHistoryCity } from "../../../services/redisService"; export default function (app: Application) { new HandlerService(app, {}); 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 index = getGAIndexInPinus(this.aid); let declareIndex = getDeclareIndex(); let statusResult = getGuildActivityStatus(this.aid); if (!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); let obj = getCityActivityObj(); if(obj.guildActivityStatus == GUILD_ACTIVITY_STATUS.START) { await autoDeclareMyCity(serverId, roleId, guildCode, declareIndex); } const dbCities = await GuildActivityCityModel.getAllCities(serverId, declareIndex); let cities = getCities(guildCode, dbCities); let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid, index); let ranks = await getCityActivityRank(guildCode, serverId, guildActivityRec?.challengeCityId, roleId, roleName); return resResult(STATUS.SUCCESS, { ...statusResult, cities, ...ranks }); } // 获取单个城池状态 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 index = getGAIndexInPinus(this.aid); let declareIndex = getDeclareIndex(); 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.CITY_NOT_FOUND); let obj = getCityActivityObj(); let {gateHp, maxHp} = await obj.getGateHpAndInc(serverId, cityId); let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid, index); if (!guildActivityRec) return resResult(STATUS.WRONG_PARMS); let myGuildActivityRec = await UserGuildActivityRecModel.findByRoleId(roleId, guildActivityRec.code); let challengeTime = 0; if (myGuildActivityRec) { challengeTime = myGuildActivityRec.challengeTime; } const dbCities = await GuildActivityCityModel.getAllCities(serverId, declareIndex); let cityStatus = pubGetCityStatus(guildCode, cityId, dicCity, dbCities); if (cityStatus == CITY_STATUS.DECLARED) { obj.pushGuild(guildCode, serverId, cityId); } let historyCity = await getHistoryCity(roleId); if (historyCity) { await leaveCityChannel(roleId, sid, serverId, `${historyCity}`); } await addRoleToCityChannel(roleId, sid, serverId, cityId); await setHistoryCity(roleId, cityId); let ranks = await getCityActivityRank(guildCode, serverId, cityId, roleId, roleName); return resResult(STATUS.SUCCESS, { cityId, ...statusResult, cityStatus, gateHp, maxHp, 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'); let { cityId } = msg; let dicCity = gameData.cityActivity.get(cityId); if (dicCity.preCity.length > 0) return resResult(STATUS.CAN_NOT_DECLARE); let declareIndex = getDeclareIndex(); let checkResult = await GuildActivityCityDeclareModel.checkDeclartion(serverId, guildCode, declareIndex); if (!!checkResult) return resResult(STATUS.HAS_DECLARED); let curCity = await GuildActivityCityModel.getCity(serverId, cityId, declareIndex); if (curCity && curCity.guardGuildCode) { return resResult(STATUS.CITY_IS_GUARD); } let declareResult = await declareCity(serverId, roleId, guildCode, cityId, false, declareIndex); if(!declareResult) return resResult(STATUS.HAS_DECLARED); const dbCities = await GuildActivityCityModel.getAllCities(serverId, declareIndex); let cities = getCities(guildCode, dbCities); return resResult(STATUS.SUCCESS, { cities }); } // 开始挑战 async checkBattle(msg: guildInter & { cityId: number, heroes: number[] }, session: BackendSession) { let { cityId, heroes, myUserGuild: userGuild } = msg; 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 index = getGAIndexInPinus(this.aid); let declareIndex = getDeclareIndex(); if (!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); let checkResult = await GuildActivityCityDeclareModel.checkDeclartion(serverId, guildCode, declareIndex); if (!checkResult) return resResult(STATUS.HAS_NOT_DECLARED); let obj = getCityActivityObj(); const dicCity = gameData.cityActivity.get(cityId); if (!dicCity) return resResult(STATUS.CITY_NOT_FOUND); let { gateHp, maxHp } = await obj.getGateHpAndInc(serverId, cityId); if (gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO); let statusResult = getGuildActivityStatus(this.aid); if (!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); if(!statusResult.isOpen) return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN); let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid, index, [], cityId); if (!guildActivityRec) return resResult(STATUS.WRONG_PARMS); let { code: sourceCode } = guildActivityRec; let myGuildActivityRec = await UserGuildActivityRecModel.getRecord(roleId, roleName, guildCode, serverId, sourceCode, this.aid); 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, myGuildActivityRec.code); // 返回当前军团总军功 let r = new Rank(REDIS_KEY.CITY_ACTIVITY, { serverId, cityId, index }, true); let guildScore = await r.getMyScore({ guildCode }); const dbCities = await GuildActivityCityModel.getAllCities(serverId, declareIndex); let cityStatus = pubGetCityStatus(guildCode, cityId, dicCity, dbCities); // 全服活跃统计 await ServerRecordModel.addActiveGuild(serverId, roleId, guildCode); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.GUILD_ACTIVITY, { aid: this.aid }); return resResult(STATUS.SUCCESS, { code, cityId, cityStatus, ...statusResult, gateHp, maxHp, guildScore, myScore: 0 }); } async resetChallengeTime(msg: {}, 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 index = getGAIndexInPinus(this.aid); if (!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); let guildActivityRec = await GuildActivityRecordModel.getRecord(guildCode, serverId, this.aid, index); if (!guildActivityRec) return resResult(STATUS.WRONG_PARMS); let { code: sourceCode } = guildActivityRec; let myGuildActivityRec = await UserGuildActivityRecModel.getRecord(roleId, roleName, guildCode, serverId, sourceCode, this.aid); let goldObj = getGoldObject(GUILDACTIVITY.CITYACTIVITY_CD_COST); const costRes = await handleCost(roleId, sid, [goldObj], ITEM_CHANGE_REASON.CITY_ACT_RESET_CHALLENGE_TIME); if (!costRes) { return resResult(STATUS.BATTLE_GOLD_NOT_ENOUGH); } myGuildActivityRec = await UserGuildActivityRecModel.updateInfo(myGuildActivityRec.code, { challengeTime: 0 }); return resResult(STATUS.SUCCESS, { challengeTime: myGuildActivityRec.challengeTime }); } // 上报城门受到伤害 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; let obj = getCityActivityObj(); let { gateHp, maxHp } = await obj.getGateHpAndInc(serverId, cityId); if (gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO); let statusResult = getGuildActivityStatus(this.aid); if (!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); if(!statusResult.isOpen) return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN); if(statusResult.status != GUILD_ACTIVITY_STATUS.START) { return resResult(STATUS.SUCCESS, { code, ...statusResult }) } let challengeTime = nowSeconds() + GUILDACTIVITY.CITYACTIVITY_CHALLENGE_CD; if(isDebugTime()) { let guilds = pinus.app.getServersByType('guild'); let guild = dispatch(roleId, guilds, 'guild'); let currentTime = await pinus.app.rpc.guild.guildActivityRemote.getCurrentTime.toServer(guild.id); challengeTime = Math.floor(currentTime/1000) + GUILDACTIVITY.CITYACTIVITY_CHALLENGE_CD; } let pushResult = await UserGuildActivityRecModel.pushCityRecord(code, { round, hid, damage }, challengeTime); if (!pushResult) return resResult(STATUS.WRONG_PARMS); let nextWeek = getTimeFun().getAfterDayWithHour(7); // 更新redis数据 let index = getGAIndexInPinus(this.aid); let myR = new Rank(REDIS_KEY.USER_CITY_ACTIVITY, { serverId, guildCode, index }, true); let myScore = await myR.setRankWithRoleInfo(roleId, damage, obj.getTimeGap(), null, true); await myR.setExpire(nextWeek); let r = new Rank(REDIS_KEY.CITY_ACTIVITY, { serverId, cityId, index }, true); let guildScore = await r.setRankWithGuildInfo(guildCode, damage, obj.getTimeGap(), null, true); await r.setExpire(nextWeek); ({gateHp, maxHp} = await obj.getGateHpAndInc(serverId, cityId, -1 * damage)); if (gateHp <= 0) { // 推送 停止活动并结算奖励 await sendSingleCityActEndMsg(cityId, serverId); } // 推送 城门血量 await sendMessageToCityWithSuc(serverId, cityId, PUSH_ROUTE.GUILD_CITY_ACT_HP, { cityId, gateHp, maxHp }); await sendCityGuildRankToUser(serverId, cityId, guildCode, roleId); 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 sid = session.get('sid'); 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 = nowSeconds() + GUILDACTIVITY.CITYACTIVITY_CHALLENGE_CD; if(isDebugTime()) { let guilds = pinus.app.getServersByType('guild'); let guild = dispatch(roleId, guilds, 'guild'); let currentTime = await pinus.app.rpc.guild.guildActivityRemote.getCurrentTime.toServer(guild.id); challengeTime = Math.floor(currentTime/1000) + GUILDACTIVITY.CITYACTIVITY_CHALLENGE_CD; } let myGuildActivityRec = await UserGuildActivityRecModel.updateInfo(code, { isSuccess, isCompleted: true, cityId, challengeTime }); if (!myGuildActivityRec) return resResult(STATUS.WRONG_PARMS); // 返回当前军团总军功 let index = getGAIndexInPinus(this.aid); let myR = new Rank(REDIS_KEY.USER_CITY_ACTIVITY, { serverId, guildCode, index }, true); let myScore = await myR.getMyScore({ roleId }); let r = new Rank(REDIS_KEY.CITY_ACTIVITY, { serverId, cityId, index }, true); let guildScore = await r.getMyScore({ guildCode }); let { gateHp, maxHp } = await obj.getGateHpAndInc(serverId, cityId); return resResult(STATUS.SUCCESS, { isSuccess, code, ...statusResult, guildScore, myScore, gateHp, maxHp, challengeTime: myGuildActivityRec.challengeTime }); } async debugTestAutoDeclare(msg: { }, session: BackendSession) { let serverId = session.get('serverId'); let roleId = session.get('roleId'); let guildCode = session.get('guildCode'); let declareIndex = getDeclareIndex(); for(let i = 0; i < 1000; i++) { autoDeclareMyCity(serverId, roleId, guildCode, declareIndex); } return resResult(STATUS.SUCCESS) } private interval: NodeJS.Timer; async debugStartHitGate(msg: { param: number }, session: BackendSession) { const roleId = session.get('roleId'); const serverId = session.get('serverId'); let { param = 1000 } = msg; let statusResult = getGuildActivityStatus(this.aid); if (!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND); if(!statusResult.isOpen) return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN); if(statusResult.status != GUILD_ACTIVITY_STATUS.START) return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN); if(this.interval) { clearInterval(this.interval); } let fun = async () => { for(let [cityId] of gameData.cityActivity) { let guilds = pinus.app.getServersByType('guild'); let guild = dispatch(`${cityId}`, guilds); await pinus.app.rpc.guild.guildActivityRemote.debugSendGateHp.toServer(guild.id, serverId, cityId); } await pinus.app.rpc.guild.guildActivityRemote.sendRankToGuilds.broadcast(this.aid); }; await fun(); this.interval = setInterval(fun, param) return resResult(STATUS.SUCCESS) } async debugStopHitGate(msg: { magicWord: string }, session: BackendSession) { if(this.interval) { clearInterval(this.interval); } return resResult(STATUS.SUCCESS); } }