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;
}