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

339 lines
14 KiB
TypeScript

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;
}