diff --git a/serverlogic/src/main/java/com/ljsd/jieling/chat/logic/ChatLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/chat/logic/ChatLogic.java index 344f7247a..09cf4edbc 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/chat/logic/ChatLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/chat/logic/ChatLogic.java @@ -12,11 +12,14 @@ import com.ljsd.jieling.exception.ErrorCode; import com.ljsd.jieling.exception.ErrorCodeException; import com.ljsd.jieling.ktbeans.ReportEventEnum; import com.ljsd.jieling.ktbeans.ReportUtil; +import com.ljsd.jieling.logic.GlobleSystemLogic; import com.ljsd.jieling.logic.OnlineUserManager; +import com.ljsd.jieling.logic.activity.crossService.CrossServiceLogic; import com.ljsd.jieling.logic.dao.FriendManager; import com.ljsd.jieling.logic.dao.GuilidManager; import com.ljsd.jieling.logic.dao.PlayerManager; import com.ljsd.jieling.logic.dao.UserManager; +import com.ljsd.jieling.logic.dao.gm.ArenaOfUser; import com.ljsd.jieling.logic.dao.root.User; import com.ljsd.jieling.logic.family.GuildLogic; import com.ljsd.jieling.network.session.ISession; @@ -30,6 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import util.TimeUtils; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -93,6 +97,15 @@ public class ChatLogic { RedisUtil.getInstence().del(GameApplication.serverId + RedisKey.CUser_Chat + uid); } break; + + case 4: + int group = GlobleSystemLogic.getInstence().getCrossGroup(); + if(group==-1){ + throw new ErrorCodeException(ErrorCode.CHAT_NOT_CROSS); + } + chatInfoList = MessageCache.getCrossMsg(messageId,String.valueOf(group)); + + break; default:{ LOGGER.info("getAllChatMessageInfo wrong chatType=>{} uid=>{}", chatType, uid); } @@ -167,6 +180,9 @@ public class ChatLogic { case 3: result = ShieldedWordUtils.checkName(user,message,false,ChatContentType.PRIVATE_CHAT,UserManager.getUser(friendId)); break; + case 4: + result = ShieldedWordUtils.checkName(user,message,false,ChatContentType.CROSS_CHAT); + break; default: break; } @@ -228,6 +244,20 @@ public class ChatLogic { RedisUtil.getInstence().hset(GameApplication.serverId + RedisKey.CUser_Chat + friendId, uid + "#" + nowTime, message, -1); } + break; + + case 4: //跨服 + int group = GlobleSystemLogic.getInstence().getCrossGroup(); + if(group==-1){ + throw new ErrorCodeException(ErrorCode.CHAT_NOT_CROSS); + } + + messageId = RedisUtil.getInstence().increment( RedisKey.CHAT_CROSS_MSG_ID + group); + chatInfo = CBean2Proto.getCrossChatInfoBuilder(user,message,nowTime,messageId); + MessageCache.addCrossMsg(chatInfo,messageId,String.valueOf(group)); + + checkSaveUser(user); + break; default: { break; @@ -238,6 +268,13 @@ public class ChatLogic { MessageUtil.sendMessage(iSession, 1, msgId, null, true); } + private void checkSaveUser(User user) throws Exception { + ArenaOfUser query = CrossServiceLogic.getInstance().query(user.getId()); + if (query == null){ + CrossServiceLogic.getInstance().dispose(user); + } + } + //记录聊天信息 private void onSendChatSuccess(User user,int chatType,String message){ RedisUtil redisUtil = RedisUtil.getInstence(); diff --git a/serverlogic/src/main/java/com/ljsd/jieling/chat/messge/MessageCache.java b/serverlogic/src/main/java/com/ljsd/jieling/chat/messge/MessageCache.java index d57ddd6a5..c24594d81 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/chat/messge/MessageCache.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/chat/messge/MessageCache.java @@ -1,9 +1,17 @@ package com.ljsd.jieling.chat.messge; +import com.google.gson.Gson; +import com.ljsd.jieling.db.redis.RedisKey; +import com.ljsd.jieling.db.redis.RedisUtil; +import org.luaj.vm2.ast.Str; import rpc.protocols.ChatProto; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; public class MessageCache { private static final int capuatiy =200; @@ -13,7 +21,7 @@ public class MessageCache { public static LoopQueue worldMsg = new LoopQueue(capuatiy,perCaught,-1); public static LoopQueue sysMsg = new LoopQueue(capuatiy,perCaught,msgInterval); public static Map guildMsg = new ConcurrentHashMap(); - + private static Gson gson = new Gson(); public static void addWordMsg(ChatProto.ChatInfo chatInfo,long messageId){ worldMsg.push(chatInfo,messageId); @@ -29,4 +37,60 @@ public class MessageCache { guildMsg.get(guildId).push(chatInfo,messageId); } + public static void addCrossMsg(ChatProto.ChatInfo chatInfo,long messageId,String group){ + long index = messageId % capuatiy; + String key = RedisKey.CHAT_CROSS_INFO_CACHE+group; + + RedisUtil.getInstence().hset(key,String.valueOf(index),gson.toJson(chatInfo)); + } + + public static List getCrossMsg(long messageId,String group){ + String key = RedisKey.CHAT_CROSS_INFO_CACHE+group; + Map map = new HashMap<>(); + Map collect = RedisUtil.getInstence().hmget(key); + collect.entrySet().forEach(o -> map.put(Integer.parseInt(o.getKey().toString()), + gson.fromJson(o.getValue().toString(),ChatProto.ChatInfo.class))); + List objs = new ArrayList<>(); + Object obj = RedisUtil.getInstence().get(RedisKey.CHAT_CROSS_MSG_ID + group); + if(obj==null){ + return objs; + } + int writeIndex = Integer.parseInt(String.valueOf(obj)); + + Integer nextIndex = writeIndex%capuatiy; + + if(nextIndex==-1){ + nextIndex = capuatiy - 1; + } + if(collect.size()<=0){ + return objs; + } + boolean needCompareTime = (messageId == 0); + + while(map.containsKey(nextIndex)){ + + ChatProto.ChatInfo o = map.get(nextIndex); + if(!needCompareTime){ + //比较消息id + if(messageId>=o.getMessageId()){ + break; + } + + } + objs.add(0, o); + if(objs.size()>perCaught){ + break; + } + nextIndex--; + if(nextIndex == -1){ + nextIndex = capuatiy - 1; + } + } + if(!needCompareTime && objs.size()>perCaught){ + return objs.subList(0,perCaught); + } + + return objs; + } + } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/dataReport/reportBeans_37/ChatContentType.java b/serverlogic/src/main/java/com/ljsd/jieling/dataReport/reportBeans_37/ChatContentType.java index 168cabcb6..20331f1d0 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/dataReport/reportBeans_37/ChatContentType.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/dataReport/reportBeans_37/ChatContentType.java @@ -14,7 +14,8 @@ public enum ChatContentType { FAMILY_HEAD(11,"会长"), FAMILY_NAME(12,"公会名"), ROLE_NAME(13,"角色名"), - ANNOUNCE(14,"公告"); + ANNOUNCE(14,"公告"), + CROSS_CHAT(15,"跨服"); private Integer type; private String text; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisKey.java b/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisKey.java index 3c063d980..982c1b4ff 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisKey.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisKey.java @@ -125,10 +125,14 @@ public class RedisKey { public static final String CHAT_GUILD_MSG_ID = ":ChatGuildMsgId:"; + public static final String CHAT_CROSS_MSG_ID = "ChatCrossMsgId:"; + public static final String CHAT_FRIEND_MSG_ID = ":ChatFriendMsgId:"; public static final String CUser_Chat = ":CUser_Chat:"; + public static final String CHAT_CROSS_INFO_CACHE = "CHAT_CROSS_INFO_CACHE:";//跨服聊天缓存 + public static final String USER_LOGIN_URL = "USER_LOGIN_URL:"; public static final String CAR_DEALY_PLAY = "CAR_DEALY_PLAY"; @@ -259,6 +263,8 @@ public class RedisKey { public static final String CHAT_INFO_CACHE = "CHAT_INFO_CACHE";//聊天信息缓存,gm后台使用 + + public static final String MAIL_RED_POINT = "MAIL_RED_POINT";//全服红点加入 public static final String PLAYER_INFO_CACHE = "PLAYER_INFO_CACHE"; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisUtil.java b/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisUtil.java index 1768cf42e..da80ecfd5 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisUtil.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/db/redis/RedisUtil.java @@ -1288,6 +1288,14 @@ public class RedisUtil { return getKey(type,key,true); } + /** + * 获取key + * @param type + * @param key + * @param judge + * 本服: true 跨服: false + * @return + */ public String getKey(String type,String key,boolean judge){ if (!judge){ return type + RedisKey.Delimiter_colon + key; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/exception/ErrorCode.java b/serverlogic/src/main/java/com/ljsd/jieling/exception/ErrorCode.java index 901d6f912..ee4ff549b 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/exception/ErrorCode.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/exception/ErrorCode.java @@ -170,8 +170,8 @@ public enum ErrorCode implements IErrorCode { LOCK_FILL(140,"锁定数量已满,无法刷新"), REDPACKET_DAILY_LIMIT(141,"今日福利红包已达领取上限"), - CHAMPION_BET_GUESS_OVER_TIME(142,"巅峰赛竞猜超时,请重新进入页面") - + CHAMPION_BET_GUESS_OVER_TIME(142,"巅峰赛竞猜超时,请重新进入页面"), + CHAT_NOT_CROSS(143,"聊天检查 没有跨服分组"), ; private static final Set CodeSet = new HashSet<>(); diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/activity/crossService/CrossServiceLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/activity/crossService/CrossServiceLogic.java index a83d33693..a86dce064 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/activity/crossService/CrossServiceLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/activity/crossService/CrossServiceLogic.java @@ -147,14 +147,22 @@ public class CrossServiceLogic { return arenaOfPlayerManager; } private ArenaOfHeroManager buildArenaOfHeroManager(User user){ + // 编队列表 Map> teams = new HashMap<>(); - List infos = - user.getTeamPosManager().getTeamPosForHero().getOrDefault(GlobalsDef.WORLD_TEAM_ARENA_DEFENSE,new ArrayList<>()); - teams.put(GlobalsDef.WORLD_TEAM_ARENA_DEFENSE,infos); + // 需要存储的英雄列表 + HashSet set = new HashSet<>(); + // 跨服世界阵编队 + List worldTeam = user.getTeamPosManager().getTeamPosForHero().getOrDefault(GlobalsDef.WORLD_TEAM_ARENA_DEFENSE,new ArrayList<>()); + teams.put(GlobalsDef.WORLD_TEAM_ARENA_DEFENSE,worldTeam); + set.addAll(worldTeam); + // 主线阵容编队 + List firstTeam = user.getTeamPosManager().getTeamPosForHero().getOrDefault(GlobalsDef.FORMATION_NORMAL,new ArrayList<>()); + teams.put(GlobalsDef.FORMATION_NORMAL,firstTeam); + set.addAll(firstTeam); // 英雄 Map heroes = new HashMap<>(); Map heroMap = user.getHeroManager().getHeroMap(); - infos.forEach(v->{ + set.forEach(v->{ Hero hero = heroMap.get(v.getHeroId()); heroes.put(v.getHeroId(),buildArenaOfHero(user,hero)); }); diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/TeamPosHeroInfo.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/TeamPosHeroInfo.java index 540977509..11b066b14 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/TeamPosHeroInfo.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/TeamPosHeroInfo.java @@ -1,6 +1,8 @@ package com.ljsd.jieling.logic.dao; +import java.util.Objects; + public class TeamPosHeroInfo implements Comparable { private String heroId; private int position; @@ -30,6 +32,18 @@ public class TeamPosHeroInfo implements Comparable { this.position = position; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TeamPosHeroInfo that = (TeamPosHeroInfo) o; + return Objects.equals(heroId, that.heroId); + } + + @Override + public int hashCode() { + return Objects.hash(heroId, position); + } @Override public int compareTo(TeamPosHeroInfo o) { diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/player/PlayerLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/player/PlayerLogic.java index faad5c52f..0d733464a 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/player/PlayerLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/player/PlayerLogic.java @@ -672,10 +672,13 @@ public class PlayerLogic { .setUid(id); CommonProto.TeamOneTeamInfo.Builder teamOneTeamInfo = CommonProto.TeamOneTeamInfo.newBuilder(); List teamPosHeroInfos = query.getHeroManager().getTeams().get(teamId); - for (TeamPosHeroInfo heroInfo:teamPosHeroInfos) { - ArenaOfHero hero = query.getHeroManager().getHeros().get(heroInfo.getHeroId()); - teamOneTeamInfo.addTeam(CBean2Proto.getCrossSimpleHero(hero,heroInfo.getPosition())); + if(teamPosHeroInfos!=null){ + for (TeamPosHeroInfo heroInfo:teamPosHeroInfos) { + ArenaOfHero hero = query.getHeroManager().getHeros().get(heroInfo.getHeroId()); + teamOneTeamInfo.addTeam(CBean2Proto.getCrossSimpleHero(hero,heroInfo.getPosition())); + } } + for(Map.Entry entry:query.getPokemons().entrySet()){ teamOneTeamInfo.addPokemonInfos(CBean2Proto.getSimpleTeamInfoByPokeMon(entry.getValue(), entry.getKey())); } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/rank/rankImpl/AbstractRank.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/rank/rankImpl/AbstractRank.java index fd3e2ef08..50e34ae61 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/rank/rankImpl/AbstractRank.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/rank/rankImpl/AbstractRank.java @@ -58,7 +58,12 @@ public abstract class AbstractRank implements IRank { } /** - * 跨服排行数据 + * 获取跨服排行 + * @param uid + * @param rkey + * @param page + * @param rankEndLine + * @return * @throws Exception */ public PlayerInfoProto.RankResponse getCrossRank(int uid, String rkey, int page, int rankEndLine) throws Exception { diff --git a/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java b/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java index 47e51174b..512df7354 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java @@ -1,5 +1,6 @@ package com.ljsd.jieling.util; +import com.ljsd.GameApplication; import com.ljsd.jieling.config.clazzStaticCfg.CommonStaticConfig; import com.ljsd.jieling.db.redis.RedisKey; import com.ljsd.jieling.db.redis.RedisUtil; @@ -8,6 +9,7 @@ import com.ljsd.jieling.handler.map.Cell; import com.ljsd.jieling.handler.map.MapManager; import com.ljsd.jieling.handler.map.TowerBuff; import com.ljsd.jieling.logic.OnlineUserManager; +import com.ljsd.jieling.logic.activity.crossService.CrossServiceLogic; import com.ljsd.jieling.logic.dao.*; import com.ljsd.jieling.logic.dao.gm.ArenaOfHero; import com.ljsd.jieling.logic.dao.root.GuildInfo; @@ -23,6 +25,7 @@ import util.TimeUtils; import com.ljsd.fight.ArenaRecord; import rpc.protocols.CommonProto; +import java.net.UnknownHostException; import java.util.*; import java.util.stream.Collectors; @@ -532,6 +535,25 @@ public class CBean2Proto { return chatInfo.build(); } + public static ChatProto.ChatInfo getCrossChatInfoBuilder(User user,String message,long time,long messageId){ + ChatProto.ChatInfo.Builder chatInfo = ChatProto.ChatInfo.newBuilder(); + PlayerManager playerInfoManager = user.getPlayerInfoManager(); + chatInfo.setSenderId(user.getId()); + chatInfo.setSenderName(playerInfoManager.getNickName()); + chatInfo.setSenderlevel(playerInfoManager.getLevel()); + chatInfo.setSendervip(playerInfoManager.getVipLevel()); + chatInfo.setTimes(time); + chatInfo.setMsg(message); + chatInfo.setHead(playerInfoManager.getHead()); + chatInfo.setFrame(playerInfoManager.getHeadFrame()); + chatInfo.setSoulVal(playerInfoManager.getMaxForce()); + chatInfo.setMessageId(messageId); + chatInfo.setUserTitle(playerInfoManager.getUserTitle()); + chatInfo.setPracticeLevel(user.getHeroManager().getPracticeLevel()); + chatInfo.setServerName(CrossServiceLogic.getInstance().findServerName(GameApplication.serverId)); + return chatInfo.build(); + } + public static ChatProto.ChatInfo getSysChatInfoBuilder(String message,int messageType,String itemId,int type,int startTime, int endTime, int priorityLevel, int multiple,long messageId) { ChatProto.ChatInfo.Builder chatInfo = ChatProto.ChatInfo.newBuilder(); chatInfo.setItemId(itemId);