From 7f3e8984ac5bcb64e8c04062dded1b2218be446f Mon Sep 17 00:00:00 2001
From: zhaodice <63996691+zhaodice@users.noreply.github.com>
Date: Thu, 2 Jun 2022 07:13:48 +0800
Subject: [PATCH] Fix receiving reward repeatedly (#1140)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Fix receiving reward repeatedly

fix #1105 锛坖ust fix "鏃犻檺鍙戦€侀鍙栬姹�"锛�

* Fix dead code and prevent getting item repeatedly

* fix again
---
 .../recv/HandlerTakePlayerLevelRewardReq.java | 32 ++++----
 .../packet/send/PacketGetMailItemRsp.java     | 76 ++++++++++---------
 2 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerTakePlayerLevelRewardReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerTakePlayerLevelRewardReq.java
index c9e4d27b..8701a747 100644
--- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerTakePlayerLevelRewardReq.java
+++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerTakePlayerLevelRewardReq.java
@@ -1,40 +1,40 @@
 package emu.grasscutter.server.packet.recv;
 
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
-import emu.grasscutter.Grasscutter;
 import emu.grasscutter.data.GameData;
 import emu.grasscutter.data.common.ItemParamData;
 
-import emu.grasscutter.game.inventory.GameItem;
+import emu.grasscutter.game.player.Player;
 import emu.grasscutter.game.props.ActionReason;
 import emu.grasscutter.net.packet.Opcodes;
 import emu.grasscutter.net.packet.PacketHandler;
 import emu.grasscutter.net.packet.PacketOpcodes;
 import emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq;
 import emu.grasscutter.server.game.GameSession;
-import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
 import emu.grasscutter.server.packet.send.PacketTakePlayerLevelRewardRsp;
 
 @Opcodes(PacketOpcodes.TakePlayerLevelRewardReq)
 public class HandlerTakePlayerLevelRewardReq extends PacketHandler {
     @Override
     public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
-        TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload);
-
-        int level = req.getLevel();
-        int rewardId = GameData.getPlayerLevelDataMap().get(level).getRewardId();
-
-        if (rewardId != 0) {
-            List<ItemParamData> rewardItems = GameData.getRewardDataMap().get(rewardId).getRewardItemList();
-            session.getPlayer().getInventory().addItemParamDatas(rewardItems, ActionReason.PlayerUpgradeReward);
+        Player pl = session.getPlayer();
+        synchronized (pl) {
+            TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload);
+            int level = req.getLevel();
             Set<Integer> rewardedLevels = session.getPlayer().getRewardedLevels();
-            rewardedLevels.add(level);
-            session.getPlayer().setRewardedLevels(rewardedLevels);
+            if (!rewardedLevels.contains(level)) {// No duplicated reward
+                int rewardId = GameData.getPlayerLevelDataMap().get(level).getRewardId();
+                if (rewardId != 0) {
+                    List<ItemParamData> rewardItems = GameData.getRewardDataMap().get(rewardId).getRewardItemList();
+                    pl.getInventory().addItemParamDatas(rewardItems, ActionReason.PlayerUpgradeReward);
+                    rewardedLevels.add(level);
+                    pl.setRewardedLevels(rewardedLevels);
+                    pl.save();
+                    session.send(new PacketTakePlayerLevelRewardRsp(level, rewardId));
+                }
+            }
         }
-
-        session.send(new PacketTakePlayerLevelRewardRsp(level, rewardId));
     }
 }
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketGetMailItemRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketGetMailItemRsp.java
index 37f753c1..cdf2e234 100644
--- a/src/main/java/emu/grasscutter/server/packet/send/PacketGetMailItemRsp.java
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketGetMailItemRsp.java
@@ -18,52 +18,60 @@ public class PacketGetMailItemRsp  extends BasePacket {
 
     public PacketGetMailItemRsp(Player player, List<Integer> mailList) {
         super(PacketOpcodes.GetMailItemRsp);
-
         List<Mail> claimedMessages = new ArrayList<>();
         List<EquipParamOuterClass.EquipParam> claimedItems = new ArrayList<>();
 
         GetMailItemRsp.Builder proto = GetMailItemRsp.newBuilder();
 
-        for (int mailId : mailList) {
-            Mail message = player.getMail(mailId);
+        synchronized (player) {
+            boolean modified = false;
+            for (int mailId : mailList) {
+                Mail message = player.getMail(mailId);
+                if (!message.isAttachmentGot) {//No duplicated item
+                    for (Mail.MailItem mailItem : message.itemList) {
+                        EquipParamOuterClass.EquipParam.Builder item = EquipParamOuterClass.EquipParam.newBuilder();
+                        int promoteLevel = 0;
 
-            for(Mail.MailItem mailItem : message.itemList) {
-                EquipParamOuterClass.EquipParam.Builder item = EquipParamOuterClass.EquipParam.newBuilder();
-                int promoteLevel = 0;
-                if (mailItem.itemLevel > 20) { // 20/40
-                    promoteLevel = 1;
-                } else if (mailItem.itemLevel > 40) { // 40/50
-                    promoteLevel = 2;
-                } else if (mailItem.itemLevel > 50) { // 50/60
-                    promoteLevel = 3;
-                } else if (mailItem.itemLevel > 60) { // 60/70
-                    promoteLevel = 4;
-                } else if (mailItem.itemLevel > 70) { // 70/80
-                    promoteLevel = 5;
-                } else if (mailItem.itemLevel > 80) { // 80/90
-                    promoteLevel = 6;
-                }
+                        if (mailItem.itemLevel > 80) { // 80/90
+                            promoteLevel = 6;
+                        } else if (mailItem.itemLevel > 70) { // 70/80
+                            promoteLevel = 5;
+                        } else if (mailItem.itemLevel > 60) { // 60/70
+                            promoteLevel = 4;
+                        } else if (mailItem.itemLevel > 50) { // 50/60
+                            promoteLevel = 3;
+                        } else if (mailItem.itemLevel > 40) { // 40/50
+                            promoteLevel = 2;
+                        } else if (mailItem.itemLevel > 20) { // 20/40
+                            promoteLevel = 1;
+                        }
 
-                item.setItemId(mailItem.itemId);
-                item.setItemNum(mailItem.itemCount);
-                item.setItemLevel(mailItem.itemLevel);
-                item.setPromoteLevel(promoteLevel);
-                claimedItems.add(item.build());
+                        item.setItemId(mailItem.itemId);
+                        item.setItemNum(mailItem.itemCount);
+                        item.setItemLevel(mailItem.itemLevel);
+                        item.setPromoteLevel(promoteLevel);
+                        claimedItems.add(item.build());
 
-                GameItem gameItem = new GameItem(GameData.getItemDataMap().get(mailItem.itemId));
-                gameItem.setCount(mailItem.itemCount);
-                gameItem.setLevel(mailItem.itemLevel);
-                gameItem.setPromoteLevel(promoteLevel);
-                player.getInventory().addItem(gameItem, ActionReason.MailAttachment);
-            }
+                        GameItem gameItem = new GameItem(GameData.getItemDataMap().get(mailItem.itemId));
+                        gameItem.setCount(mailItem.itemCount);
+                        gameItem.setLevel(mailItem.itemLevel);
+                        gameItem.setPromoteLevel(promoteLevel);
+                        player.getInventory().addItem(gameItem, ActionReason.MailAttachment);
+                    }
 
-            message.isAttachmentGot = true;
-            claimedMessages.add(message);
+                    message.isAttachmentGot = true;
+                    claimedMessages.add(message);
 
-            player.replaceMailByIndex(mailId, message);
+                    player.replaceMailByIndex(mailId, message);
+                    modified = true;
+                }
+            }
+            if(modified) {
+                player.save();
+            }
         }
 
-        proto.addAllMailIdList(claimedMessages.stream().map(message -> player.getMailId(message)).collect(Collectors.toList()));
+        proto.addAllMailIdList(claimedMessages.stream().map(player::getMailId).collect(Collectors.toList()));
         proto.addAllItemList(claimedItems);
 
         this.setData(proto.build());
-- 
GitLab