From 267fddbb2e3130e6c11e905f50ebe2ea2290a3a3 Mon Sep 17 00:00:00 2001 From: luying Date: Thu, 2 Mar 2023 17:02:45 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20fix(gvg):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AE=88=E5=9F=8E=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/services/gvg/gvgBattleService.ts | 138 ++++++++++++------ 1 file changed, 92 insertions(+), 46 deletions(-) diff --git a/game-server/app/services/gvg/gvgBattleService.ts b/game-server/app/services/gvg/gvgBattleService.ts index 710ae509d..b4c4f930d 100644 --- a/game-server/app/services/gvg/gvgBattleService.ts +++ b/game-server/app/services/gvg/gvgBattleService.ts @@ -505,54 +505,9 @@ export async function gvgBattleSeconds() { export async function gvgBattleEnd() { console.log('######### gvgBattleEnd #######') let { configId } = getGVGConfig(); - let guardLeagueCnt = new Map(); // 城池占领情况 - let keys = await findKeys(`${REDIS_KEY.GVG_BATTLE_LEAGUE_RANK_BY_CITY}:${configId}:`); - let rankKeys = keys.map(key => { - let [,, groupKey, _cityId] = key.split(':'); - return { groupKey, cityId: parseInt(_cityId) }; - }).sort((a, b) => { - let dicCityA = gameData.gvgCity.get(a.cityId); - let dicCityB = gameData.gvgCity.get(b.cityId); - if(dicCityA.cityType == dicCityB.cityType) return a.cityId - b.cityId; - return dicCityA.cityType - dicCityB.cityType; - }); - let lastCities = await GVGCityModel.findByConfig(configId); - for(let { cityId, groupKey } of lastCities) { - let hasKey = rankKeys.find(cur => cur.cityId == cityId && cur.groupKey == groupKey); - if(!hasKey) rankKeys.push({ cityId, groupKey }); - } - - for(let { groupKey, cityId } of rankKeys) { - let dicCity = gameData.gvgCity.get(cityId); - if(!dicCity) continue; - - let r = new Rank(REDIS_KEY.GVG_BATTLE_LEAGUE_RANK_BY_CITY, { configId, groupKey, cityId }); - let ranks = await r.getRankByRange(); - // 排名最高占领城池 - let hasGuard = false; - for(let obj of ranks) { - let rankInfo = obj; - let cnt = guardLeagueCnt.get(rankInfo.code)||0; - if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { - await addGuardCity(configId, groupKey, cityId, rankInfo.code); - guardLeagueCnt.set(rankInfo.code, cnt + 1); - hasGuard = true; - break; - } - } - if(!hasGuard) { - let guardCity = lastCities.find(city => city.cityId == cityId && city.groupKey == groupKey); - if(guardCity) { - let cnt = guardLeagueCnt.get(guardCity.guardLeague)||0; - if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { - await addGuardCity(configId, groupKey, cityId, guardCity.guardLeague); - guardLeagueCnt.set(guardCity.guardLeague, cnt + 1); - } - } - } - } + await calCityGuard(configId); // 联军排行榜发放奖励 let leagueKeys = await findKeys(`${REDIS_KEY.GVG_BATTLE_LEAGUE_RANK}:${configId}:`); @@ -584,6 +539,97 @@ export async function gvgBattleEnd() { } +interface SortCities { cityType: number, cityId: number, index: number, league: string, score: number }; +interface RankAndLastLeague { ranks: LeagueRankInfo[], lastLeague: string }; + +// 赛期末结算守城 +export async function calCityGuard(configId: number) { + + let sortCities = new Map(); // groupKey => cities + let rankByCity = new Map>(); // groupKey => city => {ranks, lastLeague} + await generateData(configId, sortCities, rankByCity); + + for(let [groupKey, cities] of sortCities) { + let cityResult: number[] = []; + + while(cityResult.length != cities.length) { + let sorted = cities + .filter(city => cityResult.indexOf(city.cityId) == -1) + .sort((a, b) => { + if(a.cityType != b.cityType) return a.cityType - b.cityType; + if(a.score != b.score) return b.score - a.score; + return b.cityId - a.cityId; + }); + + let guardLeagueCnt = new Map(); + for(let { league: leagueCode, cityId } of sorted) { + let cnt = guardLeagueCnt.get(leagueCode)||0; + if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { + await addGuardCity(configId, groupKey, cityId, leagueCode); + guardLeagueCnt.set(leagueCode, cnt + 1); + cityResult.push(cityId); + } + } + + for(let city of cities) { // 没有成功防守到联军的城池,进行下一轮处理 + if(cityResult.indexOf(city.cityId) != -1) continue; + if(city.index == -1) { + cityResult.push(city.cityId); continue; + } + let nextIndex = city.index + 1; + let { ranks, lastLeague } = rankByCity.get(groupKey)?.get(city.cityId)||{ ranks: [], lastLeague: '' }; + if(ranks[nextIndex]) { + city.index = nextIndex; + city.league = ranks[nextIndex].code; + city.score = ranks[nextIndex].num; + } else { + if(lastLeague) { + city.index = -1; + city.league = lastLeague; + city.score = 0; + } else { + cityResult.push(city.cityId); continue; + } + } + } + } + + } +} + +// 结算守城处理数据 +async function generateData(configId: number, sortCities: Map, rankByCity: Map>) { + let keys = await findKeys(`${REDIS_KEY.GVG_BATTLE_LEAGUE_RANK_BY_CITY}:${configId}:`); + let lastCities = await GVGCityModel.findByConfig(configId); + for(let key of keys) { + let [,, groupKey, _cityId] = key.split(':'); + let cityId = parseInt(_cityId); + let dicCity = gameData.gvgCity.get(cityId); + if(!dicCity) continue; + + let r = new Rank(REDIS_KEY.GVG_BATTLE_LEAGUE_RANK_BY_CITY, { configId, groupKey, cityId }); + let ranks = await r.getRankByRange(); + let guardCity = lastCities.find(city => city.cityId == cityId && city.groupKey == groupKey); + if(!sortCities.has(groupKey)) sortCities.set(groupKey, []); + sortCities.get(groupKey).push({ cityType: dicCity.cityType, cityId, index: 0, league: ranks.length > 0? ranks[0].code: (guardCity?.guardLeague), score: ranks.length > 0? ranks[0].num: 0 }); + + if(!rankByCity.has(groupKey)) rankByCity.set(groupKey, new Map()); + if(!rankByCity.get(groupKey).has(cityId)) rankByCity.get(groupKey).set(cityId, { ranks, lastLeague: guardCity?.guardLeague??'' }) + } + for(let { groupKey, cityId, guardLeague } of lastCities) { + if(rankByCity.has(groupKey) && rankByCity.get(groupKey).has(cityId)) continue; + + let dicCity = gameData.gvgCity.get(cityId); + if(!dicCity) continue; + + if(!sortCities.has(groupKey)) sortCities.set(groupKey, []); + sortCities.get(groupKey).push({ cityType: dicCity.cityType, cityId, index: -1, league: guardLeague, score: 0 }); + + if(!rankByCity.has(groupKey)) rankByCity.set(groupKey, new Map()); + if(!rankByCity.get(groupKey).has(cityId)) rankByCity.get(groupKey).set(cityId, { ranks: [], lastLeague: guardLeague||'' }) + } +} + async function addGuardCity(configId: number, groupKey: string, cityId: number, leagueCode: string) { let dicCity = gameData.gvgCity.get(cityId); let dicCityAdd = gameData.gvgCityAdd.get(dicCity.cityType);