军团活动:诸侯混战露出的接口

This commit is contained in:
luying
2021-03-22 20:51:59 +08:00
parent a56a6cf2f3
commit ecb4b87abc
14 changed files with 550 additions and 87 deletions

View File

@@ -27,7 +27,9 @@ export class GuildRemote {
private GUILD_REC_ADD = 'onGuildRecAdd';
private GUILD_ACT_RANK = 'onGuildGateRankUpdate'; // 军团活动排行榜
private GUILD_GATE_ACT_HP = 'onGuildGateHpUpdate'; // 军团活动蛮夷入侵排行榜
private GUILD_ACTIVITY_END = 'onGuildActivityEnd';
private GUILD_ACTIVITY_END = 'onGuildActivityEnd'; // 军团活动结束
private GUILD_CITY_DECLARE = 'onGuildCityDeclare'; // 有军团对这个城池进行宣战了
private GUILD_CITY_ACT_HP = 'onGuildCityGateHpUpdate'; // 诸侯入侵城门血条
/**
* 封装军团相关channel名: 'guild'+guildCode
@@ -76,6 +78,31 @@ export class GuildRemote {
return channel
}
/**
* 诸侯混战按城池区分channel
* @param cityId 城池id
* @param create 是否创建channel
*/
private getCityChannel(cityId: number, create: boolean = false) {
let channelName = groupRoomId(CHANNEL_PREFIX.CITY, cityId);
let channel = this.channelService.getChannel(channelName, create);
return channel
}
/**
* 封装向channel发推送
* @param cityId 城池id
* @param path 推送地址
* @param message 推送信息
*/
private pushMessageToCity(cityId: number, path: string, message: any) {
let channel = this.getCityChannel(cityId);
if(!!channel) {
channel.pushMessage(path, resResult(STATUS.SUCCESS, message));
}
return channel
}
/**
* 踢出某个成员
* @param guildCode 军团code
@@ -163,8 +190,8 @@ export class GuildRemote {
* 向军团推送城门血量
* @param guildCode
*/
public pushGateHp(guildCode: string, msg: GuildGateRankParam) {
this.pushMessage(guildCode, this.GUILD_GATE_ACT_HP, msg);
public pushGateHp(guildCode: string, gateHp: number) {
this.pushMessage(guildCode, this.GUILD_GATE_ACT_HP, { gateHp });
}
/**
@@ -183,4 +210,29 @@ export class GuildRemote {
console.log("MSG END")
this.pushMessage(guildCode, this.GUILD_ACTIVITY_END, {});
}
/**
* @description 向城池推送有宣战
* @param cityId 城池
* @param declareGuildCode 宣战的军团code
* @param declareCount 宣战数量
*/
public async sendGuildCityDeclare(cityId: number, declareGuildCode: string, declareCount: number ) {
this.pushMessageToCity(cityId, this.GUILD_CITY_DECLARE, {
cityId,
declareGuildCode,
declareCount
});
}
/**
* @description 推送城池城门血条
* @param guildCode
*/
public async pushCityGateHp(cityId: number, gateHp: number ) {
this.pushMessageToCity(cityId, this.GUILD_CITY_ACT_HP, {
cityId,
gateHp
});
}
}

View File

@@ -1,10 +1,22 @@
import { Application, ChannelService, BackendSession } from "pinus";
import { GUILD_ACTIVITY_TYPE, STATUS, CITY_STATUS } from "../../../consts";
import { Application, ChannelService, BackendSession, pinus } from "pinus";
import { GUILD_ACTIVITY_TYPE, STATUS, REDIS_KEY, GUILD_POINT_WAYS } from "../../../consts";
import { resResult } from "../../../pubUtils/util";
import { getGuildActivityStatus } from "../../../services/guildActivityService";
import { getGuildActivityStatus, getCityActivityObj, getCityStatus as pubGetCityStatus, getCities, getCityActivityRank } from "../../../services/guildActivityService";
import { GuildActivityCityModel } from "../../../db/GuildActivityCity";
import { CityParam } from "../../../domain/battleField/guildActivity";
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, getBeforeMinuteSeconds } from "../../../pubUtils/timeUtil";
import { getGoldObject } from "../../../pubUtils/itemUtils";
import { GUILDACTIVITY } from "../../../pubUtils/dicParam";
import { handleCost } from "../../../services/rewardService";
import { getRankScore, getCityKeyName, getGuildKeyName, setGuildActivityRank, 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);
@@ -30,36 +42,7 @@ export class CityActivityHandler {
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
const dbCities = await GuildActivityCityModel.getAllCities(serverId);
let cities = new Array<CityParam>();
for(let [ cityId, dic ] of gameData.cityActivity) {
let param = new CityParam(cityId);
let curCity = dbCities.find(cur => cur.cityId == cityId);
let preCity = dic.preCity;
if(preCity && preCity.length) {
let hasGuardCity = dbCities.find(cur => {
return preCity.includes(cur.cityId) && cur.guardGuildCode == guildCode;
});
if(!!hasGuardCity) {
param.status = CITY_STATUS.CAN_DECLARE;
}
} else {
param.status = CITY_STATUS.CAN_DECLARE;
}
if(curCity) {
if(curCity.guardGuildCode == guildCode) {
param.status = CITY_STATUS.GUARD;
} else if (curCity.declareGuilds.includes(guildCode)) {
param.status = CITY_STATUS.DECLARED;
}
param.guardGuildCode = curCity.guardGuildCode;
param.guardGuildName = curCity.guardGuildName;
param.declareCount = curCity.declareCount;
}
cities.push(param);
}
let cities = getCities(guildCode, dbCities);
return resResult(STATUS.SUCCESS, {
...statusResult,
@@ -68,27 +51,234 @@ export class CityActivityHandler {
}
// 获取单个城池状态
async getCityStatus(msg: {}, session: BackendSession) {
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.preCity, dbCities);
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: {}, session: BackendSession) {
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 checkResult = await GuildActivityCityModel.checkDeclartion(serverId, guildCode);
if(!!checkResult) return resResult(STATUS.HAS_DECLARED);
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: {}, session: BackendSession) {
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 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.preCity, dbCities);
return resResult(STATUS.SUCCESS, {
code,
cityId,
cityStatus,
...statusResult,
gateHp,
guildScore,
myScore: 0
});
}
// 上报城门受到伤害
async hitGate(msg: {}, session: BackendSession) {
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);
gateHp = obj.getGateHpAndInc(serverId, cityId, -1 * damage);
if(gateHp <= 0) {
// TODO 推送 停止活动并结算奖励
}
// 推送 城门血量
let chatSid = await getCityChannelSid(cityId);
pinus.app.rpc.chat.guildRemote.pushCityGateHp.toServer(chatSid, cityId, gateHp);
// 更新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 setGuildActivityRank(REDIS_KEY.USER_CITY_ACTIVITY, guildCode, serverId, roleId, damage, Date.now(), userParam);
let guild = await GuildModel.findByCode(guildCode, serverId);
let leader = <RoleType>guild.leader;
let params = new GuildRankParam(guild.icon, guild.name, guild.lv, leader);
let guildScore = await setRank(REDIS_KEY.GATE_ACTIVITY, serverId, guild.code, damage, Date.now(), params, true);
return resResult(STATUS.SUCCESS, {
code,
...statusResult,
guildScore,
myScore,
gateHp
})
}
// 结束挑战
async battleEnd(msg: {}, session: BackendSession) {
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 = getBeforeMinuteSeconds(-1 * GUILDACTIVITY.CITYACTIVITY_CD_COST);
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
});
}
}

View File

@@ -1,13 +1,12 @@
import { Application, BackendSession, ChannelService, pinus } from "pinus";
import { setMedianCe, getMedianCe, getGuildActivityStatus, getRecordScore, getGuildActivityObj, getGuildActivityRank, sendSingleGuildGateActEndMsg, sendGuildActEndMsg, participants } from "../../../services/guildActivityService";
import { getMedianCe, getGuildActivityStatus, getRecordScore, getGateActivityObj, sendSingleGuildGateActEndMsg, sendGuildActEndMsg, participants, getGateActivityRank } from "../../../services/guildActivityService";
import { resResult } from "../../../pubUtils/util";
import { STATUS, GUILD_ACTIVITY_TYPE, GUILD_POINT_WAYS, ENEMIES_TYPE, GET_POINT_WAYS } from "../../../consts";
import { GameModel } from "../../../db/Game";
import { ServerlistModel } from "../../../db/Serverlist";
import { UserGuildActivityRecModel, Record } from "../../../db/UserGuildActivityRec";
import { UserGuildActivityRecModel } from "../../../db/UserGuildActivityRec";
import { GUILDACTIVITY } from "../../../pubUtils/dicParam";
import { GuildActivityRecordModel } from "../../../db/GuildActivityRec";
import { GuildActivityCityModel } from "../../../db/GuildActivityCity";
import { RoleModel, RoleType } from "../../../db/Role";
import { GuildModel } from "../../../db/Guild";
import { RankParam, GuildRankParam } from "../../../domain/rank";
@@ -49,7 +48,7 @@ export class GateActivityHandler {
let myGuildActivityRec = await UserGuildActivityRecModel.getRecord(roleId, roleName, guildCode, serverId, sourceCode, this.aid);
let { challengeCnt } = myGuildActivityRec;
let ranks = await getGuildActivityRank(guildCode, serverId, roleId, roleName);
let ranks = await getGateActivityRank(guildCode, serverId, roleId, roleName);
return resResult(STATUS.SUCCESS, {
...statusResult,
@@ -68,7 +67,7 @@ export class GateActivityHandler {
const serverId = session.get('serverId');
const guildCode = session.get('guildCode');
if(!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
let obj = getGuildActivityObj(this.aid);
let obj = getGateActivityObj();
let gateHp = obj.getGateHpAndInc(guildCode);
if(gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO);
@@ -88,7 +87,7 @@ export class GateActivityHandler {
if(myGuildActivityRec.challengeCnt > 0) {
return resResult(STATUS.CHALLENGE_CNT_NOT_ENOUGH);
}
await UserGuildActivityRecModel.incChallengeCnt(myGuildActivityRec.code, heroes);
myGuildActivityRec = await UserGuildActivityRecModel.incChallengeCnt(myGuildActivityRec.code, heroes);
let { code, challengeCnt } = myGuildActivityRec;
// 更新公会参与的玩家
@@ -119,7 +118,7 @@ export class GateActivityHandler {
let serverId = session.get('serverId');
let { code, record } = msg;
let obj = getGuildActivityObj(this.aid);
let obj = getGateActivityObj();
let statusResult = getGuildActivityStatus(this.aid);
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
@@ -166,7 +165,7 @@ export class GateActivityHandler {
let serverId = session.get('serverId');
let { code, damage } = msg;
let obj = getGuildActivityObj(this.aid);
let obj = getGateActivityObj();
let gateHp = obj.getGateHpAndInc(guildCode);
if(gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO);
@@ -182,7 +181,7 @@ export class GateActivityHandler {
}
// 推送 城门血量
let chatSid = await getGuildChannelSid(guildCode);
pinus.app.rpc.chat.guildRemote.pushGateHp.toServer(chatSid, guildCode, { gateHp });
pinus.app.rpc.chat.guildRemote.pushGateHp.toServer(chatSid, guildCode, gateHp);
// 返回当前军团总军功
let guildScore = await getRankScore(REDIS_KEY.GATE_ACTIVITY, serverId, guildCode);
@@ -205,7 +204,7 @@ export class GateActivityHandler {
let serverId = session.get('serverId');
let { code, isSuccess } = msg;
let obj = getGuildActivityObj(this.aid);
let obj = getGateActivityObj();
let statusResult = getGuildActivityStatus(this.aid);
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
@@ -280,7 +279,7 @@ export class GateActivityHandler {
let guildCode = session.get('guildCode');
console.log(guildCode);
let serverId = session.get('serverId');
let res = getGuildActivityObj(this.aid).getObj(guildCode, serverId);
let res = getGateActivityObj().getObj(guildCode, serverId);
return resResult(STATUS.SUCCESS, res)
}

View File

@@ -41,6 +41,11 @@ export async function addRoleToGuildChannel(roleId: string, sid: string, guildCo
await addRoleToChannel(roomId, roleId, sid);
}
export async function addRoleToCityChannel(roleId: string, sid: string, cityId: number) {
const roomId = groupRoomId(CHANNEL_PREFIX.CITY, cityId);
await addRoleToChannel(roomId, roleId, sid);
}
async function leaveChannel(roomId: string, roleId: string, sid: string) {
const channelSid = await channelServer(roomId);
await pinus.app.rpc.chat.chatRemote.leaveChannel.toServer(channelSid, roomId, roleId, sid);
@@ -56,6 +61,12 @@ export async function leaveWorldChannel(roleId: string, sid: string, serverId: n
await leaveChannel(roomId, roleId, sid);
}
export async function leaveCityChannel(roleId: string, sid: string, cityId: number) {
const roomId = groupRoomId(CHANNEL_PREFIX.CITY, cityId);
await leaveChannel(roomId, roleId, sid);
}
export async function leaveGuildChannel(roleId: string, sid: string) {
const { guildCode } = await RoleModel.findByRoleId(roleId, 'guildCode');
if (!guildCode) return;
@@ -74,3 +85,9 @@ export async function getGuildChannelSid(guildCode: string) {
const channelSid = await channelServer(roomId);
return channelSid;
}
export async function getCityChannelSid(cityId: number) {
const roomId = groupRoomId(CHANNEL_PREFIX.CITY, cityId);
const channelSid = await channelServer(roomId);
return channelSid;
}

View File

@@ -2,14 +2,14 @@ import { ServerlistModel } from "../db/Serverlist";
import { RoleModel } from "../db/Role";
import { reduceCe } from "../pubUtils/util";
import { GUILDACTIVITY } from "../pubUtils/dicParam";
import { gameData, getGuildAuctionRewards, getTodayGuildActivity } from "../pubUtils/data";
import { gameData, getGuildAuctionRewards } from "../pubUtils/data";
import { getCurHourPoint, getCutDay, nowSeconds } from "../pubUtils/timeUtil";
import { GUILD_ACTIVITY_STATUS, GET_POINT_WAYS, GUILD_ACTIVITY_TYPE, REDIS_KEY, AUCTION_SOURCE, MAIL_TYPE } from "../consts";
import { GUILD_ACTIVITY_STATUS, GET_POINT_WAYS, GUILD_ACTIVITY_TYPE, REDIS_KEY, AUCTION_SOURCE, MAIL_TYPE, CITY_STATUS } from "../consts";
import { Record, UserGuildActivityRecModel } from "../db/UserGuildActivityRec";
import { GateMembersRec, GateActivityObject } from "../domain/battleField/guildActivity";
import { GateMembersRec, GateActivityObject, CityActivityObject, CityParam } from "../domain/battleField/guildActivity";
import { DicGuildActivity } from "../pubUtils/dictionary/DicGuildActivity";
import { getUnionRank, getRank, getGuildKeyName, getMyUnionRank, getRankScore } from "./redisService";
import Guild, { GuildModel } from "../db/Guild";
import { getUnionRank, getRank, getGuildKeyName, getMyUnionRank, getRankScore, getCityKeyName } from "./redisService";
import { GuildModel } from "../db/Guild";
import { SimpleGuildRankParam, SimpleRoleRankParam } from "../domain/rank";
import { getGuildChannelSid, getWorldChannelSid } from "./chatChannelService";
import { pinus } from "pinus";
@@ -18,15 +18,22 @@ import { uniq } from 'underscore'
import { genAuction } from "./auctionService";
import { sendMail } from "./mailService";
import { getHonourObject } from '../pubUtils/itemUtils';
import { GuildActivityCityType } from "../db/GuildActivityCity";
let gateActivityObj: GateActivityObject;
export function getGuildActivityObj(aid: number) {
if(aid == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) {
if(!gateActivityObj) {
gateActivityObj = new GateActivityObject()
}
return gateActivityObj;
let cityActivityObj: CityActivityObject;
export function getGateActivityObj() {
if(!gateActivityObj) {
gateActivityObj = new GateActivityObject();
}
return gateActivityObj;
}
export function getCityActivityObj() {
if(!cityActivityObj) {
cityActivityObj = new CityActivityObject();
}
return cityActivityObj
}
/**
@@ -137,6 +144,20 @@ export function getRecordScore(aid: number, record: { round: number, dataId: num
return { score: sum, newRecords, memberRecord }
}
export async function getGateActivityRank(guildCode: string, serverId: number, roleId?: string, roleName?: string) {
let guildKey = REDIS_KEY.GATE_ACTIVITY;
let memberKey = getGuildKeyName(REDIS_KEY.USER_GATE_ACTIVITY, guildCode);
let rec = await getGuildActivityRank(guildKey, memberKey, guildCode, serverId, roleId, roleName);
return rec;
}
export async function getCityActivityRank(guildCode: string, serverId: number, cityId: number, roleId?: string, roleName?: string) {
let guildKey = getCityKeyName(REDIS_KEY.USER_CITY_ACTIVITY, cityId);
let memberKey = getGuildKeyName(REDIS_KEY.USER_CITY_ACTIVITY, guildCode);
let rec = await getGuildActivityRank(guildKey, memberKey, guildCode, serverId, roleId, roleName);
return rec;
}
/**
* 获得军团活动排行榜
* @param guildCode
@@ -144,9 +165,9 @@ export function getRecordScore(aid: number, record: { round: number, dataId: num
* @param roleId
* @param roleName
*/
export async function getGuildActivityRank(guildCode: string, serverId: number, roleId?: string, roleName?: string) {
export async function getGuildActivityRank(guildKey: string, memberKey: string, guildCode: string, serverId: number, roleId?: string, roleName?: string) {
let guildRankResult = await getUnionRank(REDIS_KEY.GATE_ACTIVITY, serverId, guildCode);
let guildRankResult = await getUnionRank(guildKey, serverId, guildCode);
let guildRank = new Array<SimpleGuildRankParam>();
for(let { rank, code, name, num } of guildRankResult.ranks) {
let param = new SimpleGuildRankParam(rank, code, name, num);
@@ -161,7 +182,7 @@ export async function getGuildActivityRank(guildCode: string, serverId: number,
myGuildRank = new SimpleGuildRankParam(0, guildCode, guild.name, 0);
}
let memberRankResult = await getRank(getGuildKeyName(REDIS_KEY.USER_GATE_ACTIVITY, guildCode), serverId, roleId);
let memberRankResult = await getRank(memberKey, serverId, roleId);
let memberRank = new Array<SimpleRoleRankParam>();
for(let { rank, roleId, roleName, num } of memberRankResult.ranks) {
let param = new SimpleRoleRankParam(rank, roleId, roleName, num);
@@ -185,14 +206,16 @@ export async function getGuildActivityRank(guildCode: string, serverId: number,
* @param aid 活动类型
*/
export async function sendAllGuildRanks(aid: number) {
let obj = getGuildActivityObj(aid);
let guilds = obj.getGuilds();
for(let [ serverId, guildCodes ] of guilds) {
// TODO 不需要每个军团都排序一次
for(let guildCode of guildCodes) {
let ranks = await getGuildActivityRank(guildCode, serverId);
let chatSid = await getGuildChannelSid(guildCode);
pinus.app.rpc.chat.guildRemote.pushRank.toServer(chatSid, guildCode, ranks);
if(aid == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) {
let obj = getGateActivityObj();
let guilds = obj.getGuilds();
for(let [ serverId, guildCodes ] of guilds) {
// TODO 不需要每个军团都排序一次
for(let guildCode of guildCodes) {
let ranks = await getGateActivityRank(guildCode, serverId);
let chatSid = await getGuildChannelSid(guildCode);
pinus.app.rpc.chat.guildRemote.pushRank.toServer(chatSid, guildCode, ranks);
}
}
}
}
@@ -202,7 +225,7 @@ export async function sendAllGuildRanks(aid: number) {
* @param aid 活动类型
*/
export async function sendGuildActEndMsg(aid: number) {
let obj = getGuildActivityObj(aid);
let obj = getGateActivityObj();
let guilds = obj.getGuilds();
for(let [ serverId, guildCodes ] of guilds) {
let chatSid = await getWorldChannelSid(serverId);
@@ -232,7 +255,7 @@ export async function sendSingleGuildGateActEndMsg(guildCode: string, serverId:
* @param serverId
*/
export async function gateActivitySettleReward(guildCode: string, serverId: number) {
let obj = getGuildActivityObj(GUILD_ACTIVITY_TYPE.GATE_ACTIVITY);
let obj = getGateActivityObj();
let { gateHp, members } = obj.getObj(guildCode, serverId);
members = uniq(members, cur => cur.roleId);
@@ -277,4 +300,54 @@ export async function participants(guildCode: string, sourceType: number, source
if(!rec) return [];
return rec.members||[];
}
export function getCities(guildCode: string, dbCities: GuildActivityCityType[]) {
let cities = new Array<CityParam>();
for(let [ cityId, dic ] of gameData.cityActivity) {
let param = new CityParam(cityId);
let curCity = dbCities.find(cur => cur.cityId == cityId);
if(curCity) {
param.guardGuildCode = curCity.guardGuildCode;
param.guardGuildName = curCity.guardGuildName;
param.declareCount = curCity.declareCount;
}
param.status = getCityStatus(guildCode, cityId, dic.preCity, dbCities);
cities.push(param);
}
return cities
}
/**
* 诸侯混战 获取城池状态
* @param guildCode
* @param cityId
* @param preCity
* @param dbCities
*/
export function getCityStatus(guildCode: string, cityId: number, preCity: number[], dbCities: GuildActivityCityType[]) {
let status = CITY_STATUS.NOT_OPEN;
if(preCity && preCity.length) {
let hasGuardCity = dbCities.find(cur => {
return preCity.includes(cur.cityId) && cur.guardGuildCode == guildCode;
});
if(!!hasGuardCity) {
status = CITY_STATUS.CAN_DECLARE;
}
} else {
status = CITY_STATUS.CAN_DECLARE;
}
let curCity = dbCities.find(cur => cur.cityId == cityId);
if(curCity) {
if(curCity.guardGuildCode == guildCode) {
status = CITY_STATUS.GUARD;
} else if (curCity.declareGuilds.includes(guildCode)) {
status = CITY_STATUS.DECLARED;
}
}
return status;
}

View File

@@ -182,7 +182,8 @@ export async function getRank(key: string, serverId: number, roleId: string, lim
let ranks = [], myRank = null;
const rankFromDb = await redisClient().zrevrangebyscoreAsync(getKeyName(key, serverId), '+inf', '-inf', "WITHSCORES", "LIMIT", 0, limit);
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
let _key = key.split(':')[0];
let infoKey = REDIS_RANK_TO_INFO.get(_key)||REDIS_KEY.USER_INFO;
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
const _roleId = rankFromDb[ii];
@@ -604,7 +605,8 @@ export async function getUnionRank(key: string, serverId: number, roleId: string
let unionKey = await generateUnionRank(key, serverId);
const rankFromDb = await redisClient().zrevrangebyscoreAsync(unionKey, '+inf', '-inf', "WITHSCORES", "LIMIT", 0, limit);
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
let _key = key.split(':')[0];
let infoKey = REDIS_RANK_TO_INFO.get(_key)||REDIS_KEY.USER_INFO;
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
const _roleId = rankFromDb[ii];
@@ -661,6 +663,10 @@ export function getGuildKeyName(key: string, guildCode: string) {
return `${key}:${guildCode}`;
}
export function getCityKeyName(key: string, cityId: number) {
return `${key}:${cityId}`;
}
/**
* debug接口使用直接删除排行榜数据
* @param params serverId => guildCodes
@@ -676,4 +682,5 @@ export async function delGuildActivityRank(params: Map<number, string[]>) {
}
}
}
/**************** 军团活动排行end */

View File

@@ -20,7 +20,7 @@ import { STATUS } from '../consts/statusCode';
import { getMailContent, sendMail } from './mailService';
import { reportOnline } from '../pubUtils/httpUtil';
import User, { UserModel } from '../db/User';
import { getGuildActivityByDic, getGuildActivityRank, setMedianCe } from './guildActivityService';
import { getGuildActivityByDic, setMedianCe } from './guildActivityService';
import { sendUngotDividend, startGuildAuction, startWorldAuction, stopAuction } from './auctionService';
import { DicGuildActivity } from '../pubUtils/dictionary/DicGuildActivity';
const PER_SECOND = 1 * 1000;

View File

@@ -20,6 +20,7 @@ export const CHANNEL_PREFIX = {
WORLD: 'world',
GUILD: 'guild',
TEAM: 'com_btl_team',
CITY: 'city', // 军团活动诸侯混战按城池分channel
}
// 消息来源

View File

@@ -232,8 +232,11 @@ export const REDIS_KEY = {
DB_GAME: 'db_game', // 服务器列表
ONLINE_USERS: 'onlineUsers', // 在线用户情况
CHANNEL_SERVERS: 'chat:channelServers', // 渠道对应的 chat 服务器 Id,
USER_GATE_ACTIVITY: 'usrGateAct',
GATE_ACTIVITY: 'gateAct',
USER_GATE_ACTIVITY: 'usrGateAct', // 蛮夷入侵玩家排行
GATE_ACTIVITY: 'gateAct', // 蛮夷入侵军团排行
USER_CITY_ACTIVITY: 'usrCityAct', // 诸侯混战玩家排行
CITY_ACTIVITY: 'cityAct', // 诸侯混战军团排行
}
// 各排行榜对应hash的key

View File

@@ -34,6 +34,7 @@ export const STATUS = {
BATTLE_HERO_NOT_FOUND: { code: 20006, simStr: '使用的武将不存在' },
BATTLE_CONSUMES_NOT_ENOUGH: { code: 20007, simStr: '道具不足' },
BATTLE_END_WRONG_TYPE: { code: 20008, simStr: '此类型无法使用通用结算' },
BATTLE_GOLD_NOT_ENOUGH: { code: 20009, simStr: '元宝不足' },
// 主线 20100 - 20199
BATTLE_INFO_VALIDATE_ERR: { code: 20101, simStr: '关卡信息不同' },
@@ -202,6 +203,8 @@ export const STATUS = {
GUILD_ACTIVITY_NOT_OPEN: { code: 21100, simStr: '活动未开放' },
GATE_HP_IS_ZERO: { code: 21101, simStr: '城门已被击破' },
CHALLENGE_CNT_NOT_ENOUGH: { code: 21102, simStr: '挑战次数不足' },
HAS_DECLARED: { code: 21103, simStr: '已宣战过' },
CHALLENGE_TIME_NOT_REACH: { code: 21104, simStr: '挑战冷却中' },
// 通用 30000 - 30099
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },

View File

@@ -32,11 +32,20 @@ export default class GuildActivityCity extends BaseModel {
return rec;
}
// 检查是否宣战过
public static async checkDeclartion(serverId: number, guildCode: string) {
let today = getTodayZeroDate();
let rec: GuildActivityCityType = await GuildActivityCityModel.findOne(
{ serverId, createdAt: { $gte: today }, $in: { declareGuilds: [guildCode]}}).lean();
return rec;
}
// 每天宣战一次
public static async declare(serverId: number, cityId: number, guildCode: string) {
let today = getTodayZeroDate();
let rec: GuildActivityCityType = await GuildActivityCityModel.findOneAndUpdate(
{ serverId, cityId, createdAt: { $gte: today }, declareGuilds: { $nin: [guildCode] }},
{ serverId, cityId, createdAt: { $gte: today } },
{ $setOnInsert: { cityId }, $push: { declareGuilds: guildCode }, $inc: {declareCount: 1 } },
{new: true, upsert: true}).lean();

View File

@@ -18,6 +18,17 @@ export class Record {
}
export class DamageRecord {
@prop({ required: true })
round: number; // 第几回合
@prop({ required: true })
hid: number; // 造成伤害的武将
@prop({ required: true })
damage: number; // 伤害
}
@index({ code: 1 })
export default class UserGuildActivityRec extends BaseModel {
@@ -54,17 +65,26 @@ export default class UserGuildActivityRec extends BaseModel {
@prop({ required: true, default: 0 })
challengeCnt: number; // 向上累加的挑战次数
// 南蛮入侵字段
@prop({ required: true, type: Number })
heroes: number[]; // 使用的武将
heroes: number[]; // 南蛮&诸侯混战 使用的武将
@prop({ required: true })
score: number; // 个人总军功
score: number; // 个人总军功/个人总伤害
// 南蛮入侵字段
@prop({ required: true, type: Record, _id: false })
record: Record[]; // 个人总军功
// 诸侯混战字段
@prop({ required: true, default: 0 })
challengeTime: number; // cd结束时间
@prop({ required: true, type: DamageRecord, _id: false })
damageRecord: DamageRecord[]; // 城门伤害记录
@prop({ required: true, default: 0 })
cityId: number; // 挑战城池
// 每天一条记录
public static async getRecord(roleId: string, roleName: string, guildCode: string, serverId: number, sourceCode: string, aid: number) {
let today = getTodayZeroDate();
@@ -80,6 +100,14 @@ export default class UserGuildActivityRec extends BaseModel {
return rec;
}
public static async findByRoleId(roleId: string, aid: number) {
let today = getTodayZeroDate();
let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOne({ roleId, aid, createdAt: { $gte: today }}).lean();
return rec;
}
public static async incChallengeCnt(code: string, heroes: number[], inc: number = 1 ) {
let rec = await UserGuildActivityRecModel.findOneAndUpdate( { code}, { $push: { heroes: { $each: heroes}}, $inc: { challengeCnt: inc }}, {new: true}).lean();
return rec;
@@ -94,6 +122,15 @@ export default class UserGuildActivityRec extends BaseModel {
return rec;
}
public static async pushCityRecord(code: string, damageRecord: DamageRecord) {
let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate(
{ code },
{ $push: { damageRecord }},
{ new: true }
).lean();
return rec;
}
public static async updateInfo(code: string, update: UserGuildActivityRecUpdateParam) {
let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate({ code }, { $set: update }, { new: true }).lean();
return rec;

View File

@@ -16,7 +16,7 @@ export class GateMembersRec {
export class GateActivityObject {
private gateHp: Map<string, number> = new Map(); // 城门血条,每个军团有一条血条 guildCode => hp
private members: Map<string, Array<Member>> = new Map(); // 每个军团参与的成员 guildCode => [roleId]
private members: Map<string, Array<Member>> = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}]
private membersRecord: Map<string, GateMembersRec> = new Map(); // 每个成员的回合数和敌军数,防刷 recCode => GateMembersRec
private guilds: Map<number, string[]> = new Map(); // 参加的所有军团 server => [guildCode]
@@ -89,6 +89,73 @@ export class GateActivityObject {
}
}
// 军团诸侯混战等数据
export class CityActivityObject {
private gateHp: Map<string, number> = new Map(); // 城门血条每个cityId有一条血条 serverId&cityId => gateHp
private members: Map<string, Array<Member>> = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}]
private cities: Map<string, string[]> = new Map(); // 各个城池参与的军团 serverId&cityId => [guildCode]
private guilds: Map<string, number> = new Map(); // 军团所在的城池 guildCode => cityId
private historyCity: Map<string, number> = new Map(); // 获取自己打开过的城池的页面 roleId => cityId
private getKey(serverId: number, cityId: number) {
return `${serverId}_${cityId}`;
}
public getObj( serverId: number, cityId: number, guildCode: string) {
let key = this.getKey(serverId, cityId);
return {
gateHp: this.gateHp.get(key),
members: this.members.get(guildCode),
city: this.cities.get(key),
guild: this.guilds.get(guildCode)
}
}
public getGateHpAndInc(serverId: number, cityId: number, maxHp: number, inc: number = 0) {
let key = this.getKey(serverId, cityId);
let gateHp = this.gateHp.get(key);
if(!this.gateHp.has(key)) {
gateHp = maxHp;
}
if(inc != 0) {
gateHp += inc;
this.gateHp.set(key, gateHp);
}
if(gateHp <= 0) gateHp = 0;
return gateHp
}
public getHistoryCity(roleId: string) {
return this.historyCity.get(roleId)
}
public setHistoryCity(roleId: string, cityId: number) {
return this.historyCity.set(roleId, cityId);
}
public pushMembers(guildCode: string, roleId: string, job: number) {
if(this.members.has(guildCode)) {
this.members.get(guildCode).push({ roleId, job });
} else {
let arr = new Array<string>();
arr.push(roleId);
this.members.set(guildCode, [{ roleId, job }]);
}
}
public pushGuild(guildCode: string, serverId: number, cityId: number) {
let key = this.getKey(serverId, cityId);
if(!this.cities.has(key)) {
this.cities.set(key, [guildCode]);
} else {
this.cities.get(key).push(guildCode);
}
this.guilds.set(guildCode, cityId);
}
}
export interface GuildGateRankParam {
guildRank: SimpleGuildRankParam[],
myGuildRank: SimpleGuildRankParam,

View File

@@ -2,6 +2,7 @@ import { TIME_FORMAT } from '../consts';
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
const PER_MINUTE = 60;
const PER_HOUR = 60 * 60;
export function getSeconds(time: Date) {
@@ -47,6 +48,10 @@ export function getBeforeHourSeconds(hour: number) {
return time;
}
export function getBeforeMinuteSeconds(minute: number) {
let time = nowSeconds() - minute * PER_MINUTE;
return time;
}
export function getCurWeekDate(day: number, hour: number) {
return getWeekDate(new Date(), day, hour);