Browse Source

Merge remote-tracking branch 'origin/master'

xhb 4 months ago
parent
commit
bad26a03bd

+ 1 - 1
incubator-common/build.gradle

@@ -14,7 +14,7 @@ dependencies {
     api 'org.slf4j:slf4j-api:2.0.16'
     //声明slf4j转SLF4J的桥接包
 //    api 'org.apache.logging.log4j:log4j-slf4j-impl:2.19.0'
-    testImplementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.24.1'
+    api 'org.apache.logging.log4j:log4j-slf4j2-impl:2.24.1'
     //使用log4j2作为实际的日志实现
     api 'org.apache.logging.log4j:log4j-api:2.24.1'
     api 'org.apache.logging.log4j:log4j-core:2.24.1'

+ 18 - 0
incubator-game/build.gradle

@@ -11,9 +11,22 @@ repositories {
     mavenCentral()
 }
 
+sourceSets {
+    main {
+        resources {
+            srcDirs += 'conf'
+        }
+    }
+}
+
 application {
     // 使用新的方法设置主类,适应 Gradle 7.0 及以上版本
     mainClass.set('com.incubator.game.GameServerStart')
+
+    // 添加 JVM 参数,指定 conf 目录下的配置文件路径
+    applicationDefaultJvmArgs = [
+            "-Dlog4j.configurationFile=conf/log4j2.xml"
+    ]
 }
 
 // 禁用默认的 JAR 任务,因为我们使用 Shadow JAR
@@ -38,6 +51,11 @@ tasks.shadowJar {
         )
     }
 
+    // 将 conf 目录包含到最终的 JAR 文件中
+    from('conf') {
+        into('conf') // 指定 JAR 内的路径
+    }
+
     // 可选:排除不必要的依赖
     exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA'
 }

+ 2 - 2
incubator-game/conf/log4j2.xml

@@ -2,8 +2,8 @@
 <configuration status="WARN" monitorInterval="1800">
 	<properties>
 		<property name="LOG_HOME">logs</property>
-		<property name="LOG_LEVEL_FILE">INFO</property>
-		<property name="LOG_LEVEL_CONSOLE">INFO</property>
+		<property name="LOG_LEVEL_FILE">DEBUG</property>
+		<property name="LOG_LEVEL_CONSOLE">DEBUG</property>
 		<property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</property>
 	</properties>
 

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

@@ -46,22 +46,37 @@ public class Contest {
     /**
      * 初始化
      *
-     * @param roomType
-     * @param contestId
+     * @param roomType  比赛玩法类型
+     * @param contestId 比赛id
+     * @param startTime 比赛开始时间
      */
-    public void init(int roomType, int contestId) {
+    public void init(int roomType, int contestId, long startTime) {
         // 初始化比赛
         this.data = new ContestPO();
         this.data.contestId = contestId;
-        this.data.startTime = System.currentTimeMillis() + (2 * 60 * 1000);
-        this.data.endTime = this.data.startTime + (1 * 60 * 60 * 1000);
+        this.data.startTime = startTime;
         this.data.contestType = 1;
         this.data.level = 1;
-        this.data.name = "五常大米第一期大奖赛";
+        this.data.name = "测试:五常大米第一期大奖赛";
         this.data.url = "https://pic.616pic.com/ad_preview/00/05/85/62733634ac95e.jpg-0.jpg";
         this.data.type = roomType;
     }
 
+    /**
+     * 玩家报名加入比赛
+     *
+     * @param player
+     */
+    public synchronized void joinContest(Player player) {
+        // 加入比赛角色缓存
+        if (!this.actors.containsKey(player.getId())) {
+            this.actors.put(player.getId(), player);
+        }
+        if (!this.data.playerList.contains(player.getId())) {
+            this.data.playerList.add(player.getId());
+        }
+    }
+
     /**
      * 开启官方比赛主线程
      */
@@ -81,8 +96,8 @@ public class Contest {
 //        logger.debug("检测: 官方比赛主线程执行...");
         switch (this.data.state) {
             case 0:
-//                logger.debug("检测: 官方比赛主线程执行...等待开始...比赛id : {}, 人数 : {}, 比赛开始时间 : {}",
-//                        this.data.contestId, this.actors.size(), DateUtils.formatFullDate(new Date(this.data.startTime)));
+                logger.debug("检测: 官方比赛主线程执行...等待开始...比赛id : {}, 人数 : {}, 比赛开始时间 : {}",
+                        this.data.contestId, this.actors.size(), DateUtils.formatFullDate(new Date(this.data.startTime)));
                 // 等待开始
                 if (this.checkReadyStart()) {
                     this.data.state = 1;
@@ -110,7 +125,7 @@ public class Contest {
                         this.data.state = 2;
                         this.data.flag = false;
                         this.data.time = 0;
-                        logger.debug("检测: 比赛id:{}, 比赛人数:{}, 状态:比赛开始...", this.data.contestId, this.data.actors.size());
+                        logger.debug("检测: 比赛id:{}, 比赛人数:{}, 状态:比赛开始...", this.data.contestId, this.actors.size());
                     }
                 }
                 break;
@@ -127,7 +142,7 @@ public class Contest {
                 if (!this.data.flag) {
                     this.data.flag = true;
                     this.data.time = 0;
-                    logger.debug("比赛结束: 比赛id : {}, 比赛人数 : {}", this.data.contestId, this.data.actors.size());
+                    logger.debug("比赛结束: 比赛id : {}, 比赛人数 : {}", this.data.contestId, this.actors.size());
                 }
 //                else {
 //                    // 小于最大局数,切等待状态
@@ -252,9 +267,11 @@ public class Contest {
         this.reset();
         this.scheduler.shutdownNow();
         this.scheduler = null;
-        // 重置比赛数据
+        // 从缓存中移除
+        ContestService.getInstance().contestMap.remove(this.data.contestId);
+        // 重置数据
         this.resetContest();
-        // 归还比赛对象
+        // 归还对象
         ContestService.getInstance().contestPool.releaseContest(this);
         logger.debug("Contest {} has been destroyed.", this.data.contestId);
     }

+ 11 - 11
incubator-game/src/main/java/com/incubator/game/contest/ContestService.java

@@ -36,8 +36,9 @@ public class ContestService {
         logger.info("初始化官方比赛服务...");
         // 初始化对象池
         this.contestPool = new ContestPool(maxIdleContest);
-        //todo 测试创建一个比赛,5分钟后开始
-        this.creatContest(1, 1001);
+        //todo 测试创建一个4人比赛,2分钟后开始
+        long startTime = System.currentTimeMillis() + (2 * 60 * 1000);
+        this.creatContest(1, 1001, startTime);
     }
 
     /**
@@ -58,15 +59,16 @@ public class ContestService {
     /**
      * 创建比赛
      *
-     * @param roomType
-     * @param contestId
+     * @param roomType  比赛房间玩法类型
+     * @param contestId 比赛id
+     * @param startTime 比赛开始时间
      * @return
      */
-    public Contest creatContest(int roomType, int contestId) {
+    public synchronized Contest creatContest(int roomType, int contestId, long startTime) {
         // 从对象池获取比赛实例
         Contest contest = this.contestPool.acquireContest(roomType);
         // 初始化比赛数据
-        contest.init(roomType, contestId);
+        contest.init(roomType, contestId, startTime);
         // 开始主线程逻辑
         contest.startContestTask();
         // 加入缓存
@@ -80,15 +82,13 @@ public class ContestService {
      * @param player
      * @param contestId
      */
-    public Contest joinContest(Player player, int contestId) {
+    public synchronized Contest joinContest(Player player, int contestId) {
         Contest contest = this.contestMap.getOrDefault(contestId, null);
         if (contest == null) {
             return null;
         }
-        // 加入比赛角色缓存
-        if (!contest.actors.containsKey(player.getId())) {
-            contest.actors.put(player.getId(), player);
-        }
+        // 执行玩家加入比赛逻辑
+        contest.joinContest(player);
         // 绑定官方比赛
         player.data.contestId = contestId;
         return contest;

+ 3 - 6
incubator-game/src/main/java/com/incubator/game/data/po/ContestPO.java

@@ -13,11 +13,9 @@ public class ContestPO {
     /** 赛事id */
     public int contestId;
     /** 已报名角色id **/
-    public List<String> actors = new ArrayList<>();
-    /** 开始时间 **/
+    public List<String> playerList = new ArrayList<>();
+    /** 比赛开始时间 **/
     public long startTime;
-    /** 结束时间 **/
-    public long endTime;
 
     /** 比赛类型 1:大奖赛 **/
     public int contestType;
@@ -41,9 +39,8 @@ public class ContestPO {
 
     public void init() {
         this.contestId = 0;
-        this.actors.clear();
+        this.playerList.clear();
         this.startTime = 0L;
-        this.endTime = 0L;
         this.contestType = 0;
         this.level = 0;
         this.name = "";

+ 62 - 0
incubator-game/src/main/java/com/incubator/game/handler/contest/GetSignUpListHandler.java

@@ -0,0 +1,62 @@
+package com.incubator.game.handler.contest;
+
+import com.incubator.common.MessageHandler;
+import com.incubator.common.net.Connection;
+import com.incubator.core.net.ws.NetHandler;
+import com.incubator.core.net.ws.WSRequest;
+import com.incubator.core.net.ws.WSResponse;
+import com.incubator.game.contest.Contest;
+import com.incubator.game.contest.ContestService;
+import com.incubator.game.player.Player;
+import com.incubator.game.util.PlayerUtil;
+import com.incubator.game.util.ProtoUtil;
+import com.incubator.message.proto.CommonProto;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 获取官方比赛报名名单 请求
+ *
+ * @author johnc
+ */
+@MessageHandler(id = CommonProto.Cmd.MatchSignupListReq_VALUE)
+public class GetSignUpListHandler extends NetHandler {
+
+    @Override
+    public void onDate(Connection session, WSRequest request, WSResponse response) {
+        response.setCmd(CommonProto.Cmd.MatchSignupListRes_VALUE);
+
+        Player player = (Player) PlayerUtil.getOnlinePlayer(session.getPlayerId());
+        if (player == null) {
+            logger.info("创建房间失败,找不到玩家");
+            response.setCode(CommonProto.Code.SYSTEM_ERR_VALUE);
+            response.setMessage("操作失败...");
+            return;
+        }
+
+        // 判断参数
+        int contestId = request.getDataValue("contestId", Integer.class, 0);
+        if (contestId <= 0) {
+            logger.info("参数错误");
+            response.setCode(CommonProto.Code.PARAMETER_ERR_VALUE);
+            response.setMessage("参数错误...");
+            return;
+        }
+
+        // 比赛是否存在
+        Contest contest = ContestService.getInstance().contestMap.getOrDefault(contestId, null);
+        if (contest == null) {
+            logger.info("比赛不存在或已结束");
+            response.setCode(CommonProto.Code.CONTEST_NOT_EXIST_ERR_VALUE);
+            response.setMessage("操作失败,比赛不存在或已结束...");
+            return;
+        }
+
+        // 正常返回 比赛报名列表
+        Map<String, Object> data = new HashMap<>();
+        data.put("contestId", contest.data.contestId);
+        data.put("regisList", ProtoUtil.contestRegisListToMessage(contest));
+        response.setData(data);
+    }
+}

+ 18 - 20
incubator-game/src/main/java/com/incubator/game/room/JDGDRoom.java

@@ -45,29 +45,27 @@ public class JDGDRoom extends Room implements GRoomInterface {
      * 玩家加入房间
      */
     @Override
-    public void joinRoom(Player player) {
-        synchronized (this) {
-            // 加入房间角色缓存
-            if (!this.actors.containsKey(player.getId())) {
-                this.actors.put(player.getId(), player);
-            }
+    public synchronized void joinRoom(Player player) {
+        // 加入房间角色缓存
+        if (!this.actors.containsKey(player.getId())) {
+            this.actors.put(player.getId(), player);
+        }
 
-            // 设置座位号
-            int index = 0;
-            for (Player tmpPlayer : this.actors.values()) {
-                if (tmpPlayer != null) {
-                    tmpPlayer.data.pos = index;
-                    this.data.playerMap.put(index, tmpPlayer);
-                    index++;
-                }
+        // 设置座位号
+        int index = 0;
+        for (Player tmpPlayer : this.actors.values()) {
+            if (tmpPlayer != null) {
+                tmpPlayer.data.pos = index;
+                this.data.playerMap.put(index, tmpPlayer);
+                index++;
             }
+        }
 
-            // 推送房间其他3个玩家
-            for (Player tmPlayer : this.actors.values()) {
-                if (tmPlayer != null && !Objects.equals(tmPlayer.getId(), player.getId())) {
-                    Map<String, Object> data = ProtoUtil.roomToMessage(this, tmPlayer, null);
-                    tmPlayer.receive(CommonProto.Cmd.RoomPlayerJoin_VALUE, data);
-                }
+        // 推送房间其他3个玩家
+        for (Player tmPlayer : this.actors.values()) {
+            if (tmPlayer != null && !Objects.equals(tmPlayer.getId(), player.getId())) {
+                Map<String, Object> data = ProtoUtil.roomToMessage(this, tmPlayer, null);
+                tmPlayer.receive(CommonProto.Cmd.RoomPlayerJoin_VALUE, data);
             }
         }
     }

+ 2 - 0
incubator-game/src/main/java/com/incubator/game/room/Room.java

@@ -95,6 +95,8 @@ public class Room {
         this.reset();
         this.scheduler.shutdownNow();
         this.scheduler = null;
+        // 从缓存移除
+        RoomService.getInstance().roomMap.remove(this.roomId);
         // 重置房间数据
         this.resetRoom();
         // 归还房间对象

+ 9 - 11
incubator-game/src/main/java/com/incubator/game/room/RoomService.java

@@ -93,20 +93,18 @@ public class RoomService {
      * @param jsonData  房间规则数据
      * @return
      */
-    public Room creatRoom(Player player, int roomType, JSONObject jsonData) {
+    public synchronized Room creatRoom(Player player, int roomType, JSONObject jsonData) {
         // 从对象池获取房间
         Room room = this.roomPool.acquireRoom(roomType);
 //        int roomId = this.randomRoomId();
-        synchronized (room) {
-            // 初始化房间
-            room.init(player, jsonData);
-            // 开启房间主线程
-//            room.startRoomTask();
-            // 房主加入房间
-            room.joinRoom(player);
-            // 加入管理映射
-            this.roomMap.put(room.roomId, room);
-        }
+        // 初始化房间
+        room.init(player, jsonData);
+        // 开启房间主线程
+//      room.startRoomTask();
+        // 房主加入房间
+        room.joinRoom(player);
+        // 加入管理映射
+        this.roomMap.put(room.roomId, room);
         return room;
     }
 

+ 10 - 10
incubator-game/src/main/java/com/incubator/game/util/JDGDUtils.java

@@ -282,36 +282,36 @@ public final class JDGDUtils {
             return CardType.BOMB;
         }
 
-        // 6. 顺子(5张牌)
+        // 6. 同花顺(可选规则)
+        if (isRoyalFlush(disCardList, curLevel)) {
+            return CardType.ROYAL_FLUSH;
+        }
+
+        // 7. 顺子(5张牌)
         if (cardCount == 5 && uniqueCount == cardCount && isStraight(sortedPoints, curLevel)) {
             return CardType.STRAIGHT;
         }
 
-        // 7. 3连对(3个连续对子)
+        // 8. 3连对(3个连续对子)
         if (cardCount == 6 && uniqueCount * 2 == cardCount && isPairSequence(pointFrequency, curLevel)) {
             return CardType.PAIR_SEQUENCE;
         }
 
-        // 8. 三不带
+        // 9. 三不带
         if (cardCount == 3 && uniqueCount == 1) {
             return CardType.TRIPLE;
         }
 
-        // 9. 三带二
+        // 10. 三带二
         if (cardCount == 5 && uniqueCount == 2 && pointFrequency.containsValue(3L) && pointFrequency.containsValue(2L)) {
             return CardType.TRIPLE_WITH_TWO;
         }
 
-        // 10. 三顺(二个连续三张)
+        // 11. 三顺(二个连续三张)
         if (cardCount == 6 && uniqueCount == cardCount / 3 && isTripleSequence(pointFrequency, curLevel)) {
             return CardType.TRIPLE_SEQUENCE;
         }
 
-        // 11. 同花顺(可选规则)
-        if (isRoyalFlush(disCardList, curLevel)) {
-            return CardType.ROYAL_FLUSH;
-        }
-
         return CardType.INVALID; // 非法牌型
     }
 

+ 25 - 15
incubator-game/src/main/java/com/incubator/game/util/ProtoUtil.java

@@ -188,23 +188,33 @@ public final class ProtoUtil {
             data.put("regisCount", 0);
             data.put("regisMoney", "");
             data.put("regisMoneyType", "");
-            List<Map<String, Object>> regisList = new ArrayList<>();
-            if (!contest.actors.isEmpty()) {
-                Map<String, Object> playerInfo;
-                for (Player player : contest.actors.values()) {
-                    if (player == null) {
-                        continue;
-                    }
-                    playerInfo = new HashMap<>();
-                    playerInfo.put("id", player.getId());
-                    playerInfo.put("name", player.data.name);
-                    playerInfo.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
-                    playerInfo.put("sex", player.data.sex);
-                    regisList.add(playerInfo);
+            data.put("regisList", ProtoUtil.contestRegisListToMessage(contest));
+        }
+        return data;
+    }
+
+    /**
+     * 官方比赛报名列表
+     *
+     * @param contest
+     * @return
+     */
+    public static List<Map<String, Object>> contestRegisListToMessage(Contest contest) {
+        List<Map<String, Object>> regisList = new ArrayList<>();
+        if (!contest.actors.isEmpty()) {
+            Map<String, Object> playerInfo;
+            for (Player player : contest.actors.values()) {
+                if (player == null) {
+                    continue;
                 }
+                playerInfo = new HashMap<>();
+                playerInfo.put("id", player.getId());
+                playerInfo.put("name", player.data.name);
+                playerInfo.put("avatar", "https://img95.699pic.com/element/40109/0194.png_300.png");
+                playerInfo.put("sex", player.data.sex);
+                regisList.add(playerInfo);
             }
-            data.put("regisList", regisList);
         }
-        return data;
+        return regisList;
     }
 }

+ 2 - 0
incubator-message/src/main/proto/CommonProto.proto

@@ -101,6 +101,8 @@ enum Cmd {
     //官方比赛
     MatchSignUpReq = 200701;     // 赛事报名请求
     MatchSignUpRes = 200702;     // 赛事报名响应
+    MatchSignupListReq = 200703;  // 获取官方比赛报名名单请求
+    MatchSignupListRes = 200704;  // 获取官方比赛报名名单响应
 
     // 服务器推送消息 900000-999999 (全部以偶数结尾)
     PlayerInfoUpdate = 900002;  // 玩家信息数据变更推送