diff --git a/game-server/app/servers/battle/handler/rougeHandler.ts b/game-server/app/servers/battle/handler/rougeHandler.ts index 4a3aceb6e..f15ff05c2 100644 --- a/game-server/app/servers/battle/handler/rougeHandler.ts +++ b/game-server/app/servers/battle/handler/rougeHandler.ts @@ -1160,7 +1160,10 @@ export class RougeHandler { let sid: string = session.get('sid'); let roleName: string = session.get('roleName'); let { index } = msg; - let dicScore = gameData.rougeScoreReward.get(index); + const lastMaxLv = await RougelikeRecordModel.getLastMaxLv(roleId); + const rougeScoreRewardByLvData = gameData.rougeScoreRewardByLv.get(lastMaxLv); + if (!rougeScoreRewardByLvData) return resResult(STATUS.DIC_DATA_NOT_FOUND); + let dicScore = rougeScoreRewardByLvData.get(index); if (!dicScore) return resResult(STATUS.DIC_DATA_NOT_FOUND); let scoreData = await RougelikeScoreModel.findByRoleId(roleId); diff --git a/game-server/app/services/battle/rougeService.ts b/game-server/app/services/battle/rougeService.ts index 8f1a9f313..e5093ab82 100644 --- a/game-server/app/services/battle/rougeService.ts +++ b/game-server/app/services/battle/rougeService.ts @@ -13,11 +13,10 @@ import { DicRougeQuestionMarkPlan } from "../../pubUtils/dictionary/DicRougeQues import { DicRougeRandomEventPlan } from "../../pubUtils/dictionary/DicRougeRandomEventPlan"; import * as util from 'util'; import { RougelikeCollectionModel, } from "../../db/RougelikeCollection"; -import { RougelikeScoreModel } from "../../db/RougelikeScore"; +import { RougelikeScoreModel, RougelikeScorePara } from "../../db/RougelikeScore"; import { getTechData } from "./rougeTechService"; import { getZeroPointOfTimeD } from "../../pubUtils/timeUtil"; import { sendMailByContent } from "../mailService"; -import { DicRougeCharaCardPlan } from "../../pubUtils/DicRougeCharaCardPlan"; import { MAIL_TYPE, PUSH_ROUTE } from "../../consts"; import { sendMessageToUserWithSuc } from "../pushService"; import { RougeEffect, getAddChoosePassive, getAddPassiveWeight, getChooseQualityPassives, getShopDiscount } from "./rougeEffectService"; @@ -25,6 +24,7 @@ import { formateCharasOrCards } from "./rougeCollectService"; import { errlogger } from "../../util/logger"; import { RougelikeExtendModel } from "../../db/RougelikeExtend"; import { isDevelopEnv } from "../utilService"; +import { DicRougeCharaCardPlan } from "../../pubUtils/dictionary/DicRougeCharaCardPlan"; export async function getRougeData(roleId: string) { @@ -41,8 +41,8 @@ export async function getRougeData(roleId: string) { const dbExtends = await RougelikeExtendModel.findByRoleId(roleId); const limitIds = dbExtends.map(cur => cur.limitId); - - return { isPlaying, gameCode, weeklyScore: dbScore?.score || 0, receivedScore: dbScore?.received || [], ...techData, collections, limitIds, takeoutRewardCnt: dbScore?.takeoutRewardCnt } + const lastMaxLv = await RougelikeRecordModel.getLastMaxLv(roleId); + return { isPlaying, gameCode, weeklyScore: dbScore?.score || 0, receivedScore: dbScore?.received || [], ...techData, collections, limitIds, takeoutRewardCnt: dbScore?.takeoutRewardCnt, lastMaxLv } } /* @@ -899,19 +899,24 @@ export function getAuthorTypeCardNum(authorType: number, cards: Card[]) { } export async function repaireSendScoreReward() { - let maxNum = gameData.rougeScoreNum.num || 0; - let refTime = getZeroPointOfTimeD(Date.now() - 86400000, SHOP_REFRESH_TYPE.WEEKLY); - let allRewards = await RougelikeScoreModel.findByReceiveNum(refTime, maxNum); - let _ids: string[] = []; - for (let { roleId, received, _id, score } of allRewards) { + let refTime = new Date(getZeroPointOfTimeD(Date.now() - 86400000, SHOP_REFRESH_TYPE.WEEKLY).getTime() - (86400000 * 7)); + let allRewards = await RougelikeScoreModel.findByRefTime(refTime); + let updateArr: RougelikeScorePara[] = []; + + const roleIds = allRewards.map(cur => { return cur.roleId }); + const lastMaxLvMap = await RougelikeRecordModel.getLastMaxLvMap(roleIds); + for (let { roleId, received, score, receiveNum } of allRewards) { + if (!lastMaxLvMap.has(roleId)) continue; let goods: RewardInter[] = []; - for (let [index, { reward, score: targetScore }] of gameData.rougeScoreReward) { - if (score >= targetScore && !received.includes(index)) goods.push(...reward); + const rougeScoreRewardByLvData = gameData.rougeScoreRewardByLv.get(lastMaxLvMap.get(roleId)); + if (receiveNum >= rougeScoreRewardByLvData.size) continue; + for (let [index, { reward, score: targetScore }] of rougeScoreRewardByLvData) { + if (score >= targetScore && !received.includes(index)) { goods.push(...reward); } } await sendMailByContent(MAIL_TYPE.ROUGE_SCORE_REPAIRE, roleId, { goods }); - _ids.push(_id); + updateArr.push({ roleId, refTime, receiveNum: rougeScoreRewardByLvData.size }); } - await RougelikeScoreModel.receiveAll(_ids, maxNum + 1); + await RougelikeScoreModel.bulkWriteUpdate(updateArr); } /** diff --git a/shared/db/RougelikeChara.ts b/shared/db/RougelikeChara.ts index bf0106c6e..64519246d 100644 --- a/shared/db/RougelikeChara.ts +++ b/shared/db/RougelikeChara.ts @@ -123,7 +123,7 @@ export default class RougelikeChara extends BaseModel { await RougelikeCharaModel.bulkWrite(updateArr.map((param) => { delete param._id; const { gameCode, charaCode } = param - return { updateOne: { filter: { gameCode, charaCode }, update: { $set: { ...param } } } } + return { updateOne: { filter: { gameCode, charaCode }, update: { $set: { ...param } }, upsert: true } } })) } diff --git a/shared/db/RougelikeExtend.ts b/shared/db/RougelikeExtend.ts index 7716f5408..31dd9b34e 100644 --- a/shared/db/RougelikeExtend.ts +++ b/shared/db/RougelikeExtend.ts @@ -43,6 +43,7 @@ export default class RougelikeExtend extends BaseModel { const result: RougelikeExtendType = await RougelikeExtendModel.findOne({ roleId, limitId }).lean(lean); return result; } + } export const RougelikeExtendModel = getModelForClass(RougelikeExtend); diff --git a/shared/db/RougelikeRecord.ts b/shared/db/RougelikeRecord.ts index 35ab4ca32..d5e5fc26a 100644 --- a/shared/db/RougelikeRecord.ts +++ b/shared/db/RougelikeRecord.ts @@ -1,3 +1,6 @@ +import { SHOP_REFRESH_TYPE } from '../consts'; +import { gameData } from '../pubUtils/data'; +import { getZeroPointOfTimeD } from '../pubUtils/timeUtil'; import BaseModel from './BaseModel'; import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose'; @@ -103,6 +106,30 @@ export default class RougelikeRecord extends BaseModel { return result; } + public static async getLastMaxLv(roleId: string) { + let endTime = getZeroPointOfTimeD(Date.now() - 86400000, SHOP_REFRESH_TYPE.WEEKLY); + let startTime = new Date(endTime.getTime() - (86400000 * 7)); + const result: RougelikeRecordType[] = await RougelikeRecordModel.find({ roleId, updatedAt: { $gt: startTime, $lt: endTime } }).lean(true); + let lastMaxLv = 1; + for (const { grade = 1 } of result) { + lastMaxLv = Math.max(lastMaxLv, grade); + } + return lastMaxLv; + } + + public static async getLastMaxLvMap(roleIds: string[]) { + let endTime = getZeroPointOfTimeD(Date.now() - 86400000, SHOP_REFRESH_TYPE.WEEKLY); + let startTime = new Date(endTime.getTime() - (86400000 * 7)); + const result: RougelikeRecordType[] = await RougelikeRecordModel.find({ roleId: { $in: roleIds }, updatedAt: { $gt: startTime, $lt: endTime } }).lean(true); + let lastMaxLvMap = new Map(); + for (const { roleId, grade } of result) { + if (!grade) continue; + let tempLv = lastMaxLvMap.has(roleId) ? lastMaxLvMap.get(roleId) : 1; + lastMaxLvMap.set(roleId, Math.max(tempLv, grade)); + } + return lastMaxLvMap; + } + }; export const RougelikeRecordModel = getModelForClass(RougelikeRecord); export interface RougelikeRecordType extends Pick, keyof RougelikeRecord> { }; diff --git a/shared/db/RougelikeScore.ts b/shared/db/RougelikeScore.ts index 572c36d8b..47d6bee12 100644 --- a/shared/db/RougelikeScore.ts +++ b/shared/db/RougelikeScore.ts @@ -48,6 +48,11 @@ export default class RougelikeScore extends BaseModel { return result; } + public static async findByRefTime(refTime: Date) { + let result: RougelikeScoreType[] = await RougelikeScoreModel.find({ refTime }).lean(); + return result; + } + public static async receiveAll(_ids: string[], maxNum: number) { await RougelikeScoreModel.updateMany({ _id: { $in: _ids } }, { $set: { receiveNum: maxNum } }); } @@ -59,6 +64,16 @@ export default class RougelikeScore extends BaseModel { return result; } + public static async bulkWriteUpdate(updateArr: RougelikeScorePara[]) { + if (updateArr.length == 0) return; + await RougelikeScoreModel.bulkWrite(updateArr.map((param) => { + delete param._id; + const { roleId, refTime } = param + return { updateOne: { filter: { roleId, refTime }, update: { $set: { ...param } }, upsert: true } } + })) + } + + } export const RougelikeScoreModel = getModelForClass(RougelikeScore); diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index 0c7a5c917..6217b5b86 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -159,20 +159,19 @@ import { dicRougeChallenge, loadRougeChallenge } from "./dictionary/DicRougeChal import { dicRougeChallengePlan, loadRougeChallengePlan } from "./dictionary/DicRougeChallengePlan"; import { dicRougeQuestionMarkPlan, loadRougeQuestionMarkPlan } from "./dictionary/DicRougeQuestionMarkPlan"; import { dicRougeRandomEventPlan, loadRougeRandomEventPlan } from "./dictionary/DicRougeRandomEventPlan"; -import { dicRougeCharaCardPlan, loadRougeCharaCardPlan } from "./DicRougeCharaCardPlan"; -import { dicRougeHolyCardPlan, loadRougeHolyCardPlan } from "./DicRougeHolyCardPlan"; import { dicRougeEventOption, loadRougeEventOption } from "./dictionary/DicRougeEventOption"; - import { dicRougeTech, loadRougeTech, dicRougeTechIdByRow } from "./dictionary/DicRougeTech"; import { dicRougeTechCircle, dicRougeTechCircleByTechId, loadRougeTechCircle } from "./dictionary/DicRougeTechCircle"; import { dicRougeTechLevel, loadRougeTechLevel } from "./dictionary/DicRougeTechLevel"; import { dicRougeOptionGroup, loadRougeOptionGroup } from "./dictionary/DicRougeOptionGroup"; import { dicRougePassiveCollect, loadRougePassiveCollect } from "./dictionary/DicRougePassiveCollect"; -import { dicRougeScoreNum, dicRougeScoreReward, loadRougeScoreReward } from "./dictionary/DicRougeScoreReward"; +import { dicRougeScoreRewardByLv, loadRougeScoreReward } from "./dictionary/DicRougeScoreReward"; import { dicRougeEffect, loadRougeEffect } from "./dictionary/DicRougeEffect"; import { dicRougeEffectType, loadRougeEffectType } from "./dictionary/DicRougeEffectType"; import { dicSpiritPlan, loadSpiritPlan } from "./dictionary/DicSpiritPlan"; import { dicRougePassiveWeight, loadRougePassiveWeight } from "./dictionary/DicRougePassiveWeight"; +import { dicRougeCharaCardPlan, loadRougeCharaCardPlan } from "./dictionary/DicRougeCharaCardPlan"; +import { dicRougeHolyCardPlan, loadRougeHolyCardPlan } from "./dictionary/DicRougeHolyCardPlan"; export const gameData = { daily: dicDaily, @@ -423,8 +422,7 @@ export const gameData = { rougeEventOption: dicRougeEventOption, rougeOptionGroup: dicRougeOptionGroup, rougePassiceCollect: dicRougePassiveCollect, - rougeScoreReward: dicRougeScoreReward, - rougeScoreNum: dicRougeScoreNum, + rougeScoreRewardByLv: dicRougeScoreRewardByLv, rougeEffect: dicRougeEffect, rougeEffectType: dicRougeEffectType, diff --git a/shared/pubUtils/DicRougeCharaCardPlan.ts b/shared/pubUtils/dictionary/DicRougeCharaCardPlan.ts similarity index 89% rename from shared/pubUtils/DicRougeCharaCardPlan.ts rename to shared/pubUtils/dictionary/DicRougeCharaCardPlan.ts index a09b615c3..1fd530d5a 100644 --- a/shared/pubUtils/DicRougeCharaCardPlan.ts +++ b/shared/pubUtils/dictionary/DicRougeCharaCardPlan.ts @@ -2,8 +2,8 @@ * 角色卡奖励卡池方案 */ -import { FILENAME } from "../consts"; -import { readFileAndParse } from "./util"; +import { FILENAME } from "../../consts"; +import { readFileAndParse } from "../util"; export interface DicRougeCharaCardPlan { readonly id: number; diff --git a/shared/pubUtils/DicRougeHolyCardPlan.ts b/shared/pubUtils/dictionary/DicRougeHolyCardPlan.ts similarity index 88% rename from shared/pubUtils/DicRougeHolyCardPlan.ts rename to shared/pubUtils/dictionary/DicRougeHolyCardPlan.ts index 0d4c54ba4..17a961789 100644 --- a/shared/pubUtils/DicRougeHolyCardPlan.ts +++ b/shared/pubUtils/dictionary/DicRougeHolyCardPlan.ts @@ -2,8 +2,10 @@ * 圣物卡奖励卡池方案 */ -import { FILENAME } from "../consts"; -import { readFileAndParse } from "./util"; +import { FILENAME } from "../../consts"; +import { readFileAndParse } from "../util"; + + export interface DicRougeHolyCardPlan { diff --git a/shared/pubUtils/dictionary/DicRougeScoreReward.ts b/shared/pubUtils/dictionary/DicRougeScoreReward.ts index b13734746..f848b6cfd 100644 --- a/shared/pubUtils/dictionary/DicRougeScoreReward.ts +++ b/shared/pubUtils/dictionary/DicRougeScoreReward.ts @@ -10,18 +10,19 @@ export interface DicRougeScoreReward { readonly index: number; readonly score: number; // 积分 readonly reward: RewardInter[]; // 图鉴收集奖励(同Group只领取一次奖励) + readonly level: number; // 难度等级 } -export const dicRougeScoreReward = new Map(); -export const dicRougeScoreNum = { num: 0 } +export const dicRougeScoreRewardByLv = new Map>(); export function loadRougeScoreReward() { - dicRougeScoreReward.clear(); + dicRougeScoreRewardByLv.clear(); let arr = readFileAndParse(FILENAME.DIC_ROUGE_SCORE_REWARD); arr.forEach(o => { o.reward = parseGoodStr(o.reward); - dicRougeScoreReward.set(o.index, o); - dicRougeScoreNum.num++; + + if (!dicRougeScoreRewardByLv.has(o.level)) dicRougeScoreRewardByLv.set(o.level, new Map); + dicRougeScoreRewardByLv.get(o.level).set(o.index, o); }); arr = undefined; } \ No newline at end of file diff --git a/shared/resource/jsons/dic_rougeScoreReward.json b/shared/resource/jsons/dic_rougeScoreReward.json index 4ad1f3c50..4d4282bfe 100644 --- a/shared/resource/jsons/dic_rougeScoreReward.json +++ b/shared/resource/jsons/dic_rougeScoreReward.json @@ -1,44 +1,247 @@ [ { "id": 1, + "level": 1, "index": 1, "score": 10, "reward": "31002&50" }, { "id": 2, + "level": 1, "index": 2, "score": 20, "reward": "31002&60" }, { "id": 3, + "level": 1, "index": 3, "score": 30, "reward": "31002&70" }, { "id": 4, + "level": 1, "index": 4, "score": 40, "reward": "31002&80" }, { "id": 5, + "level": 1, "index": 5, "score": 50, "reward": "31002&90" }, { "id": 6, + "level": 1, "index": 6, "score": 60, "reward": "31002&100" }, { "id": 7, + "level": 1, "index": 7, "score": 70, "reward": "31002&110" + }, + { + "id": 8, + "level": 2, + "index": 1, + "score": 10, + "reward": "31002&100" + }, + { + "id": 9, + "level": 2, + "index": 2, + "score": 20, + "reward": "31002&200" + }, + { + "id": 10, + "level": 2, + "index": 3, + "score": 30, + "reward": "31002&300" + }, + { + "id": 11, + "level": 2, + "index": 4, + "score": 40, + "reward": "31002&400" + }, + { + "id": 12, + "level": 2, + "index": 5, + "score": 50, + "reward": "31002&500" + }, + { + "id": 13, + "level": 2, + "index": 6, + "score": 60, + "reward": "31002&600" + }, + { + "id": 14, + "level": 2, + "index": 7, + "score": 70, + "reward": "31002&700" + }, + { + "id": 15, + "level": 3, + "index": 1, + "score": 10, + "reward": "31002&200" + }, + { + "id": 16, + "level": 3, + "index": 2, + "score": 20, + "reward": "31002&300" + }, + { + "id": 17, + "level": 3, + "index": 3, + "score": 30, + "reward": "31002&400" + }, + { + "id": 18, + "level": 3, + "index": 4, + "score": 40, + "reward": "31002&500" + }, + { + "id": 19, + "level": 3, + "index": 5, + "score": 50, + "reward": "31002&600" + }, + { + "id": 20, + "level": 3, + "index": 6, + "score": 60, + "reward": "31002&700" + }, + { + "id": 21, + "level": 3, + "index": 7, + "score": 70, + "reward": "31002&800" + }, + { + "id": 22, + "level": 4, + "index": 1, + "score": 10, + "reward": "31002&300" + }, + { + "id": 23, + "level": 4, + "index": 2, + "score": 20, + "reward": "31002&400" + }, + { + "id": 24, + "level": 4, + "index": 3, + "score": 30, + "reward": "31002&500" + }, + { + "id": 25, + "level": 4, + "index": 4, + "score": 40, + "reward": "31002&600" + }, + { + "id": 26, + "level": 4, + "index": 5, + "score": 50, + "reward": "31002&700" + }, + { + "id": 27, + "level": 4, + "index": 6, + "score": 60, + "reward": "31002&800" + }, + { + "id": 28, + "level": 4, + "index": 7, + "score": 70, + "reward": "31002&900" + }, + { + "id": 29, + "level": 5, + "index": 1, + "score": 10, + "reward": "31002&300" + }, + { + "id": 30, + "level": 5, + "index": 2, + "score": 20, + "reward": "31002&400" + }, + { + "id": 31, + "level": 5, + "index": 3, + "score": 30, + "reward": "31002&500" + }, + { + "id": 32, + "level": 5, + "index": 4, + "score": 40, + "reward": "31002&600" + }, + { + "id": 33, + "level": 5, + "index": 5, + "score": 50, + "reward": "31002&700" + }, + { + "id": 34, + "level": 5, + "index": 6, + "score": 60, + "reward": "31002&800" + }, + { + "id": 35, + "level": 5, + "index": 7, + "score": 70, + "reward": "31002&900" } ] \ No newline at end of file