262 lines
12 KiB
TypeScript
262 lines
12 KiB
TypeScript
import { Channel, pinus } from "pinus";
|
||
import { CHANNEL_PREFIX, PUSH_BATCH, PUSH_INTERVAL, PUSH_ROUTE, STATUS } from "../consts";
|
||
import { genCode, resResult } from "../pubUtils/util";
|
||
import { getCityChannelSid, getGuildChannelSid, getWorldChannelSid, groupRoomId, getGroupShopSid, getGVGAreaChannelSid, getGVGAreaTeamChannelSid, getGVGCityTeamChannelSid } from "./chatService";
|
||
import { getAllOnlineRoles, getAllServers, getRoleOnlineInfo } from "./redisService";
|
||
import { errlogger, infologger } from '../util/logger';
|
||
import { MsgEncrypt } from "../pubUtils/sysUtil";
|
||
import { isSkipEncode } from "../pubUtils/sdkUtil";
|
||
import { isDevelopEnv } from "./utilService";
|
||
|
||
export async function sendMessageToAllWithSuc(route: string, data: any, filterCb?: ({ lv, topLineupCe }) => boolean) {
|
||
await sendMessageToAll(route, resResult(STATUS.SUCCESS, data), filterCb);
|
||
}
|
||
|
||
export async function sendMessageToAll(route: string, data: any, filterCb?: ({ lv, topLineupCe }) => boolean) {
|
||
let allOnlineUsers = await getAllOnlineRoles();
|
||
if(filterCb) {
|
||
allOnlineUsers = allOnlineUsers.filter(filterCb);
|
||
}
|
||
let n = Math.ceil(allOnlineUsers.length / PUSH_BATCH); // 一共多少批
|
||
let sendToUser = (i: number) => {
|
||
let users = allOnlineUsers.slice(i * PUSH_BATCH, (i + 1) * PUSH_BATCH - 1);
|
||
let uids = users.map(cur => ({ uid: cur.roleId, sid: cur.sid }));
|
||
sendMessageToUsers(route, data, uids);
|
||
}
|
||
let i = -1;
|
||
sendToUser(++i);
|
||
let interval = setInterval(() => {
|
||
if (++i < n) {
|
||
sendToUser(i);
|
||
} else {
|
||
clearInterval(interval);
|
||
}
|
||
}, PUSH_INTERVAL);
|
||
}
|
||
|
||
export async function sendMessageToAllServersWithSuc(route: string, data: any) {
|
||
let servers = await getAllServers();
|
||
for(let serverId of servers) {
|
||
await sendMessageToServerWithSuc(serverId, route, data);
|
||
}
|
||
}
|
||
|
||
export async function sendMessageToServerWithSuc(serverId: number, route: string, data: any, isBatch = false) {
|
||
await sendMessageToServer(serverId, route, resResult(STATUS.SUCCESS, data), isBatch);
|
||
}
|
||
|
||
export async function sendMessageToServer(serverId: number, route: string, data: any, isBatch = false) {
|
||
let channelSid = await getWorldChannelSid(serverId);
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, data, isBatch);
|
||
}
|
||
|
||
export async function sendMessageToGuildWithSuc(guildCode: string, route: string, data: any) {
|
||
await sendMessageToGuild(guildCode, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
export async function sendMessageToGuild(guildCode: string, route: string, data: any) {
|
||
let channelSid = await getGuildChannelSid(guildCode);
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.GUILD, guildCode);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, data);
|
||
}
|
||
|
||
export async function sendMessageToGVGAreaWithSuc(groupKey: string, areaId: number, route: string, data: any) {
|
||
let channelSid = await getGVGAreaChannelSid(groupKey, areaId);
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, `${groupKey}_${areaId}`);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
export async function sendMessageToGVGAreaByTeamWithSuc(groupKey: string, areaId: number, route: string, data: any) {
|
||
let channelSid = await getGVGAreaTeamChannelSid(groupKey, areaId);
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, `${groupKey}_${areaId}`);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
export async function sendMessageToGVGCityWithSuc(groupKey: string, cityId: number, route: string, data: any) {
|
||
let channelSid = await getGVGCityTeamChannelSid(groupKey, cityId);
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.GVG_CITY, `${groupKey}_${cityId}`);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
export async function sendMessageToCityWithSuc(serverId: number, cityId: number, route: string, data: any) {
|
||
await sendMessageToCity(serverId, cityId, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
export async function sendMessageToCity(serverId: number, cityId: number, route: string, data: any) {
|
||
let channelSid = await getCityChannelSid(serverId, cityId);
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.CITY, `${serverId}_${cityId}`);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, data);
|
||
}
|
||
|
||
export async function sendMessageToGroupShopWithSuc(route: string, data: any) {
|
||
let channelSid = await getGroupShopSid();
|
||
let roomId = groupRoomId(CHANNEL_PREFIX.GROUP_SHOP);
|
||
await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
export async function sendMessageToUserWithSuc(roleId: string, route: string, data: any, sid?: string) {
|
||
await sendMessageToUser(roleId, route, resResult(STATUS.SUCCESS, data), sid);
|
||
}
|
||
|
||
export async function sendMessageToUser(roleId: string, route: string, data: any, sid?: string) {
|
||
let uids = [];
|
||
if (!sid) {
|
||
let onlineUser = await getRoleOnlineInfo(roleId);
|
||
sid = onlineUser.sid;
|
||
}
|
||
if (!!sid) {
|
||
uids.push({ uid: roleId, sid });
|
||
sendMessageToUsers(route, data, uids);
|
||
}
|
||
}
|
||
|
||
export async function sendMessageToUsersWithSuc(route: string, data: any, uids: { uid: string, sid: string }[]) {
|
||
await sendMessageToUsers(route, resResult(STATUS.SUCCESS, data), uids);
|
||
}
|
||
|
||
// 推送给个人的方法收束于这个函数
|
||
export async function sendMessageToUsers(route: string, data: any, uids: { uid: string, sid: string }[]) {
|
||
if(uids.length > 0) {
|
||
pinus.app.get('channelService').pushMessageByUids(route, encryptMsg(route, data), uids);
|
||
infologger.debug(`pushMessage route: ${route} data: ${JSON.stringify(data)} members: ${uids.map(obj => obj.uid).join()}`);
|
||
}
|
||
}
|
||
|
||
export async function sendMessageToTeam(teamCode: string, route: string, data: any) {
|
||
const channel = pinus.app.get('channelService').getChannel(teamCode);
|
||
sendMessageToChannel(channel, route, resResult(STATUS.SUCCESS, data));
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param user
|
||
*/
|
||
export function addUserToTeamChannel(teamCode: string, isCreate: boolean, roleId: string, sid: string) {
|
||
let channel = pinus.app.get('channelService').getChannel(teamCode, isCreate);
|
||
addUserToChannel(channel, roleId, sid);
|
||
return channel
|
||
}
|
||
|
||
export function addUserToChannel(channel: Channel, roleId: string, sid: string) {
|
||
const users = channel.getMembers();
|
||
if (users.indexOf(roleId) === -1) {
|
||
channel.add(roleId, sid);
|
||
}
|
||
}
|
||
|
||
export function sendMessgeToChannelByBatch(channel: Channel, route: string, data: any) {
|
||
let members = channel.getMembers();
|
||
if(members.length > PUSH_BATCH) {
|
||
let n = Math.ceil(members.length / PUSH_BATCH); // 一共多少批
|
||
// console.log(n)
|
||
let i = -1;
|
||
let interval = setInterval(() => {
|
||
if (++i < n) {
|
||
let uidlist = members.slice(i * PUSH_BATCH, (i + 1) * PUSH_BATCH - 1);
|
||
let uids: { uid: string, sid: string }[] = [];
|
||
for (let uid of uidlist) {
|
||
uids.push(channel.getMember(uid));
|
||
}
|
||
sendMessageToUsers(route, data, uids);
|
||
} else {
|
||
clearInterval(interval);
|
||
}
|
||
}, PUSH_INTERVAL);
|
||
} else {
|
||
sendMessageToChannel(channel, route, data);
|
||
}
|
||
}
|
||
|
||
// 抽下下来pushMessage收束
|
||
export function sendMessageToChannel(channel: Channel, route: string, data: any) {
|
||
if(channel.getMembers().length <= 0) return;
|
||
channel.pushMessage(route, encryptMsg(route, data));
|
||
infologger.debug(`pushMessage route: ${route} data: ${JSON.stringify(data)} members: ${channel.getMembers().join()}`);
|
||
}
|
||
|
||
export function delTeamChannel(teamCode: string) {
|
||
let channel = pinus.app.get('channelService').getChannel(teamCode);
|
||
if(!!channel) channel.destroy();
|
||
}
|
||
|
||
export function removeFromTeamChannel(teamCode: string, roleId: string) {
|
||
let channel = pinus.app.get('channelService').getChannel(teamCode);
|
||
if(!channel) return null;
|
||
|
||
let users: string[] = channel.getMembers();
|
||
if (users.indexOf(roleId) !== -1) {
|
||
channel.removeMember(roleId);
|
||
}
|
||
}
|
||
|
||
function getKvFromMemory() {
|
||
let aesKey = pinus.app.get('aesKey');
|
||
let aesIV = pinus.app.get('aesIV');
|
||
let originK = pinus.app.get('originK');
|
||
let originV = pinus.app.get('originV');
|
||
let kvRefTime = pinus.app.get('kvRefTime');
|
||
let now = new Date().setMinutes(0, 0, 0);
|
||
if(!kvRefTime || now - kvRefTime >= 60 * 60 * 1000) {
|
||
originK = genCode(24);
|
||
originV = genCode(16);
|
||
let msgEncrypt = new MsgEncrypt({ k: originK, v: originV });
|
||
({ aesKey, aesIV } = msgEncrypt.getEncodeKv());
|
||
|
||
setKvToRemote(originK, originV, aesKey, aesIV, now);
|
||
}
|
||
return { aesKey, aesIV, originK, originV, now }
|
||
}
|
||
|
||
function setKvToRemote(originK: string, originV: string, aesKey: string, aesIV: string, now: number) {
|
||
pinus.app.rpc.activity.activityRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.battle.battleRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.chat.chatRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.connector.connectorRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.guild.guildRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.order.orderRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.role.roleRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
pinus.app.rpc.systimer.systimerRemote.setKvToMemory.broadcast(originK, originV, aesKey, aesIV, now);
|
||
}
|
||
|
||
export function setKvToMemory(originK: string, originV: string, aesKey: string, aesIV: string, now: number) {
|
||
pinus.app.set('originK', originK);
|
||
pinus.app.set('originV', originV);
|
||
pinus.app.set('aesKey', aesKey);
|
||
pinus.app.set('aesIV', aesIV);
|
||
pinus.app.set('kvRefTime', now);
|
||
}
|
||
|
||
function encryptMsg(event: string, json: any) {
|
||
if(checkNotEncryptRoute(event)) return json
|
||
let { aesKey, aesIV, originK, originV } = getKvFromMemory();
|
||
let msgEncrypt = new MsgEncrypt({ originK, originV });
|
||
let data = msgEncrypt.encryptMsg(json);
|
||
return { data, k: aesKey, v: aesIV }
|
||
}
|
||
|
||
function checkNotEncryptRoute(event: string) {
|
||
return isSkipEncode(isDevelopEnv()) || [
|
||
PUSH_ROUTE.PUSH_CURRENT_TIME, // onPushCurrentTime 推送时间
|
||
PUSH_ROUTE.RACE_START, // onRaceStart 粮草先行开始
|
||
PUSH_ROUTE.GUILD_ACTIVITY_END, // onGuildActivityEnd 军团活动结束
|
||
PUSH_ROUTE.GUILD_RACE_UPDATE, // onRaceHorseUpdate 粮草先行状态
|
||
PUSH_ROUTE.GUILD_RACE_EVENT, // onRaceEventUpdate 更新木马事件
|
||
PUSH_ROUTE.TEAMMATE_ACT, // onTeammateAct 寻宝队友行动
|
||
PUSH_ROUTE.CITY_ACT_RANK, // onGuildCityRankUpdate 诸侯混战排行榜
|
||
PUSH_ROUTE.GUILD_CITY_ACT_HP, // onGuildCityGateHpUpdate 诸侯混战城门血条
|
||
PUSH_ROUTE.GUILD_GATE_ACT_HP, // onGuildGateHpUpdate 蛮夷入侵城门血条
|
||
PUSH_ROUTE.GATE_ACT_RANK, // onGuildGateRankUpdate 蛮夷入侵排行榜
|
||
PUSH_ROUTE.BOSS_HP_UPDATE, // onBossHpUpdate 演武台更新
|
||
PUSH_ROUTE.DIVIDEND_UPDATE, // onDividendsUpdate 拍卖行分红更新
|
||
PUSH_ROUTE.AUCTION_OVER, // onAuctionOver 拍卖价格超过
|
||
PUSH_ROUTE.GUILD_BOSS_ENCOURAGE, // onGuildBossEncourage 鼓舞
|
||
PUSH_ROUTE.GVG_TEAM_ATTACKED, // onTeamAttacked 当队伍受到攻击
|
||
PUSH_ROUTE.GVG_AREA_SPINE_CHANGE, // onAreaSpinesChange 可见区域内spine的变动,每隔5秒会下发
|
||
PUSH_ROUTE.GVG_AREA_POINT_CHANGE, // onMyAreaPointChange 积分点上的驻守人变更
|
||
PUSH_ROUTE.GVG_PLAYER_AREA_ADD, // onPlayerAddToArea 积分点上的驻守人变更
|
||
PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, // onPlayerLeaveArea 积分点上的驻守人变更
|
||
PUSH_ROUTE.GVG_CITY_RANK_UPDATE, // onGVGCityRankUpdate 城池积分排名
|
||
PUSH_ROUTE.GVG_SPINE_ATTACKED, // onSpinesAttacked 队伍在地图上受到攻击
|
||
].indexOf(event) != -1
|
||
} |