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 efab751..8556972 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 @@ -481,6 +481,9 @@ public class RedisKey { public static final String CROSS_SERVER_GROUP = "CROSS_SERVER_GROUP";// public static final String MAIL_REWARD_MARK = "MAIL_REWARD_MARK";// 邮件奖励 public static final String CROSS_ARENA_RANK_MARK = "CROSS_ARENA_RANK_MARK";//跨服竞技场(九境)赛季排行奖励标示 + public static final String CROSS_CAMPWAR_DAILY_MARK = "CROSS_CAMPWAR_DAILY_MARK"; + public static final String CROSS_CAMPWAR_SEASON_MARK = "CROSS_CAMPWAR_SEASON_MARK";//混乱之治赛季结束个人排名奖励 + public static final String CROSS_CAMPWAR_SEASON_CAMP_MARK = "CROSS_CAMPWAR_SEASON_CAMP_MARK";//混乱之治赛季结束阵营排名奖励 public static final String RANK_REWARD_SLAVE_GROUPS = "RANK_REWARD_SLAVE_GROUPS";//存储合服后的从服的老跨服分组id,用于加载合服后的用户老跨服榜单奖励 //public static Set worldDeathPathCacChe = new HashSet<>(); 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 d5f1c90..224809a 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 @@ -1754,4 +1754,23 @@ public class RedisUtil { e.printStackTrace(); } } + + /** + * 获取key 所有member (Score从高到低排序) + * @param key + * @return + */ + public Set getReverseAllZsetMember(String key){ + return redisTemplate.opsForZSet().reverseRange(key, 0, -1); + } + + /** + * 根据key获取指定Member的Score + * @param key + * @param member + * @return + */ + public Double getZsetScore(String key, String member){ + return redisTemplate.opsForZSet().score(key, member); + } } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/LoginRequestHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/LoginRequestHandler.java index 4665184..35f5dd9 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/handler/LoginRequestHandler.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/LoginRequestHandler.java @@ -10,6 +10,7 @@ import com.ljsd.jieling.logic.dao.GuildMyInfo; import com.ljsd.jieling.logic.dao.GuilidManager; import com.ljsd.jieling.logic.dao.UserManager; import com.ljsd.jieling.logic.dao.UserRecentLoginInfo; +import com.ljsd.jieling.logic.dao.root.GuildInfo; import com.ljsd.jieling.logic.dao.root.User; import com.ljsd.jieling.netty.cocdex.PacketNetData; import com.ljsd.jieling.network.server.Blocker; @@ -142,9 +143,10 @@ public class LoginRequestHandler extends BaseHandler 0) { - if (GuilidManager.guildInfoMap.get(user.getPlayerInfoManager().getGuildId()) == null) { + GuildInfo guildInfo = GuilidManager.guildInfoMap.get(user.getPlayerInfoManager().getGuildId()); + if (guildInfo == null || !guildInfo.isMemberExist(user.getId())){ user.getPlayerInfoManager().setGuildId(0); GuildMyInfo guildMyInfo = new GuildMyInfo(); guildMyInfo.init(userId, MongoKey.guildMyInfo); diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarBattleRecordGetReqHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarBattleRecordGetReqHandler.java index d77b1e5..0bf4c49 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarBattleRecordGetReqHandler.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarBattleRecordGetReqHandler.java @@ -48,7 +48,6 @@ public class CampWarBattleRecordGetReqHandler extends BaseHandler scoreEntries = new ArrayList<>(); for (UserSimpleInfo userSimpleInfo : userSimpleInfos) { - int serverId = userSimpleInfo.getServerId(); int serverGroupId = GlobleSystemLogic.getInstence().getCrossGroup(); int userId = userSimpleInfo.getUserId(); String key = CampWarRedisKeyUtility.generateCampWarScoreKey(serverGroupId); diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarInfoGetReqHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarInfoGetReqHandler.java index 792ae72..ded38ad 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarInfoGetReqHandler.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/campWar/CampWarInfoGetReqHandler.java @@ -67,7 +67,6 @@ public class CampWarInfoGetReqHandler extends BaseHandler= 0; - boolean open = false; + boolean open = GlobleSystemLogic.getInstence().getCrossGroup() >= 0; CampWar.GetCampWarStateResponse getCampWarStateResponse = CampWar.GetCampWarStateResponse.newBuilder().setOpen(open).build(); MessageUtil.sendMessage(iSession, 1, MessageTypeProto.MessageType.GET_CAMP_WAR_STATE_RESPONSE_VALUE, getCampWarStateResponse); } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/arena/ArenaLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/arena/ArenaLogic.java index 7e4fcc1..d8b9a47 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/arena/ArenaLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/arena/ArenaLogic.java @@ -803,49 +803,6 @@ public class ArenaLogic { return drop; } - //跨服竞技场结算 (跨服竞技场活动结束排行结算)(跨服竞技场邮件) - public void worldSendReward() { -// TimeControllerOfFunction timeControllerOfFunction = GlobalDataManaager.getInstance().getTimeControllerOfFunctionByFunctinoType(FunctionIdEnum.World_Arena); -// -// if (null == timeControllerOfFunction) { -// return; -// } -// long diff = (System.currentTimeMillis() - timeControllerOfFunction.getStartTime()) / 1000; -// -// SMServerArenaSetting setting = STableManager.getConfig(SMServerArenaSetting.class).get(1); -// -// TreeMap rewardMapByRank = SSkyLadderReward.rewardMapByRank; -// if (setting == null) { -// return; -// } -// if (diff >= setting.getBattleTime()[1] && diff < setting.getBattleTime()[1] + 50) { -// int myGroup = GlobleSystemLogic.getInstence().getCrossGroup(); -// if (myGroup == 0) { -// return; -// } -// try { -// WorldProto.GetArenaRankRewardResponse response = WorldHelper.sendMessageToWorldWithResult(0, WorldProto.GetArenaRankRewardRequest.newBuilder().setGroupId(myGroup).build(), WorldProto.GetArenaRankRewardResponse.class); -// if (response == null || response.getRankInfoList().size() == 0) { -// return; -// } -// for (WorldProto.ArenaRank rank : response.getRankInfoList()) { -// int myRank = rank.getRank(); -// //sendmail -// String title = SErrorCodeEerverConfig.getI18NMessage("SkyLadder_title"); -// List content = SErrorCodeEerverConfig.getI18NMessageNew("SkyLadder_txt", new Object[]{myRank}); -// -// Map.Entry entry = rewardMapByRank.floorEntry(myRank); -// String mailReward = ItemUtil.getMailReward(entry.getValue().getRankAwards()); -// MailLogic.getInstance().sendMail(rank.getUid(), title, content, mailReward, TimeUtils.nowInt(), Global.MAIL_EFFECTIVE_TIME); -// //MailLogic.getInstance().sendMail(rank.getUid(), "跨服竞技场奖励", "跨服竞技场奖励", StringUtil.parseArrayToString(entry.getValue().getRankAwards()), TimeUtils.nowInt(), Global.MAIL_EFFECTIVE_TIME); -// } -// } catch (Exception e) { -// LOGGER.error("world arena reward error", e); -// } -// } - - } - public void worldSendRewardNew() { TimeControllerOfFunction timeControllerOfFunction = GlobalDataManaager.getInstance().getTimeControllerOfFunctionByFunctinoType(FunctionIdEnum.World_Arena); @@ -889,10 +846,12 @@ public class ArenaLogic { if(users.size() == 0){ return; } - //备份榜单结算信息 + //备份榜单结算信息,同分组内其他服务器调用RankRewardLogic.getInstance().checkAllCrossReward方法去异步加载, + //并需要自己在checkAllCrossReward方法中处理相关逻辑 int time = (int)(start/1000); RankRewardLogic.getInstance().markCrossRankRewards(RankRewardEunm.CROSS_ARENA.getType(), myGroup,time,users); - ClientAdapterPo rPCClient = null; + //在线玩家直接推送 + RankRewardLogic.getInstance().noticeOnline(time,RankRewardEunm.CROSS_ARENA); } catch (Exception e) { LOGGER.error("world arena reward error", e); } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/campWar/CampWarLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/campWar/CampWarLogic.java index 2ee1c77..05d3262 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/campWar/CampWarLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/campWar/CampWarLogic.java @@ -26,6 +26,9 @@ import com.ljsd.jieling.logic.hero.HeroLogic; import com.ljsd.jieling.logic.mission.GameEvent; import com.ljsd.jieling.logic.mission.MissionLoigc; import com.ljsd.jieling.logic.player.PlayerLogic; +import com.ljsd.jieling.logic.rankReward.RankRewardEunm; +import com.ljsd.jieling.logic.rankReward.RankRewardLogic; +import com.ljsd.jieling.protocols.world.CampWar; import com.ljsd.jieling.util.ItemUtil; import config.SCampWarRewardConfig; import config.SGlobalSystemConfig; @@ -761,4 +764,181 @@ public class CampWarLogic implements IEventHandler { updateTeamInfoCache(((MotherShipChangeEvent) event).getUserId()); } } + + /** + * 混乱之治每日排名结算 + */ + public void sendDailyReward() throws Exception { + Date now = TimeUtils.getCurDate(); + long start = now.getTime(); + if (!SCampWarGlobalSystemConfigHelper.getInstance().isSeasonOpen(now)) return; + int groupId = GlobleSystemLogic.getInstence().getCrossGroup(); + if(groupId <=0){ + return; + } + //分布式锁,保证一个组只有一个服进行结算 + String lockKey = "CAMPWAR_DAILY_REWARD_LOCK:" + groupId; + boolean lock = RedisUtil.getInstence().lock(lockKey, TimeUtils.ONE_MINUTE *10); + if (!lock) { + LOGGER.error("混乱之治发奖退出, 未获取到锁!耗时:{} ms, 当前时间:{}", TimeUtils.now() - start, TimeUtils.getTimeStamp(TimeUtils.now())); + return; + } + LOGGER.info("CampWarLogic::settleServerGroupDailyRank. groupId={}", groupId); + String key = CampWarRedisKeyUtility.generateCampWarScoreKey(groupId); + Set userIds = RedisUtil.getInstence().getReverseAllZsetMember(key); + List userSimpleInfos = RedisUtil.getInstence().hmget(RedisKey.USER_SIMPLE_INFO, new ArrayList<>(userIds), UserSimpleInfo.class); + List playerInfos = new ArrayList<>(); + for (UserSimpleInfo userSimpleInfo : userSimpleInfos) { + int userId = userSimpleInfo.getUserId(); + Double result = RedisUtil.getInstence().getZsetScore(CampWarRedisKeyUtility.generateCampWarScoreKey(groupId), Integer.toString(userId)); + if (result == null) continue; + int score = (int)(double)result; + playerInfos.add(new CampWarRankingListPlayerInfo(userSimpleInfo, score)); + } + // 积分相同 战力高的排在前面 + int teamId = GlobalsDef.FORMATION_NORMAL; + playerInfos.sort((c1,c2) -> { + if (c1.getScore() != c2.getScore()) return c2.getScore() - c1.getScore(); + return c2.getUserSimpleInfo().getFight(teamId) - c1.getUserSimpleInfo().getFight(teamId); + }); + //备份榜单结算信息 + Map users = new HashMap(); + for (int i = 0; i < playerInfos.size(); i++) { + int rank = i + 1; + UserSimpleInfo userSimpleInfo = playerInfos.get(i).getUserSimpleInfo(); + int userId = userSimpleInfo.getUserId(); + users.put(userId, rank); + } + //没有需要结算的用户 + if(users.size() == 0){ + return; + } + //备份榜单结算信息,同分组内其他服务器调用RankRewardLogic.getInstance().checkAllCrossReward方法去异步加载, + //并需要自己在checkAllCrossReward方法中处理相关逻辑 + int time = (int)(start/1000); + RankRewardLogic.getInstance().markCrossRankRewards(RankRewardEunm.CROSS_CAMPWAR_DAILY.getType(), groupId,time,users); + //在线玩家直接推送 + RankRewardLogic.getInstance().noticeOnline(time,RankRewardEunm.CROSS_CAMPWAR_DAILY); + } + + /** + * 混乱之治赛季结算 + * @param calendar + * @throws Exception + */ + public void sendSeasonReward(Calendar calendar) throws Exception { + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + int w = calendar.get(Calendar.DAY_OF_WEEK) - 1; + boolean flag = false; + //混乱之治赛季结算每周五22点 + if (w == 5 && hour == 22 && minute ==0) { + flag = true; + } + if(!flag){ + return; + } + int groupId = GlobleSystemLogic.getInstence().getCrossGroup(); + if(groupId <=0){ + return; + } + //分布式锁,保证一个组只有一个服进行结算 + String lockKey = "CAMPWAR_SEASON_REWARD_LOCK:" + groupId; + boolean lock = RedisUtil.getInstence().lock(lockKey, TimeUtils.ONE_MINUTE *10); + long start = TimeUtils.now(); + if (!lock) { + LOGGER.error("混乱之治发奖退出, 未获取到锁!耗时:{} ms, 当前时间:{}", TimeUtils.now() - start, TimeUtils.getTimeStamp(TimeUtils.now())); + return; + } + LOGGER.info("CampWarLogic::settleServerGroupDailyRank. groupId={}", groupId); + List keys = getCampSimpleInfoKeys(groupId); + List campSimpleInfos = RedisUtil.getInstence().multiGet(keys, CampSimpleInfo.class); + campSimpleInfos.sort((c1,c2) -> { + if (c1.getTotalScore() != c2.getTotalScore()) return c2.getTotalScore() - c1.getTotalScore(); + if (c1.getTotalFight() != c2.getTotalFight()) return c2.getTotalFight() - c1.getTotalFight(); + if (c1.getTotalNum() != c2.getTotalNum()) return c1.getTotalNum() - c2.getTotalNum(); + return c2.getCamp() - c1.getCamp(); + } ); + Map users = new HashMap(); + Map camps = new HashMap(); + for (int i = 0; i < campSimpleInfos.size(); i++) { + int campRank = i + 1; //阵营排名 + int camp = campSimpleInfos.get(i).getCamp(); + String key = CampWarRedisKeyUtility.generateCampWarCampScoreKey(groupId, camp); + List allRankingList = getAllRankingList(key); + allRankingList.sort((c1,c2) -> { + if (c1.getScore() != c2.getScore()) return c2.getScore() - c1.getScore(); + return c2.getUserSimpleInfo().getFight(GlobalsDef.FORMATION_NORMAL) - c1.getUserSimpleInfo().getFight(GlobalsDef.FORMATION_NORMAL); + }); + for (int j = 0; j < allRankingList.size(); j++) { + int playerRank = j+1; //阵营中个人排名 + UserSimpleInfo userSimpleInfo = allRankingList.get(j).getUserSimpleInfo(); + int userId = userSimpleInfo.getUserId(); + //存储个人排名奖励 + users.put(userId, playerRank); + //存储阵营排名奖励 + camps.put(userId, campRank); + } + } + int time = (int)(start/1000); + //赛季个人奖励 + if(users.size() > 0){ + //备份榜单结算信息,同分组内其他服务器调用RankRewardLogic.getInstance().checkAllCrossReward方法去异步加载, + //并需要自己在checkAllCrossReward方法中处理相关逻辑 + RankRewardLogic.getInstance().markCrossRankRewards(RankRewardEunm.CROSS_CAMPWAR_SEASON.getType(), groupId,time,users); + } + //赛季阵营奖励 + if(camps.size() > 0){ + //备份榜单结算信息,同分组内其他服务器调用RankRewardLogic.getInstance().checkAllCrossReward方法去异步加载, + //并需要自己在checkAllCrossReward方法中处理相关逻辑 + RankRewardLogic.getInstance().markCrossRankRewards(RankRewardEunm.CROSS_CAMPWAR_SEASON_CAMP.getType(), groupId,time,users); + } + //在线玩家直接推送 + RankRewardLogic.getInstance().noticeOnline(time,RankRewardEunm.CROSS_CAMPWAR_SEASON); + RankRewardLogic.getInstance().noticeOnline(time,RankRewardEunm.CROSS_CAMPWAR_SEASON_CAMP); + //删除相关信息 + RedisUtil.getInstence().del(CampWarRedisKeyUtility.generateGodBattleRecordKey(groupId)); + RedisUtil.getInstence().del(CampWarRedisKeyUtility.generateCampWarScoreKey(groupId)); + for (Integer camp : Camp.getValues(c -> c != Camp.None)) { + RedisUtil.getInstence().del(CampWarRedisKeyUtility.generateCampWarCampScoreKey(groupId, camp)); + RedisUtil.getInstence().del(CampWarRedisKeyUtility.generateCampSimpleInfoKey(groupId, camp)); + } + // 删除大神战报 + RedisUtil.getInstence().del(CampWarRedisKeyUtility.generateGodBattleRecordKey(groupId)); + //删除战斗记录 + RedisUtil.getInstence().del(RedisKey.CAMP_WAR_BATTLE_RECORD); + } + + /** + * 获取所有阵营简要信息key + * @param serverGroupId + * @return + */ + private List getCampSimpleInfoKeys(int serverGroupId){ + List keys = new ArrayList<>(); + for (Integer camp : Camp.getValues(c -> c != Camp.None)) { + String key = CampWarRedisKeyUtility.generateCampSimpleInfoKey(serverGroupId, camp); + keys.add(key); + } + return keys; + } + + private List getAllRankingList(String key) { + List top100 = new ArrayList<>(); + Set> results = RedisUtil.getInstence().getZsetreverseRangeWithScores(key, 0, -1); + int rank = 0; + for (ZSetOperations.TypedTuple typedTuple : results) { + String userId = typedTuple.getValue(); + double score = typedTuple.getScore(); + UserSimpleInfo userSimpleInfo = RedisUtil.getInstence().hget(RedisKey.USER_SIMPLE_INFO, userId, UserSimpleInfo.class); + if (userSimpleInfo == null) + { + LOGGER.error("GetUserSimpleInfo fail. UserId={}", userId); + continue; + } + CampWarRankingListPlayerInfo playerInfo = new CampWarRankingListPlayerInfo(userSimpleInfo, (int) score, ++rank); + top100.add(playerInfo); + } + return top100; + } } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/GuildInfo.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/GuildInfo.java index 30003b1..2ed2dfa 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/GuildInfo.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/root/GuildInfo.java @@ -363,4 +363,21 @@ public class GuildInfo extends MongoBase { updateString("guildSheJiScore",guildSheJiScore); this.guildSheJiScore = guildSheJiScore; } + + /** + * 判断公会是否有个某人 + * @param uid + * @return + */ + public boolean isMemberExist(int uid){ + for (Map.Entry> memberEntry : members.entrySet()) { + Set value = memberEntry.getValue(); + for (Integer uidTmp : value) { + if(uidTmp == uid){ + return true; + } + } + } + return false; + } } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/family/GuildLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/family/GuildLogic.java index 002db5d..c1f9ad6 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/family/GuildLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/family/GuildLogic.java @@ -4,6 +4,7 @@ import com.google.protobuf.GeneratedMessage; import com.ljsd.GameApplication; import com.ljsd.jieling.core.GlobalsDef; import com.ljsd.jieling.core.VipPrivilegeType; +import com.ljsd.jieling.db.mongo.MongoKey; import com.ljsd.jieling.logic.activity.ActivityLogic; import com.ljsd.jieling.logic.activity.ActivityTypeEnum; import com.ljsd.jieling.logic.mission.MissionLoigc; @@ -612,7 +613,7 @@ public class GuildLogic{ if (userTmp != null) { long lastLoginTime = userTmp.getPlayerInfoManager().getLoginTime(); //离线超过一周,且不是会长,踢出公会,并清除内存 - if((now - lastLoginTime) >= TimeUtils.WEEK){ + if((now - lastLoginTime) >= TimeUtils.WEEK && position != GlobalsDef.CHAIRMAN ){ removes.add(uidTmp); UserManager.removeUser(userTmp.getId()); continue; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardEunm.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardEunm.java index 0548679..eab632e 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardEunm.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardEunm.java @@ -7,7 +7,10 @@ public enum RankRewardEunm { ARENA_DAILY(1, RedisKey.AREAN_DAY_RANK_MARK), ARENA_SEASON(2, RedisKey.AREAN_SEASON_RANK_MARK), DEFTRAINING_RANK(3, RedisKey.DEFTRAINING_RANK_MARK), - CROSS_ARENA(4, RedisKey.CROSS_ARENA_RANK_MARK); + CROSS_ARENA(4, RedisKey.CROSS_ARENA_RANK_MARK), + CROSS_CAMPWAR_DAILY(5, RedisKey.CROSS_CAMPWAR_DAILY_MARK), + CROSS_CAMPWAR_SEASON(6, RedisKey.CROSS_CAMPWAR_SEASON_MARK), + CROSS_CAMPWAR_SEASON_CAMP(7, RedisKey.CROSS_CAMPWAR_SEASON_CAMP_MARK); private int type; private String redisKey; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardLogic.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardLogic.java index 788f721..7a86489 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardLogic.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/rankReward/RankRewardLogic.java @@ -2,12 +2,16 @@ package com.ljsd.jieling.logic.rankReward; import com.ljsd.GameApplication; import com.ljsd.jieling.core.GlobalsDef; +import com.ljsd.jieling.db.mongo.MongoUtil; import com.ljsd.jieling.db.redis.RedisKey; import com.ljsd.jieling.db.redis.RedisUtil; import com.ljsd.jieling.globals.Global; import com.ljsd.jieling.logic.GlobleSystemLogic; import com.ljsd.jieling.logic.OnlineUserManager; import com.ljsd.jieling.logic.arena.ArenaLogic; +import com.ljsd.jieling.logic.campWar.CampWarLogic; +import com.ljsd.jieling.logic.campWar.CampWarRewardType; +import com.ljsd.jieling.logic.dao.CampWarManager; import com.ljsd.jieling.logic.dao.UserManager; import com.ljsd.jieling.logic.dao.root.User; import com.ljsd.jieling.logic.mail.MailLogic; @@ -15,9 +19,13 @@ import com.ljsd.jieling.logic.mission.GameEvent; import com.ljsd.jieling.logic.mission.event.MissionEventDistributor; import com.ljsd.jieling.network.session.ISession; import com.ljsd.jieling.util.ItemUtil; +import config.SCampWarRewardConfig; import config.SDefTrainingRanking; import config.SErrorCodeEerverConfig; import config.SSkyLadderReward; +import configHelper.SCampWarGlobalSystemConfigHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import util.TimeUtils; import java.util.*; @@ -27,6 +35,7 @@ import java.util.*; */ public class RankRewardLogic { + private static final Logger LOGGER = LoggerFactory.getLogger(RankRewardLogic.class); //按照榜单类型,结算时间,用户uid,rankValue(可以为排名,段位值,伤害,积分等) public Map>> rankMarks = new HashMap>>(); //按类型存储的排好序的榜单结算时间集合 @@ -798,6 +807,49 @@ public class RankRewardLogic { MailLogic.getInstance().sendMail(user.getId(), title, content, mailReward, key, Global.MAIL_EFFECTIVE_TIME); isCalc = true; } + if(type == RankRewardEunm.CROSS_CAMPWAR_DAILY.getType()){ + //跨服混乱之治每日奖励 + List configs = SCampWarRewardConfig.getCampWarRewardConfigByType(CampWarRewardType.DAILY_PLAYER_RANK.value); + SCampWarRewardConfig config = configs.stream().filter(c -> c.getParam1() <= rank && c.getParam2() >= rank).findFirst().get(); + if (config != null) { + int[][] reward = config.getReward(); + List title = SErrorCodeEerverConfig.getI18NMessageNew("CampWar_DailyRanking_title", new Object[0]); + List content = SErrorCodeEerverConfig.getI18NMessageNew("CampWar_Daily_txt", new Object[]{rank}); + int sendTime = (int) (TimeUtils.now() / 1000) ; + MailLogic.getInstance().sendMail(userId, title, content, ItemUtil.getMailReward(reward), sendTime, Global.MAIL_EFFECTIVE_TIME); + } + isCalc = true; + } + if(type == RankRewardEunm.CROSS_CAMPWAR_SEASON.getType()){ + //跨服混乱之治赛季排名奖励 + List playerRankConfigs = SCampWarRewardConfig.getCampWarRewardConfigByType(CampWarRewardType.CAMP_PLAYER_RANK.value); + CampWarManager campWarManager = user.getCampWarManager(); + SCampWarRewardConfig playerRankConfig = playerRankConfigs.stream().filter(c-> c.getParam1() == campWarManager.getCamp() + && c.getParam2() <= rank && c.getParam3()[0][0] >= rank).findFirst().orElse(null); + if (playerRankConfig != null) { + int[][] reward = playerRankConfig.getReward(); + List title = SErrorCodeEerverConfig.getI18NMessageNew("CampWar_CampRanking_title", new Object[0]); + List content = SErrorCodeEerverConfig.getI18NMessageNew("CampWar_CampRanking_txt", new Object[]{rank}); + int sendTime = (int) (TimeUtils.now() / 1000) ; + MailLogic.getInstance().sendMail(userId, title, content, ItemUtil.getMailReward(reward), sendTime, Global.MAIL_EFFECTIVE_TIME); + } + isCalc = true; + } + if(type == RankRewardEunm.CROSS_CAMPWAR_SEASON_CAMP.getType()){ + //跨服混乱之治赛季阵营排名奖励 + List campRankConfigs = SCampWarRewardConfig.getCampWarRewardConfigByType(CampWarRewardType.CAMP_RANK.value); + SCampWarRewardConfig campRankConfig = campRankConfigs.stream().filter(c-> c.getParam1() <= rank && c.getParam2() >= rank).findFirst().orElse(null); + //阵营排名奖励 + if (campRankConfig != null){ + int[][] reward = campRankConfig.getReward(); + List title = SErrorCodeEerverConfig.getI18NMessageNew("CampWar_Camp_title", new Object[0]); + List content = SErrorCodeEerverConfig.getI18NMessageNew("CampWar_Camp_txt", new Object[]{rank}); + int sendTime = (int) (TimeUtils.now() / 1000) ; + MailLogic.getInstance().sendMail(userId, title, content, ItemUtil.getMailReward(reward), sendTime, Global.MAIL_EFFECTIVE_TIME); + } + isCalc = true; + } + } } //有删除的榜单时间记录,则重置榜单结算时间顺序表 @@ -832,15 +884,49 @@ public class RankRewardLogic { //结算跨服榜单奖励 type = RankRewardEunm.CROSS_ARENA.getType(); this.calcCrossRankReward(user, now, type); + //结算混乱之治每日奖励 + type = RankRewardEunm.CROSS_CAMPWAR_DAILY.getType(); + this.calcCrossRankReward(user, now, type); + //结算混乱之治赛季奖励 + type = RankRewardEunm.CROSS_CAMPWAR_SEASON.getType(); + this.calcCrossRankReward(user, now, type); + //结算混乱之治赛季阵营奖励 + type = RankRewardEunm.CROSS_CAMPWAR_SEASON_CAMP.getType(); + this.calcCrossRankReward(user, now, type); } /** - * 检测是否结算了,因为不一定哪个服务器结算,每周结算时间后的半小时内循环检查,过了则不再检查 + * 所有的开服结算离线奖励异步加载检测 + * @param calendar + * @param time + * @throws Exception + */ + public void checkAllCrossReward(Calendar calendar,long time) throws Exception { + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + int w = calendar.get(Calendar.DAY_OF_WEEK) - 1; + //九境每周日23点到23点10分检测是否加载新的离线奖励 + if (w == 0 && hour == 23 && minute > 0 && minute <=10) { + this.checkCrossReward(time, RankRewardEunm.CROSS_ARENA); + } + //混乱之治(即周二到周五的0点结算前一天每日奖励,周五结算22点赛季结算了,不结算每日奖励)每日奖励0点到0点10检测是否加载新的离线奖励 + if(w >=2 && w<= 5 && hour == 0 && minute > 0 && minute <=10){ + this.checkCrossReward(time, RankRewardEunm.CROSS_CAMPWAR_DAILY); + } + //混乱之治赛季奖励每周五22点到22点10检测是否加载新的离线奖励 + if(w == 5 &&hour == 22 && minute > 0 && minute <=10){ + this.checkCrossReward(time, RankRewardEunm.CROSS_CAMPWAR_SEASON); + this.checkCrossReward(time, RankRewardEunm.CROSS_CAMPWAR_SEASON_CAMP); + } + } + + /** + * 检测是否结算了,因为不一定哪个服务器结算,每周结算时间后的10分钟内循环检查,过了则不再检查 * @param time */ - public void checkCrossArenaReward(long time) throws Exception { + public void checkCrossReward(long time,RankRewardEunm e) throws Exception { int crossGroup = GlobleSystemLogic.getInstence().getCrossGroup(); - long timeKey = this.getCrossTimeKey(RankRewardEunm.CROSS_ARENA.getType(),crossGroup) * 1000; + long timeKey = this.getCrossTimeKey(e.getType(),crossGroup) * 1000; //已经加载过奖励,不需要再加载 if(TimeUtils.isSameDay(timeKey,time)){ return; @@ -848,13 +934,25 @@ public class RankRewardLogic { int now = (int)(time/1000); int diff = now - SAVE_TIME; //更新跨服榜单奖励 - this.loadCrossRank(RankRewardEunm.CROSS_ARENA,crossGroup,diff); + this.loadCrossRank(e,crossGroup,diff); + //在线玩家直接推送 + this.noticeOnline(now,e); + LOGGER.info("checkCrossReward ..." + e.getType()); + } + + /** + * 直接推送在线玩家离线奖励 + * @param now + * @param e + * @throws Exception + */ + public void noticeOnline(int now,RankRewardEunm e) throws Exception { //在线玩家直接推送 Map uids = OnlineUserManager.getAllOnlineUids(); for(int uid:uids.keySet()){ User user = UserManager.getUserOnlyInMap(uid,true); if(user != null){ - this.calcCrossRankReward(user, now, RankRewardEunm.CROSS_ARENA.getType()); + this.calcCrossRankReward(user, now, e.getType()); } } } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/thread/task/MinuteTask.java b/serverlogic/src/main/java/com/ljsd/jieling/thread/task/MinuteTask.java index 2dc890a..6a7606a 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/thread/task/MinuteTask.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/thread/task/MinuteTask.java @@ -18,12 +18,14 @@ import com.ljsd.jieling.logic.activity.ActivityLogic; import com.ljsd.jieling.logic.activity.event.MinuteTaskEvent; import com.ljsd.jieling.logic.activity.event.Poster; import com.ljsd.jieling.logic.arena.ArenaLogic; +import com.ljsd.jieling.logic.campWar.CampWarLogic; import com.ljsd.jieling.logic.dao.GuilidManager; import com.ljsd.jieling.logic.encourage.EncourageLogic; import com.ljsd.jieling.logic.family.DeathPathLogic; import com.ljsd.jieling.logic.family.GuildFightLogic; import com.ljsd.jieling.logic.mail.MailLogic; import com.ljsd.jieling.logic.question.QuestionLogic; +import com.ljsd.jieling.logic.rankReward.RankRewardEunm; import com.ljsd.jieling.logic.rankReward.RankRewardLogic; import com.ljsd.jieling.logic.store.BuyGoodsLogic; import com.ljsd.jieling.logic.store.StoreLogic; @@ -73,6 +75,8 @@ public class MinuteTask extends Thread { if (TimeUtils.getHourOfDay() == 0 && TimeUtils.getMinute() == 0) { // 深渊试炼,每日0点结算 DefTrainingLogic.getInstance().sendMailReward(); + //混乱之治每日0点结算日奖励 + CampWarLogic.getInstance().sendDailyReward(); } } catch (Exception e) { LOGGER.error("Exception::2=>{}", e.toString()); @@ -118,7 +122,12 @@ public class MinuteTask extends Thread { GuildFightLogic.familyFightStatus(); //修改公会战状态分钟定时器 QuestionLogic.getInstence().checkQuestion(); MailLogic.getInstance().checkReadyToMail(); - everySundaySpecialClockTask(); + Calendar calendar = Calendar.getInstance(); + everySundaySpecialClockTask(calendar); + //混乱之治每周五22点结算 + CampWarLogic.getInstance().sendSeasonReward(calendar); + //跨服离线结算奖励信息检测 + RankRewardLogic.getInstance().checkAllCrossReward(calendar,System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); LOGGER.error("Exception::13=>{}", e.toString()); @@ -190,8 +199,7 @@ public class MinuteTask extends Thread { } } - public void everySundaySpecialClockTask() throws Exception { - Calendar calendar = Calendar.getInstance(); + public void everySundaySpecialClockTask(Calendar calendar) throws Exception { int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int w = calendar.get(Calendar.DAY_OF_WEEK) - 1; @@ -201,12 +209,6 @@ public class MinuteTask extends Thread { ArenaLogic.getInstance().worldSendRewardNew(); LOGGER.info("everySundaySpecialClockTask worldArena send reward end ..."); } - //九境每周日23点到23点30分检测是否加载新的离线奖励 - if (w == 0 && hour == 23 && minute > 0 && minute <=30) { - LOGGER.info("everySundaySpecialClockTask worldArena check reward"); - RankRewardLogic.getInstance().checkCrossArenaReward(System.currentTimeMillis()); - LOGGER.info("everySundaySpecialClockTask worldArena send reward end ..."); - } } /** diff --git a/worldserver/src/main/java/com/WorldServerApplication.java b/worldserver/src/main/java/com/WorldServerApplication.java index e2db24b..538fbff 100644 --- a/worldserver/src/main/java/com/WorldServerApplication.java +++ b/worldserver/src/main/java/com/WorldServerApplication.java @@ -102,7 +102,6 @@ public class WorldServerApplication { ThreadManager threadManager = ThreadManager.getInstance(); threadManager.init(); - CampWarLogic.getInstance().init(); bean = ConfigurableApplicationContextManager.getBean(WorldCoreSettings.class); LOGGER.info("ServerProperties ->{}", bean.toString()); CampWarLogic.getInstance().init(); diff --git a/worldserver/src/main/java/com/world/db/mongo/MongoUtil.java b/worldserver/src/main/java/com/world/db/mongo/MongoUtil.java index a80e5ca..a3990bb 100644 --- a/worldserver/src/main/java/com/world/db/mongo/MongoUtil.java +++ b/worldserver/src/main/java/com/world/db/mongo/MongoUtil.java @@ -3,6 +3,7 @@ package com.world.db.mongo; import com.world.config.ConfigurableApplicationContextManager; import com.world.db.mongo.core.CServerInfo; import org.springframework.data.mongodb.core.MongoTemplate; +import util.TimeUtils; import java.util.HashMap; import java.util.List; @@ -26,6 +27,8 @@ public class MongoUtil { private volatile Map cServerInfoMap; + private volatile long lastLoadServerInfoTime = 0;//上次加载服务器列表时间 + public void init() { if(coreMongoTemplate==null){ coreMongoTemplate = (MongoTemplate) ConfigurableApplicationContextManager.getBean("coreMongoTemplate"); @@ -34,6 +37,7 @@ public class MongoUtil { Map serverInfoMap = new HashMap<>(cServerInfos.size()); cServerInfos.forEach(n->serverInfoMap.put(n.getServerId(),n)); cServerInfoMap = serverInfoMap; + lastLoadServerInfoTime = System.currentTimeMillis(); } public String getServerNameById(int serverId){ CServerInfo cServerInfo = cServerInfoMap.get(serverId); @@ -43,4 +47,29 @@ public class MongoUtil { return cServerInfo.getName(); } + /** + * 获取服务器的主服id + * @param serverId + * @return + */ + public int getRealServerId(int serverId){ + long now = System.currentTimeMillis(); + //每次查询间隔超过20分钟,重新加载服务器列表 + if(now - lastLoadServerInfoTime > TimeUtils.ONE_MINUTE * 20){ + List cServerInfos = coreMongoTemplate.findAll(CServerInfo.class); + Map serverInfoMap = new HashMap<>(cServerInfos.size()); + cServerInfos.forEach(n->serverInfoMap.put(n.getServerId(),n)); + cServerInfoMap = serverInfoMap; + lastLoadServerInfoTime = System.currentTimeMillis(); + } + if(this.cServerInfoMap.containsKey(serverId)){ + int realServerId = cServerInfoMap.get(serverId).getRealServerId(); + if(realServerId > 0){ + return realServerId; + } + return serverId; + } + return serverId; + } + } diff --git a/worldserver/src/main/java/com/world/db/mongo/core/CServerInfo.java b/worldserver/src/main/java/com/world/db/mongo/core/CServerInfo.java index 0b70abb..b1e1b1b 100644 --- a/worldserver/src/main/java/com/world/db/mongo/core/CServerInfo.java +++ b/worldserver/src/main/java/com/world/db/mongo/core/CServerInfo.java @@ -14,6 +14,8 @@ public class CServerInfo { private int serverId; @Field(value = "name") private String name; + @Field(value = "real_server_id") + private int realServerId; public int getId() { return id; } @@ -38,4 +40,12 @@ public class CServerInfo { public void setName(String name) { this.name = name; } + + public int getRealServerId() { + return realServerId; + } + + public void setRealServerId(int realServerId) { + this.realServerId = realServerId; + } } diff --git a/worldserver/src/main/java/com/world/handler/GetWorldArenaChallengeRequestHandler.java b/worldserver/src/main/java/com/world/handler/GetWorldArenaChallengeRequestHandler.java index 10b380c..0a2f7ab 100644 --- a/worldserver/src/main/java/com/world/handler/GetWorldArenaChallengeRequestHandler.java +++ b/worldserver/src/main/java/com/world/handler/GetWorldArenaChallengeRequestHandler.java @@ -5,6 +5,7 @@ import com.google.protobuf.GeneratedMessage; import com.ljsd.jieling.logic.fight.result.FightResult; import com.ljsd.jieling.protocols.CommonProto; import com.ljsd.jieling.protocols.world.WorldProto; +import com.world.db.mongo.MongoUtil; import config.SMServerArenaSetting; import manager.STableManager; import util.KeyGenUtils; @@ -96,7 +97,8 @@ public class GetWorldArenaChallengeRequestHandler extends gtGBaseHandler userIds = RedisUtil.getInstence().getReverseAllZsetMember(key); - List userSimpleInfos = RedisUtil.getInstence().hmget(RedisKey.USER_SIMPLE_INFO, new ArrayList<>(userIds), UserSimpleInfo.class); - List playerInfos = new ArrayList<>(); - for (UserSimpleInfo userSimpleInfo : userSimpleInfos) { - int userId = userSimpleInfo.getUserId(); - Double result = RedisUtil.getInstence().getZsetScore(CampWarRedisKeyUtility.generateCampWarScoreKey(groupId), Integer.toString(userId)); - if (result == null) continue; - - int score = (int)(double)result; - playerInfos.add(new CampWarRankingListPlayerInfo(userSimpleInfo, score)); - } - - // 积分相同 战力高的排在前面 - int teamId = GlobalsDef.FORMATION_NORMAL; - playerInfos.sort((c1,c2) -> { - if (c1.getScore() != c2.getScore()) return c2.getScore() - c1.getScore(); - return c2.getUserSimpleInfo().getFight(teamId) - c1.getUserSimpleInfo().getFight(teamId); - }); - for (int i = 0; i < playerInfos.size(); i++) { - int rank = i + 1; - UserSimpleInfo userSimpleInfo = playerInfos.get(i).getUserSimpleInfo(); - int serverId = userSimpleInfo.getServerId(); - int userId = userSimpleInfo.getUserId(); - CampWar.Ws2GsCampWarDailyRankSettleNtf rpcNtf = CampWar.Ws2GsCampWarDailyRankSettleNtf.newBuilder().setRank(rank).build(); - // 这里ws通知gs 不用care回复 protoClazz理论上不用填 临时用一下这个rpc接口 - gsHelper.sendMessageToGs(serverId, userId, rpcNtf, CampWar.Ws2GsCampWarDailyRankSettleNtf.class); - } - } - /** * 混乱之治赛季结束结算 */ public void seasonEndSettle() throws Exception { LOGGER.info("CampWarLogic::seasonEndSettle"); - settleCampWarRank(); - // 清除redis for (Integer serverGroupId : ArenaLogic.getInstance().getAllServerGroup()) { RedisUtil.getInstence().del(CampWarRedisKeyUtility.generateGodBattleRecordKey(serverGroupId)); @@ -298,51 +249,6 @@ public class CampWarLogic { RedisUtil.getInstence().del(RedisKey.CAMP_WAR_BATTLE_RECORD); } - /** - * 排名结算 包括阵营排名和个人排名 - */ - private void settleCampWarRank() throws Exception { - for (Integer groupId : ArenaLogic.getInstance().getAllServerGroup()) { - try { - settleCampWarRank(groupId); - } catch (Exception e) { - LOGGER.error("settle CampWarRank error, serverGroupId: {}, e:", groupId, e); - } - } - } - - private void settleCampWarRank(int serverGroupId) throws Exception { - List keys = getCampSimpleInfoKeys(serverGroupId); - List campSimpleInfos = RedisUtil.getInstence().multiGet(keys, CampSimpleInfo.class); - campSimpleInfos.sort((c1,c2) -> { - if (c1.getTotalScore() != c2.getTotalScore()) return c2.getTotalScore() - c1.getTotalScore(); - if (c1.getTotalFight() != c2.getTotalFight()) return c2.getTotalFight() - c1.getTotalFight(); - if (c1.getTotalNum() != c2.getTotalNum()) return c1.getTotalNum() - c2.getTotalNum(); - return c2.getCamp() - c1.getCamp(); - } ); - for (int i = 0; i < campSimpleInfos.size(); i++) { - int campRank = i + 1; //阵营排名 - int camp = campSimpleInfos.get(i).getCamp(); - String key = CampWarRedisKeyUtility.generateCampWarCampScoreKey(serverGroupId, camp); - List allRankingList = getAllRankingList(key); - allRankingList.sort((c1,c2) -> { - if (c1.getScore() != c2.getScore()) return c2.getScore() - c1.getScore(); - return c2.getUserSimpleInfo().getFight(GlobalsDef.FORMATION_NORMAL) - c1.getUserSimpleInfo().getFight(GlobalsDef.FORMATION_NORMAL); - }); - - for (int j = 0; j < allRankingList.size(); j++) { - int playerRank = j+1; //阵营中个人排名 - UserSimpleInfo userSimpleInfo = allRankingList.get(j).getUserSimpleInfo(); - int serverId = userSimpleInfo.getServerId(); - int userId = userSimpleInfo.getUserId(); - CampWar.Ws2GsCampWarRankSettleNtf rpcNtf = CampWar.Ws2GsCampWarRankSettleNtf.newBuilder() - .setCampRank(campRank) - .setPlayerRank(playerRank).build(); - gsHelper.sendMessageToGs(serverId, userId, rpcNtf, CampWar.Ws2GsCampWarRankSettleNtf.class); - } - } - } - private List getAllRankingList(String key) { List top100 = new ArrayList<>(); Set> results = RedisUtil.getInstence().getZsetreverseRangeWithScores(key, 0, -1); diff --git a/worldserver/src/main/java/com/world/xxljob/handler/CampWarDailyRankJobHandler.java b/worldserver/src/main/java/com/world/xxljob/handler/CampWarDailyRankJobHandler.java index ab4b2da..436c58b 100644 --- a/worldserver/src/main/java/com/world/xxljob/handler/CampWarDailyRankJobHandler.java +++ b/worldserver/src/main/java/com/world/xxljob/handler/CampWarDailyRankJobHandler.java @@ -13,7 +13,7 @@ public class CampWarDailyRankJobHandler { @XxlJob("settleCampWarDailyRankJob") public void settleCampWarDailyRankJob() throws Exception { XxlJobHelper.log("settleCampWarDailyRankJob start...."); - CampWarLogic.getInstance().settleAllServerGroupDailyRank(); +// CampWarLogic.getInstance().settleAllServerGroupDailyRank(); XxlJobHelper.log("settleCampWarDailyRankJob end...."); } } diff --git a/worldserver/src/main/java/com/world/xxljob/handler/CampWarSeasonSettleJobHandler.java b/worldserver/src/main/java/com/world/xxljob/handler/CampWarSeasonSettleJobHandler.java index 94708d7..76fbafb 100644 --- a/worldserver/src/main/java/com/world/xxljob/handler/CampWarSeasonSettleJobHandler.java +++ b/worldserver/src/main/java/com/world/xxljob/handler/CampWarSeasonSettleJobHandler.java @@ -13,7 +13,7 @@ public class CampWarSeasonSettleJobHandler { @XxlJob("CampWarSeasonSettleJob") public void seasonEndSettleJob() throws Exception { XxlJobHelper.log("seasonEndSettleJob start...."); - CampWarLogic.getInstance().seasonEndSettle(); +// CampWarLogic.getInstance().seasonEndSettle(); XxlJobHelper.log("seasonEndSettleJob end...."); } }