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

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,6 +239,26 @@ public class EXGameController extends GameController {
String roomId = params.getString("roomid"); String roomId = params.getString("roomid");
int groupId = params.getInt("groupid"); int groupId = params.getInt("groupid");
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;
}
}
}
//检查Redis中该房间是否真的包含当前机器人 //检查Redis中该房间是否真的包含当前机器人
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) { if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
//Redis中不存在该机器人 清理本地可能的错误映射 //Redis中不存在该机器人 清理本地可能的错误映射
@ -267,6 +287,7 @@ public class EXGameController extends GameController {
} }
} }
} }
}
log.info("225开始进房间: room:{} robot:{}", roomId, robotId); log.info("225开始进房间: room:{} robot:{}", roomId, robotId);
//加入房间 //加入房间
joinRoomCommon(robotId, roomId, groupId, params); joinRoomCommon(robotId, roomId, groupId, params);
@ -548,4 +569,82 @@ public class EXGameController extends GameController {
return taurusClient; 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();
}
}
} }