diff --git a/robots/majiang/robot_mj_hz/pom.xml b/robots/majiang/robot_mj_hz/pom.xml index f4e2433..8faa7fa 100644 --- a/robots/majiang/robot_mj_hz/pom.xml +++ b/robots/majiang/robot_mj_hz/pom.xml @@ -25,7 +25,26 @@ - + + + + + + + + + + + + + + + + + + + + robot @@ -41,7 +60,29 @@ + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + robot.mj.EXMainServer + + + + + + + - + + diff --git a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/Config.java b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/Config.java index 684ded3..c9e85e7 100644 --- a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/Config.java +++ b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/Config.java @@ -29,6 +29,9 @@ public class Config { /** Web组加入房间协议 */ public static final String WEB_GROUP_JOIN_ROOM = "225"; + public static final String WEB_GROUP_JOIN_ROOM11 = "285"; + + /** Web组主动重连协议 */ public static final String WEB_GROUP_ACTIVE_RECONNECT = "226"; @@ -37,10 +40,10 @@ public class Config { /*public static final String GAME_SERVER_HOST = "8.134.76.43"; public static final String DEFAULT_GROUP_ID = "762479";*/ public static final String DEFAULT_GROUP_ID = "426149"; - public static final String GAME_SERVER_HOST = "127.0.0.1"; + public static final String GAME_SERVER_HOST = "8.138.162.178"; /** 游戏服务器端口 */ - public static final String GAME_SERVER_PORT = "6421"; + public static final String GAME_SERVER_PORT = "16421"; /** 默认密码 */ public static final String DEFAULT_PASSWORD = "123456"; @@ -48,5 +51,13 @@ public class Config { /** 默认PID */ public static final String DEFAULT_PID = "22"; + /** + * 机器人HTTP服务端口(接收 web_group 通过 HTTP 发送的 225 协议) + * 规则:TCP端口 + 1000(TCP=8722,HTTP=9722) + */ + public static final int HTTP_SERVER_PORT = 9722; + + /** 机器人HTTP服务路径 */ + public static final String HTTP_PATH_JOIN_ROOM = "/robot/joinRoom"; } \ No newline at end of file diff --git a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXGameController.java b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXGameController.java index 2af2725..71550fc 100644 --- a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXGameController.java +++ b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXGameController.java @@ -229,15 +229,43 @@ public class EXGameController extends GameController { } } + /** - * 接收来自web_group的加入房间协议 + * 接收来自web_group的加入房间协议(TCP 入口,保留原有行为) + * 核心逻辑已提取到 processWebGroupJoin,供 HTTP 入口复用 */ @ActionKey(value = Config.WEB_GROUP_JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER) public void webGroup(Session session, ITObject params, int gid) { int robotId = params.getInt("robotid"); String roomId = params.getString("roomid"); int groupId = params.getInt("groupid"); - + + ITObject result = processWebGroupJoin(robotId, roomId, groupId, params); + + // 仅在"ID冲突"场景下回错误响应,其他场景保持原有静默行为不变 + int code = result.containsKey("code") ? result.getInt("code") : 0; + if (code == 1) { + ITObject errorResponse = TObject.newInstance(); + errorResponse.putString("status", "failed"); + errorResponse.putString("message", result.containsKey("message") ? result.getString("message") : "处理失败"); + MainServer.instance.sendResponse(gid, 1, errorResponse, session); + } + } + + /** + * 处理 web_group 加入房间请求 - 核心逻辑(与传输方式无关) + * 供 TCP 入口(webGroup)和 HTTP 入口(RobotHttpServer)共用 + * + * @param robotId 机器人ID + * @param roomId 房间ID + * @param groupId 群组ID + * @param params 原始参数 + * @return ITObject 处理结果,包含: + * code (0=成功, 1=ID冲突需告知调用方, 2=不同机器人冲突静默忽略) + * message (描述信息) + */ + public ITObject processWebGroupJoin(int robotId, String roomId, int groupId, ITObject params) { + ITObject result = TObject.newInstance(); String lockKey = "room_lock:" + roomId; synchronized (lockKey.intern()) { if (checkRobotInRoomRedis(roomId, String.valueOf(robotId))) { @@ -249,11 +277,9 @@ public class EXGameController extends GameController { } 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; + result.putInt("code", 1); + result.putString("message", "机器人 ID 与房间内玩家冲突"); + return result; } } } @@ -281,7 +307,9 @@ public class EXGameController extends GameController { if (robotId != existingRobotId) { //不同机器人的冲突 log.warn("房间{"+roomId+"}中Redis已存在机器人{"+existingRobotId+"},当前机器人{"+robotId+"}不执行加入逻辑"); - return; + result.putInt("code", 2); + result.putString("message", "Redis已存在其他机器人,不执行加入逻辑"); + return result; } } } @@ -291,8 +319,76 @@ public class EXGameController extends GameController { joinRoomCommon(robotId, roomId, groupId, params); log.info("225 已进入房间准备成功:room:{"+roomId+"} robot:{"+robotId+"}"); } + result.putInt("code", 0); + result.putString("message", "success"); + return result; } + +// /** +// * 接收来自web_group的加入房间协议 +// */ +// @ActionKey(value = Config.WEB_GROUP_JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER) +// public void webGroup(Session session, ITObject params, int gid) { +// int robotId = params.getInt("robotid"); +// String roomId = params.getString("roomid"); +// 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中该房间是否真的包含当前机器人 +// 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("房间{"+roomId+"}中Redis未找到机器人{"+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("房间{"+roomId+"}中Redis已存在机器人{"+existingRobotId+"},当前机器人{"+robotId+"}不执行加入逻辑"); +// return; +// } +// } +// } +// } +// log.info("225 开始进房间:room:{"+roomId+"} robot:{"+robotId+"}"); +// //加入房间 +// joinRoomCommon(robotId, roomId, groupId, params); +// log.info("225 已进入房间准备成功:room:{"+roomId+"} robot:{"+robotId+"}"); +// } +// } + /** * 接收来自web_group的主动重连协议 */ @@ -416,6 +512,8 @@ public class EXGameController extends GameController { //成功响应后才建立映射关系 synchronized (robotRoomMapping) { robotRoomMapping.put(robotUser.getConnecId(), robotUser); + robotConnectionManager.reconnectToGameServer(response, robotUser, client); + } log.info("机器人{"+robotId+"}已成功加入房间{"+roomId+"},建立映射关系"); diff --git a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXMainServer.java b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXMainServer.java index 2a9f209..bed482d 100644 --- a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXMainServer.java +++ b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/EXMainServer.java @@ -17,19 +17,28 @@ import taurus.client.NetManager; import static robot.mj.EXGameController.robotRoomMapping; -/** - * 红中麻将机器人主服务器 - * TCP服务端接收robot_mgr的协议 同时作为客户端连接game_mj_cs处理AI逻辑 - */ + public class EXMainServer extends MainServer{ private static final Logger log = LoggerFactory.getLogger(EXMainServer.class); private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager(); + /** 机器人HTTP服务(接收 web_group 通过 HTTP 发送的 225 协议,替代TCP异步方式) */ + private RobotHttpServer robotHttpServer; + @Override public void onStart() { super.onStart(); + // 启动机器人HTTP服务(接收 web_group 通过 HTTP 发送的 225 协议) + // 替代原 TCP 异步多线程方式(TaurusClient+CompletableFuture),降低CPU占用 + try { + robotHttpServer = new RobotHttpServer(); + robotHttpServer.start(Config.HTTP_SERVER_PORT); + } catch (Exception e) { + log.error("启动 RobotHttpServer 失败,端口:" + Config.HTTP_SERVER_PORT, e); + } + //JVM关闭钩子 Runtime.getRuntime().addShutdownHook(new Thread(() -> { log.info("收到JVM关闭信号,开始优雅关闭..."); @@ -163,6 +172,12 @@ public class EXMainServer extends MainServer{ public void onStop() { super.onStop(); + // 停止机器人HTTP服务 + if (robotHttpServer != null) { + robotHttpServer.stop(); + robotHttpServer = null; + } + log.info("红中麻将机器人服务器已停止"); } } \ No newline at end of file diff --git a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotConnectionManager.java b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotConnectionManager.java index dac1d3b..10ca3f5 100644 --- a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotConnectionManager.java +++ b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotConnectionManager.java @@ -8,8 +8,8 @@ import com.taurus.core.events.Event; import com.taurus.core.events.IEventListener; import com.taurus.core.plugin.redis.Redis; import com.taurus.core.util.ICallback; +import com.taurus.core.util.Logger; import com.taurus.core.util.StringUtil; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; import robot.mj.business.AccountBusiness; import robot.mj.handler.HuNanHongZhong; @@ -20,6 +20,7 @@ import taurus.client.TaurusClient; import taurus.client.SocketCode; import redis.clients.jedis.Jedis; import taurus.util.ROBOTEventType; +import com.taurus.core.util.Logger; import java.util.*; import java.util.concurrent.*; @@ -31,8 +32,9 @@ import static robot.mj.thread.ThreadPoolConfig.scheduleDelay; * 机器人连接管理器 - 管理与游戏服务器的连接 */ public class RobotConnectionManager { + private static final Logger log = Logger.getLogger(RobotConnectionManager.class); - private static final Logger log = LoggerFactory.getLogger(RobotConnectionManager.class); + // private static final Logger log = LoggerFactory.getLogger(RobotConnectionManager.class); private static final Map huNanHongZhongInstances = new ConcurrentHashMap<>(); //记录活跃连接 用于资源清理判断 @@ -45,8 +47,8 @@ public class RobotConnectionManager { private static final long MAX_CONNECTION_LIFETIME = 5 * 60 * 1000; private final EXGameController exGameController; - private final String host= Config.GAME_SERVER_HOST; - private final int port= Integer.parseInt(Config.GAME_SERVER_PORT); + private final String host = Config.GAME_SERVER_HOST; + private final int port = Integer.parseInt(Config.GAME_SERVER_PORT); public RobotConnectionManager() { exGameController = new EXGameController(); @@ -69,7 +71,7 @@ public class RobotConnectionManager { } HuNanHongZhong newInstance = new HuNanHongZhong(); - + //从Redis恢复状态 boolean restored = newInstance.restoreFromRedis(connecId); if (restored) { @@ -77,7 +79,7 @@ public class RobotConnectionManager { } else { log.info("创建新的HuNanHongZhong实例: " + connecId); } - + huNanHongZhongInstances.put(connecId, newInstance); log.info("当前HuNanHongZhong实例总数: " + huNanHongZhongInstances.size()); return newInstance; @@ -103,7 +105,7 @@ public class RobotConnectionManager { //创建Taurus客户端 TaurusClient client = new TaurusClient(host + ":" + port, clientId, TaurusClient.ConnectionProtocol.Tcp); - + //设置事件监听器 setupEventListeners(client, connecId); @@ -204,18 +206,18 @@ public class RobotConnectionManager { try { //获取 msg Message message = (Message) event.getParameter("msg"); - + ITObject param = message.param; //回调协议号 String command = message.command; - + log.info("收到游戏协议 " + command); //根据玩法 ID 处理不同的回调 if (StringUtil.isNotEmpty(command)) { //直接处理协议 handleProtocol(command, message, client, connecId); } } catch (Exception e) { - log.error("处理游戏协议时发生异常:connecId: {}, command: {}", connecId, ((Message)event.getParameter("msg")).command, e); + log.error("处理游戏协议时发生异常:connecId: {}, command: {}", connecId, ((Message) event.getParameter("msg")).command, e); } } }; @@ -243,14 +245,14 @@ public class RobotConnectionManager { * 机器人断线重连 */ public void reconnectToGameServer(MessageResponse response, RobotUser robotUser, TaurusClient client) { - String connecId = robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(); + String connecId = robotUser.getCurrentRoomId() + "_" + robotUser.getRobotId(); //先设置机器人状态为准备状态 robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_READY); - - if(client.isConnected()){ + + if (client.isConnected()) { try { log.info(String.valueOf(response.messageData.param)); - if (response.messageData.param==null) { + if (response.messageData.param == null) { log.info("警告:reconnectToGameServer 重连时未获取到参数"); return; } @@ -363,10 +365,10 @@ public class RobotConnectionManager { } } } - }finally { + } finally { } - }else { + } else { renconnect(robotUser); } } @@ -376,326 +378,321 @@ public class RobotConnectionManager { */ private void handleProtocol(String command, Message message, TaurusClient client, String connecId) { RobotUser robotUser = robotRoomMapping.get(connecId); + log.info("connecId " + connecId); - //更新连接的最后访问时间 - EXGameController.updateLastAccessTime(connecId); - if (robotUser == null) { - log.info("未找到机器人用户信息,连接ID: " + connecId); - return; + for (Map.Entry entry : robotRoomMapping.entrySet()) { + String key = entry.getKey(); + RobotUser user = entry.getValue(); + log.info("Key" + key); + log.info("user seat" + user.getSeat()); + log.info("user connecId" + user.getConnecId()); + log.info("user robotId" + user.getRobotId()); + + log.info("robotRoomMapping " + robotRoomMapping); } - int robotId = Integer.parseInt(robotUser.getRobotId()); - ITObject param = message.param; - HuNanHongZhong huNanHongZhong = getHuNanHongZhongInstance(connecId); - Jedis jedis0 = Redis.use().getJedis(); - Jedis jedis2 = Redis.use("group1_db2").getJedis(); - try { - //红中麻将 机器人处理事件 - //初始化手牌 - if ("811".equalsIgnoreCase(command)) { - robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_WORKING); - huNanHongZhong.cardInHead(command, message, client); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); + //更新连接的最后访问时间 + EXGameController.updateLastAccessTime(connecId); + + if (robotUser == null) { + log.info("未找到机器人用户信息,连接ID: " + connecId); + return; } - //出牌广播 - else if ("812".equalsIgnoreCase(command)) { - huNanHongZhong.drawCard(command, message); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); - } - //摸牌 - else if ("819".equalsIgnoreCase(command)) { - huNanHongZhong.getCard(command, message); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); - } - //出牌,牌权 - else if ("813".equalsIgnoreCase(command)) { - huNanHongZhong.outCard(client); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); - } - //结算 - else if ("817".equalsIgnoreCase(command)) { - huNanHongZhong.getHongZhongCardInhand().clear(); - huNanHongZhong.getChuGuoCardInhand().clear(); - log.info("红中结算"); - Integer type = param.getInt("type"); - if (type == 1 || type == 2) { //为1为大结算 为2为解散 - //更新机器人剩余数量 - updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId())); - - //游戏结束后主动断开连接 - disconnectFromGameServer(connecId); + + int robotId = Integer.parseInt(robotUser.getRobotId()); + ITObject param = message.param; + HuNanHongZhong huNanHongZhong = getHuNanHongZhongInstance(connecId); + Jedis jedis0 = Redis.use().getJedis(); + Jedis jedis2 = Redis.use("group1_db2").getJedis(); + try { + //红中麻将 机器人处理事件 + //初始化手牌 + if ("811".equalsIgnoreCase(command)) { + robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_WORKING); + huNanHongZhong.cardInHead(command, message, client); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); } - ITObject params = TObject.newInstance(); - params.putString("session", client.getSession()); - client.send("1003", params, new ICallback() { - @Override - public void action(MessageResponse messageResponse) { + //出牌广播 + else if ("812".equalsIgnoreCase(command)) { + huNanHongZhong.drawCard(command, message); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); + } + //摸牌 + else if ("819".equalsIgnoreCase(command)) { + huNanHongZhong.getCard(command, message, robotUser); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); + } + //出牌,牌权 + else if ("813".equalsIgnoreCase(command)) { + huNanHongZhong.outCard(client); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); + } + //结算 + else if ("817".equalsIgnoreCase(command)) { + huNanHongZhong.getHongZhongCardInhand().clear(); + huNanHongZhong.getChuGuoCardInhand().clear(); + log.info("红中结算"); + Integer type = param.getInt("type"); + if (type == 1 || type == 2) { //为1为大结算 为2为解散 + //更新机器人剩余数量 + updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId())); + //游戏结束后主动断开连接 + disconnectFromGameServer(connecId); } - }); - } - //杠碰胡通知协议 - else if ("814".equalsIgnoreCase(command)) { - huNanHongZhong.actionCard(param, client); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); - } else if ("820".equalsIgnoreCase(command)) { - HuNanHongZhong.changePlayer(command, message); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); - } - //服务器通知客户端有玩家执行了操作 - else if ("815".equalsIgnoreCase(command)) { - huNanHongZhong.shanchuchuguopai(param); - //处理完协议后保存到Redis - HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); - currentInstance.saveToRedis(connecId); - } - //玩家加入房间 - else if ("2001".equalsIgnoreCase(command)) { - scheduleDelay(() -> { - Jedis jedis = Redis.use().getJedis(); - try { - String roomKey = String.valueOf(robotUser.getCurrentRoomId()); + ITObject params = TObject.newInstance(); + params.putString("session", client.getSession()); + client.send("1003", params, new ICallback() { + @Override + public void action(MessageResponse messageResponse) { - //查询该房间的玩家信息 - String playersStr = jedis.hget("room:"+roomKey, "players"); - if (!playersStr.equals("[]")) { - String players = playersStr.substring(1, playersStr.length() - 1); - String[] playerIds = players.split(","); - - //判断只有当前机器人一个玩家 - if (playerIds.length == 1) { - int playerId = Integer.parseInt(playerIds[0].trim()); - if (playerId == robotId) { - - //发送退出房间协议 - ITObject params = TObject.newInstance(); - client.send("1005", params, response -> { - EXGameController.removeRobotRoomInfo(String.valueOf(robotId)); - //更新机器人剩余数量 - updateLeftoverRobot(robotId); - disconnectFromGameServer(connecId); - log.info("2002发送退出房间协议1005,robotId: {"+robotId+"}"); - }); - } - } } - } catch (Exception e) { - log.error("处理玩家加入房间检查时发生异常", e); - } finally { - //确保Jedis连接关闭 - if (jedis != null) { - jedis.close(); - } - } - }, 6, TimeUnit.SECONDS); - log.info("玩家{"+ robotUser.getCurrentRoomId()+"}加入房间:"+ param); - } - //玩家退出房间也要检查 - else if ("2002".equalsIgnoreCase(command)) { - //直接使用定时任务替代Thread.sleep,避免嵌套异步调用 - scheduleDelay(() -> { - Jedis jedis = Redis.use().getJedis(); - try { - String roomKey = String.valueOf(robotUser.getCurrentRoomId()); - - //查询该房间的玩家信息 - String playersStr = jedis.hget("room:"+roomKey, "players"); - if (!playersStr.equals("[]")) { - String players = playersStr.substring(1, playersStr.length() - 1); - String[] playerIds = players.split(","); - - //判断只有当前机器人一个玩家 - if (playerIds.length == 1) { - int playerId = Integer.parseInt(playerIds[0].trim()); - if (playerId == robotId) { - - //发送退出房间协议 - ITObject params = TObject.newInstance(); - client.send("1005", params, response -> { - EXGameController.removeRobotRoomInfo(String.valueOf(robotId)); - //更新机器人剩余数量 - updateLeftoverRobot(robotId); - disconnectFromGameServer(connecId); - log.info("2002发送退出房间协议1005,robotId: {"+robotId+"}"); - }); - } - } - } - } catch (Exception e) { - log.error("处理玩家退出房间检查时发生异常"); - } finally { - if (jedis != null) { - jedis.close(); - } - } - }, 6, TimeUnit.SECONDS); - } - //玩家解散房间 - else if ("2005".equalsIgnoreCase(command)) { - EXGameController.removeRobotRoomInfo(String.valueOf(robotId)); - //更新机器人剩余数量 - updateLeftoverRobot(robotId); - disconnectFromGameServer(connecId); - log.info("2005玩家发送解散房间协议,robotId: {"+robotId+"}"); - } - //解散房间时候恢复机器人账号可以使用 - else if ("2008".equalsIgnoreCase(command)) { - updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId())); - disconnectFromGameServer(connecId); - } - else if ("2009".equalsIgnoreCase(command)) { - scheduleDelay(() -> { - Jedis jedis = null; - try { - jedis = Redis.use().getJedis(); - Integer paramRobotId = param.getInt("aid"); - if (robotUser != null && paramRobotId != null) { + }); + } + //杠碰胡通知协议 + else if ("814".equalsIgnoreCase(command)) { + huNanHongZhong.actionCard(param, client); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); + } else if ("820".equalsIgnoreCase(command)) { + HuNanHongZhong.changePlayer(command, message); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); + } + //服务器通知客户端有玩家执行了操作 + else if ("815".equalsIgnoreCase(command)) { + huNanHongZhong.shanchuchuguopai(param); + //处理完协议后保存到Redis + HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); + currentInstance.saveToRedis(connecId); + } + //玩家加入房间 + else if ("2001".equalsIgnoreCase(command)) { + scheduleDelay(() -> { + Jedis jedis = Redis.use().getJedis(); + try { String roomKey = String.valueOf(robotUser.getCurrentRoomId()); //查询该房间的玩家信息 - String playersStr = jedis.hget(roomKey, "players"); - if (playersStr != null && !playersStr.equals("[]")) { + String playersStr = jedis.hget("room:" + roomKey, "players"); + if (!playersStr.equals("[]")) { String players = playersStr.substring(1, playersStr.length() - 1); String[] playerIds = players.split(","); //判断只有当前机器人一个玩家 if (playerIds.length == 1) { int playerId = Integer.parseInt(playerIds[0].trim()); - if (playerId == paramRobotId) { + if (playerId == robotId) { + //发送退出房间协议 ITObject params = TObject.newInstance(); client.send("1005", params, response -> { - EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId)); - //断开连接 - disconnectFromGameServer(connecId); + EXGameController.removeRobotRoomInfo(String.valueOf(robotId)); //更新机器人剩余数量 - updateLeftoverRobot(paramRobotId); - log.info("2009发送退出房间协议1005,robotId: {"+paramRobotId+"}"); + updateLeftoverRobot(robotId); + disconnectFromGameServer(connecId); + log.info("2002发送退出房间协议1005,robotId: {" + robotId + "}"); }); } } } + } catch (Exception e) { + log.error("处理玩家加入房间检查时发生异常", e); + } finally { + //确保Jedis连接关闭 + if (jedis != null) { + jedis.close(); + } } - } catch (NumberFormatException e) { - log.error("2009协议数字格式异常,robotId: " + param.get("aid") + ", connecId: " + connecId); - } catch (NullPointerException e) { - log.error("2009协议空指针异常,connecId: " + connecId); - } catch (Exception e) { - log.error("2009协议处理异常: " + e.getMessage() + ", connecId: " + connecId); - } finally { - if (jedis != null) { - jedis.close(); + }, 6, TimeUnit.SECONDS); + log.info("玩家{" + robotUser.getCurrentRoomId() + "}加入房间:" + param); + } + //玩家退出房间也要检查 + else if ("2002".equalsIgnoreCase(command)) { + //直接使用定时任务替代Thread.sleep,避免嵌套异步调用 + scheduleDelay(() -> { + Jedis jedis = Redis.use().getJedis(); + try { + String roomKey = String.valueOf(robotUser.getCurrentRoomId()); + + //查询该房间的玩家信息 + String playersStr = jedis.hget("room:" + roomKey, "players"); + if (!playersStr.equals("[]")) { + String players = playersStr.substring(1, playersStr.length() - 1); + String[] playerIds = players.split(","); + + //判断只有当前机器人一个玩家 + if (playerIds.length == 1) { + int playerId = Integer.parseInt(playerIds[0].trim()); + if (playerId == robotId) { + + //发送退出房间协议 + ITObject params = TObject.newInstance(); + client.send("1005", params, response -> { + EXGameController.removeRobotRoomInfo(String.valueOf(robotId)); + //更新机器人剩余数量 + updateLeftoverRobot(robotId); + disconnectFromGameServer(connecId); + log.info("2002发送退出房间协议1005,robotId: {" + robotId + "}"); + }); + } + } + } + } catch (Exception e) { + log.error("处理玩家退出房间检查时发生异常"); + } finally { + if (jedis != null) { + jedis.close(); + } + } + }, 6, TimeUnit.SECONDS); + } + //玩家解散房间 + else if ("2005".equalsIgnoreCase(command)) { + EXGameController.removeRobotRoomInfo(String.valueOf(robotId)); + //更新机器人剩余数量 + updateLeftoverRobot(robotId); + disconnectFromGameServer(connecId); + log.info("2005玩家发送解散房间协议,robotId: {" + robotId + "}"); + } + //解散房间时候恢复机器人账号可以使用 + else if ("2008".equalsIgnoreCase(command)) { + updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId())); + disconnectFromGameServer(connecId); + } else if ("2009".equalsIgnoreCase(command)) { + scheduleDelay(() -> { + Jedis jedis = null; + try { + jedis = Redis.use().getJedis(); + Integer paramRobotId = param.getInt("aid"); + if (robotUser != null && paramRobotId != null) { + String roomKey = String.valueOf(robotUser.getCurrentRoomId()); + + //查询该房间的玩家信息 + String playersStr = jedis.hget(roomKey, "players"); + if (playersStr != null && !playersStr.equals("[]")) { + String players = playersStr.substring(1, playersStr.length() - 1); + String[] playerIds = players.split(","); + + //判断只有当前机器人一个玩家 + if (playerIds.length == 1) { + int playerId = Integer.parseInt(playerIds[0].trim()); + if (playerId == paramRobotId) { + //发送退出房间协议 + ITObject params = TObject.newInstance(); + client.send("1005", params, response -> { + EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId)); + //断开连接 + disconnectFromGameServer(connecId); + //更新机器人剩余数量 + updateLeftoverRobot(paramRobotId); + log.info("2009发送退出房间协议1005,robotId: {" + paramRobotId + "}"); + }); + } + } + } + } + } catch (NumberFormatException e) { + log.error("2009协议数字格式异常,robotId: " + param.get("aid") + ", connecId: " + connecId); + } catch (NullPointerException e) { + log.error("2009协议空指针异常,connecId: " + connecId); + } catch (Exception e) { + log.error("2009协议处理异常: " + e.getMessage() + ", connecId: " + connecId); + } finally { + if (jedis != null) { + jedis.close(); + } + } + }, 6, TimeUnit.SECONDS); + } + } catch (Exception e) { + log.error("处理接收到的游戏协议异常"); + } finally { + jedis0.close(); + jedis2.close(); + } + } + + /** + * 增加leftover_robot数量 机器人退出房间 + */ + private void updateLeftoverRobot ( int robotId){ + Jedis jedis2 = Redis.use("group1_db2").getJedis(); + try { + + jedis2.hset("gallrobot", String.valueOf(robotId), "0"); + + jedis2.hset("{grobot}:" + robotId, "start", "0"); + + log.info("机器人 {" + robotId + "} 退出房间,修改gallrobot为0"); + } finally { + jedis2.close(); + } + } + + /** + * 机器人登录 + */ + public void login (RobotUser robotUser){ + log.info("开始机器人登录,robotId: {" + robotUser.getRobotId() + "}"); + ITObject object = null; + AccountBusiness accountBusiness = null; + accountBusiness = new AccountBusiness(); + try { + //先快速登录 + object = accountBusiness.fastLogin(Integer.parseInt(robotUser.getRobotId())); + log.info("机器人登录成功,robotId: {" + robotUser.getRobotId() + "}"); + if (object == null) { + object = accountBusiness.idPasswordLogin(Integer.parseInt(robotUser.getRobotId()), robotUser.getPassword()); + } + ITObject finalObject = object; + CompletableFuture.runAsync(() -> { + if (finalObject != null) { + //判断是否有房间 + if (finalObject.getTObject("account") != null) { + ITObject validate = TObject.newInstance(); + validate.putString("token", finalObject.getString("token")); + robotUser.setToken(finalObject.getString("token")); + ; + robotUser.setLoginsession("{user}:" + robotUser.getRobotId()); + if (robotUser.getLoginsession() != null) { + robotUser.setIsLogin(true); + } + if (finalObject.getTObject("account").get("roomid") != null) { + String roomid = finalObject.getTObject("account").get("roomid").toString(); + robotUser.setCurrentRoomId(Integer.parseInt(roomid)); + connectGame(robotUser); + + robotUser.setConnecId(robotUser.getCurrentRoomId() + "_" + robotUser.getRobotId()); + log.info("重启获取的机器人还有当前房间,准备加入: " + robotUser.getConnecId()); + exGameController.webGroupJoinRoom(robotUser); + } } } - }, 6, TimeUnit.SECONDS); + }); + } catch (Exception e) { + log.error("机器人登录异常"); } - } catch (Exception e) { - log.error("处理接收到的游戏协议异常"); - } finally { - jedis0.close(); - jedis2.close(); } - } - /** - * 增加leftover_robot数量 机器人退出房间 - */ - private void updateLeftoverRobot(int robotId) { - Jedis jedis2 = Redis.use("group1_db2").getJedis(); - try { - - jedis2.hset("gallrobot", String.valueOf(robotId), "0"); - - jedis2.hset("{grobot}:" + robotId, "start", "0"); - - log.info("机器人 {"+robotId+"} 退出房间,修改gallrobot为0"); - } finally { - jedis2.close(); - } - } - - /** - * 机器人登录 - */ - public void login(RobotUser robotUser){ - log.info("开始机器人登录,robotId: {"+robotUser.getRobotId()+"}"); - ITObject object = null; - AccountBusiness accountBusiness = null; - accountBusiness = new AccountBusiness(); - try { - //先快速登录 - object = accountBusiness.fastLogin(Integer.parseInt(robotUser.getRobotId())); - log.info("机器人登录成功,robotId: {"+robotUser.getRobotId()+"}"); - if(object==null){ - object = accountBusiness.idPasswordLogin(Integer.parseInt(robotUser.getRobotId()), robotUser.getPassword()); - } - ITObject finalObject = object; - CompletableFuture.runAsync(() -> { - if (finalObject != null) { - //判断是否有房间 - if(finalObject.getTObject("account")!=null){ - ITObject validate = TObject.newInstance(); - validate.putString("token", finalObject.getString("token")); - robotUser.setToken(finalObject.getString("token"));; - robotUser.setLoginsession("{user}:"+robotUser.getRobotId()); - if (robotUser.getLoginsession() != null) { - robotUser.setIsLogin(true); - } - if(finalObject.getTObject("account").get("roomid")!=null){ - String roomid = finalObject.getTObject("account").get("roomid").toString(); - robotUser.setCurrentRoomId(Integer.parseInt(roomid)); - connectGame(robotUser); - - robotUser.setConnecId(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId()); - log.info("重启获取的机器人还有当前房间,准备加入: "+robotUser.getConnecId()); - exGameController.webGroupJoinRoom(robotUser); - } - } - } - }); - } catch (Exception e) { - log.error("机器人登录异常"); - } - } - - public void connectGame(RobotUser robotUser){ - if(robotUser.isLogin){ - if(robotUser.getClient()==null){ - TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "hz"+robotUser.getRobotId(), TaurusClient.ConnectionProtocol.Tcp); - client.setSession(robotUser.getLoginsession()); - client.connect(); - setupEventListeners(client, robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId()); - robotUser.setIsconnect(client.isConnected()); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - log.error("连接超时异常"); - } - robotUser.setClient(client); - EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser); - }else{ - log.info("机器人已连接,准备加入房间"); - log.info("client.isConnected()"+robotUser.getClient().isConnected()); - if(robotUser.getClient().isConnected()){ - robotUser.setIsconnect(true); - }else{ - log.info("reconnect"+robotUser.getClient().getGameID()); - TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "hz"+robotUser.getRobotId(), TaurusClient.ConnectionProtocol.Tcp); + public void connectGame (RobotUser robotUser){ + if (robotUser.isLogin) { + if (robotUser.getClient() == null) { + TaurusClient client = new TaurusClient(robotUser.getGameHost() + ":" + robotUser.getGamePort(), "hz" + robotUser.getRobotId(), TaurusClient.ConnectionProtocol.Tcp); client.setSession(robotUser.getLoginsession()); client.connect(); + setupEventListeners(client, robotUser.getCurrentRoomId() + "_" + robotUser.getRobotId()); robotUser.setIsconnect(client.isConnected()); try { Thread.sleep(1000); @@ -703,44 +700,62 @@ public class RobotConnectionManager { log.error("连接超时异常"); } robotUser.setClient(client); - EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser); + EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId() + "_" + robotUser.getRobotId(), robotUser); + } else { + log.info("机器人已连接,准备加入房间"); + log.info("client.isConnected()" + robotUser.getClient().isConnected()); + if (robotUser.getClient().isConnected()) { + robotUser.setIsconnect(true); + } else { + log.info("reconnect" + robotUser.getClient().getGameID()); + TaurusClient client = new TaurusClient(robotUser.getGameHost() + ":" + robotUser.getGamePort(), "hz" + robotUser.getRobotId(), TaurusClient.ConnectionProtocol.Tcp); + client.setSession(robotUser.getLoginsession()); + client.connect(); + robotUser.setIsconnect(client.isConnected()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + log.error("连接超时异常"); + } + robotUser.setClient(client); + EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId() + "_" + robotUser.getRobotId(), robotUser); + } } } } - } - /** - * 重连 - */ - public void renconnect(RobotUser robotUser){ - TaurusClient client = robotUser.getClient(); - if(client!=null){ - if(client.isConnected()){ - client.connect(); - robotUser.setIsconnect(client.isConnected()); + /** + * 重连 + */ + public void renconnect (RobotUser robotUser){ + TaurusClient client = robotUser.getClient(); + if (client != null) { + if (client.isConnected()) { + client.connect(); + robotUser.setIsconnect(client.isConnected()); + } } } - } - /** - * 根据connecId获取游戏服务器连接 - */ - public TaurusClient getGameClient(String connecId) { - return robotRoomMapping.get(connecId) != null ? robotRoomMapping.get(connecId).getClient() : null; - } - - - public int getTime(){ - return Integer.parseInt((System.currentTimeMillis() + "").substring(0, 10)); - } - - public static void sleepTime(int time) { - try { - //添加延迟 - Thread.sleep(time); - } catch (InterruptedException e) { - log.error("连接超时异常"); + /** + * 根据connecId获取游戏服务器连接 + */ + public TaurusClient getGameClient (String connecId){ + return robotRoomMapping.get(connecId) != null ? robotRoomMapping.get(connecId).getClient() : null; } - } -} \ No newline at end of file + + public int getTime () { + return Integer.parseInt((System.currentTimeMillis() + "").substring(0, 10)); + } + + public static void sleepTime ( int time){ + try { + //添加延迟 + Thread.sleep(time); + } catch (InterruptedException e) { + log.error("连接超时异常"); + } + } + + } \ No newline at end of file diff --git a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotHttpServer.java b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotHttpServer.java new file mode 100644 index 0000000..519fd17 --- /dev/null +++ b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/RobotHttpServer.java @@ -0,0 +1,175 @@ +package robot.mj; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.taurus.core.entity.ITObject; +import com.taurus.core.entity.TObject; +import com.taurus.core.util.Logger; +import com.robot.Global; + + +public class RobotHttpServer { + private static final Logger log = Logger.getLogger(RobotHttpServer.class); + + /** 工作线程数(同时处理的并发请求数) */ + private static final int WORKER_THREADS = 8; + + /** HTTP 响应超时(用于优雅关闭,秒) */ + private static final int STOP_DELAY = 2; + + private HttpServer server; + private ExecutorService executor; + private final Gson gson = new Gson(); + + /** + * 启动 HTTP 服务 + * @param port 监听端口 + * @throws IOException 端口被占用等异常 + */ + public void start(int port) throws IOException { + server = HttpServer.create(new InetSocketAddress(port), 0); + server.createContext(Config.HTTP_PATH_JOIN_ROOM, new JoinRoomHandler()); + executor = Executors.newFixedThreadPool(WORKER_THREADS); + server.setExecutor(executor); + server.start(); + log.info("RobotHttpServer已启动,监听端口:" + port + ",路径:" + Config.HTTP_PATH_JOIN_ROOM + ",工作线程:" + WORKER_THREADS); + } + + /** + * 停止 HTTP 服务 + */ + public void stop() { + if (server != null) { + server.stop(STOP_DELAY); + server = null; + } + if (executor != null) { + executor.shutdown(); + try { + if (!executor.awaitTermination(STOP_DELAY, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + executor = null; + } + log.info("RobotHttpServer已停止"); + } + + /** + * 处理 /robot/joinRoom 请求的 Handler + */ + private class JoinRoomHandler implements HttpHandler { + @Override + public void handle(HttpExchange exchange) throws IOException { + // 仅接受 POST + if (!"POST".equalsIgnoreCase(exchange.getRequestMethod())) { + writeJsonResponse(exchange, 405, buildErrorResponse("Method Not Allowed", "只支持POST请求")); + return; + } + + Map respData = new HashMap<>(); + try { + // 读取请求体 + String body = readRequestBody(exchange); + log.info("HTTP 收到加入房间请求:" + body); + + // 解析 JSON + @SuppressWarnings("unchecked") + Map data = gson.fromJson(body, Map.class); + if (data == null) { + writeJsonResponse(exchange, 400, buildErrorResponse("Bad Request", "请求体为空或非合法JSON")); + return; + } + + Number robotIdNum = (Number) data.get("robotid"); + Object roomIdObj = data.get("roomid"); + Number groupIdNum = (Number) data.get("groupid"); + + if (robotIdNum == null || roomIdObj == null || groupIdNum == null) { + writeJsonResponse(exchange, 400, buildErrorResponse("Bad Request", "缺少必要参数 robotid/roomid/groupid")); + return; + } + + int robotId = robotIdNum.intValue(); + String roomId = String.valueOf(roomIdObj); + int groupId = groupIdNum.intValue(); + + // 构造 ITObject 参数(与原 TCP 入参保持一致) + ITObject params = TObject.newInstance(); + params.putInt("robotid", robotId); + params.putString("roomid", roomId); + params.putInt("groupid", groupId); + + // 调用公共处理逻辑(与 TCP webGroup 方法共用) + ITObject result = ((EXGameController) Global.gameCtr).processWebGroupJoin(robotId, roomId, groupId, params); + + int code = result.containsKey("code") ? result.getInt("code") : 0; + String message = result.containsKey("message") ? result.getString("message") : "success"; + respData.put("code", code); + respData.put("message", message); + } catch (Exception e) { + log.error("HTTP处理加入房间请求异常", e); + respData.put("code", 500); + respData.put("message", "服务器内部错误: " + e.getMessage()); + } + + writeJsonResponse(exchange, 200, respData); + } + + /** + * 读取请求体为字符串 + */ + private String readRequestBody(HttpExchange exchange) throws IOException { + InputStream in = exchange.getRequestBody(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + int n; + while ((n = in.read(buf)) > 0) { + baos.write(buf, 0, n); + } + in.close(); + return new String(baos.toByteArray(), StandardCharsets.UTF_8); + } + + /** + * 写入 JSON 响应 + */ + private void writeJsonResponse(HttpExchange exchange, int httpCode, Map data) throws IOException { + String json = gson.toJson(data); + byte[] bytes = json.getBytes(StandardCharsets.UTF_8); + exchange.getResponseHeaders().set("Content-Type", "application/json; charset=UTF-8"); + exchange.sendResponseHeaders(httpCode, bytes.length); + OutputStream out = exchange.getResponseBody(); + out.write(bytes); + out.close(); + } + + /** + * 构造错误响应 + */ + private Map buildErrorResponse(String error, String message) { + Map data = new HashMap<>(); + data.put("code", -1); + data.put("error", error); + data.put("message", message); + return data; + } + } +} diff --git a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/handler/HuNanHongZhong.java b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/handler/HuNanHongZhong.java index 0306c91..17e40d8 100644 --- a/robots/majiang/robot_mj_hz/src/main/java/robot/mj/handler/HuNanHongZhong.java +++ b/robots/majiang/robot_mj_hz/src/main/java/robot/mj/handler/HuNanHongZhong.java @@ -6,22 +6,26 @@ import com.taurus.core.entity.ITArray; import com.taurus.core.entity.ITObject; import com.taurus.core.entity.TObject; import com.taurus.core.plugin.redis.Redis; +import com.taurus.core.util.Logger; import com.taurus.core.util.StringUtil; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; +import robot.mj.info.RobotUser; import taurus.client.Message; import taurus.client.TaurusClient; import taurus.util.CardUtil; import taurus.util.HongZhongSuanFaTest; import taurus.util.Util; +import com.taurus.core.util.Logger; import java.util.*; import static robot.mj.thread.ThreadPoolConfig.getBusinessThreadPool; public class HuNanHongZhong { - private static final Logger log = LoggerFactory.getLogger(HuNanHongZhong.class); + // private static final Logger log = LoggerFactory.getLogger(HuNanHongZhong.class); + private static final Logger log = Logger.getLogger(HuNanHongZhong.class); + //红中麻将手牌 private final List hongZhongCardInhand = new ArrayList<>(); @@ -78,7 +82,7 @@ public class HuNanHongZhong { public void setSession(String session) { this.session = session; } - + public String getToken() { return token; } @@ -92,9 +96,9 @@ public class HuNanHongZhong { } - /** * 将当前实例状态序列化为JSON字符串并保存到Redis + * * @param connecId 连接ID */ public void saveToRedis(String connecId) { @@ -122,6 +126,7 @@ public class HuNanHongZhong { /** * 从Redis恢复实例状态 + * * @param connecId 连接ID * @return 是否成功恢复 */ @@ -140,14 +145,16 @@ public class HuNanHongZhong { if (stateMap.containsKey("hongZhongCardInhand")) { hongZhongCardInhand.clear(); List handCards = gson.fromJson(stateMap.get("hongZhongCardInhand"), - new TypeToken>(){}.getType()); + new TypeToken>() { + }.getType()); if (handCards != null) hongZhongCardInhand.addAll(handCards); } if (stateMap.containsKey("hongZhongchuguopai")) { hongZhongchuguopai.clear(); List handCards = gson.fromJson(stateMap.get("hongZhongchuguopai"), - new TypeToken>(){}.getType()); + new TypeToken>() { + }.getType()); if (handCards != null) hongZhongchuguopai.addAll(handCards); } @@ -167,6 +174,7 @@ public class HuNanHongZhong { /** * 从Redis清除实例状态 + * * @param connecId 连接ID */ public static void removeFromRedis(String connecId) { @@ -184,6 +192,7 @@ public class HuNanHongZhong { /** * 同步手牌 + * * @param handCard */ public void updateHandCard(List handCard) { @@ -227,18 +236,19 @@ public class HuNanHongZhong { * @param message 消息对象 * @return */ - public String getCard(String command, Message message) { - log.info("摸牌协议-----{} message---{}", command, message); + public String getCard(String command, Message message, RobotUser robotUser) { if (command.equalsIgnoreCase("819")) { ITObject param = message.param; if (param == null) { return null; } -// {seat=2, Ishupai=0, isBaoTing=-1, tingcard=0, isgang=0, card=101, left_count=106} - log.info("轮到用户:{}的用户摸牌, 牌为:{}", param.getInt("player"), param.getInt("card")); - log.debug("用户id: {}", playerId); - log.debug("座位号: {}", param.getInt("seat")); - if (param.getInt("player") != null) { + log.info("819机器人摸牌所有参数" + param); + Integer seat1 = param.getInt("seat"); + Integer seat2 = robotUser.getSeat(); + log.info("819摸牌 后台发的座位号" + seat1); + log.info("819摸牌 机器人座位号" + seat2); + + if (Objects.equals(seat1, seat2)) { int drawnCard = param.getInt("card"); hongZhongSuanFaTest.drawnCards = drawnCard; @@ -434,56 +444,55 @@ public class HuNanHongZhong { public String outCard(TaurusClient client) { // 调用分离分析方法,将刻子、顺子、红中单独拎出后分析剩余牌 try { - System.out.println("当前机器人手牌" + hongZhongCardInhand); - log.info("[HuNanHongZhong] 出牌前分离分析手牌结构..."); - hongZhongSuanFaTest.separateAndAnalyzeHand(hongZhongCardInhand); + System.out.println("当前机器人手牌" + hongZhongCardInhand); + log.info("[HuNanHongZhong] 出牌前分离分析手牌结构..."); + hongZhongSuanFaTest.separateAndAnalyzeHand(hongZhongCardInhand); - // 红中麻将出牌 - String hongzhongOutCard = hongZhongSuanFaTest.outCardSuanFa(hongZhongCardInhand, hongZhongCard); -// String hongzhongOutCard = hongZhongSuanFaTest.outCardSuanFa(list, hongZhongCard); - ITObject params = TObject.newInstance(); - int cardToOut; - if (StringUtil.isNotEmpty(hongzhongOutCard)) { - cardToOut = Integer.parseInt(hongzhongOutCard); - } else { - cardToOut = hongZhongCardInhand.get(0); - } - params.putInt("card", cardToOut); - - int outCountBefore = hongZhongchuguopai.size(); // 当前历史出牌数量 - - // 第n次出牌时,发送前n-1张出牌 - if (outCountBefore >= 1) { - // 发送前n-1张(所有历史出牌) - List cardsToSend = hongZhongchuguopai.subList(0, outCountBefore); - params.putTArray("outcard_list", CardUtil.maJiangToTArray(cardsToSend)); - } - params.putTArray("card_list", CardUtil.maJiangToTArray(hongZhongCardInhand)); - log.info("机器人牌============{}", params); - // 将当前出的牌添加到历史出牌列表 - hongZhongchuguopai.add(cardToOut); - // 从手牌中移除 - hongZhongCardInhand.remove(Integer.valueOf(cardToOut)); - log.info("出牌: {}", cardToOut); - log.info("目前机器人剩余手牌:{}", hongZhongCardInhand.toString()); - params.putString("session", session + "," + token); - - //使用线程池替代CompletableFuture.runAsync + Thread.sleep - getBusinessThreadPool().execute(() -> { - try { - int ot = new Random().nextInt(2); - Thread.sleep(ot * 1000+1000); - client.send("611", params, response -> { - - }); - } catch (Exception e) { - log.error("线程执行错误"); + // 红中麻将出牌 + String hongzhongOutCard = hongZhongSuanFaTest.outCardSuanFa(hongZhongCardInhand, hongZhongCard); + // String hongzhongOutCard = hongZhongSuanFaTest.outCardSuanFa(list, hongZhongCard); + ITObject params = TObject.newInstance(); + int cardToOut; + if (StringUtil.isNotEmpty(hongzhongOutCard)) { + cardToOut = Integer.parseInt(hongzhongOutCard); + } else { + cardToOut = hongZhongCardInhand.get(0); } - }); + params.putInt("card", cardToOut); + + int outCountBefore = hongZhongchuguopai.size(); // 当前历史出牌数量 + + // 第n次出牌时,发送前n-1张出牌 + if (outCountBefore >= 1) { + // 发送前n-1张(所有历史出牌) + List cardsToSend = hongZhongchuguopai.subList(0, outCountBefore); + params.putTArray("outcard_list", CardUtil.maJiangToTArray(cardsToSend)); + } + params.putTArray("card_list", CardUtil.maJiangToTArray(hongZhongCardInhand)); + // 将当前出的牌添加到历史出牌列表 + hongZhongchuguopai.add(cardToOut); + // 从手牌中移除 + hongZhongCardInhand.remove(Integer.valueOf(cardToOut)); + log.info("机器人 出牌"+ cardToOut); + log.info("目前机器人剩余手牌"+ hongZhongCardInhand); + params.putString("session", session + "," + token); + log.info("机器人params" + params); + //使用线程池替代CompletableFuture.runAsync + Thread.sleep + getBusinessThreadPool().execute(() -> { + try { + int ot = new Random().nextInt(2); + Thread.sleep(ot * 1000 + 1000); + client.send("611", params, response -> { + + }); + } catch (Exception e) { + log.error("线程执行错误"); + } + }); - }catch (Exception e) { - // e.printStackTrace(); + } catch (Exception e) { + // e.printStackTrace(); } return null; }