优化排行榜和好友系统

main
grimm 2025-03-19 16:44:44 +08:00
parent 0690a68dee
commit 36014b9c73
13 changed files with 499 additions and 149 deletions

View File

@ -41,4 +41,5 @@ public final class RedisKey {
*
*/
public static final String CAMPWAR_TEAM_FORMATION_INFO = "CAMPWAR_TEAM_FORMATION_INFO";
public static final String PLAYER_INFO_CACHE = "PLAYER_INFO_CACHE";
}

View File

@ -8,6 +8,10 @@ public class PlayerInfoCache {
private int level;
private int guildPosition;
private int id;
private int designation;
private int maxForce;
private int sex;
private long offLineTime;// 离线时间
public String getName() {
@ -65,4 +69,37 @@ public class PlayerInfoCache {
public void setId(int id) {
this.id = id;
}
public int getDesignation() {
return designation;
}
public void setDesignation(int designation) {
this.designation = designation;
}
public int getMaxForce() {
return maxForce;
}
public void setMaxForce(int maxForce) {
this.maxForce = maxForce;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public long getOffLineTime() {
return offLineTime;
}
public void setOffLineTime(long offLineTime) {
this.offLineTime = offLineTime;
}
}

View File

@ -473,6 +473,7 @@ public class RedisKey {
public static final String AREAN_DAY_RANK_MARK = "AREAN_DAY_RANK_MARK";//竞技场每日奖励排行标记信息
public static final String AREAN_SEASON_RANK_MARK = "AREAN_SEASON_RANK_MARK";//竞技场赛季奖励排行标记信息
public static final String USER_SIMPLE_INFO = "USER_SIMPLE_INFO";
//public static Set<String> worldDeathPathCacChe = new HashSet<>();

View File

@ -1422,6 +1422,27 @@ public class RedisUtil {
return result;
}
public <T> List<T> getMapEntrys(String key, Collection<Object> mapKeys, Class<T> valueClazz) {
List<T> result = new ArrayList<>();
for (int i = 0; i < MAX_TRY_TIMES; i++) {
try {
List<Object> objects = redisTemplate.opsForHash().multiGet(key, mapKeys);
if (objects != null && !objects.isEmpty()) {
for (Object o : objects) {
if (o != null) {
result.add(gson.fromJson(o.toString(), valueClazz));
}
}
return result;
}
} catch (Exception e) {
LOGGER.info("redis {}",e);
sleep(FAILED_SLEEP);
}
}
return result;
}
//跨服
public <K, T> Map<K, T> getMapValuesWorld(String type, String key, Class<K> keyClazz, Class<T> valueClazz) {
Map<K, T> result = new HashMap<>();

View File

@ -1,9 +1,10 @@
package com.ljsd.jieling.logic.dao;
import com.google.common.collect.Maps;
import com.ljsd.GameApplication;
import com.ljsd.common.pojo.user.UserSimpleInfo;
import com.ljsd.common.redis.RedisKey;
import com.ljsd.jieling.db.redis.RedisKey;
import com.ljsd.jieling.config.clazzStaticCfg.CommonStaticConfig;
import com.ljsd.jieling.core.GlobalsDef;
import com.ljsd.jieling.core.VipPrivilegeType;
@ -12,9 +13,6 @@ import com.ljsd.jieling.db.redis.RedisUtil;
import com.ljsd.jieling.globals.BIReason;
import com.ljsd.jieling.ktbeans.ReportEventEnum;
import com.ljsd.jieling.ktbeans.ReportUtil;
import com.ljsd.jieling.ktbeans.ReportEventEnum;
import com.ljsd.jieling.ktbeans.ReportUtil;
import com.ljsd.jieling.loader.GsCommonFunction;
import com.ljsd.jieling.logic.Blitz.BlitzLogic;
import com.ljsd.jieling.logic.OnlineUserManager;
import com.ljsd.jieling.logic.activity.ActivityLogic;
@ -46,7 +44,13 @@ public class UserManager {
private static Map<Integer, User> userMap = new ConcurrentHashMap<>();
private static Map<Integer, Long> userMapPutTime = new ConcurrentHashMap<>(); //离线读入
private static AtomicInteger login_f_num = new AtomicInteger(0);//登陆计数
private static final int LOGIN_F_LIMIT = 100;//报警界限
private static final int LOGIN_F_LIMIT = 100;//
/**
* ,(redis),(redis),
* redis,redisuserredis,
*/
private static Map<Integer,PlayerInfoCache> playerInfoCacheMap = Maps.newConcurrentMap();
public static void addUser(User user) {
userMap.put(user.getId(), user);
@ -384,4 +388,61 @@ public class UserManager {
return user;
}
/**
*
* @param uid
* @return
*/
public static PlayerInfoCache getPlayerInfoCache(int uid) {
if(playerInfoCacheMap.containsKey(uid)){
return playerInfoCacheMap.get(uid);
}
return null;
}
/**
* ,redis
* @param uid
* @return
*/
public static PlayerInfoCache getPlayerInfoCacheWithRedis(int uid) {
if(playerInfoCacheMap.containsKey(uid)){
PlayerInfoCache info = playerInfoCacheMap.get(uid);
if(info != null){
return info;
}
info = RedisUtil.getInstence().hget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, Integer.toString(uid), PlayerInfoCache.class);
return info;
}
PlayerInfoCache info = RedisUtil.getInstence().hget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, Integer.toString(uid), PlayerInfoCache.class);
return info;
}
public static PlayerInfoCache getPlayerInfoCacheWithRedisAndSaveMap(int uid) {
if(playerInfoCacheMap.containsKey(uid)){
PlayerInfoCache info = playerInfoCacheMap.get(uid);
if(info != null){
return info;
}
info = RedisUtil.getInstence().hget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, Integer.toString(uid), PlayerInfoCache.class);
if(info != null){
updatePlayerInfoCache(info);
}
return info;
}
PlayerInfoCache info = RedisUtil.getInstence().hget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, Integer.toString(uid), PlayerInfoCache.class);
if(info != null){
updatePlayerInfoCache(info);
}
return info;
}
/**
*
* @param playerInfoCache
*/
public static void updatePlayerInfoCache(PlayerInfoCache playerInfoCache) {
playerInfoCacheMap.put(playerInfoCache.getId(), playerInfoCache);
}
}

View File

@ -8,10 +8,7 @@ import com.ljsd.jieling.exception.ErrorCode;
import com.ljsd.jieling.exception.ErrorCodeException;
import com.ljsd.jieling.globals.BIReason;
import com.ljsd.jieling.logic.OnlineUserManager;
import com.ljsd.jieling.logic.dao.FriendManager;
import com.ljsd.jieling.logic.dao.Hero;
import com.ljsd.jieling.logic.dao.PlayerManager;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.*;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.mission.GameEvent;
import com.ljsd.jieling.logic.player.PlayerLogic;
@ -75,20 +72,32 @@ public class FriendLogic {
FriendManager friendManager = user.getFriendManager();
List<Integer> friends = friendManager.getFriends();
List<CommonProto.Friend> friendList = new CopyOnWriteArrayList<>();
List<Integer> notExistFriendIds = new ArrayList<>();
List<String> redisIds = new ArrayList<>();
for (Integer friendId :friends){
User friendData = UserManager.getUser(friendId, true);
PlayerInfoCache friendData = UserManager.getPlayerInfoCache(friendId);
//内存里没有基本信息,缓存起来,批量从redis查询
if (friendData == null) {
notExistFriendIds.add(friendId);
continue;
redisIds.add(String.valueOf(friendId));
continue;
}
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendId,friendManager);
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
}
//清理不存在的好友
if (notExistFriendIds.size() > 0) {
notExistFriendIds.forEach(e-> user.getFriendManager().delFriends(e));
if(redisIds.size() > 0){
List<PlayerInfoCache> infos = RedisUtil.getInstence().hmget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, redisIds, PlayerInfoCache.class);
if(infos != null && infos.size() > 0) {
for (PlayerInfoCache friendData :infos){
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
//后续好友信息扩展到全服的话则不缓存到内存中,只从redis直接查询
UserManager.updatePlayerInfoCache(friendData);
}
}
}
//清理不存在的好友
// if (notExistFriendIds.size() > 0) {
// notExistFriendIds.forEach(e-> user.getFriendManager().delFriends(e));
// }
PlayerInfoProto.GetFriendInfoResponse getFriendInfoResponse = PlayerInfoProto.GetFriendInfoResponse
.newBuilder().addAllFriends(friendList)
.build();
@ -105,22 +114,29 @@ public class FriendLogic {
List<Integer> blackFriends = friendManager.getBlackFriends();
List<CommonProto.Friend> friendList = new CopyOnWriteArrayList<>();
List<Integer> notExistBlackIds = new ArrayList<>();
List<String> redisIds = new ArrayList<>();
for (Integer friendId :blackFriends){
CommonProto.Friend friend = null;
try{
User friendData = UserManager.getUser(friendId, true);
if (friendData == null) {
//好友数据不存在 则删除好
notExistBlackIds.add(friendId);
continue;
}
friend = CBean2Proto.getFriendInfo(friendId,friendManager);
} catch (Exception e){
throw new ErrorCodeException(ErrorCode.FRIEND_NOT_ADD);
PlayerInfoCache friendData = UserManager.getPlayerInfoCache(friendId);
//内存里没有基本信息,缓存起来,批量从redis查询
if (friendData == null) {
redisIds.add(String.valueOf(friendId));
continue;
}
friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
}
if(redisIds.size() > 0){
List<PlayerInfoCache> infos = RedisUtil.getInstence().hmget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, redisIds, PlayerInfoCache.class);
if(infos != null && infos.size() > 0) {
for (PlayerInfoCache friendData :infos){
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
//后续好友信息扩展到全服的话则不缓存到内存中,只从redis直接查询
UserManager.updatePlayerInfoCache(friendData);
}
}
}
//清理不存在的好友
if (notExistBlackIds.size() > 0) {
@ -148,6 +164,7 @@ public class FriendLogic {
int level = playerInfoManager.getLevel();
int randomLevel = MathUtils.random(5, 20);
List<Integer> recommandFriends = new ArrayList<>();
List<String> redisIds = new ArrayList<String>();
List<CommonProto.Friend> friendList = new CopyOnWriteArrayList<>();
for (Integer recommandId : onlineUIds) {
if (recommandId == uid) {
@ -198,10 +215,26 @@ public class FriendLogic {
// }
for (Integer commondUid : recommandFriends) {
CommonProto.Friend friend = CBean2Proto.getFriendInfo(commondUid, friendManager);
PlayerInfoCache friendData = UserManager.getPlayerInfoCache(commondUid);
//内存里没有基本信息,缓存起来,批量从redis查询
if (friendData == null) {
redisIds.add(String.valueOf(commondUid));
continue;
}
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData, friendManager);
friendList.add(friend);
}
if(redisIds.size() > 0){
List<PlayerInfoCache> infos = RedisUtil.getInstence().hmget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, redisIds, PlayerInfoCache.class);
if(infos != null && infos.size() > 0) {
for (PlayerInfoCache friendData :infos){
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
//后续好友信息扩展到全服的话则不缓存到内存中,只从redis直接查询
UserManager.updatePlayerInfoCache(friendData);
}
}
}
PlayerInfoProto.GetFriendInfoResponse getFriendInfoResponse = PlayerInfoProto.GetFriendInfoResponse
.newBuilder().addAllFriends(friendList)
@ -240,15 +273,28 @@ public class FriendLogic {
List<Integer> applyFriends = friendManager.getApplyFriends();
List<CommonProto.Friend> friendList = new CopyOnWriteArrayList<>();
List<Integer> removeIds = new ArrayList<>();
for (Integer applyFriendId :applyFriends){
User friendUser = UserManager.getUser(applyFriendId, true);
if (friendUser == null){
removeIds.add(applyFriendId);
List<String> redisIds = new ArrayList<>();
for (Integer friendId :applyFriends){
PlayerInfoCache friendData = UserManager.getPlayerInfoCache(friendId);
//内存里没有基本信息,缓存起来,批量从redis查询
if (friendData == null) {
redisIds.add(String.valueOf(friendId));
continue;
}
CommonProto.Friend friend = CBean2Proto.getFriendInfo(applyFriendId,friendManager);
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
}
if(redisIds.size() > 0){
List<PlayerInfoCache> infos = RedisUtil.getInstence().hmget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, redisIds, PlayerInfoCache.class);
if(infos != null && infos.size() > 0) {
for (PlayerInfoCache friendData :infos){
CommonProto.Friend friend = CBean2Proto.getFriendInfo(friendData,friendManager);
friendList.add(friend);
//后续好友信息扩展到全服的话则不缓存到内存中,只从redis直接查询
UserManager.updatePlayerInfoCache(friendData);
}
}
}
for (int removeId : removeIds) {
friendManager.delApplyFriend(removeId);
}
@ -327,10 +373,13 @@ public class FriendLogic {
if (isOnline) {
ISession session = OnlineUserManager.getSessionByUid(inviteUid);
User user = UserManager.getUser(inviteUid);
PlayerInfoProto.sendFriendInfoIndication.Builder sendFriendInfoIndication = PlayerInfoProto.sendFriendInfoIndication.newBuilder();
sendFriendInfoIndication.setType(type);
sendFriendInfoIndication.setFriends(CBean2Proto.getFriendInfo(uid, user.getFriendManager()));
MessageUtil.sendIndicationMessage(session, 1, MessageTypeProto.MessageType.SEND_FRIEND_INFO_INDICATION_VALUE, sendFriendInfoIndication.build(), true);
PlayerInfoCache info = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(inviteUid);
if(info != null){
PlayerInfoProto.sendFriendInfoIndication.Builder sendFriendInfoIndication = PlayerInfoProto.sendFriendInfoIndication.newBuilder();
sendFriendInfoIndication.setType(type);
sendFriendInfoIndication.setFriends(CBean2Proto.getFriendInfo(info,user.getFriendManager()));
MessageUtil.sendIndicationMessage(session, 1, MessageTypeProto.MessageType.SEND_FRIEND_INFO_INDICATION_VALUE, sendFriendInfoIndication.build(), true);
}
}
}
//t推送赠送体力状态
@ -718,10 +767,14 @@ public class FriendLogic {
}else if (applyFriends.contains(friendId)){
type = 3;
}
PlayerInfoCache info = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(friendId);
if(info == null){
throw new ErrorCodeException(ErrorCode.FRIENDS_USER_NULL);
}
PlayerInfoProto.FriendSearchResponse friendSearchResponse = PlayerInfoProto.FriendSearchResponse
.newBuilder()
.setType(type)
.setFriends(CBean2Proto.getFriendInfo(friendId,null))
.setFriends(CBean2Proto.getFriendInfo(info,null))
.build();
MessageUtil.sendMessage(iSession, 1, msgId, friendSearchResponse, true);
}

View File

@ -422,7 +422,7 @@ public class PlayerLogic {
}
playerInfoManager.vipFlush(removePrivileges); // 特权隔天刷新只用重置次数
//vip刷新后才能发给前端
if (fBuilder != null) {
for (Map.Entry<Integer, VipInfo> vipInfoItem : vipInfo.entrySet()) {
@ -1314,7 +1314,38 @@ public class PlayerLogic {
int memberType = GuildLogic.getMemberType(user.getId(), GuilidManager.guildInfoMap.get(user.getPlayerInfoManager().getGuildId()).getMembers());
cache.setGuildPosition(memberType);
}
cache.setSex(playerInfoManager.getSex());
cache.setDesignation(playerInfoManager.getDesignation());
cache.setMaxForce(playerInfoManager.getMaxForce());
cache.setOffLineTime(playerInfoManager.getLoginTime());
RedisUtil.getInstence().putMapEntry(RedisKey.PLAYER_INFO_CACHE, "", String.valueOf(user.getId()), cache);
//同步到内存中
UserManager.updatePlayerInfoCache(cache);
}
public PlayerInfoCache initPlayerInfoCache(User user){
PlayerManager playerInfoManager = user.getPlayerInfoManager();
PlayerInfoCache cache = new PlayerInfoCache();
cache.setHead(playerInfoManager.getHead());
cache.setHeadFrame(playerInfoManager.getHeadFrame());
cache.setName(playerInfoManager.getNickName());
cache.setLevel(playerInfoManager.getLevel());
cache.setId(user.getId());
cache.setServerId(GameApplication.serverId);
if (user.getPlayerInfoManager().getGuildId() == 0) {
cache.setGuildPosition(0);
} else {
int memberType = GuildLogic.getMemberType(user.getId(), GuilidManager.guildInfoMap.get(user.getPlayerInfoManager().getGuildId()).getMembers());
cache.setGuildPosition(memberType);
}
cache.setSex(playerInfoManager.getSex());
cache.setDesignation(playerInfoManager.getDesignation());
cache.setMaxForce(playerInfoManager.getMaxForce());
cache.setOffLineTime(playerInfoManager.getLoginTime());
RedisUtil.getInstence().putMapEntry(RedisKey.PLAYER_INFO_CACHE, "", String.valueOf(user.getId()), cache);
//同步到内存中
UserManager.updatePlayerInfoCache(cache);
return cache;
}
/**

View File

@ -1,13 +1,19 @@
package com.ljsd.jieling.logic.rank;
import com.google.common.collect.Maps;
import com.ljsd.GameApplication;
import com.ljsd.common.pojo.user.UserSimpleInfo;
import com.ljsd.jieling.db.redis.RedisKey;
import com.ljsd.jieling.db.redis.RedisUtil;
import com.ljsd.jieling.exception.ErrorCode;
import com.ljsd.jieling.exception.ErrorCodeException;
import com.ljsd.jieling.globals.BIReason;
import com.ljsd.jieling.logic.dao.PlayerInfoCache;
import com.ljsd.jieling.logic.dao.PlayerManager;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.mission.GameEvent;
import com.ljsd.jieling.logic.player.PlayerLogic;
import com.ljsd.jieling.logic.rank.rankImpl.AbstractRank;
import com.ljsd.jieling.network.server.WorldHelper;
import com.ljsd.jieling.network.session.ISession;
@ -20,9 +26,15 @@ import com.ljsd.jieling.util.MessageUtil;
import config.SSpecialConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.ZSetOperations;
import util.TimeUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
/**
* @author lvxinran
@ -31,6 +43,8 @@ import java.util.List;
*/
public class RankLogic {
private static final Logger LOGGER = LoggerFactory.getLogger(RankLogic.class);
//记录排行榜用户基本信息被批量加载的时间,加载过了就不再加载
private Map<Integer, Long> rankUserBaseInfoLoadTime = Maps.newConcurrentMap();
private RankLogic() {
@ -151,6 +165,32 @@ public class RankLogic {
MessageUtil.sendMessage(session, 1, messageType.getNumber(), response, true);
}
public void checkLoadUserBaseInfo(int type, Set<ZSetOperations.TypedTuple<String>> userIds){
if(!this.rankUserBaseInfoLoadTime.containsKey(type)){
//批量查询后将信息加载到内存里
List<String> list = new ArrayList<>();
if(userIds!= null && userIds.size() > 0){
userIds.stream().forEach(data->{
try {
list.add(String.valueOf(data.getValue()));
} catch (Exception e) {
e.printStackTrace();
}
});
}
if(list.size() > 0){
List<PlayerInfoCache> infos = RedisUtil.getInstence().hmget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, list, PlayerInfoCache.class);
if(infos != null && infos.size() > 0){
for(PlayerInfoCache info : infos){
UserManager.updatePlayerInfoCache(info);
}
}
}
//直接保存type和时间目前加载过就不再重复加载后续可根基情况根据时间做固定间隔重新加载
this.rankUserBaseInfoLoadTime.put(type,System.currentTimeMillis());
}
}
/**
* value
* @param type

View File

@ -3,11 +3,14 @@ package com.ljsd.jieling.logic.rank.rankImpl;
import com.ljsd.GameApplication;
import com.ljsd.jieling.db.redis.RedisKey;
import com.ljsd.jieling.db.redis.RedisUtil;
import com.ljsd.jieling.logic.dao.PlayerInfoCache;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.family.DeathPathLogic;
import com.ljsd.jieling.logic.player.PlayerLogic;
import com.ljsd.jieling.logic.rank.IRank;
import com.ljsd.jieling.logic.rank.RankEnum;
import com.ljsd.jieling.logic.rank.RankLogic;
import com.ljsd.jieling.logic.rankingReward.RankingRewardLogic;
import com.ljsd.jieling.protocols.CommonProto;
import com.ljsd.jieling.protocols.PlayerInfoProto;
@ -71,6 +74,8 @@ public abstract class AbstractRank implements IRank {
if(start==0){
start=1;
}
//判断是否加载过批量排行榜基础数据
RankLogic.getInstance().checkLoadUserBaseInfo(this.getType(),zsetreverseRangeWithScores);
PlayerInfoProto.RankResponse.Builder allUserResponse = getAllUserResponse(zsetreverseRangeWithScores,start);
//当前用户信息
getMyInfo(user,rkey,allUserResponse, inAreaTime);
@ -356,7 +361,13 @@ public abstract class AbstractRank implements IRank {
return builder;
}
ZSetOperations.TypedTuple<String> data = rankByKey.iterator().next();
User everyUser = UserManager.getUser(Integer.parseInt(data.getValue()), true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(Integer.parseInt(data.getValue()));
if(everyUser == null){
User user = UserManager.getUser(Integer.parseInt(data.getValue()), true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(1)
.setParam1(getParam1(data.getScore()))
@ -381,7 +392,13 @@ public abstract class AbstractRank implements IRank {
return builder;
}
ZSetOperations.TypedTuple<String> data = rankByKey.iterator().next();
User everyUser = UserManager.getUser(Integer.parseInt(data.getValue()), true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(Integer.parseInt(data.getValue()));
if(everyUser == null){
User user = UserManager.getUser(Integer.parseInt(data.getValue()), true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(1)
.setParam1(getParam1(data.getScore()))
@ -403,7 +420,16 @@ public abstract class AbstractRank implements IRank {
}
protected void getOptional(int index,ZSetOperations.TypedTuple<String> data,PlayerInfoProto.RankResponse.Builder builder) throws Exception {
User everyUser = UserManager.getUser(Integer.parseInt(data.getValue()), true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(Integer.parseInt(data.getValue()));
if(everyUser == null){
User user = UserManager.getUser(Integer.parseInt(data.getValue()), true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
if(everyUser == null){
return;
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(index)
.setParam1(getParam1(data.getScore()))
@ -412,18 +438,18 @@ public abstract class AbstractRank implements IRank {
CommonProto.UserRank.Builder oneUserRank = getOneUserRank(everyUser, everyRankInfo);
builder.addRanks(oneUserRank);
}
public CommonProto.UserRank.Builder getOneUserRank(User everyUser,CommonProto.RankInfo.Builder everyRankInfo) throws Exception {
public CommonProto.UserRank.Builder getOneUserRank(PlayerInfoCache everyUser, CommonProto.RankInfo.Builder everyRankInfo) throws Exception {
CommonProto.UserRank.Builder everyRank = CommonProto.UserRank.newBuilder();
if(everyUser !=null){
everyRank.setUid(everyUser.getId())
.setUserName(everyUser.getPlayerInfoManager().getNickName())
.setHead(everyUser.getPlayerInfoManager().getHead())
.setHeadFrame(everyUser.getPlayerInfoManager().getHeadFrame())
.setLevel(everyUser.getPlayerInfoManager().getLevel())
.setUserName(everyUser.getName())
.setHead(everyUser.getHead())
.setHeadFrame(everyUser.getHeadFrame())
.setLevel(everyUser.getLevel())
.setRankInfo(everyRankInfo)
.setForce(everyUser.getPlayerInfoManager().getMaxForce())
.setSex(everyUser.getPlayerInfoManager().getSex())
.setLikeNum(everyUser.getFriendManager().getBeLikedCount());
.setForce(everyUser.getMaxForce())
.setSex(everyUser.getSex())
.setLikeNum(50);
}
return everyRank;

View File

@ -8,9 +8,11 @@ import com.ljsd.jieling.logic.activity.event.HeroForceChangeEvent;
import com.ljsd.jieling.logic.activity.event.IEvent;
import com.ljsd.jieling.logic.activity.event.Poster;
import com.ljsd.jieling.logic.dao.Hero;
import com.ljsd.jieling.logic.dao.PlayerInfoCache;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.hero.HeroLogic;
import com.ljsd.jieling.logic.player.PlayerLogic;
import com.ljsd.jieling.logic.rank.RankEnum;
import com.ljsd.jieling.logic.rankingReward.RankingRewardLogic;
import com.ljsd.jieling.protocols.CommonProto;
@ -30,15 +32,15 @@ public class HeroForceRank extends AbstractRank implements IEventHandler {
public final int USER_HERO_NUM_LIMIT = 5;//每个user上榜英雄数量
public HeroForceRank(int type, String redisKey) {
super(type, redisKey);
Poster.getPoster().listenEvent(this, HeroForceChangeEvent.class);
// Poster.getPoster().listenEvent(this, HeroForceChangeEvent.class);
}
@Override
public void onEvent(IEvent event) throws Exception {
if(event instanceof HeroForceChangeEvent){
HeroForceChangeEvent _event = (HeroForceChangeEvent) event;
addRank(_event.getUid(),"");
}
// if(event instanceof HeroForceChangeEvent){
// HeroForceChangeEvent _event = (HeroForceChangeEvent) event;
// addRank(_event.getUid(),"");
// }
}
@Override
@ -62,17 +64,26 @@ public class HeroForceRank extends AbstractRank implements IEventHandler {
String[] valueStrArray = StringUtil.getStringList(data.getValue(),RedisKey.Delimiter_colon);
int uid = Integer.parseInt(valueStrArray[0]);
String heroId = valueStrArray[1];
User everyUser = UserManager.getUser(uid, true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(uid);
if(everyUser == null){
User user = UserManager.getUser(uid, true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(1)
.setParam1(getParam1(data.getScore()))
.setParam2(getParam2(data.getScore()))
.setParam3(getParam3(data.getScore()));
builder = getOneUserRank(everyUser,everyRankInfo);
Hero hero = everyUser.getHeroManager().getHero(heroId);
builder.setHeroTemplateId(hero.getTemplateId());
builder.setHeroLevel(hero.getLevel());
builder.setHeroStar(hero.getStar());
User user = UserManager.getUser(uid, true);
if(user != null){
Hero hero = user.getHeroManager().getHero(heroId);
builder.setHeroTemplateId(hero.getTemplateId());
builder.setHeroLevel(hero.getLevel());
builder.setHeroStar(hero.getStar());
}
return builder;
}
@ -88,17 +99,26 @@ public class HeroForceRank extends AbstractRank implements IEventHandler {
String[] valueStrArray = StringUtil.getStringList(data.getValue(),RedisKey.Delimiter_colon);
int uid = Integer.parseInt(valueStrArray[0]);
String heroId = valueStrArray[1];
User everyUser = UserManager.getUser(uid, true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(uid);
if(everyUser == null){
User user = UserManager.getUser(uid, true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(1)
.setParam1(getParam1(data.getScore()))
.setParam2(getParam2(data.getScore()))
.setParam3(getParam3(data.getScore()));
builder = getOneUserRank(everyUser,everyRankInfo);
Hero hero = everyUser.getHeroManager().getHero(heroId);
builder.setHeroTemplateId(hero.getTemplateId());
builder.setHeroLevel(hero.getLevel());
builder.setHeroStar(hero.getStar());
User user = UserManager.getUser(uid, true);
if(user != null){
Hero hero = user.getHeroManager().getHero(heroId);
builder.setHeroTemplateId(hero.getTemplateId());
builder.setHeroLevel(hero.getLevel());
builder.setHeroStar(hero.getStar());
}
return builder;
}
@ -107,17 +127,29 @@ public class HeroForceRank extends AbstractRank implements IEventHandler {
String[] valueStrArray = StringUtil.getStringList(data.getValue(),RedisKey.Delimiter_colon);
int uid = Integer.parseInt(valueStrArray[0]);
String heroId = valueStrArray[1];
User everyUser = UserManager.getUser(uid, true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(uid);
if(everyUser == null){
User user = UserManager.getUser(uid, true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
if(everyUser == null){
return;
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(index)
.setParam1(getParam1(data.getScore()))
.setParam2(getParam2(data.getScore()))
.setParam3(getParam3(data.getScore()));
CommonProto.UserRank.Builder oneUserRank = getOneUserRank(everyUser, everyRankInfo);
Hero hero = everyUser.getHeroManager().getHero(heroId);
oneUserRank.setHeroTemplateId(hero.getTemplateId());
oneUserRank.setHeroLevel(hero.getLevel());
oneUserRank.setHeroStar(hero.getStar());
User user = UserManager.getUser(uid, true);
if(user != null){
Hero hero = user.getHeroManager().getHero(heroId);
oneUserRank.setHeroTemplateId(hero.getTemplateId());
oneUserRank.setHeroLevel(hero.getLevel());
oneUserRank.setHeroStar(hero.getStar());
}
builder.addRanks(oneUserRank);
}
@ -158,50 +190,51 @@ public class HeroForceRank extends AbstractRank implements IEventHandler {
@Override
public void addRank(int uid, String rkey, double... data) {
try{
User user = UserManager.getUser(uid);
//额外添加战区排行榜
int areaDuration = SSpecialConfig.getIntegerValue(SSpecialConfig.ServerZone_AutoMerge_Times);
boolean inAreaTime = false;
int area = user.getPlayerInfoManager().getArea();
if(area > 0 && TimeUtils.now() < TimeUtils.dateToStamp(GameApplication.serverConfig.getOpenTime()) + areaDuration * 1000) {
inAreaTime = true;
}
Map<Integer, String> heroForceSortMap = user.getHeroManager().getHeroForceSort();
if(!heroForceSortMap.isEmpty()){
for(Map.Entry<Integer,String> e : heroForceSortMap.entrySet()){
String heroId = e.getValue();
StringBuilder value = new StringBuilder();
value.append(uid).append(RedisKey.Delimiter_colon).append(heroId);
//全区的排行榜
String key = RedisKey.getKey(redisKey,rkey,false);
RedisUtil.getInstence().zsetRemoveOne(key,value.toString());
if(inAreaTime) {
String areaKey = RedisKey.getKey(redisKey + RedisKey.Delimiter_colon + area, rkey,false);
RedisUtil.getInstence().zsetRemoveOne(areaKey,value.toString());
}
}
}
refreshHeroForceSort(user);
heroForceSortMap = user.getHeroManager().getHeroForceSort();
if(!heroForceSortMap.isEmpty()){
for(Map.Entry<Integer,String> e : heroForceSortMap.entrySet()){
int force = e.getKey();
String heroId = e.getValue();
StringBuilder value = new StringBuilder();
value.append(uid).append(RedisKey.Delimiter_colon).append(heroId);
String key = RedisKey.getKey(redisKey,rkey,false);
RedisUtil.getInstence().zsetAddOne(key,value.toString(),force);
if( inAreaTime ) {
String areaKey = RedisKey.getKey(redisKey + RedisKey.Delimiter_colon + area, rkey,false);
RedisUtil.getInstence().zsetAddOne(areaKey, value.toString(), force);
}
RankingRewardLogic.getInstance().updateRankingData(uid,RankingRewardLogic.getInstance().HERO_FORCE_RANK_TYPE,force,heroId);
}
}
}catch (Exception e){
LOGGER.error("HeroForceRank exception ",e);
}
//废弃常驻的英雄战力排行榜
// try{
// User user = UserManager.getUser(uid);
// //额外添加战区排行榜
// int areaDuration = SSpecialConfig.getIntegerValue(SSpecialConfig.ServerZone_AutoMerge_Times);
// boolean inAreaTime = false;
// int area = user.getPlayerInfoManager().getArea();
// if(area > 0 && TimeUtils.now() < TimeUtils.dateToStamp(GameApplication.serverConfig.getOpenTime()) + areaDuration * 1000) {
// inAreaTime = true;
// }
// Map<Integer, String> heroForceSortMap = user.getHeroManager().getHeroForceSort();
// if(!heroForceSortMap.isEmpty()){
// for(Map.Entry<Integer,String> e : heroForceSortMap.entrySet()){
// String heroId = e.getValue();
// StringBuilder value = new StringBuilder();
// value.append(uid).append(RedisKey.Delimiter_colon).append(heroId);
// //全区的排行榜
// String key = RedisKey.getKey(redisKey,rkey,false);
// RedisUtil.getInstence().zsetRemoveOne(key,value.toString());
// if(inAreaTime) {
// String areaKey = RedisKey.getKey(redisKey + RedisKey.Delimiter_colon + area, rkey,false);
// RedisUtil.getInstence().zsetRemoveOne(areaKey,value.toString());
// }
// }
// }
// refreshHeroForceSort(user);
// heroForceSortMap = user.getHeroManager().getHeroForceSort();
// if(!heroForceSortMap.isEmpty()){
// for(Map.Entry<Integer,String> e : heroForceSortMap.entrySet()){
// int force = e.getKey();
// String heroId = e.getValue();
// StringBuilder value = new StringBuilder();
// value.append(uid).append(RedisKey.Delimiter_colon).append(heroId);
// String key = RedisKey.getKey(redisKey,rkey,false);
// RedisUtil.getInstence().zsetAddOne(key,value.toString(),force);
// if( inAreaTime ) {
// String areaKey = RedisKey.getKey(redisKey + RedisKey.Delimiter_colon + area, rkey,false);
// RedisUtil.getInstence().zsetAddOne(areaKey, value.toString(), force);
// }
// RankingRewardLogic.getInstance().updateRankingData(uid,RankingRewardLogic.getInstance().HERO_FORCE_RANK_TYPE,force,heroId);
// }
// }
// }catch (Exception e){
// LOGGER.error("HeroForceRank exception ",e);
// }
}

View File

@ -5,8 +5,10 @@ import com.ljsd.jieling.db.redis.RedisKey;
import com.ljsd.jieling.db.redis.RedisUtil;
import com.ljsd.jieling.logic.dao.Hero;
import com.ljsd.jieling.logic.dao.HeroManager;
import com.ljsd.jieling.logic.dao.PlayerInfoCache;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.player.PlayerLogic;
import com.ljsd.jieling.logic.rank.RankEnum;
import com.ljsd.jieling.protocols.CommonProto;
import com.ljsd.jieling.protocols.PlayerInfoProto;
@ -36,18 +38,31 @@ public class NewHeroForceRank extends AbstractRank {
@Override
protected void getOptional(int index, ZSetOperations.TypedTuple<String> data, PlayerInfoProto.RankResponse.Builder builder) throws Exception {
int uid = Integer.parseInt(data.getValue());
User everyUser = UserManager.getUser(uid, true);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(uid);
if(everyUser == null){
User user = UserManager.getUser(uid, true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
CommonProto.RankInfo.Builder everyRankInfo = CommonProto.RankInfo.newBuilder()
.setRank(index)
.setParam1(getParam1(data.getScore()))
.setParam2(getParam2(data.getScore()))
.setParam3(getParam3(data.getScore()));
CommonProto.UserRank.Builder oneUserRank = getOneUserRank(everyUser, everyRankInfo);
String maxForceHero = everyUser.getHeroManager().getMaxForceHero();
Hero hero = everyUser.getHeroManager().getHero(maxForceHero);
oneUserRank.setHeroTemplateId(hero.getTemplateId());
oneUserRank.setHeroLevel(hero.getLevel());
oneUserRank.setHeroStar(hero.getStar());
// User user = UserManager.getUser(uid, true);
// if(user!= null){
// String maxForceHero = user.getHeroManager().getMaxForceHero();
// Hero hero = user.getHeroManager().getHero(maxForceHero);
// oneUserRank.setHeroTemplateId(hero.getTemplateId());
// oneUserRank.setHeroLevel(hero.getLevel());
// oneUserRank.setHeroStar(hero.getStar());
// }
//英雄信息不展示,设置默认值
oneUserRank.setHeroTemplateId(10001);
oneUserRank.setHeroLevel(200);
oneUserRank.setHeroStar(10);
builder.addRanks(oneUserRank);
}

View File

@ -10,9 +10,11 @@ import com.ljsd.jieling.exception.ErrorCodeException;
import com.ljsd.jieling.globals.BIReason;
import com.ljsd.jieling.globals.Global;
import com.ljsd.jieling.logic.dao.Hero;
import com.ljsd.jieling.logic.dao.PlayerInfoCache;
import com.ljsd.jieling.logic.dao.PlayerManager;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.player.PlayerLogic;
import com.ljsd.jieling.network.session.ISession;
import com.ljsd.jieling.protocols.CommonProto;
import com.ljsd.jieling.protocols.MessageTypeProto;
@ -26,6 +28,7 @@ import config.SRankingRewardConfig;
import manager.STableManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.ZSetOperations;
import util.StringUtil;
import util.TimeUtils;
@ -44,6 +47,7 @@ public class RankingRewardLogic {
private boolean loadRankingData = false;
public LinkedBlockingQueue<Runnable> taskLinkedQueue = new LinkedBlockingQueue();
private Map<Integer, TreeMap<Long,Integer>> rankingDataMap = new HashMap<>();// id ->{time,uid} 加载一份redis中的数据,这份数据只能在数据更新线程里访问
private boolean load = false;
private RankingRewardLogic(){
loadRankingDataMap();
updateDataThread = new Thread(this::doWork,"RankingRewardUpdateDataThread");
@ -219,27 +223,33 @@ public class RankingRewardLogic {
public void fillUpRankingInfoProto(List<CommonProto.RankingInfo> rankingInfoList) throws Exception {
Map<Integer, TreeMap<Long,Integer>> _rankingDataMap = getRankingDataMap();
//检测是否加载过基础信息
this.checkLoadUserBaseInfo(_rankingDataMap);
for(Map.Entry<Integer, TreeMap<Long,Integer>> e : _rankingDataMap.entrySet()){
int _id = e.getKey();
//英雄战力榜的奖励不发
if(_id >=4000){
continue;
}
int rank = 0;
for(Map.Entry<Long,Integer> _e : e.getValue().entrySet()){
int _uid = _e.getValue();
long _time = _e.getKey();
User user = null;
try{
user = UserManager.getUser(_uid);
}catch (Exception ee) {
LOGGER.error("load user failed {}", _uid, e);
PlayerInfoCache everyUser = UserManager.getPlayerInfoCacheWithRedisAndSaveMap(_uid);
if(everyUser == null){
User user = UserManager.getUser(_uid, true);
if(user != null){
everyUser = PlayerLogic.getInstance().initPlayerInfoCache(user);
}
}
if(user == null) continue;
PlayerManager playerManager = user.getPlayerInfoManager();
if(everyUser == null) continue;
CommonProto.RankingInfo info = CommonProto.RankingInfo.newBuilder()
.setId(_id)
.setUid(_uid)
.setLevel(playerManager.getLevel())
.setHead(playerManager.getHead())
.setName(playerManager.getNickName())
.setHeadFrame(playerManager.getHeadFrame())
.setLevel(everyUser.getLevel())
.setHead(everyUser.getHead())
.setName(everyUser.getName())
.setHeadFrame(everyUser.getHeadFrame())
.setTime(_time)
.setRank(++rank)
.build();
@ -248,5 +258,28 @@ public class RankingRewardLogic {
}
}
public void checkLoadUserBaseInfo(Map<Integer, TreeMap<Long,Integer>> _rankingDataMap) throws Exception {
if(!this.load && _rankingDataMap != null && !_rankingDataMap.isEmpty()){
//批量查询后将信息加载到内存里
List<String> list = new ArrayList<>();
for(Map.Entry<Integer, TreeMap<Long,Integer>> e : _rankingDataMap.entrySet()){
for(Map.Entry<Long,Integer> _e : e.getValue().entrySet()){
int _uid = _e.getValue();
list.add(String.valueOf(_uid));
}
}
if(list.size() > 0){
List<PlayerInfoCache> infos = RedisUtil.getInstence().hmget(RedisKey.PLAYER_INFO_CACHE + RedisKey.Delimiter_colon, list, PlayerInfoCache.class);
if(infos != null && infos.size() > 0){
for(PlayerInfoCache info : infos){
UserManager.updatePlayerInfoCache(info);
}
}
}
//标记为加载过了
this.load = true;
}
}
}

View File

@ -731,39 +731,37 @@ public class CBean2Proto {
}
public static CommonProto.Friend getFriendInfo(int friendId, FriendManager friendManager) throws Exception {
User user = UserManager.getUser(friendId);
PlayerManager playerInfoManager = user.getPlayerInfoManager();
public static CommonProto.Friend getFriendInfo(PlayerInfoCache user, FriendManager friendManager) throws Exception {
int isGrive = 0;
int haveReward = 0;
CommonProto.Friend.Builder friend = CommonProto.Friend.newBuilder();
if (friendManager != null) {
Map<Integer, Integer> giveMap = friendManager.getGiveMap();
Map<Integer, Integer> haveRewardMap = friendManager.getHaveRewardMap();
if (giveMap.size() != 0 && giveMap.containsKey(friendId)) {
isGrive = giveMap.get(friendId);
if (giveMap.size() != 0 && giveMap.containsKey(user.getId())){
isGrive = giveMap.get(user.getId());
}
if (haveRewardMap.size() != 0 && giveMap.containsKey(friendId) && haveRewardMap.containsKey(friendId)) {
haveReward = haveRewardMap.get(friendId) == 2 ? 0 : haveRewardMap.get(friendId);
if (haveRewardMap.size() != 0 && giveMap.containsKey(user.getId()) && haveRewardMap.containsKey(user.getId())) {
haveReward = haveRewardMap.get(user.getId()) == 2 ? 0 : haveRewardMap.get(user.getId());
}
if (friendManager.getMyApplyFriends().contains(friendId)) {
if (friendManager.getMyApplyFriends().contains(user.getId())) {
friend.setIsApplyed(1);
}
}
friend.setId(user.getId());
friend.setName(playerInfoManager.getNickName());
friend.setLv(playerInfoManager.getLevel());
friend.setName(user.getName());
friend.setLv(user.getLevel());
long isOnline = 0;
if (!OnlineUserManager.checkUidOnline(friendId)) {
isOnline = playerInfoManager.getOffLineTime();
if (!OnlineUserManager.checkUidOnline(user.getId())) {
isOnline = user.getOffLineTime();
}
friend.setOffLineTime(isOnline);
friend.setHaveReward(haveReward);
friend.setIsGive(isGrive);
friend.setHead(playerInfoManager.getHead());
friend.setFrame(playerInfoManager.getHeadFrame());
friend.setSoulVal(playerInfoManager.getMaxForce());
friend.setTitleId(playerInfoManager.getDesignation());
friend.setHead(user.getHead());
friend.setFrame(user.getHeadFrame());
friend.setSoulVal(user.getMaxForce());
friend.setTitleId(user.getDesignation());
return friend.build();
}