Parcourir la source

Merge remote-tracking branch 'origin/master'

xhb il y a 2 mois
Parent
commit
917fadc2fd

+ 1 - 1
incubator-common/build.gradle

@@ -25,7 +25,7 @@ dependencies {
     api 'org.dom4j:dom4j:2.1.4' // XML 操作工具
 
     // 网络通信和序列化
-    api 'io.netty:netty-all:4.1.116.Final' // Netty 全功能包
+    api 'io.netty:netty-all:4.1.117.Final' // Netty 全功能包
     api 'org.msgpack:msgpack-core:0.9.8' // MessagePack 序列化
     api 'com.dyuproject.protostuff:protostuff-core:1.3.1' // Protostuff 核心
     api 'com.dyuproject.protostuff:protostuff-runtime:1.3.1' // Protostuff 运行时

+ 1 - 0
incubator-game/src/main/java/com/incubator/game/GGame.java

@@ -181,6 +181,7 @@ public class GGame extends AbstractService {
         String name = RedisKeyConstant.WK_SERVE_KEY;
         String type = RedisKeyConstant.WK_SERVE_TYPE;
         WkServerStatus wkServerStatus = new WkServerStatus();
+        wkServerStatus.setIntranetIp(RedisKeyConstant.WK_SERVE_IP);
         wkServerStatus.setName(name);
         wkServerStatus.setNum(0);
         wkServerStatus.setType(type);

+ 4 - 2
incubator-game/src/main/java/com/incubator/game/constant/RedisKeyConstant.java

@@ -38,9 +38,11 @@ public class RedisKeyConstant {
      * 服务域名或者ip端口信息 value当前服务域名或者ip端口信息,分割符为: 比如127.0.0.1:8080,127.0.0.1:8081
      */
     public static final String WK_SERVE = "wk:serve";
-    public static final String WK_SERVE_KEY = "192.168.0.236:9000";
+    public static final String WK_SERVE_KEY = "192.168.0.112:9000";
     // 0:普通房间 1:赛事房间  8 大厅
-    public static final String WK_SERVE_TYPE = "8";
+    public static final String WK_SERVE_TYPE = "0";
+
+    public static final String WK_SERVE_IP = "192.168.0.112";
 
     /**
      * 服务在线普通房间

+ 10 - 0
incubator-game/src/main/java/com/incubator/game/constant/WkServerStatus.java

@@ -10,6 +10,16 @@ public  class WkServerStatus {
     private int num;
     // 服务器类型 8:大厅 0:好友房间 1:比赛房间
     private String type;
+    //内网ip
+    private String intranetIp;
+
+    public String getIntranetIp() {
+        return intranetIp;
+    }
+
+    public void setIntranetIp(String intranetIp) {
+        this.intranetIp = intranetIp;
+    }
 
     public WkServerStatus(String name, int num, String type) {
         this.type = type;

+ 29 - 29
incubator-game/src/main/java/com/incubator/game/contest/Contest.java

@@ -321,29 +321,29 @@ public class Contest {
         switch (this.contestState) {
             case 0:
                 // 等待开始
-                Date date = new Date();
-                if (date.getTime() >= this.data.startTime - (30 * 1000)){
-                    for (Player tmPlayer : this.actors.values()) {
-                        if (tmPlayer != null) {
-                            Map<String, Object> data = new HashMap<>();
-                            HashMap<String, WkServerStatus> wkServes = RedisUtil.getWkToRedis(RedisKeyConstant.WK_SERVE);
-                            AtomicReference<String> wkIp = new AtomicReference<>("");
-                            wkServes.forEach((k,v) ->{
-                                if (v.getType().equals("1")){
-                                    wkIp.set(v.getName());
-                                }
-                            });
-                            data.put("wkIp", wkIp.toString());
-                            Log.debug("比赛准备开始 : 比赛 : {},切换ip: {}", this.data.contestId, wkIp);
-                            tmPlayer.receive(CommonProto.Cmd.ToggleIPRes_VALUE, data);
-                        }
-                    }
-                    List<String> keyList = new ArrayList<>(actors.keySet());
-                    //将所有的玩家加入到赛事
-                    RedisUtil.set(RedisKeyConstant.COMPETE_PLAYERS+this.data.contestId, keyList);
-                }
+//                Date date = new Date();
+//                if (date.getTime() >= this.data.startTime - (30 * 1000)){
+//                    for (Player tmPlayer : this.actors.values()) {
+//                        if (tmPlayer != null) {
+//                            Map<String, Object> data = new HashMap<>();
+//                            HashMap<String, WkServerStatus> wkServes = RedisUtil.getWkToRedis(RedisKeyConstant.WK_SERVE);
+//                            AtomicReference<String> wkIp = new AtomicReference<>("");
+//                            wkServes.forEach((k,v) ->{
+//                                if (v.getType().equals("1")){
+//                                    wkIp.set(v.getName());
+//                                }
+//                            });
+//                            data.put("wkIp", wkIp.toString());
+//                            Log.debug("比赛准备开始 : 比赛 : {},切换ip: {}", this.data.contestId, wkIp);
+//                            tmPlayer.receive(CommonProto.Cmd.ToggleIPRes_VALUE, data);
+//                        }
+//                    }
+//                    List<String> keyList = new ArrayList<>(actors.keySet());
+//                    //将所有的玩家加入到赛事
+//                    RedisUtil.set(RedisKeyConstant.COMPETE_PLAYERS+this.data.contestId, keyList);
+//                }
                 //从redis中获取玩家
-                String ids = RedisUtil.get(RedisKeyConstant.COMPETE_PLAYERS);
+                String ids = RedisUtil.get(RedisKeyConstant.COMPETE_PLAYERS+this.data.contestId);
                 if (ids!=null){
                     JSONArray jsonArray = new JSONArray(ids);
                     for (Object o : jsonArray) {
@@ -354,15 +354,15 @@ public class Contest {
                         }
                     }
                 }
-                if (this.checkReadyStart()) {
-                    this.isActive = false;
-                }
 //                if (this.checkReadyStart()) {
-//                    this.state = 1;
-//                    this.contestState = 1;
-//                    this.flag = false;
-//                    this.time = 0;
+//                    this.isActive = false;
 //                }
+                if (this.checkReadyStart()) {
+                    this.state = 1;
+                    this.contestState = 1;
+                    this.flag = false;
+                    this.time = 0;
+                }
                 break;
             case 1:
                 // 比赛开始

+ 6 - 6
incubator-game/src/main/java/com/incubator/game/handler/room/LeaveRoomHandler.java

@@ -52,12 +52,12 @@ public class LeaveRoomHandler extends NetHandler {
         }
 
         // 当前状态是否可操作
-        if (room.state != 0 || player.data.state != 0) {
-            Log.info("离开房间失败,游戏已开始...");
-            response.setCode(7);
-            response.setMessage("操作失败,游戏已开始...");
-            return;
-        }
+//        if (room.state != 0 || player.data.state != 0) {
+//            Log.info("离开房间失败,游戏已开始...");
+//            response.setCode(7);
+//            response.setMessage("操作失败,游戏已开始...");
+//            return;
+//        }
 
         // 离开房间
         room.leaveRoom(player);

+ 2 - 37
incubator-game/src/main/java/com/incubator/game/player/Player.java

@@ -139,15 +139,10 @@ public class Player extends GPlayer {
         for (ModuleManager manager : this.allManagers.values()) {
             manager.onPlayerEvent(PlayerEventType.OFFLINE);
         }
-        // 有房间解散房间
+        // 有房间就离开房间
         Room room = RoomService.getInstance().getRoomByPlayerId(this.getId());
         if (room != null) {
-            for (Player tmPlayer : room.actors.values()) {
-                if (tmPlayer != null) {
-                    tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
-                }
-            }
-            room.destroy();
+            room.leaveRoom(this);
         }
 
         WkServerStatus wkToRedis = RedisUtil.getWkToRedis(RedisKeyConstant.WK_SERVE, RedisKeyConstant.WK_SERVE_KEY);
@@ -240,34 +235,4 @@ public class Player extends GPlayer {
         this.data.isChangePos = false;
     }
 
-    /**
-     * 玩家信息转消息
-     *
-     * @param flag 是否显示手牌
-     * @return
-     */
-    public Map<String, Object> playerRoomToMessage(boolean flag) {
-        Map<String, Object> data = new HashMap<>();
-        data.put("id", this.getId());
-        data.put("name", this.data.name);
-        data.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
-        data.put("sex", this.data.sex);
-        data.put("pos", this.data.pos);
-        data.put("state", this.data.state);
-        data.put("isAuto", this.data.isAuto);
-        // 转蛋积分-累计
-        data.put("accumulatedPoints", this.data.accumulatedPoints);
-        // 队友Id
-        data.put("teammateId", this.data.teammateId);
-
-        // 玩家牌数据
-        Map<String, Object> cardInfo = new HashMap<>();
-        cardInfo.put("remainCards", flag? this.data.remainCards : "");
-        cardInfo.put("remainCardsNum", this.data.remainCards.length);
-        cardInfo.put("discardList", this.data.discardList);
-        cardInfo.put("disCardType", this.data.disCardType);
-        cardInfo.put("tributeGetCard", this.data.tributeGetCard);
-        data.put("cardInfo", cardInfo);
-        return data;
-    }
 }

+ 33 - 2
incubator-game/src/main/java/com/incubator/game/room/FSGDRoom.java

@@ -595,11 +595,11 @@ public class FSGDRoom extends Room {
         data.put("curDiscardSex", this.data.disCardPlayer != null ? this.data.disCardPlayer.data.sex : 0);
         data.put("curPassList", this.data.passList);
         data.put("roomIp",this.data.roomIp);
-        data.put("myInfo", player.playerRoomToMessage(true));
+        data.put("myInfo", this.playerRoomToMessage(player, true));
         List<Map<String, Object>> otherInfo = new ArrayList<>();
         for (Player tmPlayer : this.actors.values()) {
             if (tmPlayer != null && !Objects.equals(tmPlayer.getId(), player.getId())) {
-                otherInfo.add(tmPlayer.playerRoomToMessage(false));
+                otherInfo.add(this.playerRoomToMessage(tmPlayer, false));
             }
         }
         data.put("otherInfo", otherInfo);
@@ -615,4 +615,35 @@ public class FSGDRoom extends Room {
         }
         return data;
     }
+
+    /**
+     * 玩家信息转消息
+     *
+     * @param flag 是否显示手牌
+     * @return
+     */
+    public Map<String, Object> playerRoomToMessage(Player player, boolean flag) {
+        Map<String, Object> data = new HashMap<>();
+        data.put("id", player.getId());
+        data.put("name", player.data.name);
+        data.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
+        data.put("sex", player.data.sex);
+        data.put("pos", player.data.pos);
+        data.put("state", player.data.state);
+        data.put("isAuto", player.data.isAuto);
+        // 转蛋积分-累计
+        data.put("accumulatedPoints", player.data.accumulatedPoints);
+        // 队友Id
+        data.put("teammateId", player.data.teammateId);
+
+        // 玩家牌数据
+        Map<String, Object> cardInfo = new HashMap<>();
+        cardInfo.put("remainCards", flag? player.data.remainCards : "");
+        cardInfo.put("remainCardsNum", player.data.remainCards.length);
+        cardInfo.put("discardList", player.data.discardList);
+        cardInfo.put("disCardType", player.data.disCardType);
+        cardInfo.put("tributeGetCard", player.data.tributeGetCard);
+        data.put("cardInfo", cardInfo);
+        return data;
+    }
 }

+ 33 - 2
incubator-game/src/main/java/com/incubator/game/room/FSGDTable.java

@@ -1184,11 +1184,11 @@ public class FSGDTable {
         data.put("curDiscardSex", this.data.disCardPlayer != null ? this.data.disCardPlayer.data.sex : 0);
         data.put("curPassList", this.data.passList);
 
-        data.put("myInfo", player.playerRoomToMessage(true));
+        data.put("myInfo", this.playerRoomToMessage(player, true));
         List<Map<String, Object>> otherInfo = new ArrayList<>();
         for (Player tmPlayer : this.actors.values()) {
             if (tmPlayer != null && !Objects.equals(tmPlayer.getId(), player.getId())) {
-                otherInfo.add(tmPlayer.playerRoomToMessage(false));
+                otherInfo.add(this.playerRoomToMessage(tmPlayer, false));
             }
         }
         // 增加结算玩家信息
@@ -1203,6 +1203,37 @@ public class FSGDTable {
         return data;
     }
 
+    /**
+     * 玩家信息转消息
+     *
+     * @param flag 是否显示手牌
+     * @return
+     */
+    public Map<String, Object> playerRoomToMessage(Player player, boolean flag) {
+        Map<String, Object> data = new HashMap<>();
+        data.put("id", player.getId());
+        data.put("name", player.data.name);
+        data.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
+        data.put("sex", player.data.sex);
+        data.put("pos", player.data.pos);
+        data.put("state", player.data.state);
+        data.put("isAuto", player.data.isAuto);
+        // 转蛋积分-累计
+        data.put("accumulatedPoints", player.data.accumulatedPoints);
+        // 队友Id
+        data.put("teammateId", player.data.teammateId);
+
+        // 玩家牌数据
+        Map<String, Object> cardInfo = new HashMap<>();
+        cardInfo.put("remainCards", flag? player.data.remainCards : "");
+        cardInfo.put("remainCardsNum", player.data.remainCards.length);
+        cardInfo.put("discardList", player.data.discardList);
+        cardInfo.put("disCardType", player.data.disCardType);
+        cardInfo.put("tributeGetCard", player.data.tributeGetCard);
+        data.put("cardInfo", cardInfo);
+        return data;
+    }
+
     /**
      * 房间信息转游戏回放
      *

+ 54 - 17
incubator-game/src/main/java/com/incubator/game/room/GDRoom.java

@@ -157,11 +157,15 @@ public class GDRoom extends Room {
             }
         } finally {
             lock.unlock();
-            // 房间没人直接解散
-            if (this.actors.isEmpty()) {
-                this.destroy();
+        }
+
+        // 广播
+        for (Player tmPlayer : this.actors.values()) {
+            if (tmPlayer != null) {
+                tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
             }
         }
+        this.destroy();
     }
 
     /**
@@ -276,11 +280,11 @@ public class GDRoom extends Room {
                                     this.time = 0;
                                 } else {
                                     // 广播
-//                                    for (Player tmPlayer : this.actors.values()) {
-//                                        if (tmPlayer != null) {
-//                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
-//                                        }
-//                                    }
+                                    for (Player tmPlayer : this.actors.values()) {
+                                        if (tmPlayer != null) {
+                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
+                                        }
+                                    }
                                     this.destroy();
                                 }
                                 break;
@@ -294,11 +298,11 @@ public class GDRoom extends Room {
                                     this.time = 0;
                                 } else {
                                     // 广播
-//                                    for (Player tmPlayer : this.actors.values()) {
-//                                        if (tmPlayer != null) {
-//                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
-//                                        }
-//                                    }
+                                    for (Player tmPlayer : this.actors.values()) {
+                                        if (tmPlayer != null) {
+                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
+                                        }
+                                    }
                                     this.destroy();
                                 }
                                 break;
@@ -1282,7 +1286,8 @@ public class GDRoom extends Room {
                 }
             }
             // 设置全局当前级牌点数
-            this.data.curLevelPoint = Math.max(winPlayer.data.levelPointView[0], winPlayer.data.levelPointView[1]);
+            this.data.curLevelPoint = winPlayer.data.levelPointView[0];
+//            this.data.curLevelPoint = Math.max(winPlayer.data.levelPointView[0], winPlayer.data.levelPointView[1]);
         }
 
         Log.info("升级...{}, 原级牌点数: {}, 当前级牌点数: {}", builder.toString(), oldLevelPoint, this.data.curLevelPoint);
@@ -1471,9 +1476,10 @@ public class GDRoom extends Room {
         if (!this.actors.isEmpty()) {
             for (Player player : this.actors.values()) {
                 if (player != null) {
-                    this.leaveRoom(player);
+                    player.resetRoom();
                 }
             }
+            this.actors.clear();
         }
 
         Log.debug("清理房间数据...");
@@ -1525,11 +1531,11 @@ public class GDRoom extends Room {
         data.put("curDiscardSex", this.data.disCardPlayer != null ? this.data.disCardPlayer.data.sex : 0);
         data.put("curPassList", this.data.passList);
         data.put("roomIp",this.data.roomIp);
-        data.put("myInfo", player.playerRoomToMessage(true));
+        data.put("myInfo", this.playerRoomToMessage(player, true));
         List<Map<String, Object>> otherInfo = new ArrayList<>();
         for (Player tmPlayer : this.actors.values()) {
             if (tmPlayer != null && !Objects.equals(tmPlayer.getId(), player.getId())) {
-                otherInfo.add(tmPlayer.playerRoomToMessage(false));
+                otherInfo.add(this.playerRoomToMessage(tmPlayer, false));
             }
         }
         data.put("otherInfo", otherInfo);
@@ -1548,6 +1554,37 @@ public class GDRoom extends Room {
         return data;
     }
 
+    /**
+     * 玩家信息转消息
+     *
+     * @param flag 是否显示手牌
+     * @return
+     */
+    public Map<String, Object> playerRoomToMessage(Player player, boolean flag) {
+        Map<String, Object> data = new HashMap<>();
+        data.put("id", player.getId());
+        data.put("name", player.data.name);
+        data.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
+        data.put("sex", player.data.sex);
+        data.put("pos", player.data.pos);
+        data.put("state", player.data.state);
+        data.put("isAuto", player.data.isAuto);
+        // 级数显示 [我方级数, 对方级数]
+        data.put("levelPointView", player.data.levelPointView);
+        // 队友Id
+        data.put("teammateId", player.data.teammateId);
+
+        // 玩家牌数据
+        Map<String, Object> cardInfo = new HashMap<>();
+        cardInfo.put("remainCards", flag? player.data.remainCards : "");
+        cardInfo.put("remainCardsNum", player.data.remainCards.length);
+        cardInfo.put("discardList", player.data.discardList);
+        cardInfo.put("disCardType", player.data.disCardType);
+        cardInfo.put("tributeGetCard", player.data.tributeGetCard);
+        data.put("cardInfo", cardInfo);
+        return data;
+    }
+
     /**
      * 房间信息转游戏回放
      *

+ 1 - 8
incubator-game/src/main/java/com/incubator/game/room/Room.java

@@ -106,19 +106,12 @@ public class Room implements GRoomInterface {
      */
     public void resetRoom() {}
 
-    /**
-     * 重置房间,用于对象池回收前清理状态
-     */
-    public void reset() {
-        this.isActive = false;
-    }
-
     /**
      * 销毁房间,释放资源
      */
     public void destroy() {
         Log.info("Room {} has been destroyed.", this.data.roomId);
-        this.reset();
+        this.isActive = false;
         this.scheduler.shutdownNow();
         this.scheduler = null;
         // 从缓存移除

+ 66 - 16
incubator-game/src/main/java/com/incubator/game/room/ZDRoom.java

@@ -147,11 +147,15 @@ public class ZDRoom extends Room {
             }
         } finally {
             lock.unlock();
-            // 房间没人直接解散
-            if (this.actors.isEmpty()) {
-                this.destroy();
+        }
+
+        // 广播
+        for (Player tmPlayer : this.actors.values()) {
+            if (tmPlayer != null) {
+                tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
             }
         }
+        this.destroy();
     }
 
     /**
@@ -266,11 +270,11 @@ public class ZDRoom extends Room {
                                     this.time = 0;
                                 } else {
                                     // 广播
-//                                    for (Player tmPlayer : this.actors.values()) {
-//                                        if (tmPlayer != null) {
-//                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
-//                                        }
-//                                    }
+                                    for (Player tmPlayer : this.actors.values()) {
+                                        if (tmPlayer != null) {
+                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
+                                        }
+                                    }
                                     this.destroy();
                                 }
                                 break;
@@ -284,11 +288,11 @@ public class ZDRoom extends Room {
                                     this.time = 0;
                                 } else {
                                     // 广播
-//                                    for (Player tmPlayer : this.actors.values()) {
-//                                        if (tmPlayer != null) {
-//                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
-//                                        }
-//                                    }
+                                    for (Player tmPlayer : this.actors.values()) {
+                                        if (tmPlayer != null) {
+                                            tmPlayer.receive(CommonProto.Cmd.DisbandRoom_VALUE, new HashMap<>());
+                                        }
+                                    }
                                     this.destroy();
                                 }
                                 break;
@@ -474,6 +478,20 @@ public class ZDRoom extends Room {
                     tmPlayer.data.pos = i;
                 }
             }
+
+            // 设置队友
+            Player p0 = this.data.playerMap[0];
+            Player p2 = this.data.playerMap[2];
+            if (p0 != null && p2 != null) {
+                p0.data.teammateId = p2.getId();
+                p2.data.teammateId = p0.getId();
+            }
+            Player p1 = this.data.playerMap[1];
+            Player p3 = this.data.playerMap[3];
+            if (p1 != null && p3 != null) {
+                p1.data.teammateId = p3.getId();
+                p3.data.teammateId = p1.getId();
+            }
         }
     }
 
@@ -1502,9 +1520,10 @@ public class ZDRoom extends Room {
         if (!this.actors.isEmpty()) {
             for (Player player : this.actors.values()) {
                 if (player != null) {
-                    this.leaveRoom(player);
+                    player.resetRoom();
                 }
             }
+            this.actors.clear();
         }
 
         Log.debug("清理房间数据...");
@@ -1556,11 +1575,11 @@ public class ZDRoom extends Room {
         data.put("curDiscardSex", this.data.disCardPlayer != null ? this.data.disCardPlayer.data.sex : 0);
         data.put("curPassList", this.data.passList);
         data.put("roomIp",this.data.roomIp);
-        data.put("myInfo", player.playerRoomToMessage(true));
+        data.put("myInfo", this.playerRoomToMessage(player, true));
         List<Map<String, Object>> otherInfo = new ArrayList<>();
         for (Player tmPlayer : this.actors.values()) {
             if (tmPlayer != null && !Objects.equals(tmPlayer.getId(), player.getId())) {
-                otherInfo.add(tmPlayer.playerRoomToMessage(false));
+                otherInfo.add(this.playerRoomToMessage(tmPlayer, false));
             }
         }
         data.put("otherInfo", otherInfo);
@@ -1580,6 +1599,37 @@ public class ZDRoom extends Room {
         return data;
     }
 
+    /**
+     * 玩家信息转消息
+     *
+     * @param flag 是否显示手牌
+     * @return
+     */
+    public Map<String, Object> playerRoomToMessage(Player player, boolean flag) {
+        Map<String, Object> data = new HashMap<>();
+        data.put("id", player.getId());
+        data.put("name", player.data.name);
+        data.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
+        data.put("sex", player.data.sex);
+        data.put("pos", player.data.pos);
+        data.put("state", player.data.state);
+        data.put("isAuto", player.data.isAuto);
+        // 转蛋积分-累计
+        data.put("accumulatedPoints", player.data.accumulatedPoints);
+        // 队友Id
+        data.put("teammateId", player.data.teammateId);
+
+        // 玩家牌数据
+        Map<String, Object> cardInfo = new HashMap<>();
+        cardInfo.put("remainCards", flag? player.data.remainCards : "");
+        cardInfo.put("remainCardsNum", player.data.remainCards.length);
+        cardInfo.put("discardList", player.data.discardList);
+        cardInfo.put("disCardType", player.data.disCardType);
+        cardInfo.put("tributeGetCard", player.data.tributeGetCard);
+        data.put("cardInfo", cardInfo);
+        return data;
+    }
+
     /**
      * 房间信息转游戏回放
      *

+ 1 - 0
incubator-game/src/main/java/com/incubator/game/util/ContestUtil.java

@@ -37,6 +37,7 @@ public class ContestUtil {
         contestCO.setRunStatus(params.get("runStatus"));
         contestCO.setCost(new BigDecimal(params.get("cost")));
         contestCO.setCurrencyType(params.get("currencyType"));
+        contestCO.setStates(Integer.parseInt(params.get("states")));
         contestCO.setContestSystem("规则:预赛"+Integer.parseInt(params.get("readyNum"))+"局,决赛"+Integer.parseInt(params.get("finalNum"))+"局 不可复活 报名费"+Double.parseDouble(params.get("cost"))+getCurrencyType(contestCO.getCurrencyType()) +
                 "\n赛制:转蛋,双下4分,淘汰赛");
         JSONArray objects1 = new JSONArray(params.get("rewards"));

+ 45 - 18
incubator-game/src/main/java/com/incubator/game/util/GDUtils.java

@@ -899,29 +899,56 @@ public final class GDUtils {
 
     // 判断是否为三带二牌型
     private static boolean isTripleWithTwo(Map<Integer, Long> pointFrequency, int wildCount) {
-        // 找出可以形成三张牌的牌点
-        Optional<Map.Entry<Integer, Long>> tripleEntry = pointFrequency.entrySet().stream()
-                .filter(entry -> entry.getValue() + wildCount >= 3)
-                .findFirst();
-
-        if (tripleEntry.isPresent()) {
-            int tripleCount = (int) (long) tripleEntry.get().getValue(); // 当前牌点已有数量
-            int neededWildsForTriple = 3 - tripleCount; // 补齐三张所需赖子数量
-
-            if (wildCount >= neededWildsForTriple) {
-                // 剩余赖子数量
-                int remainingWilds = wildCount - neededWildsForTriple;
+        // 统计每种点数的牌的数量
+        List<Integer> points = new ArrayList<>(pointFrequency.keySet());
+        points.sort(Comparator.naturalOrder()); // 按点数升序排序
+
+        // 初始化三张和两张的需求
+        boolean hasTriple = false;
+        boolean hasPair = false;
+
+        // 剩余赖子牌数量
+        int remainingWilds = wildCount;
+
+        // 检查是否能构成三张
+        for (Integer point : points) {
+            long count = pointFrequency.get(point);
+            if (count >= 3) {
+                hasTriple = true;
+                break;
+            } else if (count > 0) {
+                int neededWilds = 3 - (int) count;
+                if (remainingWilds >= neededWilds) {
+                    remainingWilds -= neededWilds;
+                    hasTriple = true;
+                    break;
+                }
+            }
+        }
 
-                // 统计剩余牌点的总数
-                int remainingCards = pointFrequency.values().stream().mapToInt(Long::intValue).sum()
-                        + remainingWilds - 3; // 扣除已经组成三张的牌
+        // 如果无法构成三张,直接返回 false
+        if (!hasTriple) {
+            return false;
+        }
 
-                // 判断剩余牌是否可以组成两张
-                return remainingCards >= 2;
+        // 检查是否能构成两张(不允许与三张相同点数)
+        for (Integer point : points) {
+            long count = pointFrequency.get(point);
+            if (count >= 2) {
+                hasPair = true;
+                break;
+            } else if (count > 0) {
+                int neededWilds = 2 - (int) count;
+                if (remainingWilds >= neededWilds) {
+                    remainingWilds -= neededWilds;
+                    hasPair = true;
+                    break;
+                }
             }
         }
 
-        return false; // 无法组成三带二
+        // 返回是否能同时构成三张和两张
+        return hasTriple && hasPair;
     }
 
     // 判断是否为顺子(赖子补齐)