From 78f1ec394de24754378cfdfe9fa213e7c1c7333f Mon Sep 17 00:00:00 2001 From: zhouwei <849588297@qq.com> Date: Fri, 6 Mar 2026 14:27:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=95=BF=E9=BA=BB=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=A4=9A=E4=B8=AA=E7=9C=9F=E4=BA=BA=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E6=88=BF=E9=97=B4=E6=97=B6=E7=BA=BF=E7=A8=8B=E6=8A=A5?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/robot/mj/EXGameController.java | 145 +++++++++++++++--- 1 file changed, 122 insertions(+), 23 deletions(-) diff --git a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXGameController.java b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXGameController.java index ae2b8a8..e33b82b 100644 --- a/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXGameController.java +++ b/robots/majiang/robot_mj_cs/src/main/java/robot/mj/EXGameController.java @@ -238,31 +238,52 @@ public class EXGameController extends GameController { int robotId = params.getInt("robotid"); String roomId = params.getString("roomid"); int groupId = params.getInt("groupid"); - - //检查Redis中该房间是否真的包含当前机器人 - if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) { - //Redis中不存在该机器人 清理本地可能的错误映射 - List robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId)); - if (!robotUsers.isEmpty()) { - synchronized (robotUsers) { - RobotUser robotUser = robotUsers.get(0); - log.warn("房间{}中Redis未找到机器人{},但本地映射存在{},清理本地映射", roomId, robotId, robotUser.getRobotId()); - robotRoomMapping.remove(robotUser.getConnecId()); - robotRoomMapping.remove(robotUser.getRobotId()); + + String lockKey = "room_lock:" + roomId; + synchronized (lockKey.intern()) { + if (checkRobotInRoomRedis(roomId, String.valueOf(robotId))) { + log.info("机器人{" + robotId + "}已在房间{" + roomId + "}中(Redis 中存在),直接允许加入"); + } else { + RobotUser existingRobotUser = getRobotRoomInfo(String.valueOf(robotId)); + if (existingRobotUser != null && existingRobotUser.getCurrentRoomId() == Integer.parseInt(roomId)) { + log.info("机器人{" + robotId + "}已在房间{" + roomId + "}中(本地映射存在),直接允许加入"); + } else { + if (isPlayerIdConflictInRoom(roomId, robotId)) { + log.warn("检测到机器人{" + robotId + "}与房间{" + roomId + "}中的真人玩家 ID 冲突,拒绝加入"); + ITObject errorResponse = TObject.newInstance(); + errorResponse.putString("status", "failed"); + errorResponse.putString("message", "机器人 ID 与房间内玩家冲突"); + MainServer.instance.sendResponse(gid, 1, errorResponse, session); + return; + } } } - } else { - //Redis中存在该机器人 检查是否是不同机器人的冲突 - List robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId)); - if (!robotUsers.isEmpty()) { - synchronized (robotUsers) { - RobotUser robotUser = robotUsers.get(0); - int existingRobotId = Integer.parseInt(robotUser.getRobotId()); - - if (robotId != existingRobotId) { - //不同机器人的冲突 - log.warn("房间{}中Redis已存在机器人{},当前机器人{}不执行加入逻辑", roomId, existingRobotId, robotId); - return; + + //检查Redis中该房间是否真的包含当前机器人 + if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) { + //Redis中不存在该机器人 清理本地可能的错误映射 + List robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId)); + if (!robotUsers.isEmpty()) { + synchronized (robotUsers) { + RobotUser robotUser = robotUsers.get(0); + log.warn("房间{}中Redis未找到机器人{},但本地映射存在{},清理本地映射", roomId, robotId, robotUser.getRobotId()); + robotRoomMapping.remove(robotUser.getConnecId()); + robotRoomMapping.remove(robotUser.getRobotId()); + } + } + } else { + //Redis中存在该机器人 检查是否是不同机器人的冲突 + List robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId)); + if (!robotUsers.isEmpty()) { + synchronized (robotUsers) { + RobotUser robotUser = robotUsers.get(0); + int existingRobotId = Integer.parseInt(robotUser.getRobotId()); + + if (robotId != existingRobotId) { + //不同机器人的冲突 + log.warn("房间{}中Redis已存在机器人{},当前机器人{}不执行加入逻辑", roomId, existingRobotId, robotId); + return; + } } } } @@ -548,4 +569,82 @@ public class EXGameController extends GameController { return taurusClient; } + /** + * 检查机器人 ID 是否与房间内已有玩家冲突 + */ + private boolean isPlayerIdConflictInRoom(String roomId, int robotId) { + Jedis jedis = Redis.use().getJedis(); + Jedis jedis2 = Redis.use("group1_db2").getJedis(); + try { + //查询该房间的玩家信息 + String playersStr = jedis.hget("room:" + roomId, "players"); + if (playersStr == null || playersStr.equals("[]")) { + log.info("房间{"+roomId+"}为空,机器人{"+robotId+"}可以加入"); + return false; + } + + String players = playersStr.substring(1, playersStr.length() - 1); + String[] playerIds = players.split(","); + + //统计房间中的真人数量和机器人数量 + int realPlayerCount = 0; + int robotCount = 0; + boolean hasSameRobot = false; + + for (String playerIdStr : playerIds) { + try { + int playerId = Integer.parseInt(playerIdStr.trim()); + + String robotData = jedis2.hget("{robot}:" + playerId, "password"); + boolean isRobot = (robotData != null); + + if (isRobot) { + robotCount++; + //检查是否是相同的机器人 ID + if (playerId == robotId) { + hasSameRobot = true; + } + } else { + realPlayerCount++; + } + } catch (NumberFormatException e) { + log.error("解析玩家 ID 失败:"+playerIdStr); + } + } + + if (hasSameRobot) { + log.info("房间{"+roomId+"}中已有相同机器人{"+robotId+"},允许重复加入"); + return false; + } + + if (realPlayerCount >= 2) { + log.warn("房间{"+roomId+"}中已有{"+realPlayerCount+"}个真人玩家,拒绝机器人{"+robotId+"}加入"); + return true; + } + + if (realPlayerCount == 1) { + if (robotCount == 0) { + log.info("房间{"+roomId+"}中有 1 个真人玩家,允许第一个机器人{"+robotId+"}加入陪打"); + return false; + } + log.info("房间{"+roomId+"}中已有 1 个真人 +1 个机器人,拒绝额外机器人{"+robotId+"}"); + return true; + } + + if (robotCount >= 2) { + log.warn("房间{"+roomId+"}中已有{"+robotCount+"}个机器人,不再添加新机器人{"+robotId+"}"); + return true; + } + + log.info("房间{"+roomId+"}当前状态:真人{"+realPlayerCount+"}人,机器人{"+robotCount+"}个,允许机器人{"+robotId+"}加入"); + return false; + } catch (Exception e) { + log.error("检查房间人数时发生异常,roomId:{"+roomId+"}, robotId:{"+robotId+"}" + e); + return false; + } finally { + jedis.close(); + jedis2.close(); + } + } + } \ No newline at end of file