✨ feat(gvg): 准备期:千机阁以及获取物品
This commit is contained in:
@@ -1,20 +1,23 @@
|
||||
import { Application, BackendSession, ChannelService, HandlerService, pinus } from "pinus";
|
||||
import { GVG_PERIOD, GVG_SERVER_TYPE, LEAGUE_JOB, STATUS } from "../../../consts";
|
||||
import { BATTLE_FEAT_ID, DATA_NAME, GVG_ACTIVE_TYPE, GVG_PERIOD, GVG_SERVER_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB, LEAGUE_MANAGE_TYPE, STATUS } from "../../../consts";
|
||||
import { GVGLeagueModel } from "../../../db/GVGLeague";
|
||||
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
|
||||
import { GVGMainData, LeagueDistributeInfo, LeagueMemberDistributeInfo, LeagueMemberListInfo } from "../../../domain/gvgField/returnData";
|
||||
import { resResult } from "../../../pubUtils/util";
|
||||
import { getGVGConfig, getGVGPeriodData, getGVGServerType } from "../../../services/gvg/gvgService";
|
||||
import { autoCreateLeague, checkCanChooseJob, checkCanPrepare, getMyAuth } from "../../../services/gvg/gvgTeamService";
|
||||
import { autoCreateLeague, checkCanChooseJob, checkCanPrepare, checkLeagueAuth, getMyAuth } from "../../../services/gvg/gvgTeamService";
|
||||
import { getAllServerName } from "../../../services/redisService";
|
||||
import { Distribute, GVGUserDataModel } from "../../../db/GVGUserData";
|
||||
import { GVGUserItemModel } from "../../../db/GVGUserItem";
|
||||
import { GVGUserTaskModel } from "../../../db/GVGUserTask";
|
||||
import { GVG } from "../../../pubUtils/dicParam";
|
||||
import { RoleModel } from "../../../db/Role";
|
||||
import { calProduce } from "../../../services/gvg/gvgPrepareService";
|
||||
import { nowSeconds } from "../../../pubUtils/timeUtil";
|
||||
import { GVGUserDailyDistributeModel } from "../../../db/GVGUserDailyDistribute";
|
||||
import { addGVGActive, calProduce, checkPreTech, checkTechIsIng } from "../../../services/gvg/gvgPrepareService";
|
||||
import { GVGUserDailyDataModel } from "../../../db/GVGUserDailyData";
|
||||
import { gameData } from "../../../pubUtils/data";
|
||||
import { lockLeagueData } from "../../../services/redLockService";
|
||||
import { addGVGReward, handleGVGCost } from "../../../services/gvg/gvgItemService";
|
||||
import { RewardInter } from "../../../pubUtils/interface";
|
||||
|
||||
export default function (app: Application) {
|
||||
new HandlerService(app, {});
|
||||
@@ -146,7 +149,7 @@ export class GVGHandler {
|
||||
result.push(disObj)
|
||||
}
|
||||
|
||||
const myDistribute = await GVGUserDailyDistributeModel.findByRole(configId, myLeague.leagueCode, roleId);
|
||||
const myDistribute = await GVGUserDailyDataModel.findByRole(configId, myLeague.leagueCode, roleId);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
myDistribute: {
|
||||
@@ -159,9 +162,150 @@ export class GVGHandler {
|
||||
});
|
||||
}
|
||||
|
||||
// 千机阁数据
|
||||
async getTech(msg: {}, session: BackendSession) {
|
||||
const roleId = session.get('roleId');
|
||||
const guildCode = session.get('guildCode');
|
||||
|
||||
async test(msg: { }, session: BackendSession) {
|
||||
const time = getGVGConfig();
|
||||
return resResult(STATUS.SUCCESS, { time });
|
||||
let { configId, period } = getGVGPeriodData();
|
||||
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||
|
||||
const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||
const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
activeTech: leaguePrepare?.activeTech||[],
|
||||
queue: leaguePrepare?.techQueue||[]
|
||||
});
|
||||
}
|
||||
|
||||
// 千机阁解锁
|
||||
async unlockTech(msg: { techId: number }, session: BackendSession) {
|
||||
const roleId = session.get('roleId');
|
||||
const guildCode = session.get('guildCode');
|
||||
const { techId } = msg;
|
||||
|
||||
let { configId, period } = getGVGPeriodData();
|
||||
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||
|
||||
const dicTech = gameData.gvgTech.get(techId);
|
||||
if(!dicTech) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||
|
||||
// 权限
|
||||
const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.UNLOCK_TECH);
|
||||
if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);
|
||||
|
||||
// 并发锁
|
||||
let res: any = await lockLeagueData(DATA_NAME.LEAGUE_TECH, myLeague.leagueCode);//加锁
|
||||
if (!!res.err) return resResult(STATUS.REDLOCK_ERR);
|
||||
|
||||
let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||
if(!leaguePrepare || leaguePrepare.lv < dicTech.levelLimit) {
|
||||
res.releaseCallback();
|
||||
return resResult(STATUS.GVG_TECH_LV_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
if(checkTechIsIng(techId, leaguePrepare?.activeTech||[], leaguePrepare?.techQueue||[])) {
|
||||
res.releaseCallback();
|
||||
return resResult(STATUS.GVG_TECH_HAS_UNLOCKED);
|
||||
}
|
||||
|
||||
if(!checkPreTech(techId, leaguePrepare?.activeTech||[], leaguePrepare?.techQueue||[])) {
|
||||
res.releaseCallback();
|
||||
return resResult(STATUS.GVG_TECH_PRE_POSITION_NOT_UNLOCK);
|
||||
}
|
||||
|
||||
leaguePrepare = await GVGLeaguePrepareModel.unlockTech(configId, myLeague.leagueCode, techId, dicTech.consume);
|
||||
if(!leaguePrepare) {
|
||||
res.releaseCallback();
|
||||
return resResult(STATUS.GVG_TECH_QUEUECNT_MAX);
|
||||
}
|
||||
|
||||
res.releaseCallback();
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
queue: leaguePrepare?.techQueue||[]
|
||||
});
|
||||
}
|
||||
|
||||
// 千机阁解锁
|
||||
async activate(msg: { techId: number, battleFeats: number }, session: BackendSession) {
|
||||
const roleId = session.get('roleId');
|
||||
const guildCode = session.get('guildCode');
|
||||
const sid = session.get('sid');
|
||||
const { techId, battleFeats } = msg;
|
||||
|
||||
let { configId, period } = getGVGPeriodData();
|
||||
if(period != GVG_PERIOD.PREPARE) return resResult(STATUS.GVG_NOT_PREPARE_PERIOD);
|
||||
|
||||
const dicTech = gameData.gvgTech.get(techId);
|
||||
if(!dicTech) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||
|
||||
// 权限
|
||||
const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.ACTIVATE_TECH);
|
||||
if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);
|
||||
|
||||
let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, myLeague.leagueCode);
|
||||
if(!checkTechIsIng(techId, [], leaguePrepare?.techQueue||[])) {
|
||||
return resResult(STATUS.GVG_TECH_NOT_QUEUE);
|
||||
}
|
||||
|
||||
// 扣战功
|
||||
const costResult = await handleGVGCost(roleId, myLeague.leagueCode, sid, [{ id: BATTLE_FEAT_ID, count: battleFeats }], [], ITEM_CHANGE_REASON.GVG_ACTIVE_TECH);
|
||||
if(!costResult) return resResult(STATUS.GVG_BATTLE_FEAT_NOT_ENOUGH);
|
||||
|
||||
leaguePrepare = await GVGLeaguePrepareModel.addProgress(configId, myLeague.leagueCode, techId, battleFeats);
|
||||
if(!leaguePrepare) {
|
||||
return resResult(STATUS.GVG_TECH_NOT_QUEUE);
|
||||
}
|
||||
let curQueue = leaguePrepare.techQueue.find(cur => cur.id == techId);
|
||||
if(curQueue.progress >= curQueue.maxProgress) {
|
||||
leaguePrepare = await GVGLeaguePrepareModel.activate(configId, myLeague.leagueCode, techId);
|
||||
}
|
||||
|
||||
// 添加 活跃
|
||||
let active = await addGVGActive(myLeague.leagueCode, roleId, GVG_ACTIVE_TYPE.TECH_ACTIVATE);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
active,
|
||||
activeTech: leaguePrepare?.activeTech||[],
|
||||
queue: leaguePrepare?.techQueue||[]
|
||||
});
|
||||
}
|
||||
|
||||
// 获取道具
|
||||
async debugAddLeagueItem(msg: { id: number, count: number }, session: BackendSession) {
|
||||
const roleId = session.get('roleId');
|
||||
const roleName = session.get('roleName');
|
||||
const sid = session.get('sid');
|
||||
const guildCode = session.get('guildCode');
|
||||
const { id, count } = msg;
|
||||
let dicGVGItem = gameData.gvgItem.get(id);
|
||||
if(!dicGVGItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||
const leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, [{ id, count }], [], ITEM_CHANGE_REASON.DEBUG);
|
||||
|
||||
return resResult(STATUS.SUCCESS, { leagueGoods });
|
||||
}
|
||||
|
||||
async debugHandleCost(msg: { items: RewardInter[], leagueItems: RewardInter[] }, session: BackendSession) {
|
||||
const roleId = session.get('roleId');
|
||||
const guildCode = session.get('guildCode');
|
||||
const sid = session.get('sid');
|
||||
const { items, leagueItems } = msg;
|
||||
|
||||
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
|
||||
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||
|
||||
const result = await handleGVGCost(roleId, myLeague.leagueCode, sid, leagueItems, items, ITEM_CHANGE_REASON.DEBUG);
|
||||
return resResult(STATUS.SUCCESS, { result });
|
||||
}
|
||||
}
|
||||
@@ -211,8 +211,6 @@ export class GVGManageHandler {
|
||||
let data = new LeagueGuildInfo(guild, serverNames);
|
||||
let hasInvited = !!invitations.find(cur => cur.guildCode == guild.code);
|
||||
data.setHasInvited(hasInvited);
|
||||
// TODO
|
||||
// data.setActive
|
||||
return data
|
||||
});
|
||||
|
||||
@@ -319,10 +317,23 @@ export class GVGManageHandler {
|
||||
const league = await GVGLeagueModel.findByCode(targetLeagueCode);
|
||||
if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
|
||||
|
||||
let { configId } = getGVGPeriodData();
|
||||
const guilds = await GuildModel.findByCodes(league.guildCodes);
|
||||
const members = league.members||[];
|
||||
let roleIds = members.map(member => member.roleId);
|
||||
const serverNames = await getAllServerName();
|
||||
const userdatas = await GVGUserDataModel.findByRoles(configId, targetLeagueCode, roleIds);
|
||||
const result = guilds.map(guild => {
|
||||
return new LeagueGuildInfo(guild, serverNames)
|
||||
let obj = new LeagueGuildInfo(guild, serverNames);
|
||||
let active = userdatas.reduce((pre, userdata) => {
|
||||
let member = members.find(cur => cur.roleId == userdata.roleId);
|
||||
if(member && member.guildCode == guild.code) {
|
||||
return pre + userdata.active;
|
||||
}
|
||||
return pre;
|
||||
}, 0);
|
||||
obj.setActive(active);
|
||||
return obj;
|
||||
});
|
||||
|
||||
// 返回
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { isArray, isBoolean, isNumber, isString } from "underscore";
|
||||
import { BLOCK_OPEATE, DEBUG_MAGIC_WORD, GM_MAIL_TYPE, GUILD_AUTH, GUILD_STRUCTURE, LEAGUE_JOB, LINEUP_NUM, MSG_TYPE } from "../consts";
|
||||
import { GVG } from "../pubUtils/dicParam";
|
||||
import { pvpEndParamInter } from "../pubUtils/interface";
|
||||
import { isDevelopEnv } from "./utilService";
|
||||
|
||||
@@ -1229,7 +1230,11 @@ export function checkRouteParam(route: string, msg: any) {
|
||||
if(msg.job != LEAGUE_JOB.FIGHTER && msg.job != LEAGUE_JOB.PRODUCER) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
case "guild.gvgHandler.unlockTech":
|
||||
{
|
||||
if(!isNumber(msg.techId)) return false;
|
||||
break;
|
||||
}
|
||||
case "order.orderHandler.applyOrder":
|
||||
{
|
||||
let { productID, payType, activityId, paramStr, useVoucher } = msg;
|
||||
|
||||
76
game-server/app/services/gvg/gvgItemService.ts
Normal file
76
game-server/app/services/gvg/gvgItemService.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { GVG_RETURN_ITEM_TYPE, ITEM_CHANGE_REASON, LEAGUE_ITEM_REFRESH_TYPE, PUSH_ROUTE } from "../../consts";
|
||||
import { GVGUserItemModel } from "../../db/GVGUserItem";
|
||||
import { gameData } from "../../pubUtils/data";
|
||||
import { RewardInter } from "../../pubUtils/interface";
|
||||
import { DAY_TO_SECOND, getZeroPoint } from "../../pubUtils/timeUtil";
|
||||
import { getFutureTime } from "../gmService";
|
||||
import { sendMessageToUserWithSuc } from "../pushService";
|
||||
import { addItems, handleCost } from "../role/rewardService";
|
||||
import { getGVGConfig } from "./gvgService";
|
||||
|
||||
/**
|
||||
* 获取道具(必须在guild进程下使用)
|
||||
* @param roleId
|
||||
* @param roleName
|
||||
* @param leagueCode
|
||||
* @param sid
|
||||
* @param leagueItems GVG内专用道具
|
||||
* @param items 普通道具
|
||||
* @param reason
|
||||
* @returns
|
||||
*/
|
||||
export async function addGVGReward(roleId: string, roleName: string, leagueCode: string, sid: string, leagueItems: RewardInter[], items: RewardInter[], reason: ITEM_CHANGE_REASON) {
|
||||
let returnGoods: { id: number, count: number, itemType: number }[] = [], pushGoods: { id: number, count: number, expireTime: number }[] = [];
|
||||
let { configId } = getGVGConfig();
|
||||
if(items.length > 0) {
|
||||
const goods = await addItems(roleId, roleName, sid, items, reason);
|
||||
for(let { id, count } of goods) {
|
||||
returnGoods.push({ id, count, itemType: GVG_RETURN_ITEM_TYPE.NORMAL_ITEM });
|
||||
}
|
||||
}
|
||||
for(let { id, count } of leagueItems) {
|
||||
let dicItem = gameData.gvgItem.get(id);
|
||||
if(!dicItem) continue;
|
||||
let item = await GVGUserItemModel.increaseItem(configId, leagueCode, roleId, id, count, getExpireTime(dicItem.refreshType));
|
||||
returnGoods.push({ id, count, itemType: GVG_RETURN_ITEM_TYPE.GVG_ITEM });
|
||||
pushGoods.push({ id, count: item.count, expireTime: item.expireTime });
|
||||
}
|
||||
if(pushGoods.length > 0) {
|
||||
await sendMessageToUserWithSuc(roleId, PUSH_ROUTE.LEAGUE_ITEM_UPDATE, { goods: pushGoods }, sid);
|
||||
}
|
||||
return returnGoods;
|
||||
}
|
||||
|
||||
function getExpireTime(refreshType: number) {
|
||||
if(refreshType == LEAGUE_ITEM_REFRESH_TYPE.DAILY) {
|
||||
return getZeroPoint() + DAY_TO_SECOND;
|
||||
}
|
||||
return getFutureTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 消耗道具
|
||||
* @param roleId
|
||||
* @param leagueCode
|
||||
* @param sid
|
||||
* @param leagueItems GVG内专用道具
|
||||
* @param items 普通背包道具
|
||||
* @param reason
|
||||
* @returns
|
||||
*/
|
||||
export async function handleGVGCost(roleId: string, leagueCode: string, sid: string, leagueItems: RewardInter[], items: RewardInter[], reason: ITEM_CHANGE_REASON) {
|
||||
let { configId } = getGVGConfig();
|
||||
// 检查本地道具数量
|
||||
const curItems = await GVGUserItemModel.findByRoleAndIds(configId, leagueCode, roleId, leagueItems.map(cur => cur.id));
|
||||
for(let { id, count } of leagueItems) {
|
||||
let curItem = curItems.find(cur => cur.id == id);
|
||||
if(!curItem || curItem.count < count) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const itemResult = await handleCost(roleId, sid, items, reason);
|
||||
if(!itemResult) return false;
|
||||
|
||||
const decreaseResult = await GVGUserItemModel.decreaseItem(configId, leagueCode, roleId, leagueItems);
|
||||
return decreaseResult;
|
||||
}
|
||||
@@ -1,5 +1,55 @@
|
||||
import { GVG_ACTIVE_TYPE } from "../../consts";
|
||||
import { Tech } from "../../db/GVGLeaguePrepare";
|
||||
import { GVGUserDailyDataModel } from "../../db/GVGUserDailyData";
|
||||
import { GVGUserDataModel } from "../../db/GVGUserData";
|
||||
import { gameData } from "../../pubUtils/data";
|
||||
import { getGVGConfig } from "./gvgService";
|
||||
|
||||
export function checkPreTech(techId: number, activeQueue: number[], techQueue: Tech[]) {
|
||||
const dicTech = gameData.gvgTech.get(techId);
|
||||
if(!dicTech) return false;
|
||||
|
||||
let hasOrUnlock = dicTech.prepositionId.length == 0;
|
||||
for(let andArr of dicTech.prepositionId) { // or关系
|
||||
let hasAndUnlock = true;
|
||||
for(let id of andArr) { // and关系
|
||||
if(!checkTechIsIng(id, activeQueue, techQueue)) {
|
||||
hasAndUnlock = false; break;
|
||||
}
|
||||
}
|
||||
if(hasAndUnlock) hasOrUnlock = true;
|
||||
}
|
||||
return hasOrUnlock;
|
||||
}
|
||||
|
||||
export function checkTechIsIng(techId: number, activeQueue: number[], techQueue: Tech[]) {
|
||||
return techQueue.findIndex(cur => cur.id == techId) != -1 || activeQueue.indexOf(techId) != -1
|
||||
}
|
||||
|
||||
export function calProduce(obj: { food: number, mineral: number, wood: number }) {
|
||||
let { food = 0, mineral = 0, wood = 0 } = obj||{};
|
||||
return food + mineral + wood;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得活跃
|
||||
* @param leagueCode
|
||||
* @param roleId
|
||||
* @param type GVG_ACTIVE_TYPE
|
||||
* @returns
|
||||
*/
|
||||
export async function addGVGActive(leagueCode: string, roleId: string, type: GVG_ACTIVE_TYPE) {
|
||||
let { configId } = getGVGConfig();
|
||||
|
||||
let add = gameData.gvgActive.get(type)||0;
|
||||
if(type == GVG_ACTIVE_TYPE.TECH_ACTIVATE) {
|
||||
let check = await GVGUserDailyDataModel.checkGetTechActive(configId, leagueCode, roleId);
|
||||
if(!check) {
|
||||
await GVGUserDailyDataModel.setHasGetTechActive(configId, leagueCode, roleId);
|
||||
} else {
|
||||
add = 0;
|
||||
}
|
||||
}
|
||||
let result = await GVGUserDataModel.addActive(configId, leagueCode, roleId, type, add);
|
||||
return result.active;
|
||||
}
|
||||
@@ -69,6 +69,10 @@ export async function setGVGConfig(config?: GVGConfigType) {
|
||||
pinus.app.set('gvgScheduleTime', config.scheduleTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的赛期id
|
||||
* @returns
|
||||
*/
|
||||
export function getGVGConfig() {
|
||||
let configId = pinus.app.get('gvgConfigId');
|
||||
let teamTime = pinus.app.get('gvgTeamTime');
|
||||
|
||||
@@ -197,13 +197,16 @@ function getAuthFromManageType(type: LEAGUE_MANAGE_TYPE) {
|
||||
return [LEAGUE_AUTH.SUB_LEADER];
|
||||
case LEAGUE_MANAGE_TYPE.SET_INFO:
|
||||
case LEAGUE_MANAGE_TYPE.SEND_MAIL:
|
||||
case LEAGUE_MANAGE_TYPE.UNLOCK_TECH:
|
||||
return [LEAGUE_AUTH.LEADER, LEAGUE_AUTH.SUB_LEADER];
|
||||
case LEAGUE_MANAGE_TYPE.ACTIVATE_TECH:
|
||||
return [LEAGUE_AUTH.LEADER, LEAGUE_AUTH.SUB_LEADER, LEAGUE_AUTH.MEMBER];
|
||||
}
|
||||
}
|
||||
|
||||
export async function memberJoinGuildToLeague(guild: GuildType, role: RoleType) {
|
||||
if(!guild.leagueCode) return;
|
||||
let league = await GVGLeagueModel.joinMember(guild.leagueCode, role.roleId, role.ce);
|
||||
let league = await GVGLeagueModel.joinMember(guild.leagueCode, guild.code, role.roleId, role.ce);
|
||||
// TODO redis联军更新
|
||||
console.log(league);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,13 @@ export async function lockData(serverId: number, dataName: string, id: string )
|
||||
return await lock(lockKey);
|
||||
}
|
||||
|
||||
export async function lockLeagueData(dataName: string, leagueCode: string) {
|
||||
let key = dataName+'_'+ leagueCode;
|
||||
let lockKey = 'locks:' + key;
|
||||
console.log(' lockKey = '+ lockKey);
|
||||
return await lock(lockKey);
|
||||
}
|
||||
|
||||
export async function lockDataWithNoParam(dataName: string) {
|
||||
let key = `${dataName}`;
|
||||
return await lock(key);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
'development': {
|
||||
'mongo': 'mongodb://127.0.0.1/zyz',
|
||||
'mongo': 'mongodb://127.0.0.1/zyz?replicaSet=rs0',
|
||||
'gmmongo': 'mongodb://127.0.0.1/zyzgm',
|
||||
'redis': '127.0.0.1',
|
||||
'redispw': 'zyz_2020'
|
||||
|
||||
@@ -178,4 +178,5 @@ export const PUSH_ROUTE = {
|
||||
LEAGUE_KICK: 'onKickedByLeague', // 当被踢出
|
||||
LEAGUE_DISSMISS: 'onLeagueDismiss', // 当联军解散
|
||||
LEAGUE_ABDICATE: 'onLeagueAbdicate', // 当被转让盟主
|
||||
LEAGUE_ITEM_UPDATE: 'onLeagueItemUpdate',
|
||||
}
|
||||
@@ -32,10 +32,31 @@ export enum LEAGUE_MANAGE_TYPE {
|
||||
BE_ABDICATED = 7, // 被转让
|
||||
SET_INFO = 8, // 设置信息
|
||||
RERUIT = 9, // 招募
|
||||
SEND_MAIL = 9, // 招募
|
||||
SEND_MAIL = 9, // 发邮件
|
||||
UNLOCK_TECH = 10, // 解锁科技树
|
||||
ACTIVATE_TECH = 11, // 激活
|
||||
}
|
||||
|
||||
export enum LEAGUE_JOB {
|
||||
PRODUCER = 1, // 贤臣
|
||||
FIGHTER = 2, // 猛将
|
||||
}
|
||||
|
||||
export enum LEAGUE_ITEM_REFRESH_TYPE {
|
||||
DAILY = 1, // 每日刷新
|
||||
SEASON = 2, // 赛期刷新
|
||||
}
|
||||
|
||||
export enum GVG_RETURN_ITEM_TYPE {
|
||||
NORMAL_ITEM = 1, // 普通道具
|
||||
GVG_ITEM = 2, // GVG道具
|
||||
}
|
||||
|
||||
export const BATTLE_FEAT_ID = 12; // 战功
|
||||
|
||||
export enum GVG_ACTIVE_TYPE {
|
||||
COST_PRODUCE_COIN = 1, // 消耗内政令
|
||||
COST_FIGHT_COIN = 2, // 消耗征战令
|
||||
TECH_ACTIVATE = 3, // 激活千机阁
|
||||
LOGIN = 4, // 登录逐鹿中原界面
|
||||
}
|
||||
@@ -567,6 +567,8 @@ export const FILENAME = {
|
||||
DIC_ARTIFACT_QUALITY: 'dic_zyz_artifactQuality',
|
||||
DIC_ARTIFACT_SEID: 'dic_zyz_artifactSeid',
|
||||
DIC_GVG_PERIOD: 'dic_zyz_GVGPeriod',
|
||||
DIC_GVG_TECH: 'dic_zyz_GVGTech',
|
||||
DIC_GVG_ITEM: 'dic_zyz_GVGItems',
|
||||
}
|
||||
|
||||
export const WAR_RELATE_TABLES = [
|
||||
@@ -1067,6 +1069,7 @@ export enum ITEM_CHANGE_REASON {
|
||||
ARTIFACT_QUALITY = 158, // 宝物升品
|
||||
ARTIFACT_TRANSFER = 159, // 宝物转换
|
||||
ARTIFACT_REBUILD = 160, // 宝物重铸
|
||||
GVG_ACTIVE_TECH = 161, // 千机阁解锁
|
||||
}
|
||||
|
||||
export enum TA_EVENT {
|
||||
|
||||
@@ -13,4 +13,5 @@ export enum DATA_NAME {
|
||||
DONATE = 'Donate',
|
||||
FUND = 'fund',
|
||||
SEND_AUCTION = 'sendAuction',
|
||||
LEAGUE_TECH = 'LeaguTech'
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ export const STATUS = {
|
||||
|
||||
// GVG相关
|
||||
GVG_HAS_NO_AUTH: { code: 21300, simStr: '您的权限不足' },
|
||||
GVG_NOT_TEAM_PERIOD: { code: 21301, simStr: '您只能在组建期创建联军' },
|
||||
GVG_NOT_TEAM_PERIOD: { code: 21301, simStr: '您只能在组建期进行该操作' },
|
||||
GVG_TEAM_SERVER_TYPE_ERR: { code: 21302, simStr: '单服玩法不需要联军' },
|
||||
GVG_LEAGUE_HAS_EXIST: { code: 21303, simStr: '联军已存在' },
|
||||
GVG_NO_SERVER_TYPE: { code: 21304, simStr: '服务器开服一周后开放玩法' },
|
||||
@@ -321,6 +321,12 @@ export const STATUS = {
|
||||
CONSUME_TYPE_ERR: { code: 30008, simStr: '道具类型错误' },
|
||||
DB_DATA_NOT_FOUND: { code: 30009, simStr: '数据库数据未找到' },
|
||||
BOX_CAN_NOT_RECEIVE: { code: 30010, simStr: '宝箱不可领取' },
|
||||
GVG_TECH_PRE_POSITION_NOT_UNLOCK: { code: 30011, simStr: '前置科技未激活' },
|
||||
GVG_TECH_QUEUECNT_MAX: { code: 30012, simStr: '解锁队列到达上限' },
|
||||
GVG_TECH_LV_NOT_ENOUGH: { code: 30013, simStr: '联军等级不足不可解锁' },
|
||||
GVG_TECH_HAS_UNLOCKED: { code: 30014, simStr: '该科技已解锁' },
|
||||
GVG_TECH_NOT_QUEUE: { code: 30015, simStr: '该科技不在解锁队列中' },
|
||||
GVG_BATTLE_FEAT_NOT_ENOUGH: { code: 30016, simStr: '战功不足' },
|
||||
|
||||
// 武将养成通用 30100 - 30199
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ class Member {
|
||||
@prop({ required: true })
|
||||
roleId: string;
|
||||
@prop({ required: true })
|
||||
guildCode: string;
|
||||
@prop({ required: true })
|
||||
auth: number;
|
||||
}
|
||||
|
||||
@@ -69,7 +71,7 @@ export default class GVGLeague extends BaseModel {
|
||||
const doc = new GVGLeagueModel();
|
||||
const leagueCode = genCode(6);
|
||||
let _leader = <RoleType>leader;
|
||||
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.LEADER: LEAGUE_AUTH.MEMBER }));
|
||||
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.LEADER: LEAGUE_AUTH.MEMBER, guildCode: code }));
|
||||
const update = Object.assign(doc.toJSON(), { guildCodes: [code], name: `${name}联军`, guildCnt: 1, memberCnt, isAuto: true, leagueCe: guildCe, leader: _leader?._id, members: _members, leagueCode }, params);
|
||||
delete update._id;
|
||||
|
||||
@@ -83,6 +85,7 @@ export default class GVGLeague extends BaseModel {
|
||||
public static async findLeagueByGuild(guildCode: string) {
|
||||
const league: GVGLeagueType = await GVGLeagueModel.findOne({ guildCodes: guildCode, status: 1 })
|
||||
.populate('leader', { roleId: 1, roleName: 1, head: 1, frame: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, serverId: 1, _id: 0 }, 'Role')
|
||||
.select('+serverId')
|
||||
.lean();
|
||||
return league
|
||||
}
|
||||
@@ -118,7 +121,7 @@ export default class GVGLeague extends BaseModel {
|
||||
public static async joinGuild(leagueCode: string, guild: GuildType) {
|
||||
const { code, memberCnt, leader, guildCe, members } = guild;
|
||||
let _leader = <RoleType>leader;
|
||||
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.SUB_LEADER: LEAGUE_AUTH.MEMBER }));
|
||||
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.SUB_LEADER: LEAGUE_AUTH.MEMBER, guildCode: code }));
|
||||
|
||||
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 },
|
||||
{ $push: { guildCodes: code, members: { $each: _members } }, $inc: { guildCnt: 1, memberCnt: memberCnt, leagueCe: guildCe }
|
||||
@@ -167,8 +170,8 @@ export default class GVGLeague extends BaseModel {
|
||||
return league;
|
||||
}
|
||||
|
||||
public static async joinMember(leagueCode: string, roleId: string, ce: number) {
|
||||
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $push: { members: { roleId, auth: LEAGUE_AUTH.MEMBER } }, $inc: { memberCnt: 1, leagueCe: ce } }, { new: true }).lean();
|
||||
public static async joinMember(leagueCode: string, roleId: string, guildCode: string, ce: number) {
|
||||
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $push: { members: { roleId, auth: LEAGUE_AUTH.MEMBER, guildCode } }, $inc: { memberCnt: 1, leagueCe: ce } }, { new: true }).lean();
|
||||
return league;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
|
||||
import { LEAGUE_JOB } from '../consts';
|
||||
import { GVG } from '../pubUtils/dicParam';
|
||||
|
||||
class Tech {
|
||||
export class Tech {
|
||||
@prop({ required: true, default: 0 })
|
||||
id: number;
|
||||
@prop({ required: true, default: 0 })
|
||||
progress: number; // 贡献
|
||||
@prop({ required: true, default: 0 })
|
||||
status: number; // 0-已解锁 1-已激活
|
||||
maxProgress: number; // 贡献
|
||||
|
||||
constructor(id: number, maxProgress: number) {
|
||||
this.id = id;
|
||||
this.progress = 0;
|
||||
this.maxProgress = maxProgress;
|
||||
}
|
||||
}
|
||||
|
||||
class DonateRec {
|
||||
@@ -29,6 +36,13 @@ class Resource {
|
||||
wood: number; // 木堆
|
||||
}
|
||||
|
||||
class GuildActive {
|
||||
@prop({ required: true, default: '' })
|
||||
guildCode: string; // 军团
|
||||
@prop({ required: true, default: 0 })
|
||||
active: number;
|
||||
}
|
||||
|
||||
@index({ leagueCode: 1, configId: 1 })
|
||||
export default class GVGLeaguePrepare extends BaseModel {
|
||||
|
||||
@@ -50,8 +64,14 @@ export default class GVGLeaguePrepare extends BaseModel {
|
||||
@prop({ required: true, default: 0 })
|
||||
fighterCnt: number; // 选择外政人数
|
||||
|
||||
@prop({ required: true, default: [], type: Number, _id: false })
|
||||
activeTech: number[]; // 已激活完了的
|
||||
|
||||
@prop({ required: true, default: [], type: Tech, _id: false })
|
||||
tech: Tech[]; // 千机阁
|
||||
techQueue: Tech[]; // 千机阁
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
techQueueCnt: number; // 千机阁队列数量
|
||||
|
||||
@prop({ required: true, default: [], type: DonateRec, _id: false })
|
||||
donateRec: DonateRec[]; // 捐献记录
|
||||
@@ -59,6 +79,9 @@ export default class GVGLeaguePrepare extends BaseModel {
|
||||
@prop({ required: true, default: {food: 0, mineral: 0, wood: 0}, type: Resource, _id: false })
|
||||
resources: Resource
|
||||
|
||||
@prop({ required: true, default: [], type: GuildActive, _id: false })
|
||||
guildActive: GuildActive[]; // 军团活跃
|
||||
|
||||
public static async initData(configId: number, leagueCode: string, maxMemberCnt: number) {
|
||||
const doc = new GVGLeaguePrepareModel();
|
||||
const update = Object.assign(doc.toJSON(), { maxMemberCnt });
|
||||
@@ -83,6 +106,24 @@ export default class GVGLeaguePrepare extends BaseModel {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static async unlockTech(configId: number, leagueCode: string, techId: number, maxProgress: number) {
|
||||
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||
configId, leagueCode, techQueueCnt: { $lt: GVG.GVG_LEAGUE_TECH_LIST } }, { $push: { techQueue: new Tech(techId, maxProgress) }, $inc: { techQueueCnt: 1 } }, { new: true }).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async addProgress(configId: number, leagueCode: string, techId: number, addProgress: number) {
|
||||
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||
configId, leagueCode, 'techQueue.id': techId }, { $inc: { 'techQueue.$.progress': addProgress } }, { new: true }).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async activate(configId: number, leagueCode: string, techId: number) {
|
||||
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({
|
||||
configId, leagueCode }, { $push: { activeTech: techId}, $pull: { techQueue: { id: techId } } }, { new: true }).lean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export const GVGLeaguePrepareModel = getModelForClass(GVGLeaguePrepare);
|
||||
|
||||
62
shared/db/GVGUserDailyData.ts
Normal file
62
shared/db/GVGUserDailyData.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
|
||||
import { getZeroPoint } from '../pubUtils/timeUtil';
|
||||
|
||||
@index({ leagueCode: 1, roleId: 1, configId: 1, time: 1 })
|
||||
export default class GVGUserDailyData extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
roleId: string; // 玩家
|
||||
|
||||
@prop({ required: true })
|
||||
configId: number; // 赛季信息
|
||||
|
||||
@prop({ required: true })
|
||||
leagueCode: string; // 所属联军
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
job: number; // 职能 1-贤臣 2-猛将
|
||||
|
||||
// 贡献
|
||||
@prop({ required: true, default: 0 })
|
||||
food: number; // 粮食
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
mineral: number; // 矿物
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
wood: number; // 木材
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
score: number; // 据点积分
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
time: number = 0; // 每天0点
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
hasGetTechActive: boolean; // 千机阁激活活跃是否获得
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
hasLogin: boolean; // 每日登录活跃是否获得
|
||||
|
||||
public static async findByRole(configId: number, leagueCode: string, roleId: string) {
|
||||
const result: GVGUserDailyDataType = await GVGUserDailyDataModel.findOne({ configId, leagueCode, roleId, time: getZeroPoint() }).select('food mineral wood score').lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async checkGetTechActive(configId: number, leagueCode: string, roleId: string) {
|
||||
return await GVGUserDailyDataModel.exists({ configId, leagueCode, roleId, time: getZeroPoint(), hasGetTechActive: { $exists: true } });
|
||||
}
|
||||
|
||||
public static async setHasGetTechActive(configId: number, leagueCode: string, roleId: string) {
|
||||
const result: GVGUserDailyDataType = await GVGUserDailyDataModel.findOneAndUpdate({ configId, leagueCode, roleId, time: getZeroPoint() }, { hasGetTechActive: true }, { upsert: true, new: true }).lean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export const GVGUserDailyDataModel = getModelForClass(GVGUserDailyData);
|
||||
|
||||
export interface GVGUserDailyDataType extends Pick<DocumentType<GVGUserDailyData>, keyof GVGUserDailyData> {
|
||||
id: number;
|
||||
};
|
||||
export type GVGUserDailyDataUpdate = Partial<GVGUserDailyDataType>; // 将所有字段变成可选项
|
||||
@@ -1,47 +0,0 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
|
||||
@index({ leagueCode: 1, roleId: 1, configId: 1, time: 1 })
|
||||
export default class GVGUserDailyDistribute extends BaseModel {
|
||||
|
||||
@prop({ required: true })
|
||||
roleId: string; // 玩家
|
||||
|
||||
@prop({ required: true })
|
||||
configId: number; // 赛季信息
|
||||
|
||||
@prop({ required: true })
|
||||
leagueCode: string; // 所属联军
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
job: number; // 职能 1-贤臣 2-猛将
|
||||
|
||||
// 贡献
|
||||
@prop({ required: true, default: 0 })
|
||||
food: number; // 粮食
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
mineral: number; // 矿物
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
wood: number; // 木材
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
score: number; // 据点积分
|
||||
|
||||
@prop({ required: true, default: 0 })
|
||||
time: number = 0; // 据点积分
|
||||
|
||||
public static async findByRole(configId: number, leagueCode: string, roleId: string) {
|
||||
const result: GVGUserDailyDistributeType = await GVGUserDailyDistributeModel.findOne({ configId, leagueCode, roleId, time: nowSeconds() }).select('food mineral wood score').lean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export const GVGUserDailyDistributeModel = getModelForClass(GVGUserDailyDistribute);
|
||||
|
||||
export interface GVGUserDailyDistributeType extends Pick<DocumentType<GVGUserDailyDistribute>, keyof GVGUserDailyDistribute> {
|
||||
id: number;
|
||||
};
|
||||
export type GVGUserDailyDistributeUpdate = Partial<GVGUserDailyDistributeType>; // 将所有字段变成可选项
|
||||
@@ -1,5 +1,6 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
|
||||
class ActiveRec {
|
||||
@prop({ required: true, default: 1 })
|
||||
@@ -8,6 +9,12 @@ class ActiveRec {
|
||||
count: number;
|
||||
@prop({ required: true, default: 0 })
|
||||
time: number;
|
||||
|
||||
constructor(id: number, count: number) {
|
||||
this.id = id;
|
||||
this.count = count;
|
||||
this.time = nowSeconds();
|
||||
}
|
||||
}
|
||||
|
||||
class Box {
|
||||
@@ -91,6 +98,11 @@ export default class GVGUserData extends BaseModel {
|
||||
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $set: { job } }, { new: true, upsert: true}).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async addActive(configId: number, leagueCode: string, roleId: string, activeType: number, active: number) {
|
||||
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $inc: { active }, $push: { activeRec: new ActiveRec(activeType, active) } }, { new: true, upsert: true}).lean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export const GVGUserDataModel = getModelForClass(GVGUserData);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import BaseModel from './BaseModel';
|
||||
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
|
||||
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||
import { nowSeconds } from '../pubUtils/timeUtil';
|
||||
import { RewardInter } from '../pubUtils/interface';
|
||||
|
||||
@index({ leagueCode: 1, roleId: 1, configId: 1, status: 1 })
|
||||
export default class GVGUserItem extends BaseModel {
|
||||
@@ -27,6 +28,26 @@ export default class GVGUserItem extends BaseModel {
|
||||
const result: GVGUserItemType[] = await GVGUserItemModel.find({ configId, leagueCode, roleId, expireTime: { $gte: nowSeconds() } }, { _id: 0 }).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async increaseItem(configId: number, leagueCode: string, roleId: string, id: number, inc: number, expireTime: number) {
|
||||
const result: GVGUserItemType = await GVGUserItemModel.findOneAndUpdate({ configId, leagueCode, roleId, id, expireTime }, { $inc: { count: inc } }, { new: true, upsert: true }).lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async findByRoleAndIds(configId: number, leagueCode: string, roleId: string, ids: number[]) {
|
||||
const result: GVGUserItemType[] = await GVGUserItemModel.find({ configId, leagueCode, roleId, expireTime: { $gte: nowSeconds() }, id: { $in: ids } }).select('id count').lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async decreaseItem(configId: number, leagueCode: string, roleId: string, items: RewardInter[]) {
|
||||
const result = await GVGUserItemModel.bulkWrite(items.map(({ id, count }) => {
|
||||
let filter = { configId, leagueCode, roleId, id, count: { $gte: count }, expireTime: { $gte: nowSeconds() } }
|
||||
console.log('#### filter', filter, )
|
||||
return { updateOne: { filter, update: { $inc: { count: -1 * count } } } }
|
||||
}));
|
||||
console.log(result.matchedCount, items.length)
|
||||
return result.matchedCount == items.length;
|
||||
}
|
||||
}
|
||||
|
||||
export const GVGUserItemModel = getModelForClass(GVGUserItem);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { GUILD_STRUCTURE, GUILD_STATUS, GUILD_PER_PAGE, GUILD_SELECT, REDIS_KEY,
|
||||
import { getZeroPoint, getZeroPointD, nowSeconds } from '../pubUtils/timeUtil';
|
||||
import { gameData } from '../pubUtils/data';
|
||||
import { SearchGuildParam } from '../domain/backEndField/search';
|
||||
import { GVG } from '../pubUtils/dicParam';
|
||||
|
||||
export class Structure {
|
||||
@prop({ required: true })
|
||||
@@ -325,21 +326,22 @@ export default class Guild extends BaseModel {
|
||||
}
|
||||
|
||||
public static async findGuildsForGVG(page: number, name: string, serverIds: number[]) {
|
||||
let query: any = { status: GUILD_STATUS.RUNNING, lv: { $gte: 3 }, leagueCode: '', serverId: { $in: serverIds } };
|
||||
let query: any = { status: GUILD_STATUS.RUNNING, lv: { $gte: GVG.GVG_ARMY_LEAGUE_TIME }, leagueCode: '', serverId: { $in: serverIds } };
|
||||
if(name) {
|
||||
query['name'] = { $regex: new RegExp(name, 'i') }
|
||||
}
|
||||
const result: GuildType[] = await GuildModel.find(query)
|
||||
.populate('leader', { roleId: 1, roleName: 1, _id: 0 }, 'Role')
|
||||
.skip((page - 1) * 30).limit(30)
|
||||
.select('+serverId')
|
||||
.lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async findByCodes(codes: string[]) {
|
||||
const result: GuildType[] = await GuildModel.find({ status: GUILD_STATUS.RUNNING, code: { $in: codes } })
|
||||
.select('+serverId')
|
||||
.populate('leader', { roleId: 1, roleName: 1, _id: 0 }, 'Role')
|
||||
.select('+serverId')
|
||||
.lean();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ export default class LadderMatch extends BaseModel {
|
||||
if(defenseInfo.isRobot) {
|
||||
let atkLadderMatch = await LadderMatchModel.findOne({ roleId: attackInfo.roleId }).lean();
|
||||
if(isSuccess && atkLadderMatch && (atkLadderMatch.rank == 0 || atkLadderMatch.rank > defenseInfo.oldRank)) {
|
||||
newAtkLadderMatch = await LadderMatchModel.findOneAndUpdate({ roleId: attackInfo.roleId }, { $set: { rank: defenseInfo.oldRank, oldRank: atkLadderMatch.rank } }, { new: true }).lean();
|
||||
newAtkLadderMatch = await LadderMatchModel.findOneAndUpdate({ roleId: attackInfo.roleId }, { $set: { rank: defenseInfo.oldRank, oldRank: atkLadderMatch.rank } }, { new: true, session }).lean();
|
||||
isChange = true;
|
||||
endTime = Date.now();
|
||||
} else {
|
||||
@@ -129,8 +129,8 @@ export default class LadderMatch extends BaseModel {
|
||||
let atkLadderMatch = await LadderMatchModel.findOne({ roleId: attackInfo.roleId }).lean();
|
||||
let defLadderMatch = await LadderMatchModel.findOne({ roleId: defenseInfo.roleId }).lean();
|
||||
if(isSuccess && atkLadderMatch && defLadderMatch && (atkLadderMatch.rank == 0 || atkLadderMatch.rank > defLadderMatch.rank)) {
|
||||
newAtkLadderMatch = await LadderMatchModel.findOneAndUpdate({ roleId: attackInfo.roleId }, { $set: { rank: defLadderMatch.rank, oldRank: atkLadderMatch.rank } }, { new: true }).lean();
|
||||
newDefLadderMatch = await LadderMatchModel.findOneAndUpdate({ roleId: defenseInfo.roleId }, { $set: { rank: atkLadderMatch.rank, oldRank: defLadderMatch.rank } }, { new: true }).lean();
|
||||
newAtkLadderMatch = await LadderMatchModel.findOneAndUpdate({ roleId: attackInfo.roleId }, { $set: { rank: defLadderMatch.rank, oldRank: atkLadderMatch.rank } }, { new: true, session }).lean();
|
||||
newDefLadderMatch = await LadderMatchModel.findOneAndUpdate({ roleId: defenseInfo.roleId }, { $set: { rank: atkLadderMatch.rank, oldRank: defLadderMatch.rank } }, { new: true, session }).lean();
|
||||
isChange = true;
|
||||
endTime = Date.now();
|
||||
} else {
|
||||
|
||||
@@ -98,7 +98,7 @@ export class GVGMainData {
|
||||
if(!leaguePrepare) return;
|
||||
this.lv = leaguePrepare.lv;
|
||||
this.resources = leaguePrepare.resources;
|
||||
this.activeTech = leaguePrepare.tech.filter(cur => cur.status == 1).map(cur => cur.id);
|
||||
this.activeTech = leaguePrepare.activeTech||[];
|
||||
}
|
||||
|
||||
setPlayerInfo(userData: GVGUserDataType, auth: number, canPrepare: boolean, canChooseJob: boolean, items: GVGItem[], tasks: GVGTask[]) {
|
||||
|
||||
@@ -119,6 +119,8 @@ import { DicArtifact } from "./dictionary/DicArtifact";
|
||||
import { DicArtifactQuality } from "./dictionary/DicArtifactQuality";
|
||||
import { dicGiftPackagePlan, loadGiftPackagePlan } from "./dictionary/DicGiftPackagePlan";
|
||||
import { dicGVGPeriod, loadGVGPeriod } from './dictionary/DicGVGPeriod';
|
||||
import { dicGVGTech, loadGVGTech } from "./dictionary/DicGVGTech";
|
||||
import { dicGVGItem, loadGVGItem } from "./dictionary/DicGVGItems";
|
||||
|
||||
export const gameData = {
|
||||
daily: dicDaily,
|
||||
@@ -297,6 +299,9 @@ export const gameData = {
|
||||
artifactSeid: dicArtifactSeid,
|
||||
artifactByGroupAndQuality: dicArtifactsByGroup,
|
||||
gvgPeriod: dicGVGPeriod,
|
||||
gvgTech: dicGVGTech,
|
||||
gvgItem: dicGVGItem,
|
||||
gvgActive: new Map<number, number>(),
|
||||
};
|
||||
|
||||
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
||||
@@ -1069,6 +1074,13 @@ export function getArtifactWithQuality(artifactId: number): (DicArtifact&DicArti
|
||||
return {...dicArtifact, ...dicArtifactQuality}
|
||||
}
|
||||
|
||||
function parseGVGActive() {
|
||||
let arr = decodeArrayListStr(param.GVG.GVG_LEAGUE_ACTIVE_POINT);
|
||||
for(let [id, active] of arr) {
|
||||
gameData.gvgActive.set(parseInt(id), parseInt(active));
|
||||
}
|
||||
}
|
||||
|
||||
// 初始加载
|
||||
function initDatas() {
|
||||
parseDicParam();
|
||||
@@ -1089,6 +1101,7 @@ function parseDicParam() {
|
||||
loadAuctionTime();
|
||||
decodeLadderBuyCost();
|
||||
parseComBattleRewardTime();
|
||||
parseGVGActive();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1265,6 +1278,8 @@ function loadDatas() {
|
||||
loadArtifactQualityPlan();
|
||||
loadArtifactSeid();
|
||||
loadGVGPeriod();
|
||||
loadGVGTech();
|
||||
loadGVGItem();
|
||||
}
|
||||
|
||||
// 重载dicParam
|
||||
|
||||
40
shared/pubUtils/dictionary/DicGVGItems.ts
Normal file
40
shared/pubUtils/dictionary/DicGVGItems.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
// GVG道具
|
||||
import { FILENAME } from '../../consts'
|
||||
import { RewardInter } from '../interface';
|
||||
import { parseGoodStr, readFileAndParse } from '../util'
|
||||
|
||||
export interface DicGVGItem {
|
||||
// 道具id
|
||||
id: number;
|
||||
// 点名称
|
||||
name: string
|
||||
// 1-种子 2-铲子 3-斧子 4-内政外政令 5-战功 6-激战期用的复活令&匕首
|
||||
type: number;
|
||||
// 1-每日刷新 2-赛期内刷新
|
||||
refreshType: number;
|
||||
// 兑换物品表消耗
|
||||
consume: RewardInter[];
|
||||
// 这个表里的兑换消耗
|
||||
leagueConsume: RewardInter[];
|
||||
// 耐久度或者产量
|
||||
value: number,
|
||||
// 消耗后可获得的奖励
|
||||
reward: RewardInter[];
|
||||
// 消耗后可获得的这张表里的奖励
|
||||
leagueReward: RewardInter[];
|
||||
}
|
||||
|
||||
export const dicGVGItem = new Map<number, DicGVGItem>();
|
||||
export function loadGVGItem() {
|
||||
dicGVGItem.clear();
|
||||
|
||||
let arr = readFileAndParse(FILENAME.DIC_GVG_ITEM);
|
||||
arr.forEach(o => {
|
||||
o.consume = parseGoodStr(o.consume);
|
||||
o.leagueConsume = parseGoodStr(o.leagueConsume);
|
||||
o.reward = parseGoodStr(o.reward);
|
||||
o.leagueReward = parseGoodStr(o.leagueReward);
|
||||
dicGVGItem.set(o.id, o);
|
||||
});
|
||||
arr = undefined;
|
||||
}
|
||||
44
shared/pubUtils/dictionary/DicGVGTech.ts
Normal file
44
shared/pubUtils/dictionary/DicGVGTech.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// GVG千机阁
|
||||
import { FILENAME } from '../../consts'
|
||||
import { decodeArrayListStr, readFileAndParse } from '../util'
|
||||
|
||||
export interface DicGVGTech {
|
||||
// 唯一id
|
||||
id: number;
|
||||
// 点名称
|
||||
name: string
|
||||
// 激活后获得的内容
|
||||
content: string;
|
||||
// 效果类型 1-资源产量上传 2-征战中原提升 3-激战期提升 4-复活cd减少 5-箭塔 6-攻城车
|
||||
type: number;
|
||||
// 资源提升量啊,复活cd减少量啊之类的值
|
||||
param: number;
|
||||
// 点排序
|
||||
nodeSort: number;
|
||||
// 联军等级限制
|
||||
levelLimit: number;
|
||||
// 前置id
|
||||
prepositionId: number[][];
|
||||
// 所需的战功
|
||||
consume: number;
|
||||
}
|
||||
|
||||
export const dicGVGTech = new Map<number, DicGVGTech>();
|
||||
export function loadGVGTech() {
|
||||
dicGVGTech.clear();
|
||||
|
||||
let arr = readFileAndParse(FILENAME.DIC_GVG_TECH);
|
||||
arr.forEach(o => {
|
||||
o.prepositionId = parsePrePositionId(o.prepositionId);
|
||||
dicGVGTech.set(o.id, o);
|
||||
});
|
||||
arr = undefined;
|
||||
}
|
||||
|
||||
|
||||
function parsePrePositionId(str: string) {
|
||||
let arr = decodeArrayListStr(str);
|
||||
return arr.map(arr1 => {
|
||||
return arr1.map(str => parseInt(str));
|
||||
});
|
||||
}
|
||||
@@ -9,7 +9,8 @@
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 1,
|
||||
"prepositionId": "&",
|
||||
"consume": "12&5000"
|
||||
"consume": 1000,
|
||||
"lineShow": "&"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
@@ -21,7 +22,8 @@
|
||||
"levelSeid": "1001&",
|
||||
"levelLimit": 1,
|
||||
"prepositionId": "&",
|
||||
"consume": "12&5000"
|
||||
"consume": 2000,
|
||||
"lineShow": "&"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
@@ -33,7 +35,8 @@
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 2,
|
||||
"prepositionId": "1&",
|
||||
"consume": "12&5000"
|
||||
"consume": 3000,
|
||||
"lineShow": "1&"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
@@ -45,7 +48,8 @@
|
||||
"levelSeid": "1001&",
|
||||
"levelLimit": 2,
|
||||
"prepositionId": "2&",
|
||||
"consume": "12&5000"
|
||||
"consume": 4000,
|
||||
"lineShow": "2&"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
@@ -57,34 +61,50 @@
|
||||
"levelSeid": "1001&",
|
||||
"levelLimit": 2,
|
||||
"prepositionId": "3&|4&",
|
||||
"consume": "12&5000"
|
||||
"consume": 5000,
|
||||
"lineShow": "4&|5&"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "贤臣3",
|
||||
"content": "资源产量提升15%",
|
||||
"type": 1,
|
||||
"param": "15&",
|
||||
"nodeSort": 4,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 4,
|
||||
"prepositionId": "3&",
|
||||
"consume": 6000,
|
||||
"lineShow": "3&"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "猛将3",
|
||||
"content": "征战中原联军成员攻击提升15%",
|
||||
"type": 1,
|
||||
"param": "10&",
|
||||
"nodeSort": 4,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 4,
|
||||
"prepositionId": "4&",
|
||||
"consume": 7000,
|
||||
"lineShow": "6&"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "激战2",
|
||||
"content": "激战期时联军成员攻击提升5%",
|
||||
"type": 3,
|
||||
"param": "&",
|
||||
"nodeSort": 4,
|
||||
"nodeSort": 5,
|
||||
"levelSeid": "1001&",
|
||||
"levelLimit": 4,
|
||||
"prepositionId": "5&",
|
||||
"consume": "12&5000"
|
||||
"consume": 8000,
|
||||
"lineShow": "7&"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "复活1",
|
||||
"content": "激战期时联军成员复活cd减少30s",
|
||||
"type": 4,
|
||||
"param": "30&",
|
||||
"nodeSort": 5,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 4,
|
||||
"prepositionId": "6&",
|
||||
"consume": "12&5000"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 9,
|
||||
"name": "箭塔1",
|
||||
"content": "联军中随机20名成员获得箭塔(箭塔每10s给该位置所有敌军减5点耐久,箭头耐久为50点)",
|
||||
"type": 5,
|
||||
@@ -92,19 +112,112 @@
|
||||
"nodeSort": 6,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 6,
|
||||
"prepositionId": "7&",
|
||||
"consume": "12&5000"
|
||||
"prepositionId": "8&",
|
||||
"consume": 9000,
|
||||
"lineShow": "8&"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "攻城车1",
|
||||
"content": "联军中随机20名成员获得攻城车(使用攻城车道具可击杀1名敌军)",
|
||||
"id": 10,
|
||||
"name": "匕首1",
|
||||
"content": "联军中随机5名成员获得攻城车(使用匕首道具可击杀1名敌军)",
|
||||
"type": 6,
|
||||
"param": "20&",
|
||||
"nodeSort": 6,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 6,
|
||||
"prepositionId": "7&",
|
||||
"consume": "12&5000"
|
||||
"prepositionId": "8&",
|
||||
"consume": 10000,
|
||||
"lineShow": "9&"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "复活1",
|
||||
"content": "激战期时联军成员复活cd减少30s",
|
||||
"type": 4,
|
||||
"param": "30&",
|
||||
"nodeSort": 7,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 6,
|
||||
"prepositionId": "9&|10&",
|
||||
"consume": 11000,
|
||||
"lineShow": "11&|12&"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "箭塔2",
|
||||
"content": "联军中随机20名成员获得箭塔(箭塔每10s给该位置所有敌军减5点耐久,箭头耐久为50点)",
|
||||
"type": 5,
|
||||
"param": "10&5&50",
|
||||
"nodeSort": 8,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 8,
|
||||
"prepositionId": "9&",
|
||||
"consume": 12000,
|
||||
"lineShow": "10&"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "匕首2",
|
||||
"content": "联军中随机5名成员获得攻城车(使用匕首道具可击杀1名敌军)",
|
||||
"type": 6,
|
||||
"param": "20&",
|
||||
"nodeSort": 8,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 8,
|
||||
"prepositionId": "10&",
|
||||
"consume": 13000,
|
||||
"lineShow": "13&"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "激战3",
|
||||
"content": "激战期时联军成员攻击提升10%",
|
||||
"type": 3,
|
||||
"param": "&",
|
||||
"nodeSort": 9,
|
||||
"levelSeid": "1001&",
|
||||
"levelLimit": 8,
|
||||
"prepositionId": "11&",
|
||||
"consume": 14000,
|
||||
"lineShow": "14&"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "箭塔3",
|
||||
"content": "联军中随机20名成员获得箭塔(箭塔每10s给该位置所有敌军减5点耐久,箭头耐久为50点)",
|
||||
"type": 5,
|
||||
"param": "10&5&50",
|
||||
"nodeSort": 10,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 10,
|
||||
"prepositionId": "12&",
|
||||
"consume": 15000,
|
||||
"lineShow": "15&"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "匕首3",
|
||||
"content": "联军中随机10名成员获得攻城车(使用匕首道具可击杀1名敌军)",
|
||||
"type": 6,
|
||||
"param": "20&",
|
||||
"nodeSort": 10,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 10,
|
||||
"prepositionId": "13&",
|
||||
"consume": 16000,
|
||||
"lineShow": "16&"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "复活2",
|
||||
"content": "激战期时联军成员复活cd减少30s",
|
||||
"type": 4,
|
||||
"param": "30&",
|
||||
"nodeSort": 11,
|
||||
"levelSeid": 0,
|
||||
"levelLimit": 10,
|
||||
"prepositionId": "14&",
|
||||
"consume": 17000,
|
||||
"lineShow": "17&"
|
||||
}
|
||||
]
|
||||
@@ -33,6 +33,6 @@
|
||||
"DEBUG_TIME": 1,
|
||||
"CHECK_WORD": 1,
|
||||
"CAN_PAY": 1,
|
||||
"SKIP_ENCODE": 1,
|
||||
"SKIP_ENCODE": 0,
|
||||
"NEED_REBATE": 0
|
||||
}
|
||||
Reference in New Issue
Block a user