Files
ZYZ/game-server/app/services/gvg/gvgService.ts

339 lines
14 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 { pinus } from "pinus";
import { GVGConfigModel, GVGConfigType } from "../../db/GVGConfig";
import { getSeconds, getTimeFun, nowSeconds, WEEK_TO_SECOND } from "../../pubUtils/timeUtil";
import { getServerCreateTime } from "../redisService";
import { GVG_PERIOD, GVG_SERVER_TYPE, LEAGUE_JOB, PUSH_ROUTE } from "../../consts";
import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague";
import { GVGLeaguePrepareModel } from "../../db/GVGLeaguePrepare";
import { gameData } from "../../pubUtils/data";
import { getRandSingleEelm } from "../../pubUtils/util";
import { GVG } from "../../pubUtils/dicParam";
import { GuildModel, GuildType } from "../../db/Guild";
import { GVGLeagueApplyModel } from "../../db/GVGLeagueApply";
import { GVGMainData, LeagueContributeInfo } from "../../domain/gvgField/returnData";
import { Contribute, GVGUserDataModel, GVGUserDataType } from "../../db/GVGUserData";
import { GVGUserItemModel } from "../../db/GVGUserItem";
import { GVGUserTaskModel } from "../../db/GVGUserTask";
import { getMyAuth } from "./gvgTeamService";
import { pick } from "underscore";
import { calFighterContribute, calProducerContribute } from "./gvgPrepareService";
import { calVestigeLeagueBoxRewards, getFightTimeByPeriod } from "./gvgFightService";
import { GVGVestigeLeagueRankModel } from "../../db/GVGVestigeLeagueRank";
import { GVGVestigeSumRankModel } from "../../db/GVGVestigeSumRank";
import { GVGTeamModel } from "../../db/GVGTeam";
import { sendMessageToGuildWithSuc } from "../pushService";
import { GVGCityModel } from "../../db/GVGCity";
import { GVGRoleDataModel } from "../../db/GVGRoleData";
import { getGVGGroupIdOfServer } from "../serverService";
import { UserGuildModel } from "../../db/UserGuild";
// 定时器相关
export async function createNewGVGConfig() {
let { teamTime, prepareTime, battleTime, scheduleTime } = getPeriodTime();
const config = await GVGConfigModel.createNewConfig(teamTime, prepareTime, battleTime, scheduleTime);
try {
await pinus.app.rpc.guild.guildRemote.setGVGConfig.broadcast(config);
await pinus.app.rpc.guild.guildRemote.setServerGroup.broadcast();
await pinus.app.rpc.chat.chatRemote.setServerGroup.broadcast();
await pinus.app.rpc.connector.connectorRemote.setServerGroup.broadcast();
await pinus.app.rpc.gm.gmRemote.setServerGroup.broadcast();
await pinus.app.rpc.systimer.systimerRemote.setServerGroup.broadcast();
await pinus.app.rpc.guild?.guildRemote?.clearBattleMemory.broadcast();
} catch(e) {
console.log('remote未初始完');
}
// 每周自动解散一些联军
let autoLeagues = await GVGLeagueModel.findAutoCreateLeague();
let needDissmissLeagueId: string[] = [], needDissmissLeagueCodes: string[] = [];
for(let league of autoLeagues) {
let groupKey = await getGroupKey(league.serverId);
if(!await GVGCityModel.checkLeagueHasGuard(groupKey, league.leagueCode)) {
needDissmissLeagueId.push(league._id);
needDissmissLeagueCodes.push(league.leagueCode);
}
}
await GVGLeagueModel.dismissByIds(needDissmissLeagueId);
await GuildModel.leagueAutoDismiss(needDissmissLeagueCodes);
for(let league of autoLeagues) {
if(needDissmissLeagueCodes.indexOf(league.leagueCode) == -1) continue;
for(let guildCode of league.guildCodes) {
await sendMessageToGuildWithSuc(guildCode, PUSH_ROUTE.LEAGUE_DISSMISS, { leagueCode: league.leagueCode })
}
}
await pinus.app.rpc.systimer.systimerRemote.initGVGConfigSchedule.broadcast();
return config;
}
// 获取各个周期的时间大约每周日5点的时候刷的
export function getPeriodTime() {
let now = new Date();
let curDay = now.getDay(); // 今天星期几
let teamConfig = gameData.gvgPeriod.get(GVG_PERIOD.TEAM);
let prepareConfig = gameData.gvgPeriod.get(GVG_PERIOD.PREPARE);
let battleConfig = gameData.gvgPeriod.get(GVG_PERIOD.BATTLE);
// 如果现在是周日,那么就是本周期的组队开始时间,如果是其他日子(启动初始化),就是下周期的组队开始时间
let _teamTime = <number>getTimeFun().getTimeWithWeek(teamConfig.startDay);
let _prepareTime = <number>getTimeFun().getTimeWithWeek(prepareConfig.startDay);
let _battleTime = <number>getTimeFun().getTimeWithWeek(battleConfig.startDay);
console.log('_teamTime: ', _teamTime);
let teamTime = curDay == 0? _teamTime: _teamTime - 7 * 86400;
let prepareTime = curDay == 0? _prepareTime + 7 * 86400: _prepareTime;
let battleTime = curDay == 0? _battleTime + 7 * 86400: _battleTime;
let scheduleTime = teamTime + 7 * 86400;
return { teamTime, prepareTime, battleTime, scheduleTime }
}
export async function getGVGConfigFromRemote() {
let serverType = pinus.app.getServerType();
if(serverType == 'guild') {
return getGVGConfig();
} else {
let guildServers = pinus.app.getServersByType('guild');
let server = getRandSingleEelm(guildServers);
return await pinus.app.rpc.guild.guildRemote.getGVGConfig.toServer(server.id);
}
}
export async function setGVGConfig(config?: GVGConfigType) {
if(!config) {
config = await GVGConfigModel.findConfig();
}
if(config.teamTime > nowSeconds()) {
config = null;
}
pinus.app.set('gvgConfigId', config?.configId||0);
pinus.app.set('gvgTeamTime', config?.teamTime||0);
pinus.app.set('gvgPrepareTime', config?.prepareTime||0);
pinus.app.set('gvgBattleTime', config?.battleTime||0);
pinus.app.set('gvgScheduleTime', config?.scheduleTime||0);
}
/**
* 获取当前的赛期id
* @returns
*/
export function getGVGConfig() {
let configId: number = pinus.app.get('gvgConfigId');
let teamTime: number = pinus.app.get('gvgTeamTime');
let prepareTime: number = pinus.app.get('gvgPrepareTime');
let battleTime: number = pinus.app.get('gvgBattleTime');
let scheduleTime: number = pinus.app.get('gvgScheduleTime');
return { configId, teamTime, prepareTime, battleTime, scheduleTime }
}
export function getServerTypeByTime(openTime: number) {
let today = nowSeconds();
if(today - openTime < WEEK_TO_SECOND) return GVG_SERVER_TYPE.NO;
let toWeek = getCurrentTeamTime(today);
let openWeek = getCurrentTeamTime(openTime);
let n = Math.floor((toWeek - openWeek) / WEEK_TO_SECOND);
let day = new Date(openTime * 1000).getDay();
if(day == 6) n++; // 周六开服的服务器延后一周开启跨服
return n <= GVG.GVG_CROSS_SERVICE_STARTTIME? GVG_SERVER_TYPE.SINGLE: GVG_SERVER_TYPE.MULTI;
}
function getCurrentTeamTime(time: number) {
let teamConfig = gameData.gvgPeriod.get(GVG_PERIOD.TEAM);
// 本周日
let _teamTime = <number>getTimeFun(time).getTimeWithWeek(teamConfig.startDay, teamConfig.startHour, teamConfig.startMinute, teamConfig.startSecond);
return _teamTime > time? _teamTime - WEEK_TO_SECOND: _teamTime;
}
export async function getGVGServerType(serverId: number) {
let openTime = await getServerCreateTime(serverId);
return getServerTypeByTime(openTime)
}
export function getGVGPeriodData() {
let { configId, teamTime, prepareTime, battleTime, scheduleTime } = getGVGConfig();
let period = getCurPeriod();
let countdownTime = teamTime;
switch(period) {
case GVG_PERIOD.TEAM: {
countdownTime = prepareTime; break;
}
case GVG_PERIOD.PREPARE: {
countdownTime = battleTime; break;
}
case GVG_PERIOD.BATTLE: {
countdownTime = scheduleTime; break;
}
}
// console.log('######## getGVGPeriodData', configId, teamTime, prepareTime, battleTime, scheduleTime)
return { configId, period, countdownTime };
}
export function getCurPeriod() {
let { teamTime, prepareTime, battleTime, scheduleTime } = getGVGConfig();
return getPeriodByTime(teamTime, prepareTime, battleTime, scheduleTime)
}
export function getPeriodByTime(teamTime: number, prepareTime: number, battleTime: number, scheduleTime: number) {
let now = nowSeconds();
if(now >= teamTime && now < prepareTime) {
return GVG_PERIOD.TEAM;
} else if (now >= prepareTime && now < battleTime) {
return GVG_PERIOD.PREPARE;
} else if (now >= battleTime && now < scheduleTime){
return GVG_PERIOD.BATTLE;
} else {
return GVG_PERIOD.NO;
}
}
export async function initLeaguePrepare() {
const config = await GVGConfigModel.findConfig();
if(!config) return;
const leagues = await GVGLeagueModel.findAllLeague();
let groupKeyByServerId = new Map<number, string>();
for(let { leagueCode, memberCnt, serverId } of leagues) {
let groupKey = groupKeyByServerId.get(serverId);
if(!groupKey) {
groupKey = await getGroupKey(serverId);
groupKeyByServerId.set(serverId, groupKey);
}
await GVGLeaguePrepareModel.initData(config.configId, groupKey, leagueCode, memberCnt);
}
}
export async function getGVGInfoInGuild(roleId: string, guild: GuildType) {
let hasLeague = !!guild.leagueCode;
let serverId = guild.serverId;
let { configId, period, countdownTime } = getGVGPeriodData();
let { startFightTime, endFightTime } = getFightTimeByPeriod(period);
let type = await getGVGServerType(serverId);
if(hasLeague && configId > 0) {
return {
hasLeague,
configId, period, countdownTime,
type,
applyCnt: await getApplyCnt(guild.leagueCode),
...await getMainData(roleId, guild.leagueCode, configId, period, countdownTime, type),
leagueDetailRank: await getLeagueRankBox(configId, guild.leagueCode, roleId),
myTeamCnt: await GVGTeamModel.getTeamCntByRole(roleId),
startFightTime, endFightTime
}
} else {
return {
hasLeague,
configId, period, countdownTime,
startFightTime, endFightTime,
type,
invitationCnt: await getInviteCnt(guild.code)
}
}
}
export async function calLeagueCe(league: GVGLeagueType) {
const guildCodes = league?.guildCodes||[];
const guilds = await GuildModel.findByCodes(guildCodes);
return guilds.reduce((pre, guild) => pre + guild.guildCe, 0);
}
// 检查当前赛季阶段
export async function checkGVGPeriod(p : GVG_PERIOD) {
let { period } = getGVGPeriodData();
return period == p;
}
// —————— 红点相关 —————— //
// 邀请
export async function getInviteCnt(guildCode: string) {
let invitation = await GVGLeagueApplyModel.findInviteFromGuildWithoutPopulate(guildCode);
return invitation.length
}
// 申请
export async function getApplyCnt(leagueCode: string) {
let applies = await GVGLeagueApplyModel.findApplyFromLeagueWithoutPopulate(leagueCode);
return applies.length
}
export async function getMainData(roleId: string, leagueCode: string, configId: number, period: number, countdownTime: number, serverType: number) {
let data = new GVGMainData(configId, period, countdownTime, serverType);
let league = await GVGLeagueModel.findByCode(leagueCode);
if(league) {
data.setLeague(league, {});
let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, league.leagueCode);
data.setLeagueParpare(leaguePrepare);
data.setTechQueue(leaguePrepare?.techQueue||[]);
let userData = await GVGUserDataModel.findByRole(configId, league.leagueCode, roleId);
let roleData = await GVGRoleDataModel.findByRole(configId, roleId);
let items = await GVGUserItemModel.findByRole(configId, league.leagueCode, roleId);
let tasks = await GVGUserTaskModel.findByRole(configId, league.leagueCode, roleId);
data.setPlayerInfo(userData, roleData, getMyAuth(league, roleId), undefined, undefined, items, tasks);
data.setLeagueCe(await calLeagueCe(league));
data.setConstribute(await getContribute(userData));
}
let myInfo = pick(data.myInfo, ['auth', 'items', 'tasks', 'receivedLv']);
return { ...pick(data, ['guildCnt', 'leagueLv', 'techQueue', 'constribute']), myInfo }
}
export async function getContribute(myUserData: GVGUserDataType) {
const { contribute = new Contribute(), box = [] } = myUserData||{};
const result: LeagueContributeInfo[] = [];
for(let curJob of [LEAGUE_JOB.PRODUCER, LEAGUE_JOB.FIGHTER]) {
let sumContribute = curJob == LEAGUE_JOB.PRODUCER? calProducerContribute(contribute): calFighterContribute(contribute);
let boxReceived = box.filter(boxId => {
let dicBox = gameData.gvgContributeBox.get(boxId);
return dicBox.job == curJob;
});
let disObj = new LeagueContributeInfo(curJob, sumContribute, boxReceived);
result.push(disObj)
}
return result;
}
export async function getLeagueRankBox(configId: number, leagueCode: string, roleId: string) {
let joinTime = await getMemberJoinLeagueTime(leagueCode, roleId);
let canReceiveLeagueRanks = await GVGVestigeLeagueRankModel.getCanReceiveRanks(configId, leagueCode, roleId, joinTime);
let canReceivePlayerRanks = await GVGVestigeSumRankModel.getCanReceiveRanks(configId, roleId);
let { canReceiveBox } = calVestigeLeagueBoxRewards(canReceiveLeagueRanks, canReceivePlayerRanks);
return { canReceiveBox }
}
export async function getGroupKey(serverId: number) {
let serverType = await getGVGServerType(serverId);
if(serverType == GVG_SERVER_TYPE.SINGLE) {
return `s${serverId}`;
} else {
let groupId = await getGVGGroupIdOfServer(serverId);
return `g${groupId}`;
}
}
/**
* 之前gvgLeague表的members没有记录加入联军时间所以如果查询没有time的话根据userGuild的time来更新一下这个数据
*
* 获取玩家加入联军时间
* @param leagueCode 联军id
* @param roleId
* @param league 联军表数据
* @returns
*/
export async function getMemberJoinLeagueTime(leagueCode: string, roleId: string, league?: GVGLeagueType) {
if(!league) league = await GVGLeagueModel.findByCode(leagueCode, 'members');
let members = league?.members||[];
let member = members.find(cur => cur.roleId == roleId);
if(!member) return 0;
if(!member.time) {
let userGuild = await UserGuildModel.getMyGuild(roleId, 'createdAt');
let time = getSeconds(userGuild.createdAt);
await GVGLeagueModel.setMemberTime(leagueCode, roleId, time);
return time;
}
return member.time;
}