diff --git a/serverlogic/src/main/java/com/ljsd/jieling/globals/BIReason.java b/serverlogic/src/main/java/com/ljsd/jieling/globals/BIReason.java index 6e07634af..7761dfee0 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/globals/BIReason.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/globals/BIReason.java @@ -308,4 +308,6 @@ public interface BIReason { int WORLD_ARENA = 1077;//跨服竞技场 int SHEJI_ACTIVITY_INIT_CONSUME = 1078;//社稷大典开始清除往期道具 + + int USE_HEADFRAME = 1088;// 使用头像框 } \ No newline at end of file diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/GetPlayerInfoHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/GetPlayerInfoHandler.java index 485ae1d84..7b55803dc 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/handler/GetPlayerInfoHandler.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/GetPlayerInfoHandler.java @@ -170,7 +170,8 @@ public class GetPlayerInfoHandler extends BaseHandler{ }); } - + // 处理玩家旧头像框,兼容,一个玩家只执行一次 + PlayerLogic.getInstance().checkOldHeadFrame(user); //hotfix 月卡 PlayerLogic.getInstance().getMonthCardInfo(user); @@ -184,8 +185,8 @@ public class GetPlayerInfoHandler extends BaseHandler{ Poster.getPoster().dispatchEvent(new NewWelfareEvent(user, NewWelfareTypeEnum.RECHARGE_BUY.getType(),Global.LMONTHCARDID)); } - - StoreLogic.reloadStoreInfo(user,7);//重载功能商店 + //重载功能商店 + StoreLogic.reloadStoreInfo(user,7); PlayerInfoProto.GetPlayerInfoResponse getPlayerInfoResponse = PlayerInfoProto.GetPlayerInfoResponse.newBuilder() .setPlayer(player) @@ -221,6 +222,7 @@ public class GetPlayerInfoHandler extends BaseHandler{ .setHadAdvanceLuckTime(user.getPlayerInfoManager().getLuckAdvanceWheelLimitTime()) .setWorldLeve(GlobleSystemLogic.getGloableWorldLeveCache()) .addAllDemonsTrialRewardInfo(user.getMapManager().getDemonsTrialRewardInfo()) + .addAllHeadFrameBag(CBean2Proto.getHeadFrameList(user)) .build(); ReportUtil.onReportEvent(user, ReportEventEnum.APP_LOGIN.getType()); try { diff --git a/serverlogic/src/main/java/com/ljsd/jieling/handler/player/UseHeadFrameHandler.java b/serverlogic/src/main/java/com/ljsd/jieling/handler/player/UseHeadFrameHandler.java new file mode 100644 index 000000000..16e1bf09e --- /dev/null +++ b/serverlogic/src/main/java/com/ljsd/jieling/handler/player/UseHeadFrameHandler.java @@ -0,0 +1,67 @@ +package com.ljsd.jieling.handler.player; + +import com.google.protobuf.GeneratedMessage; +import com.ljsd.jieling.exception.ErrorCode; +import com.ljsd.jieling.exception.ErrorCodeException; +import com.ljsd.jieling.globals.BIReason; +import com.ljsd.jieling.handler.BaseHandler; +import com.ljsd.jieling.logic.dao.UserManager; +import com.ljsd.jieling.logic.dao.root.User; +import com.ljsd.jieling.util.ItemUtil; +import config.SPlayerHeadIcon; +import org.springframework.stereotype.Component; +import rpc.protocols.MessageTypeProto; +import rpc.protocols.PlayerInfoProto; +import util.TimeUtils; + +/** + * @author hj + * 使用头像框 + */ +@Component +public class UseHeadFrameHandler extends BaseHandler { + @Override + public MessageTypeProto.MessageType getMessageCode() { + return MessageTypeProto.MessageType.UseHeadFrameRequest; + } + + @Override + public GeneratedMessage processWithProto(int uid, PlayerInfoProto.UseHeadFrameRequest proto) throws Exception { + // 用户信息 + User user = UserManager.getUser(uid); + if (user == null) { + throw new ErrorCodeException(ErrorCode.UNKNOWN); + } + // 头像框id + int headFrameId = proto.getHeadFrameId(); + // 读配置表 + SPlayerHeadIcon headIcon = SPlayerHeadIcon.getHeadIconMapByType().get(SPlayerHeadIcon.HeadFrameType).get(headFrameId); + if (headIcon == null){ + throw new ErrorCodeException(ErrorCode.UNKNOWN); + } + + // 验证道具是否足够 + boolean result = ItemUtil.itemCost(user, new int[][]{{headFrameId, 1}}, 1, BIReason.USE_HEADFRAME,1); + if (!result){ + throw new ErrorCodeException(ErrorCode.ITEM_NOT_ENOUGH); + } + + // 是否已经使用 + /*Long time = user.getPlayerInfoManager().getHeadFrameValidTime().get(headFrameId); + if (time != null){ + throw new ErrorCodeException(ErrorCode.newDefineCode("头像框使用中,不能再次使用")); + }*/ + + // 赋值到期时间 + long now = TimeUtils.now() / 1000; + long endTime = 0; + // 是否为永久头像框 + if (headIcon.getTime() != 0){ + endTime = now + headIcon.getTime(); + } + user.getPlayerInfoManager().putHeadFrameValidTime(headFrameId,endTime); + + return PlayerInfoProto.UseHeadFrameResponse.newBuilder().setValidTime((int)endTime).build(); + } + +} diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/PlayerManager.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/PlayerManager.java index 23853974d..2ef972381 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/PlayerManager.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/PlayerManager.java @@ -2,12 +2,16 @@ package com.ljsd.jieling.logic.dao; import com.ljsd.common.mogodb.MongoBase; +import com.ljsd.jieling.config.clazzStaticCfg.CommonStaticConfig; import com.ljsd.jieling.core.VipPrivilegeType; import com.ljsd.jieling.globals.Global; import com.ljsd.jieling.logic.dao.root.User; +import com.ljsd.jieling.util.MessageUtil; import config.SMonthcardConfig; import config.SPrivilegeTypeConfig; import manager.STableManager; +import rpc.protocols.MessageTypeProto; +import rpc.protocols.PlayerInfoProto; import util.MathUtils; import util.TimeUtils; @@ -80,6 +84,12 @@ public class PlayerManager extends MongoBase { private int headFrame; + // 头像框id,有效时间 + private Map headFrameValidTime = new HashMap<>(); + + // 限时头像旧版本兼容 + private int oldHeadFrame; + private int treasureLevel; //孙龙的宝藏等级 private int hadBuyTreasure; //是否已购 @@ -476,6 +486,22 @@ public class PlayerManager extends MongoBase { } public int getHeadFrame() { + // 获取头像框有效时间 + Long time = headFrameValidTime.getOrDefault(headFrame,0L); + // 当前时间,秒 + long now = TimeUtils.now() / 1000; + // 头像框不为永久且时间到期 + if (time != 0 && now >= time){ + // 删除过期头像 + removeHeadFrameValidTime(headFrame); + + // 默认头像框id + int headFrameId = STableManager.getFigureConfig(CommonStaticConfig.class).getGameSetting().getDefaultPicture(); + // 赋值默认头像 + setHeadFrame(headFrameId); + + return headFrameId; + } return headFrame; } @@ -484,6 +510,32 @@ public class PlayerManager extends MongoBase { this.headFrame = headFrame; } + public Map getHeadFrameValidTime() { + return headFrameValidTime; + } + + public void setHeadFrameValidTime(Map headFrameValidTime) { + this.headFrameValidTime = headFrameValidTime; + updateString("headFrameValidTime", headFrameValidTime); + } + + public void putHeadFrameValidTime(int headFrameId,Long time) { + headFrameValidTime.put(headFrameId,time); + updateString("headFrameValidTime", headFrameValidTime); + } + + public void removeHeadFrameValidTime(int headFrameId) { + headFrameValidTime.remove(headFrameId); + updateString("headFrameValidTime", headFrameValidTime); + } + + public int getOldHeadFrame() { + return oldHeadFrame; + } + + public void setOldHeadFrame(int oldHeadFrame) { + this.oldHeadFrame = oldHeadFrame; + } public int getGuildId() { return guildId; diff --git a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java index 972c6ce9d..e3ef7da2c 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/logic/dao/UserManager.java @@ -123,7 +123,10 @@ public class UserManager { playerManager.setIp(ip); playerManager.setChannel_id(channle_id); playerManager.setBundle_id(bundle_id); - playerManager.setHeadFrame(STableManager.getFigureConfig(CommonStaticConfig.class).getGameSetting().getDefaultPicture()); + int headFrameId = STableManager.getFigureConfig(CommonStaticConfig.class).getGameSetting().getDefaultPicture(); + playerManager.setHeadFrame(headFrameId); + playerManager.putHeadFrameValidTime(headFrameId,0L); + ItemUtil.itemCost(user, new int[][]{{headFrameId, 1}}, 1, BIReason.USE_HEADFRAME,1); SPlayerLevelConfig sPlayerLevelConfig = SPlayerLevelConfig.getsPlayerLevelConfigMap().get(1); playerManager.setMaxStamina(sPlayerLevelConfig.getMaxEnergy()); playerManager.setRideLevel(1); 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 fb66a0263..0d617caeb 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 @@ -435,13 +435,23 @@ public class PlayerLogic { LOGGER.info("外观物品Id{}",decorationId); User user = UserManager.getUser(session.getUid()); ItemManager itemManager = user.getItemManager(); - if(decorationId!=0){ + if(decorationId != 0 && type != 0){ if(itemManager.getItem(decorationId)==null||itemManager.getItem(decorationId).getItemNum()<1){ throw new ErrorCodeException(ErrorCode.newDefineCode("无此物品")); } } + // 当前时间,秒 + long now = TimeUtils.now()/1000; switch (type){ case 0: + // 获取头像框有效时间 + Long time = user.getPlayerInfoManager().getHeadFrameValidTime().get(decorationId); + if (time == null){ + throw new ErrorCodeException(ErrorCode.newDefineCode("无此头像框")); + } + if (time != 0 && now > time){ + throw new ErrorCodeException(ErrorCode.newDefineCode("头像框时间到期,更换无效")); + } user.getPlayerInfoManager().setHeadFrame(decorationId); break; case 1: @@ -456,16 +466,10 @@ public class PlayerLogic { case 4: user.getPlayerInfoManager().setDecoration(decorationId); break; - default: - break; + default: + break; } - if(type==0){ - user.getPlayerInfoManager().setHeadFrame(decorationId); - }else if (type ==1){ - user.getPlayerInfoManager().setHead(decorationId); - }else if(type==2){ - } playerInfoUpdate(user); MessageUtil.sendMessage(session,1,messageType.getNumber(),null,true); } @@ -971,4 +975,45 @@ public class PlayerLogic { }); return cardInfos; } + + /** + * 限时头像框,旧内容兼容,一个玩家只运行一次 + * @param user + */ + public void checkOldHeadFrame(User user){ + // 已经处理过,不再执行 + int oldHeadFrame = user.getPlayerInfoManager().getOldHeadFrame(); + if (oldHeadFrame == 1){ + return; + } + // 获取玩家道具新 + ItemManager itemManager = user.getItemManager(); + // 头像框到期时间 + Map validTime = user.getPlayerInfoManager().getHeadFrameValidTime(); + // 获取头像框表 + Map headIconMap = SPlayerHeadIcon.getHeadIconMapByType().get(SPlayerHeadIcon.HeadFrameType); + // 当前时间,秒 + long now = TimeUtils.now() / 1000; + headIconMap.forEach((k,v)->{ + // 是否有道具 + Item item = itemManager.getItem(k); + if (item != null){ + // 是否使用 + Long time = validTime.get(k); + if (time == null){ + // 0:永久,其他到期时间 + if (v.getTime() == 0){ + validTime.putIfAbsent(k,0L); + }else { + validTime.putIfAbsent(k,now+v.getTime()); + } + } + } + }); + + // 更新玩家数据 + user.getPlayerInfoManager().setHeadFrameValidTime(validTime); + user.getPlayerInfoManager().setOldHeadFrame(1); + } + } diff --git a/serverlogic/src/main/java/com/ljsd/jieling/thread/task/RetrySendIndicationThread.java b/serverlogic/src/main/java/com/ljsd/jieling/thread/task/RetrySendIndicationThread.java index f0f65659b..1032d99e8 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/thread/task/RetrySendIndicationThread.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/thread/task/RetrySendIndicationThread.java @@ -56,7 +56,11 @@ public class RetrySendIndicationThread extends Thread{ for(ISession.IndicationMsg indicationMsg : indexToIndication.values()){ long create = indicationMsg.getCreate(); int retryTimes = indicationMsg.getRetryTimes()+1; - if(now-create>retryTimes*300){ + if(retryTimes>3){ +// LOGGER.info("uid=>{}重试Indication3次以上,未收到不再发送",session.getUid()); + continue; + } + if(now-create>retryTimes*3000){ MessageUtil.retrySendIndication(session,indicationMsg.getMsg()); indicationMsg.setRetryTimes(retryTimes); } 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 227b26eec..a96f02d69 100644 --- a/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java +++ b/serverlogic/src/main/java/com/ljsd/jieling/util/CBean2Proto.java @@ -79,6 +79,35 @@ public class CBean2Proto { return itemProto; } + /** + * 获取玩家头像框列表 + * @param user + * @return + */ + public static List getHeadFrameList(User user){ + List headFrameLists = new ArrayList<>(); + // 获取玩家已使用头像框列表 + Map validTime = user.getPlayerInfoManager().getHeadFrameValidTime(); + + long now = TimeUtils.now() / 1000; + + Iterator> it = validTime.entrySet().iterator(); + while (it.hasNext()){ + Map.Entry next = it.next(); + // 过期的删除,其他返回给客户端 + if (next.getValue() != 0 && now >= next.getValue()){ + it.remove(); + }else { + CommonProto.HeadFrameList.Builder build = CommonProto.HeadFrameList.newBuilder(); + build.setHeadFrameId(next.getKey()).setValidTime(next.getValue().intValue()); + headFrameLists.add(build.build()); + } + } + // 数据库更新 + user.getPlayerInfoManager().setHeadFrameValidTime(validTime); + return headFrameLists; + } + public static CommonProto.Hero getHero(Hero hero){ List soulPoss = new ArrayList<>(); Map soulEquipMap = hero.getSoulEquipByPositionMap(); @@ -168,7 +197,7 @@ public class CBean2Proto { return CommonProto.Equip.newBuilder().setEquipId(equipId).build(); } - public static CommonProto.Drop getDrop(TemporaryItems temporaryItems) { + /*public static CommonProto.Drop getDrop(TemporaryItems temporaryItems) { CommonProto.Drop.Builder drop = CommonProto.Drop.newBuilder(); for (Item item : temporaryItems.items.values()) { drop.addItemlist(getItem(item,-1)); @@ -178,7 +207,7 @@ public class CBean2Proto { } return drop.build(); - } + }*/ private static List parseFromMap(Map propertyValueByIdMap){ List result = new ArrayList<>(); diff --git a/tablemanager/src/main/java/config/SPlayerHeadIcon.java b/tablemanager/src/main/java/config/SPlayerHeadIcon.java new file mode 100644 index 000000000..d0a07bc68 --- /dev/null +++ b/tablemanager/src/main/java/config/SPlayerHeadIcon.java @@ -0,0 +1,70 @@ +package config; + +import manager.STableManager; +import manager.Table; + +import java.util.HashMap; +import java.util.Map; + +@Table(name ="PlayerHeadIcon") +public class SPlayerHeadIcon implements BaseConfig { + + private int id; + + private int itemId; + + private int type; + + private int time; + + /** + * 头像框id,头像框类 + */ + private static Map headIconMap = new HashMap<>(); + /** + * 类型,头像框id,头像框类 + */ + private static Map> headIconMapByType = new HashMap<>(); + + // 头像框类型 + public static int HeadFrameType = 2; + + @Override + public void init() throws Exception { + Map config = STableManager.getConfig(SPlayerHeadIcon.class); + Map map = new HashMap<>(); + Map> typeMap = new HashMap<>(); + config.forEach((k,v)->{ + map.putIfAbsent(v.getItemId(),v); + typeMap.putIfAbsent(v.getType(),new HashMap<>()); + typeMap.get(v.getType()).putIfAbsent(v.getItemId(),v); + }); + headIconMap = map; + headIconMapByType = typeMap; + } + + + public int getId() { + return id; + } + + public int getItemId() { + return itemId; + } + + public int getType() { + return type; + } + + public int getTime() { + return time; + } + + public static Map getHeadIconMap() { + return headIconMap; + } + + public static Map> getHeadIconMapByType() { + return headIconMapByType; + } +} \ No newline at end of file