修改长麻,避免多个真人加入房间时线程报错

master
zhouwei 2026-03-06 14:27:31 +08:00
parent f6da891aca
commit 78f1ec394d
1 changed files with 122 additions and 23 deletions

View File

@ -239,30 +239,51 @@ public class EXGameController extends GameController {
String roomId = params.getString("roomid");
int groupId = params.getInt("groupid");
//检查Redis中该房间是否真的包含当前机器人
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
//Redis中不存在该机器人 清理本地可能的错误映射
List<RobotUser> 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<RobotUser> 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<RobotUser> 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<RobotUser> 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();
}
}
}