✨ feat(gvg): 添加联军频道

This commit is contained in:
luying
2023-02-21 17:16:49 +08:00
parent 22b3dbc551
commit 3eb6a1045f
19 changed files with 218 additions and 38 deletions
@@ -2,11 +2,12 @@ import { CHANNEL_PREFIX, MSG_SOURCE, getChannelType } from './../../../consts/co
import { Application, BackendSession, HandlerService, } from 'pinus'; import { Application, BackendSession, HandlerService, } from 'pinus';
import { resResult } from '../../../pubUtils/util'; import { resResult } from '../../../pubUtils/util';
import { DEFAULT_MSG_PER_PAGE, STATUS, TASK_TYPE } from '../../../consts'; import { DEFAULT_MSG_PER_PAGE, STATUS, TASK_TYPE } from '../../../consts';
import { createAccuseData, createGroupMsg, createPrivateMsg, getPrivateMessages, pushGroupMsgToRoom, pushMsgToRole, updatePrivateMsgReadInfo, recentPrivateChatInfos, recentWorldMsgs, recentSysMsgs, recentGuildMsgs, updatePrivateMsgIsTop, delPrivateMsg, recentServerGroupMsgs } from '../../../services/chatService'; import { createAccuseData, createGroupMsg, createPrivateMsg, getPrivateMessages, pushGroupMsgToRoom, pushMsgToRole, updatePrivateMsgReadInfo, recentPrivateChatInfos, recentWorldMsgs, recentSysMsgs, recentGuildMsgs, updatePrivateMsgIsTop, delPrivateMsg, recentServerGroupMsgs, recentLeagueMsgs } from '../../../services/chatService';
import { getSimpleRoleInfo } from '../../../services/roleService'; import { getSimpleRoleInfo } from '../../../services/roleService';
import { checkTask } from '../../../services/task/taskService'; import { checkTask } from '../../../services/task/taskService';
import { RoleModel } from '../../../db/Role'; import { RoleModel } from '../../../db/Role';
import { getFriendRelationType } from '../../../services/friendService'; import { getFriendRelationType } from '../../../services/friendService';
import { GVGLeagueModel } from '../../../db/GVGLeague';
export default function (app: Application) { export default function (app: Application) {
@@ -36,6 +37,11 @@ export class ChatHandler {
let channelId = ''; let channelId = '';
if (channel === CHANNEL_PREFIX.WORLD) channelId = `${serverId}`; if (channel === CHANNEL_PREFIX.WORLD) channelId = `${serverId}`;
if (channel === CHANNEL_PREFIX.GUILD) channelId = guildCode; if (channel === CHANNEL_PREFIX.GUILD) channelId = guildCode;
if (channel == CHANNEL_PREFIX.LEAGUE) {
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
if(!myLeague) return resResult(STATUS.GVG_NOT_JOIN_LEAGUE);
channelId = myLeague.leagueCode;
}
const msgData = await createGroupMsg(roleId, roleName, channel, channelId, type, MSG_SOURCE.ROLE_SEND_TEXT, content, targetRoleId, targetMsgCode); const msgData = await createGroupMsg(roleId, roleName, channel, channelId, type, MSG_SOURCE.ROLE_SEND_TEXT, content, targetRoleId, targetMsgCode);
if (!msgData) return resResult(STATUS.WRONG_PARMS); if (!msgData) return resResult(STATUS.WRONG_PARMS);
await pushGroupMsgToRoom(msgData); await pushGroupMsgToRoom(msgData);
@@ -108,8 +114,9 @@ export class ChatHandler {
const sysMsgs = await recentSysMsgs(serverId); const sysMsgs = await recentSysMsgs(serverId);
const guildMsgs = await recentGuildMsgs(guildCode); const guildMsgs = await recentGuildMsgs(guildCode);
const gvgMsgs = await recentServerGroupMsgs(serverId); const gvgMsgs = await recentServerGroupMsgs(serverId);
const leagueMsgs = await recentLeagueMsgs(guildCode);
return resResult(STATUS.SUCCESS, { worldMsgs, sysMsgs, guildMsgs, gvgMsgs }) return resResult(STATUS.SUCCESS, { worldMsgs, sysMsgs, guildMsgs, gvgMsgs, leagueMsgs })
} }
/** /**
@@ -599,11 +599,11 @@ export class GVGBattleHandler {
// 获取战报 // 获取战报
// type: 战报类型 // type: 战报类型
async getRecs(msg: { type: number, cityId: number }, session: BackendSession) { async getRecs(msg: { type: number }, session: BackendSession) {
const roleId = session.get('roleId'); const roleId = session.get('roleId');
const serverId = session.get('serverId'); const serverId = session.get('serverId');
const guildCode = session.get('guildCode'); const guildCode = session.get('guildCode');
const { type, cityId } = msg; const { type } = msg;
// 根据 type 获取战报 // 根据 type 获取战报
let { configId, period } = getGVGPeriodData(); let { configId, period } = getGVGPeriodData();
let groupKey = await getGroupKey(serverId); let groupKey = await getGroupKey(serverId);
@@ -613,7 +613,7 @@ export class GVGBattleHandler {
let recs: GVGRecType[] = []; let recs: GVGRecType[] = [];
if(type == GVG_REC_TYPE.BATTLE_BY_CITY) { if(type == GVG_REC_TYPE.BATTLE_BY_CITY) {
recs = await GVGRecModel.findBattleRecByCity(configId, groupKey, cityId); recs = await GVGRecModel.findBattleRecByGroup(configId, groupKey);
} else if (type == GVG_REC_TYPE.BATTLE_BY_LEAGUE) { } else if (type == GVG_REC_TYPE.BATTLE_BY_LEAGUE) {
recs = await GVGRecModel.findBattleRecByLeague(configId, myLeague.leagueCode); recs = await GVGRecModel.findBattleRecByLeague(configId, myLeague.leagueCode);
} else if (type == GVG_REC_TYPE.BATTLE_BY_ROLE) { } else if (type == GVG_REC_TYPE.BATTLE_BY_ROLE) {
@@ -24,6 +24,7 @@ import { checkGVGTask } from "../../../services/task/taskService";
import { getFightTimeByPeriod, getMyVestiges, getVestiges } from "../../../services/gvg/gvgFightService"; import { getFightTimeByPeriod, getMyVestiges, getVestiges } from "../../../services/gvg/gvgFightService";
import { getSeconds } from "../../../pubUtils/timeUtil"; import { getSeconds } from "../../../pubUtils/timeUtil";
import { GVGVestigeRankModel } from "../../../db/GVGVestigeRank"; import { GVGVestigeRankModel } from "../../../db/GVGVestigeRank";
import { addTechActivateMessage, addTechUnlockMessage } from "../../../services/gvg/gvgRecService";
export default function (app: Application) { export default function (app: Application) {
new HandlerService(app, {}); new HandlerService(app, {});
@@ -344,6 +345,7 @@ export class GVGHandler {
// 千机阁解锁 // 千机阁解锁
async unlockTech(msg: { techId: number }, session: BackendSession) { async unlockTech(msg: { techId: number }, session: BackendSession) {
const roleId = session.get('roleId'); const roleId = session.get('roleId');
const roleName = session.get('roleName');
const guildCode = session.get('guildCode'); const guildCode = session.get('guildCode');
const { techId } = msg; const { techId } = msg;
@@ -383,6 +385,8 @@ export class GVGHandler {
} }
res.releaseCallback(); res.releaseCallback();
addTechUnlockMessage(roleId, roleName, myLeague, techId);
return resResult(STATUS.SUCCESS, { return resResult(STATUS.SUCCESS, {
queue: leaguePrepare?.techQueue||[] queue: leaguePrepare?.techQueue||[]
}); });
@@ -392,6 +396,7 @@ export class GVGHandler {
async activate(msg: { techId: number, battleFeats: number }, session: BackendSession) { async activate(msg: { techId: number, battleFeats: number }, session: BackendSession) {
const serverId = session.get('serverId'); const serverId = session.get('serverId');
const roleId = session.get('roleId'); const roleId = session.get('roleId');
const roleName = session.get('roleName');
const guildCode = session.get('guildCode'); const guildCode = session.get('guildCode');
const sid = session.get('sid'); const sid = session.get('sid');
const { techId, battleFeats } = msg; const { techId, battleFeats } = msg;
@@ -436,6 +441,7 @@ export class GVGHandler {
await addGVGReward(roleId, '', myLeague.leagueCode, null, [{ id: GVG_ITEM.KNIFE, count: dicTech.param[1] }], [], ITEM_CHANGE_REASON.GVG_TECH_SEND_KNIFE); await addGVGReward(roleId, '', myLeague.leagueCode, null, [{ id: GVG_ITEM.KNIFE, count: dicTech.param[1] }], [], ITEM_CHANGE_REASON.GVG_TECH_SEND_KNIFE);
} }
} }
addTechActivateMessage(roleId, roleName, myLeague, techId);
} }
// 添加 活跃 // 添加 活跃
@@ -16,7 +16,7 @@ import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
import { createGroupMsg, pushGroupMsgToRoom } from "../../../services/chatService"; import { createGroupMsg, pushGroupMsgToRoom } from "../../../services/chatService";
import { sendMailByContent, sendMailToGuildByContent, sendMailToLeagueByContent } from "../../../services/mailService"; import { sendMailByContent, sendMailToGuildByContent, sendMailToLeagueByContent } from "../../../services/mailService";
import { getGVGCities } from "../../../services/gvg/gvgBattleService"; import { getGVGCities } from "../../../services/gvg/gvgBattleService";
import { guildQuitLeagueRecord } from "../../../services/gvg/gvgRecService"; import { changeNoticeMessage, guildQuitLeagueRecord } from "../../../services/gvg/gvgRecService";
import { LeagueLeader } from "../../../domain/rank"; import { LeagueLeader } from "../../../domain/rank";
export default function (app: Application) { export default function (app: Application) {
@@ -587,6 +587,7 @@ export class GVGManageHandler {
// 设置联军信息 // 设置联军信息
async setLeagueInfo(msg: { leagueCode: string, name: string, notice: string, icon: number }, session: BackendSession) { async setLeagueInfo(msg: { leagueCode: string, name: string, notice: string, icon: number }, session: BackendSession) {
const roleId = session.get('roleId'); const roleId = session.get('roleId');
const roleName = session.get('roleName');
const guildCode = session.get('guildCode'); const guildCode = session.get('guildCode');
const { leagueCode: targetLeagueCode, name, notice, icon } = msg; const { leagueCode: targetLeagueCode, name, notice, icon } = msg;
@@ -611,6 +612,9 @@ export class GVGManageHandler {
if(icon != undefined) { if(icon != undefined) {
await updateUserInfo(REDIS_KEY.LEAGUE_INFO, myLeague.leagueCode, [{ field: 'icon', value: name }]); await updateUserInfo(REDIS_KEY.LEAGUE_INFO, myLeague.leagueCode, [{ field: 'icon', value: name }]);
} }
if(notice != undefined) {
await changeNoticeMessage(roleId, roleName, myLeague, notice);
}
// 返回 // 返回
return resResult(STATUS.SUCCESS, { return resResult(STATUS.SUCCESS, {
@@ -227,7 +227,7 @@ export class GVGProduceHandler {
// 计算产量 // 计算产量
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(myResultFields); const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(myResultFields);
// 资源 // 资源
let resourceResult = await addResource(myLeague.leagueCode, roleId, roleName, GVG_RESOURCE_TYPE.FOOD, foodSum)||{}; let resourceResult = await addResource(myLeague, roleId, roleName, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
// 相关物品 // 相关物品
let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueRewardSum, rewardSum, ITEM_CHANGE_REASON.HARVEST) let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueRewardSum, rewardSum, ITEM_CHANGE_REASON.HARVEST)
// 活跃 // 活跃
@@ -282,7 +282,7 @@ export class GVGProduceHandler {
// 计算产量 // 计算产量
const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(resultField); const { foodSum, rewardSum, leagueRewardSum, activeSum } = await sumOutputByResults(resultField);
// 资源 // 资源
await addResource(myLeague.leagueCode, targetRoleId, resultField[0].lockRoleName, GVG_RESOURCE_TYPE.FOOD, foodSum)||{}; await addResource(myLeague, targetRoleId, resultField[0].lockRoleName, GVG_RESOURCE_TYPE.FOOD, foodSum)||{};
await sendMailByContent(MAIL_TYPE.HELP_HARVEST, targetRoleId, { sendName: roleName, goods: rewardSum }); await sendMailByContent(MAIL_TYPE.HELP_HARVEST, targetRoleId, { sendName: roleName, goods: rewardSum });
// 相关物品 // 相关物品
await addGVGReward(targetRoleId, roleName, myLeague.leagueCode, targetOnlineInfo.sid, leagueRewardSum, [], ITEM_CHANGE_REASON.HARVEST) await addGVGReward(targetRoleId, roleName, myLeague.leagueCode, targetOnlineInfo.sid, leagueRewardSum, [], ITEM_CHANGE_REASON.HARVEST)
@@ -368,7 +368,7 @@ export class GVGProduceHandler {
let { reward, leagueReward, leagueConsume } = dicGVGItem; let { reward, leagueReward, leagueConsume } = dicGVGItem;
let produceCoin = getProduceCoinCnt(leagueConsume); let produceCoin = getProduceCoinCnt(leagueConsume);
// 资源 // 资源
let resourceResult = await addResource(myLeague.leagueCode, roleId, roleName, GVG_RESOURCE_TYPE.MINERAL, output)||{}; let resourceResult = await addResource(myLeague, roleId, roleName, GVG_RESOURCE_TYPE.MINERAL, output)||{};
// 相关物品 // 相关物品
let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST) let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST)
// 活跃 // 活跃
@@ -489,7 +489,7 @@ export class GVGProduceHandler {
let { reward, leagueReward, leagueConsume } = dicGVGItem; let { reward, leagueReward, leagueConsume } = dicGVGItem;
let produceCoin = getProduceCoinCnt(leagueConsume); let produceCoin = getProduceCoinCnt(leagueConsume);
// 资源 // 资源
let resourceResult = await addResource(myLeague.leagueCode, roleId, roleName, GVG_RESOURCE_TYPE.WOOD, output)||{}; let resourceResult = await addResource(myLeague, roleId, roleName, GVG_RESOURCE_TYPE.WOOD, output)||{};
// 相关物品 // 相关物品
let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST) let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, reward, ITEM_CHANGE_REASON.HARVEST)
// 活跃 // 活跃
@@ -514,7 +514,7 @@ export class GVGProduceHandler {
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode); let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST); if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
let resourceResult = await addResource(myLeague.leagueCode, roleId, roleName, type, count); let resourceResult = await addResource(myLeague, roleId, roleName, type, count);
if(!resourceResult) return resResult(STATUS.WRONG_PARMS); if(!resourceResult) return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS, resourceResult); return resResult(STATUS.SUCCESS, resourceResult);
+25 -5
View File
@@ -18,6 +18,7 @@ import { comBtlLvInvalid } from './comBattleService';
import { gameData } from '../pubUtils/data'; import { gameData } from '../pubUtils/data';
import { RegionModel } from '../db/Region'; import { RegionModel } from '../db/Region';
import { getGroupIdOfServer, getServersByGroupId } from './gvg/gvgService'; import { getGroupIdOfServer, getServersByGroupId } from './gvg/gvgService';
import { GVGLeagueModel } from '../db/GVGLeague';
export * from './chatChannelService'; export * from './chatChannelService';
export * from './sysChatService'; export * from './sysChatService';
@@ -75,8 +76,8 @@ async function createPrivateMsgData(roleId: string, roleName: string, type: numb
/** /**
* @description 生成群聊消息数据 * @description 生成群聊消息数据
*/ */
async function createGroupMsgData(roleId: string, roleName: string, channel: string, channelId: string, type: number, source: number, content: string, targetRoleId: string, targetMsgCode: string) { async function createGroupMsgData(roleId: string, roleName: string, channel: string, channelId: string, type: number, source: number, content: string, targetRoleId: string, targetMsgCode: string, otherInfo = '') {
const result: GroupMessageParam = {roleId, roleName, channel, channelId, type, source, content, targetRoleId, targetMsgCode}; const result: GroupMessageParam = {roleId, roleName, channel, channelId, type, source, content, targetRoleId, targetMsgCode, otherInfo };
result.roomId = groupRoomId(channel, channelId); result.roomId = groupRoomId(channel, channelId);
await setupBaseMsgParm(result); await setupBaseMsgParm(result);
return result; return result;
@@ -120,8 +121,8 @@ export async function createPrivateMsg(roleId: string, roleName: string, type: n
* @param {string} targetMsgCode * @param {string} targetMsgCode
* @returns * @returns
*/ */
export async function createGroupMsg(roleId: string, roleName: string, channel: string, channelId: string, type: number, source: number, content: string, targetRoleId: string, targetMsgCode: string) { export async function createGroupMsg(roleId: string, roleName: string, channel: string, channelId: string, type: number, source: number, content: string, targetRoleId: string, targetMsgCode: string, otherInfo = '') {
const msgData: GroupMessageParam = await createGroupMsgData(roleId, roleName, channel, channelId, type, source, content, targetRoleId, targetMsgCode); const msgData: GroupMessageParam = await createGroupMsgData(roleId, roleName, channel, channelId, type, source, content, targetRoleId, targetMsgCode, otherInfo);
const result: GroupMessageType = await GroupMessageModel.createMsg(msgData); const result: GroupMessageType = await GroupMessageModel.createMsg(msgData);
return result; return result;
} }
@@ -170,6 +171,11 @@ export async function pushGroupMsgToRoom(msg: GroupMessageType) {
for(let serverId of serverIds) { for(let serverId of serverIds) {
await sendMessageToServerWithSuc(serverId, PUSH_ROUTE.GROUP_MSG, { ...msg, roleInfo }); await sendMessageToServerWithSuc(serverId, PUSH_ROUTE.GROUP_MSG, { ...msg, roleInfo });
} }
} else if (msg.channel == CHANNEL_PREFIX.LEAGUE) {
let guildCodes = msg.otherInfo? msg.otherInfo.split('|'): [];
for(let guildCode of guildCodes) {
await sendMessageToGuildWithSuc(guildCode, PUSH_ROUTE.GROUP_MSG, { ...msg, roleInfo });
}
} }
} }
@@ -231,7 +237,6 @@ async function recentGroupMsgs(roomId: string, count?: number) {
*/ */
export async function recentServerGroupMsgs(serverId: number, count?: number) { export async function recentServerGroupMsgs(serverId: number, count?: number) {
let groupId = await getGroupIdOfServer(serverId); let groupId = await getGroupIdOfServer(serverId);
console.log('####', groupId);
const result = await recentGroupMsgs(groupRoomId(CHANNEL_PREFIX.GVG, groupId), count); const result = await recentGroupMsgs(groupRoomId(CHANNEL_PREFIX.GVG, groupId), count);
return result; return result;
} }
@@ -273,6 +278,21 @@ export async function recentGuildMsgs(guildCode: string, count?: number) {
return result; return result;
} }
/**
* @description 获取最近的联军聊天消息
* @export
* @param {string} guildCode 用区服编号做房间标识
* @param {number} [count]
* @returns
*/
export async function recentLeagueMsgs(guildCode: string, count?: number) {
if(!guildCode) return [];
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
if(!myLeague) return [];
const result = await recentGroupMsgs(groupRoomId(CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode), count);
return result;
}
/** /**
* @description 创建新的私聊记录 * @description 创建新的私聊记录
* @param {boolean} sender 给发送者还是接收者创建,发送者发消息的时候也阅读了消息 * @param {boolean} sender 给发送者还是接收者创建,发送者发消息的时候也阅读了消息
+3 -2
View File
@@ -2,7 +2,7 @@
* entry触发后引起的下发 * entry触发后引起的下发
*/ */
import { getMails } from './mailService'; import { getMails } from './mailService';
import { recentGuildMsgs, recentPrivateChatInfos, recentServerGroupMsgs, recentSysMsgs, recentWorldMsgs } from './chatService'; import { recentGuildMsgs, recentLeagueMsgs, recentPrivateChatInfos, recentServerGroupMsgs, recentSysMsgs, recentWorldMsgs } from './chatService';
import { getCurTask, getPvpTask } from './task/taskService'; import { getCurTask, getPvpTask } from './task/taskService';
import { RoleType } from '../db/Role'; import { RoleType } from '../db/Role';
@@ -204,8 +204,9 @@ export async function getModuleData(type: string, data: { role: RoleType, sessio
const sysMsgs = await recentSysMsgs(serverId); const sysMsgs = await recentSysMsgs(serverId);
const guildMsgs = await recentGuildMsgs(guildCode); const guildMsgs = await recentGuildMsgs(guildCode);
const gvgMsgs = await recentServerGroupMsgs(serverId); const gvgMsgs = await recentServerGroupMsgs(serverId);
const leagueMsgs = await recentLeagueMsgs(guildCode);
const recentPrivateChats = await recentPrivateChatInfos(roleId, roleName); const recentPrivateChats = await recentPrivateChatInfos(roleId, roleName);
return { worldMsgs, sysMsgs, guildMsgs, gvgMsgs, recentPrivateChats }; return { worldMsgs, sysMsgs, guildMsgs, gvgMsgs, leagueMsgs, recentPrivateChats };
case 'event': case 'event':
return await getEvent(role.eventStatus, roleId, roleName); return await getEvent(role.eventStatus, roleId, roleName);
case 'battle': case 'battle':
@@ -1,5 +1,5 @@
import { GVGTeamMem } from "../../domain/battleField/gvgBattle"; import { GVGTeamMem } from "../../domain/battleField/gvgBattle";
import { GVGLeagueType } from "../../db/GVGLeague"; import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague";
import { GVGTeamModel, GVGTeamType, GVGTeamUpdate } from "../../db/GVGTeam"; import { GVGTeamModel, GVGTeamType, GVGTeamUpdate } from "../../db/GVGTeam";
import { GVGCityModel, GVGCityType } from "../../db/GVGCity"; import { GVGCityModel, GVGCityType } from "../../db/GVGCity";
import { gameData, getGVGBattleRankReward } from "../../pubUtils/data"; import { gameData, getGVGBattleRankReward } from "../../pubUtils/data";
@@ -20,6 +20,7 @@ import { findKeys, getAllServerName } from "../redisService";
import { sendMessageToGVGAreaByTeamWithSuc, sendMessageToGVGAreaWithSuc, sendMessageToGVGCityWithSuc } from "../pushService"; import { sendMessageToGVGAreaByTeamWithSuc, sendMessageToGVGAreaWithSuc, sendMessageToGVGCityWithSuc } from "../pushService";
import { sendMailToLeagueByContent } from "../mailService"; import { sendMailToLeagueByContent } from "../mailService";
import { GVGCityAreaPointModel } from "../../db/GVGCityAreaPoint"; import { GVGCityAreaPointModel } from "../../db/GVGCityAreaPoint";
import { addCityGuardMessage } from "./gvgRecService";
/** /**
@@ -380,7 +381,9 @@ export async function gvgBattleEnd() {
if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) {
await GVGCityModel.guardCity(configId, groupKey, cityId, rankInfo); await GVGCityModel.guardCity(configId, groupKey, cityId, rankInfo);
let dicCityAdd = gameData.gvgCityAdd.get(dicCity.cityType); let dicCityAdd = gameData.gvgCityAdd.get(dicCity.cityType);
await sendMailToLeagueByContent(MAIL_TYPE.GVG_GUARD_CITY_REWARD, rankInfo.code, { params: [dicCity.cityName], goods: dicCityAdd.occupyReward }); let league = await GVGLeagueModel.findByCodeWithoutPopulate(rankInfo.code);
await sendMailToLeagueByContent(MAIL_TYPE.GVG_GUARD_CITY_REWARD, rankInfo.code, { params: [dicCity.cityName], goods: dicCityAdd.occupyReward }, league);
await addCityGuardMessage(league, cityId);
guardLeagueCnt.set(rankInfo.code, cnt + 1); guardLeagueCnt.set(rankInfo.code, cnt + 1);
break; break;
} }
@@ -27,8 +27,8 @@ import { getHeroesAttributes } from "../playerCeService";
import { Rank } from "../rankService"; import { Rank } from "../rankService";
import { findKeys, getAllServerName, redisClient } from "../redisService"; import { findKeys, getAllServerName, redisClient } from "../redisService";
import { combinePushItem } from "./gvgItemService"; import { combinePushItem } from "./gvgItemService";
import { addVestigeLeagueRankRec } from "./gvgRecService"; import { addVestigeLeagueRankRec, addVestigeRankMessage } from "./gvgRecService";
import { getGroupIdOfServer, getGroupKey, getGVGServerType } from "./gvgService"; import { getGroupIdOfServer, getGroupKey, getGVGServerType, getPeriodByTime } from "./gvgService";
// 备战期的遗迹和激战期的开始结束战斗时间 // 备战期的遗迹和激战期的开始结束战斗时间
export function getFightTimeByPeriod(period: GVG_PERIOD, time?: number) { export function getFightTimeByPeriod(period: GVG_PERIOD, time?: number) {
@@ -390,6 +390,8 @@ export async function getVestigeRank(redisKey: REDIS_KEY, isSimple: boolean, key
// systimer 服 // systimer 服
export async function saveVestigeRankSchedule() { export async function saveVestigeRankSchedule() {
let config = await GVGConfigModel.findConfig(); let config = await GVGConfigModel.findConfig();
let period = getPeriodByTime(config.teamTime, config.prepareTime, config.battleTime, config.scheduleTime);
if(period != GVG_PERIOD.PREPARE) return;
let day = getDayKeyInfo(); let day = getDayKeyInfo();
let keys = await findKeys(`${REDIS_KEY.GVG_VESTIGE_LEAGUE}:${day}:`); let keys = await findKeys(`${REDIS_KEY.GVG_VESTIGE_LEAGUE}:${day}:`);
for(let key of keys) { for(let key of keys) {
@@ -398,6 +400,7 @@ export async function saveVestigeRankSchedule() {
let ranks = await r.getRankByRangeRaw(); let ranks = await r.getRankByRangeRaw();
await GVGVestigeLeagueRankModel.saveRank(groupKey, ranks); await GVGVestigeLeagueRankModel.saveRank(groupKey, ranks);
await addVestigeLeagueRankRec(config.configId, groupKey, ranks); await addVestigeLeagueRankRec(config.configId, groupKey, ranks);
await addVestigeRankMessage(ranks);
} }
let memberKeys = await findKeys(`${REDIS_KEY.GVG_VESTIGE_MEMBER_ALL}:${day}:`); let memberKeys = await findKeys(`${REDIS_KEY.GVG_VESTIGE_MEMBER_ALL}:${day}:`);
@@ -416,14 +419,14 @@ export function calVestigeLeagueBoxRewards(canReceiveRanks: GVGVestigeLeagueRank
for(let { rank } of canReceiveRanks) { for(let { rank } of canReceiveRanks) {
let dicRank = getGVGVestigeLeagueRank(rank); let dicRank = getGVGVestigeLeagueRank(rank);
if(!dicRank) { console.error('dic_zyz_GVGVestigeLeagueRank error'); continue; } if(!dicRank) { console.error('dic_zyz_GVGVestigeLeagueRank error'); continue; }
console.log('###### league', rank, dicRank) // console.log('###### league', rank, dicRank)
combinePushItem(rewards, dicRank.rankReward); combinePushItem(rewards, dicRank.rankReward);
combinePushItem(leagueReward, dicRank.rankLeagueReward); combinePushItem(leagueReward, dicRank.rankLeagueReward);
} }
for(let { rank } of canReceivePlayerRanks) { for(let { rank } of canReceivePlayerRanks) {
let dicRank = getGVGVestigePlayerRank(rank); let dicRank = getGVGVestigePlayerRank(rank);
if(!dicRank) { console.error('dic_zyz_GVGVestigPlayerRank error'); continue; } if(!dicRank) { console.error('dic_zyz_GVGVestigPlayerRank error'); continue; }
console.log('###### player', rank, dicRank) // console.log('###### player', rank, dicRank)
combinePushItem(rewards, dicRank.rankPlayerReward); combinePushItem(rewards, dicRank.rankPlayerReward);
combinePushItem(leagueReward, dicRank.rankPlayerLeagueReward); combinePushItem(leagueReward, dicRank.rankPlayerLeagueReward);
} }
@@ -15,7 +15,8 @@ import { addGVGReward } from "./gvgItemService";
import { getGVGConfig } from "./gvgService"; import { getGVGConfig } from "./gvgService";
import { getProduceCoinCnt } from "./gvgItemService"; import { getProduceCoinCnt } from "./gvgItemService";
import { GVGVestigeRankModel } from "../../db/GVGVestigeRank"; import { GVGVestigeRankModel } from "../../db/GVGVestigeRank";
import { addResourceRecord } from "./gvgRecService"; import { addLeagueLvUpMessage, addResourceRecord } from "./gvgRecService";
import { GVGLeagueType } from "../../db/GVGLeague";
export function checkPreTech(techId: number, activeQueue: number[], techQueue: Tech[]) { export function checkPreTech(techId: number, activeQueue: number[], techQueue: Tech[]) {
const dicTech = gameData.gvgTech.get(techId); const dicTech = gameData.gvgTech.get(techId);
@@ -116,7 +117,8 @@ export function getMyContribute(userDailyData: GVGUserDailyDataType, myRanks: {v
* @param count 数量 * @param count 数量
* @returns * @returns
*/ */
export async function addResource(leagueCode: string, roleId: string, roleName: string, resourceType: GVG_RESOURCE_TYPE, count: number) { export async function addResource(myLeague: GVGLeagueType, roleId: string, roleName: string, resourceType: GVG_RESOURCE_TYPE, count: number) {
let { leagueCode } = myLeague;
let { configId } = getGVGConfig(); let { configId } = getGVGConfig();
let resources = getResourceCnt(resourceType, count); let resources = getResourceCnt(resourceType, count);
if(!resources) return false; if(!resources) return false;
@@ -124,6 +126,7 @@ export async function addResource(leagueCode: string, roleId: string, roleName:
// 联军更新资源 // 联军更新资源
let league = await GVGLeaguePrepareModel.addResource(configId, leagueCode, food, mineral, wood); let league = await GVGLeaguePrepareModel.addResource(configId, leagueCode, food, mineral, wood);
let originLv = league?.lv||1;
// 联军升级 // 联军升级
let lv = calLeagueLv(league.resources); let lv = calLeagueLv(league.resources);
league = await GVGLeaguePrepareModel.setLv(configId, leagueCode, lv); league = await GVGLeaguePrepareModel.setLv(configId, leagueCode, lv);
@@ -135,6 +138,7 @@ export async function addResource(leagueCode: string, roleId: string, roleName:
let myContribute = getMyContribute(userDailyData, myRanks); let myContribute = getMyContribute(userDailyData, myRanks);
addResourceRecord(roleId, roleName, leagueCode, resourceType, count); addResourceRecord(roleId, roleName, leagueCode, resourceType, count);
if(lv > originLv) addLeagueLvUpMessage(roleId, roleName, myLeague, lv);
return { resources: league.resources, leagueLv: league.lv, myContribute } return { resources: league.resources, leagueLv: league.lv, myContribute }
} }
+46 -1
View File
@@ -1,12 +1,14 @@
// 动态 // 动态
import { GVG_REC_ID, GVG_REC_TYPE, GVG_RESOURCE_TYPE } from "../../consts"; import { CHANNEL_PREFIX, GVG_REC_ID, GVG_REC_TYPE, GVG_RESOURCE_TYPE, MSG_SOURCE, MSG_TYPE } from "../../consts";
import { GVGBattleRecType } from "../../db/GVGBattleRec"; import { GVGBattleRecType } from "../../db/GVGBattleRec";
import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague";
import { GVGRecModel } from "../../db/GVGRec"; import { GVGRecModel } from "../../db/GVGRec";
import { GVGTeamType } from "../../db/GVGTeam"; import { GVGTeamType } from "../../db/GVGTeam";
import { GVGVestigeRecType } from "../../db/GVGVestigeRec"; import { GVGVestigeRecType } from "../../db/GVGVestigeRec";
import { gameData } from "../../pubUtils/data"; import { gameData } from "../../pubUtils/data";
import { nowSeconds } from "../../pubUtils/timeUtil"; import { nowSeconds } from "../../pubUtils/timeUtil";
import { createGroupMsg, pushGroupMsgToRoom } from "../chatService";
import { getGVGConfig } from "./gvgService"; import { getGVGConfig } from "./gvgService";
// 加入军团 // 加入军团
@@ -115,3 +117,46 @@ export async function addTeamLeaveRec(team: GVGTeamType, pointId: number) {
let { roleId, roleName, leagueCode, configId, cityId, groupKey } = team; let { roleId, roleName, leagueCode, configId, cityId, groupKey } = team;
await GVGRecModel.addRec({ roleId, leagueCode, configId, cityId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_LEAGUE, recId: GVG_REC_ID.LEAGUE_TEAM_LEAVE, createTime: nowSeconds(), params: [`${roleName}`, getPointName(pointId)] }); await GVGRecModel.addRec({ roleId, leagueCode, configId, cityId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_LEAGUE, recId: GVG_REC_ID.LEAGUE_TEAM_LEAVE, createTime: nowSeconds(), params: [`${roleName}`, getPointName(pointId)] });
} }
// —————— 频道消息 ——————
export async function addLeagueLvUpMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, lv: number) {
const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_LV_UP, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, lv }), '', '', getGuildCodeString(myLeague));
await pushGroupMsgToRoom(msgData);
}
export async function changeNoticeMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, notice: string) {
const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.GVG, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_NOTICE, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, notice }), '', '', getGuildCodeString(myLeague));
await pushGroupMsgToRoom(msgData);
}
export function getGuildCodeString(myLeague: GVGLeagueType) {
let guildCodes = myLeague?.guildCodes||[];
return guildCodes.join('|')
}
export async function addTechActivateMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, techId: number) {
const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_LV_UP, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, techId }), '', '', getGuildCodeString(myLeague));
await pushGroupMsgToRoom(msgData);
}
export async function addTechUnlockMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, techId: number) {
const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_LV_UP, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, techId }), '', '', getGuildCodeString(myLeague));
await pushGroupMsgToRoom(msgData);
}
export async function addVestigeRankMessage(ranks: { rank: number, field: string }[]) {
let leagueCodes = ranks.map(cur => cur.field);
let leagues = await GVGLeagueModel.findByCodesWithoutPopulate(leagueCodes, 'leagueCode name guildCodes');
for(let { rank, field: leagueCode } of ranks) {
let league = leagues.find(cur => cur.leagueCode == leagueCode);
if(!league) continue;
const msgData = await createGroupMsg('', '', CHANNEL_PREFIX.LEAGUE, leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_LV_UP, JSON.stringify({ leagueCode: league.leagueCode, name: league.name, rank }), '', '', getGuildCodeString(league));
await pushGroupMsgToRoom(msgData);
}
}
export async function addCityGuardMessage(myLeague: GVGLeagueType, cityId: number) {
const msgData = await createGroupMsg('', '', CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_LV_UP, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, cityId }), '', '', getGuildCodeString(myLeague));
await pushGroupMsgToRoom(msgData);
}
@@ -148,6 +148,10 @@ export function getGVGPeriodData() {
export function getCurPeriod() { export function getCurPeriod() {
let { teamTime, prepareTime, battleTime, scheduleTime } = getGVGConfig(); 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(); let now = nowSeconds();
if(now >= teamTime && now < prepareTime) { if(now >= teamTime && now < prepareTime) {
return GVG_PERIOD.TEAM; return GVG_PERIOD.TEAM;
+9
View File
@@ -26,6 +26,7 @@ export const CHANNEL_PREFIX = {
GVG_AREAS: 'gvgAreas', // 大地图界面 GVG_AREAS: 'gvgAreas', // 大地图界面
GVG_AREA_BY_TEAM: 'gvgTeam', // 选中玩家队伍后加入频道 GVG_AREA_BY_TEAM: 'gvgTeam', // 选中玩家队伍后加入频道
GVG_CITY: 'gvgCity', // 玩家进入城池 GVG_CITY: 'gvgCity', // 玩家进入城池
LEAGUE: 'league', // 联军
} }
export const getChannelType = function(prefix: string) { export const getChannelType = function(prefix: string) {
@@ -42,6 +43,8 @@ export const getChannelType = function(prefix: string) {
return 5; return 5;
case CHANNEL_PREFIX.GVG: case CHANNEL_PREFIX.GVG:
return 6; return 6;
case CHANNEL_PREFIX.LEAGUE:
return 7;
} }
} }
@@ -90,6 +93,12 @@ export const MSG_SOURCE = {
LADDER_FIRST_CHANGE: 27, LADDER_FIRST_CHANGE: 27,
GET_UR_HERO: 28, GET_UR_HERO: 28,
GVG_RECURIT: 29, GVG_RECURIT: 29,
GVG_LV_UP: 30,
GVG_NOTICE: 31,
GVG_TECH_ACTIVATE: 32,
GVG_TECH_UNLOCK: 33,
GVG_VESTIGE_ACCOUNT: 34,
GVG_OCCUPY_CITY: 35,
} }
export const DEFAULT_MSG_PER_PAGE = 10; export const DEFAULT_MSG_PER_PAGE = 10;
+1
View File
@@ -344,6 +344,7 @@ export const STATUS = {
GVG_USER_NOT_IN_CITY: { code: 21338, simStr: '您不在该城池中' }, GVG_USER_NOT_IN_CITY: { code: 21338, simStr: '您不在该城池中' },
GVG_NOT_BATTLE_PERIOD: { code: 21339, simStr: '您只能在激战期进行此操作' }, GVG_NOT_BATTLE_PERIOD: { code: 21339, simStr: '您只能在激战期进行此操作' },
GVG_FIELD_HAS_PLANT: { code: 21340, simStr: '该田已种植' }, GVG_FIELD_HAS_PLANT: { code: 21340, simStr: '该田已种植' },
GVG_NOT_JOIN_LEAGUE: { code: 21341, simStr: '您未加入联军' },
// GVG征战中原 // GVG征战中原
GVG_VESTIGE_ERR: { code: 21350, simStr: '今日未开放该遗迹' }, GVG_VESTIGE_ERR: { code: 21350, simStr: '今日未开放该遗迹' },
+5
View File
@@ -120,6 +120,11 @@ export default class GVGLeague extends BaseModel {
return leagues return leagues
} }
public static async findByCodesWithoutPopulate(leagueCodes: string[], select = '') {
const leagues: GVGLeagueType[] = await GVGLeagueModel.find({ leagueCode: { $in: leagueCodes }, status: 1 }).select(select).lean();
return leagues
}
public static async joinGuild(leagueCode: string, guild: GuildType) { public static async joinGuild(leagueCode: string, guild: GuildType) {
const { code, memberCnt, leader, members } = guild; const { code, memberCnt, leader, members } = guild;
let _leader = <RoleType>leader; let _leader = <RoleType>leader;
+6 -1
View File
@@ -49,7 +49,12 @@ export default class GVGRec extends BaseModel {
// 查询城池战报 // 查询城池战报
public static async findBattleRecByCity(configId: number, groupKey: string, cityId: number) { public static async findBattleRecByCity(configId: number, groupKey: string, cityId: number) {
const result: GVGRecType[] = await GVGRecModel.find({ cityId, configId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_CITY }, { _id: 0, recId: 1, params: 1, createTime: 1 }).sort({ createTime: -1 }).limit(50).lean(); const result: GVGRecType[] = await GVGRecModel.find({ configId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_CITY, cityId }, { _id: 0, recId: 1, params: 1, createTime: 1 }).sort({ createTime: -1 }).limit(50).lean();
return result;
}
public static async findBattleRecByGroup(configId: number, groupKey: string) {
const result: GVGRecType[] = await GVGRecModel.find({ configId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_CITY }, { _id: 0, recId: 1, params: 1, createTime: 1 }).sort({ createTime: -1 }).limit(50).lean();
return result; return result;
} }
+3
View File
@@ -42,6 +42,9 @@ export default class GroupMessage extends BaseModel {
@prop({ required: true, default: '' }) @prop({ required: true, default: '' })
content: string; // 消息内容 content: string; // 消息内容
@prop({ required: true, default: '' })
otherInfo: string; // 其他信息
public static async createMsg(data: GroupMessageParam) { public static async createMsg(data: GroupMessageParam) {
const result = await GroupMessageModel.findOneAndUpdate({ msgCode: data.msgCode }, {...data}, {upsert: true, new: true}).lean(); const result = await GroupMessageModel.findOneAndUpdate({ msgCode: data.msgCode }, {...data}, {upsert: true, new: true}).lean();
return result; return result;
+2 -2
View File
@@ -14,7 +14,7 @@
{ {
"periodType": 3, "periodType": 3,
"day": "6&", "day": "6&",
"startTime": "20:55:00", "startTime": "17:00:00",
"endTime": "23:00:00" "endTime": "20:00:00"
} }
] ]
+67 -7
View File
@@ -3,7 +3,7 @@
"id": 0, "id": 0,
"name": "ROLE_SEND_TEXT", "name": "ROLE_SEND_TEXT",
"mean": "玩家发送消息", "mean": "玩家发送消息",
"type": "2&3&4&5", "type": "2&3&4&5&6&7",
"template": "<color=#e6a0fb>%d</color>", "template": "<color=#e6a0fb>%d</color>",
"worldchat": "<color=#e6a0fb>%d</color>", "worldchat": "<color=#e6a0fb>%d</color>",
"bubble": "<outline color=#1c1613 width=2><color=#e6a0fb>%d</color></outline>", "bubble": "<outline color=#1c1613 width=2><color=#e6a0fb>%d</color></outline>",
@@ -74,9 +74,9 @@
"name": "GUILD_STRUCTURE_LV_UP", "name": "GUILD_STRUCTURE_LV_UP",
"mean": "军团升级建筑", "mean": "军团升级建筑",
"type": "3&", "type": "3&",
"template": "<color=#2e190a>恭喜主公,军团</color><color=#e36c31>%d</color><color=#2e190a>已升至</color><color=#cf7515>%d</color><color=#2e190a>级</color>", "template": "<color=#2e190a>恭喜百家传人,军团</color><color=#e36c31>%d</color><color=#2e190a>已升至</color><color=#cf7515>%d</color><color=#2e190a>级</color>",
"worldchat": "<color=#faf3e0>恭喜各位小主公,军团</color><color=#d57e54>%d</color><color=#faf3e0>已升至</color><color=#ffc600>%d</color><color=#faf3e0>级</color>", "worldchat": "<color=#faf3e0>恭喜各位百家传人,军团</color><color=#d57e54>%d</color><color=#faf3e0>已升至</color><color=#ffc600>%d</color><color=#faf3e0>级</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>恭喜各位小主公,军团</color><color=#d57e54>%d</color><color=#faf3e0>已升至</color><color=#ffc600>%d</color><color=#faf3e0>级</color></outline>", "bubble": "<outline color=#1c1613 width=2><color=#faf3e0>恭喜各位百家传人,军团</color><color=#d57e54>%d</color><color=#faf3e0>已升至</color><color=#ffc600>%d</color><color=#faf3e0>级</color></outline>",
"comments": "1:%d(军团名);2:%d(军团升级后的等级数)" "comments": "1:%d(军团名);2:%d(军团升级后的等级数)"
}, },
{ {
@@ -94,9 +94,9 @@
"name": "GUILD_BOSS_SUC", "name": "GUILD_BOSS_SUC",
"mean": "军团BOSS胜利", "mean": "军团BOSS胜利",
"type": "3&", "type": "3&",
"template": "<color=#2e190a>恭喜主公,军团BOSS</color><color=#e36c31>%d</color><color=#2e190a>被成功压制,海量拍品已加入拍卖行</color>", "template": "<color=#2e190a>恭喜百家传人,军团BOSS</color><color=#e36c31>%d</color><color=#2e190a>被成功压制,海量拍品已加入拍卖行</color>",
"worldchat": "<color=#faf3e0>恭喜各位小主公,军团BOSS</color><color=#d57e53>%d</color><color=#faf3e0>被成功压制,海量拍品已加入拍卖行</color>", "worldchat": "<color=#faf3e0>恭喜各位百家传人,军团BOSS</color><color=#d57e53>%d</color><color=#faf3e0>被成功压制,海量拍品已加入拍卖行</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>恭喜各位小主公,军团BOSS</color><color=#d57e53>%d</color><color=#faf3e0>被成功压制,拍卖行即将开启</color></outline>", "bubble": "<outline color=#1c1613 width=2><color=#faf3e0>恭喜各位百家传人,军团BOSS</color><color=#d57e53>%d</color><color=#faf3e0>被成功压制,拍卖行即将开启</color></outline>",
"comments": "1:%d(BOSS名)" "comments": "1:%d(BOSS名)"
}, },
{ {
@@ -298,5 +298,65 @@
"worldchat": "<color=#3bbb7e>%d</color><color=#2e190a>正在扩充兵马:%d,欢迎各军团加入建设</color><color=#308909>", "worldchat": "<color=#3bbb7e>%d</color><color=#2e190a>正在扩充兵马:%d,欢迎各军团加入建设</color><color=#308909>",
"bubble": "<outline color=#1c1613 width=2><color=#7feebd>%d</color><color=#faf3e0>正在扩充兵马:%d,欢迎各军团加入建设</color></outline>", "bubble": "<outline color=#1c1613 width=2><color=#7feebd>%d</color><color=#faf3e0>正在扩充兵马:%d,欢迎各军团加入建设</color></outline>",
"comments": "1:%d(联军名);2:%d(联军招募内容)" "comments": "1:%d(联军名);2:%d(联军招募内容)"
},
{
"id": 30,
"name": "GVG_LV_UP",
"mean": "联军升级",
"type": "7&",
"template": "<color=#2e190a>恭喜百家传人,联军</color><color=#e36c31>%d</color><color=#2e190a>已升至</color><color=#cf7515>%d</color><color=#2e190a>级</color>",
"worldchat": "<color=#faf3e0>恭喜各位百家传人,联军</color><color=#d57e54>%d</color><color=#faf3e0>已升至</color><color=#ffc600>%d</color><color=#faf3e0>级</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>恭喜各位百家传人,联军</color><color=#d57e54>%d</color><color=#faf3e0>已升至</color><color=#ffc600>%d</color><color=#faf3e0>级</color></outline>",
"comments": "1:%d(联军名);2:%d(联军升级后的等级数)"
},
{
"id": 31,
"name": "GVG_NOTICE",
"mean": "联军修改公告",
"type": "7&",
"template": "<color=#2e190a>公告:%d</color>",
"worldchat": "<color=#faf3e0>公告:%d</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>公告:%d</color></outline>",
"comments": "%d:玩家发送的消息内容"
},
{
"id": 32,
"name": "GVG_TECH_ACTIVATE",
"mean": "联军千机阁激活",
"type": "7&",
"template": "<color=#2e190a>恭喜百家传人,联军</color><color=#e36c31>%d</color><color=#2e190a>已成功激活千机阁</color><color=#cf7515>%d</color><color=#2e190a>神机</color>",
"worldchat": "<color=#faf3e0>恭喜各位百家传人,联军</color><color=#d57e54>%d</color><color=#faf3e0>已成功激活千机阁</color><color=#cf7515>%d</color><color=#faf3e0>神机:%d</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>恭喜各位百家传人,联军</color><color=#d57e54>%d</color><color=#faf3e0>已成功激活千机阁</color><color=#ffc600>%d</color><color=#faf3e0>神机</color></outline>",
"comments": "1:%d(联军名);2:%d(激活的神机名); 3:%d(激活的神机内容)"
},
{
"id": 33,
"name": "GVG_TECH_UNLOCK",
"mean": "联军千机阁解锁",
"type": "7&",
"template": "<color=#2e190a>各位百家传人,联军管理</color><color=#e36c31>%d</color><color=#2e190a>已解锁千机阁</color><color=#cf7515>%d</color><color=#2e190a>神机,可进行捐献激活</color>",
"worldchat": "<color=#faf3e0>各位百家传人,联军管理</color><color=#d57e54>%d</color><color=#faf3e0>已解锁千机阁</color><color=#cf7515>%d</color><color=#faf3e0>神机,可进行捐献激活</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>各位百家传人,</color><color=#d57e54>%d</color><color=#faf3e0>神机已解锁</color></outline>",
"comments": "1:%d(激活的神机名)"
},
{
"id": 34,
"name": "GVG_VESTIGE_ACCOUNT",
"mean": "联军遗迹每日22:00结算",
"type": "7&",
"template": "<color=#2e190a>各位百家传人,联军</color><color=#e36c31>%d</color><color=#2e190a>今日遗迹驻扎排名:</color><color=#cf7515>%d</color><color=#2e190a>,奖励已发送至遗迹奖励宝箱</color>",
"worldchat": "<color=#faf3e0>各位百家传人,联军</color><color=#d57e54>%d</color><color=#faf3e0>今日遗迹驻扎排名:</color><color=#cf7515>%d</color><color=#faf3e0>,奖励已发送至遗迹奖励宝箱</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>各位百家传人,联军</color><color=#d57e54>%d</color><color=#faf3e0>今日遗迹驻扎排名:</color><color=#ffc600>%d</color>",
"comments": "1:%d(联军名);2:%d(第X名/未上榜)"
},
{
"id": 35,
"name": "GVG_OCCUPY_CITY",
"mean": "联军城池占领",
"type": "6&7&",
"template": "<color=#2e190a>联军</color><color=#e36c31>%d</color><color=#2e190a>上下一心,成功占领</color><color=#cf7515>%d</color>",
"worldchat": "<color=#faf3e0>联军</color><color=#d57e54>%d</color><color=#faf3e0>上下一心,成功占领</color><color=#cf7515>%d</color>",
"bubble": "<outline color=#1c1613 width=2><color=#faf3e0>联军</color><color=#d57e54>%d</color><color=#faf3e0>上下一心,成功占领</color><color=#ffc600>%d</color>",
"comments": "1:%d(联军名);2:%d(城池名)"
} }
] ]