修改长麻,避免多个真人加入房间时线程报错
parent
f6da891aca
commit
78f1ec394d
|
|
@ -239,30 +239,51 @@ 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");
|
||||||
|
|
||||||
//检查Redis中该房间是否真的包含当前机器人
|
String lockKey = "room_lock:" + roomId;
|
||||||
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
|
synchronized (lockKey.intern()) {
|
||||||
//Redis中不存在该机器人 清理本地可能的错误映射
|
if (checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
|
||||||
List<RobotUser> robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId));
|
log.info("机器人{" + robotId + "}已在房间{" + roomId + "}中(Redis 中存在),直接允许加入");
|
||||||
if (!robotUsers.isEmpty()) {
|
} else {
|
||||||
synchronized (robotUsers) {
|
RobotUser existingRobotUser = getRobotRoomInfo(String.valueOf(robotId));
|
||||||
RobotUser robotUser = robotUsers.get(0);
|
if (existingRobotUser != null && existingRobotUser.getCurrentRoomId() == Integer.parseInt(roomId)) {
|
||||||
log.warn("房间{}中Redis未找到机器人{},但本地映射存在{},清理本地映射", roomId, robotId, robotUser.getRobotId());
|
log.info("机器人{" + robotId + "}已在房间{" + roomId + "}中(本地映射存在),直接允许加入");
|
||||||
robotRoomMapping.remove(robotUser.getConnecId());
|
} else {
|
||||||
robotRoomMapping.remove(robotUser.getRobotId());
|
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) {
|
//检查Redis中该房间是否真的包含当前机器人
|
||||||
//不同机器人的冲突
|
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
|
||||||
log.warn("房间{}中Redis已存在机器人{},当前机器人{}不执行加入逻辑", roomId, existingRobotId, robotId);
|
//Redis中不存在该机器人 清理本地可能的错误映射
|
||||||
return;
|
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;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue