From 2c6fd5e0a0a20105ad4e8e2c4732eab50d669710 Mon Sep 17 00:00:00 2001
From: zhouwei <849588297@qq.com>
Date: Fri, 6 Feb 2026 21:57:36 +0800
Subject: [PATCH] =?UTF-8?q?init=20=20=E8=B7=91=E5=BE=97=E5=BF=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../puke/robot_pk_pdk/config/game-config.xml | 10 +
.../puke/robot_pk_pdk/config/log4j.properties | 20 +
.../puke/robot_pk_pdk/config/taurus-core.xml | 62 +
.../robot_pk_pdk/config/taurus-permanent.xml | 75 +
robots/puke/robot_pk_pdk/pom.xml | 47 +
.../src/main/java/robot/mj/Config.java | 138 +
.../src/main/java/robot/mj/EXActionEvent.java | 9 +
.../main/java/robot/mj/EXGameController.java | 413 ++
.../src/main/java/robot/mj/EXMainServer.java | 164 +
.../src/main/java/robot/mj/EXPlayer.java | 31 +
.../src/main/java/robot/mj/EXRoom.java | 53 +
.../java/robot/mj/RobotConnectionManager.java | 519 +++
.../src/main/java/robot/mj/RoomCreator.java | 326 ++
.../robot/mj/business/AccountBusiness.java | 380 ++
.../java/robot/mj/handler/HuNanPaoDeKuai.java | 307 ++
.../main/java/robot/mj/info/RobotUser.java | 164 +
.../src/main/java/taurus/util/CardObj.java | 37 +
.../src/main/java/taurus/util/CardUtil.java | 409 ++
.../main/java/taurus/util/ROBOTEventType.java | 13 +
.../src/main/java/taurus/util/test.java | 3336 +++++++++++++++++
.../test/java/robot_mj_hongzhong/Main.java | 15 +
21 files changed, 6528 insertions(+)
create mode 100644 robots/puke/robot_pk_pdk/config/game-config.xml
create mode 100644 robots/puke/robot_pk_pdk/config/log4j.properties
create mode 100644 robots/puke/robot_pk_pdk/config/taurus-core.xml
create mode 100644 robots/puke/robot_pk_pdk/config/taurus-permanent.xml
create mode 100644 robots/puke/robot_pk_pdk/pom.xml
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/Config.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXActionEvent.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXGameController.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXMainServer.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXPlayer.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXRoom.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/RobotConnectionManager.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/RoomCreator.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/business/AccountBusiness.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/handler/HuNanPaoDeKuai.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/robot/mj/info/RobotUser.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/taurus/util/CardObj.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/taurus/util/CardUtil.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/taurus/util/ROBOTEventType.java
create mode 100644 robots/puke/robot_pk_pdk/src/main/java/taurus/util/test.java
create mode 100644 robots/puke/robot_pk_pdk/src/test/java/robot_mj_hongzhong/Main.java
diff --git a/robots/puke/robot_pk_pdk/config/game-config.xml b/robots/puke/robot_pk_pdk/config/game-config.xml
new file mode 100644
index 0000000..2111373
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/config/game-config.xml
@@ -0,0 +1,10 @@
+
+
+
+ 8.134.76.43
+ 8.134.76.43
+ 8766
+ 8766
+ 66
+ true
+
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/config/log4j.properties b/robots/puke/robot_pk_pdk/config/log4j.properties
new file mode 100644
index 0000000..6786dba
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/config/log4j.properties
@@ -0,0 +1,20 @@
+
+log4j.rootLogger = INFO,consoleAppender,fileAppender
+
+# ConsoleAppender
+log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
+log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
+log4j.appender.consoleAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{2} %3x - %m%n
+
+
+# Regular FileAppender
+log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
+log4j.appender.fileAppender.File=${WORKDIR}/logs/web_main.log
+log4j.appender.fileAppender.layout.ConversionPattern=%d{dd MMM yyyy | HH:mm:ss,SSS} | %-5p | %t | %c{3} | %3x | %m%n
+log4j.appender.fileAppender.Encoding=UTF-8
+log4j.appender.fileAppender.DatePattern='.'yyyy-MM-dd
+log4j.appender.dailyFile.Append=true
+
+# The file is rolled over very day
+log4j.appender.fileAppender.DatePattern ='.'yyyy-MM-dd
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/config/taurus-core.xml b/robots/puke/robot_pk_pdk/config/taurus-core.xml
new file mode 100644
index 0000000..d7b7811
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/config/taurus-core.xml
@@ -0,0 +1,62 @@
+
+
+ log4j.properties
+
+
+ redis
+ com.taurus.core.plugin.redis.RedisPlugin
+
+
+
+ 80
+
+ 20
+
+ 5
+
+ -1
+
+ true
+
+ true
+
+ true
+
+ 100
+
+ 60000
+
+ 30000
+
+ 1800000
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/config/taurus-permanent.xml b/robots/puke/robot_pk_pdk/config/taurus-permanent.xml
new file mode 100644
index 0000000..3728386
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/config/taurus-permanent.xml
@@ -0,0 +1,75 @@
+
+
+ 1
+
+ 512
+
+ Heap
+
+ Heap
+
+ 524288
+
+ 1024
+
+ 32768
+
+ 160
+
+
+ 1
+ 2
+ 1
+
+
+ true
+
+ 300
+
+
+
+
+
+
+
+
+
+ 1.2.3.4
+
+
+ 127.0.0.1
+
+ 10000
+
+
+
+ false
+ 0.0.0.0
+ 80
+
+
+
+
+ robot - test
+ robot.mj.EXMainServer
+
+
+
+
+ Sys
+ 2
+ 8
+ 60000
+ 20000
+
+
+
+
+ Ext
+ 2
+ 8
+ 60000
+ 20000
+
+
+
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/pom.xml b/robots/puke/robot_pk_pdk/pom.xml
new file mode 100644
index 0000000..5821a88
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/pom.xml
@@ -0,0 +1,47 @@
+
+ 4.0.0
+
+ com.robot
+ robot_pk_paodekuai
+ 1.0.0
+ jar
+
+ robot_mj_changsha
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ com.robot
+ robot_common
+ 1.0.0
+
+
+
+
+
+
+
+
+ robot
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+
+
+
+
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/Config.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/Config.java
new file mode 100644
index 0000000..1b30f78
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/Config.java
@@ -0,0 +1,138 @@
+package robot.mj;
+
+public class Config {
+ public static final int FENGDING_SCORE = 28;
+ public static final int XIPAI_SCORE = 10;
+
+ public static final int ANCHOU_SCORE = 10;
+
+ public static final String ROOM_CONFIG_ZIMO = "zimo";
+ public static final String ROOM_CONFIG_ZHUANGXIAN = "zhuangxian";
+ public static final String ROOM_CONFIG_NIAO = "niao";
+ public static final String ROOM_CONFIG_NIAO_TYPE = "niao_type";
+ public static final String ROOM_CONFIG_PIAO_NIAO = "piao_niao"; //0:不嫖 1:自由票 2:固定票
+ public static final String ROOM_CONFIG_PIAO_NIAO_AUTO = "auto_piao"; //piao fen
+ public static final String ROOM_CONFIG_PIAO_NIAO_OPT = "piao_niao_opt"; //piao fen
+ public static final String ROOM_CONFIG_ZT_LIULIUSHUN = "zhongtuliuliushun";
+ public static final String ROOM_CONFIG_ZT_DASIXI = "zhongtusixi";
+ public static final String ROOM_CONFIG_QS_JIEJIEGAO = "jiejiegao";
+ public static final String ROOM_CONFIG_QS_SANTONG = "santong";
+ public static final String ROOM_CONFIG_QS_YIZHIHUA = "yizhihua";
+ public static final String ROOM_CONFIG_QUEYIMEN = "queyimen";
+ public static final String ROOM_CONFIG_FENGDING = "fengding";
+ public static final String ROOM_CONFIG_FENGDING_SCORE = "fengding_score";
+ public static final String ROOM_CONFIG_XIPAI = "xi_pai";
+ public static final String ROOM_CONFIG_XIPAI_SCORE = "xi_pai_score";
+
+ public static final String ROOM_CONFIG_ANCHOU_SCORE = "an_chou_score";
+
+ public static final String ROOM_CONFIG_DIFEN_SCORE = "difen_score";
+ public static final String ROOM_CONFIG_NIAOFEN_SCORE = "niaofen_score";
+ public static final String ROOM_CONFIG_NIAOFEN_OPT = "niaofen_opt"; //0中鸟加分,//1中鸟加倍
+ public static final String ROOM_CONFIG_KAI_GONG = "kai_gong"; //0:开杠2张,1:开杠四张
+
+
+ public static final int NIAO_TYPE_ADD = 0;
+
+ public static final int NIAO_TYPE_DOUBLE = 1;
+
+ public static final int NIAO_TYPE_CS2NIAO = 2;
+
+
+ public static final String ROOM_CONFIG_QS_JTYN = "two_pair";
+
+ public static final String ROOM_CONFIG_NO_JIANG = "no_jiang";
+
+ public static final String ROOM_CONFIG_NATIVE_HU = "native_hu";
+
+
+ public static final String ROOM_CONFIG_FOUR_WIN = "four_win";
+
+ public static final String SETTLE_XIAO_DIAN_PAO = "xiao_dian_pao";
+ public static final String SETTLE_XIAO_JIE_PAO = "xiao_jie_pao";
+ public static final String SETTLE_XIAO_ZIMO = "xiao_zimo";
+ public static final String SETTLE_DA_DIAN_PAO = "da_dian_pao";
+ public static final String SETTLE_DA_JIE_PAO = "da_jie_pao";
+ public static final String SETTLE_DA_ZIMO = "da_zimo";
+
+
+ public static final String GAME_EVT_PLAYER_DEAL = "811";
+
+ public static final String GAME_DIS_CARD = "611";
+
+ public static final String GAME_EVT_DISCARD = "812";
+
+ public static final String GAME_EVT_DISCARD_TIP = "813";
+
+ public static final String GAME_EVT_FZTIPS = "814";
+
+ public static final String GAME_ACTION = "612";
+
+ public static final String GAME_EVT_ACTION = "815";
+
+ public static final String GAME_EVT_HU = "816";
+
+ public static final String GAME_EVT_RESULT1 = "817";
+
+ public static final String GAME_EVT_RESULT2 = "818";
+
+ public static final String GAME_EVT_DRAW = "819";
+
+ public static final String GAME_EVT_CHANGE_ACTIVE_PLAYER = "820";
+
+ public static final String GAME_EVT_NIAO = "821";
+
+ public static final String GAME_EVT_QSTIP = "822";
+
+ public static final String GAME_EVT_QSWIN = "823";
+
+ public static final String GAME_EVT_OPENKONG = "824";
+
+ public static final String GAME_EVT_HAIDITIP = "825";
+
+ public static final String GAME_EVT_PIAONIAO_TIP = "833";
+
+ public static final String GAME_EVT_PIAONIAO = "834";
+
+ public static final String GAME_EVT_TING_TIP = "835";
+
+ public static final String GAME_EVT_TING = "836";
+
+ public static final String CREATE_ROOM_ROBOT = "create_room_for_robot";
+ public static final String INIT_CONNECTION = "init_connection";
+
+ /**
+ * 加入房间 - robot_mgr to robot_mj_cs 的内部协议号
+ */
+ public static final String JOIN_ROOM = "2002";
+
+ /**
+ * 发送准备 - robot_mgr to robot_mj_cs 的内部协议号
+ */
+ public static final String GAME_READY = "2003";
+
+ /**
+ * 退出房间 - robot_mgr to robot_mj_cs 的内部协议号
+ */
+ public static final String EXIT_ROOM = "2005";
+
+ /**
+ * 手动重连 - robot_mgr to robot_mj_cs 的内部协议号
+ */
+ public static final String RECONNECT = "2006";
+
+ /**
+ * 发送准备 - robot_mj_cs to game_mj_cs 的协议号
+ */
+ public static final String GAME_READY_CS = "1003";
+
+ /**
+ * 加入房间 - robot_mgr to game_mj_cs 的内部协议号
+ */
+ public static final String JOIN_ROOM_CS = "1002";
+
+ /**
+ * 退出房间 - robot_mgr to game_mj_cs 的内部协议号
+ */
+ public static final String EXIT_ROOM_CS = "1005";
+}
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXActionEvent.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXActionEvent.java
new file mode 100644
index 0000000..556d1b3
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXActionEvent.java
@@ -0,0 +1,9 @@
+package robot.mj;
+
+public class EXActionEvent {
+
+ public static final String EVENT_ACTION = "action";
+
+ public static final String EVENT_DISCARD = "discard";
+
+}
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXGameController.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXGameController.java
new file mode 100644
index 0000000..8fb3187
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXGameController.java
@@ -0,0 +1,413 @@
+package robot.mj;
+
+import com.robot.GameController;
+import com.robot.GameInterceptor;
+import com.robot.MainServer;
+import com.taurus.core.entity.ITObject;
+import com.taurus.core.entity.TObject;
+import com.taurus.core.plugin.redis.Redis;
+import com.taurus.core.routes.ActionKey;
+import com.taurus.permanent.data.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+import robot.mj.info.RobotUser;
+import taurus.client.TaurusClient;
+import taurus.client.business.GroupRoomBusiness;
+import taurus.util.ROBOTEventType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 跑得快游戏控制器 - 处理游戏协议
+ */
+public class EXGameController extends GameController {
+ private static final Logger log = LoggerFactory.getLogger(EXGameController.class);
+
+ private static final RobotConnectionManager robotConnectionManager = new RobotConnectionManager();
+
+ //机器人房间
+ protected static final Map robotRoomMapping = new ConcurrentHashMap<>();
+
+ public EXGameController() {
+ super();
+ log.info("跑得快游戏控制器已初始化");
+ }
+
+ /**
+ * 处理客户端初始化/认证协议
+ */
+ @ActionKey(value = Config.INIT_CONNECTION, validate = GameInterceptor.NOT_PLAYER)
+ public void handleInitialization(Session session, ITObject params, int gid) {
+ try {
+ log.info("收到客户端初始化请求,Session: {}, GID: {}, 参数: {}", session, gid, params);
+
+ String type = params.getString("type");
+ String client = params.getString("client");
+ log.info("客户端类型: {}, 客户端标识: {}", type, client);
+
+ //验证参数
+ if ("robot_mj_cs".equals(type) && "robot_mgr".equals(client)) {
+ //返回成功响应
+ ITObject response = TObject.newInstance();
+ response.putString("status", "success");
+ response.putString("message", "初始化成功");
+
+ log.info("客户端初始化成功,发送响应");
+ MainServer.instance.sendResponse(gid, 0, response, session);
+ } else {
+ log.warn("客户端初始化失败,参数验证不通过: type={}, client={}", type, client);
+
+ ITObject response = TObject.newInstance();
+ response.putString("status", "failed");
+ response.putString("message", "参数验证失败");
+ MainServer.instance.sendResponse(gid, 1, response, session);
+ }
+ } catch (Exception e) {
+ log.error("处理初始化请求时发生错误", e);
+
+ ITObject response = TObject.newInstance();
+ response.putString("status", "error");
+ response.putString("message", "服务器内部错误: " + e.getMessage());
+
+ MainServer.instance.sendResponse(gid, 1, response, session);
+ }
+ }
+
+ /**
+ * 接收来自robot_mgr的创建房间协议
+ */
+ @ActionKey(value = Config.CREATE_ROOM_ROBOT, validate = GameInterceptor.NOT_PLAYER)
+ public void createRoomForRobot(Session session, ITObject params, int gid) {
+ try {
+ int reqGroupId = params.getInt("groupId");
+ int wanfaId = params.getInt("wanfaId");
+ int robotId = params.getInt("robotId");
+
+ //使用统一的房间创建器在Redis中创建房间
+ RoomCreator.RoomInfo roomInfo = RoomCreator.createRoomInRedis(reqGroupId, wanfaId, robotId);
+
+ if (roomInfo != null) {
+ //返回房间信息给robot_mgr
+ ITObject response = TObject.newInstance();
+ response.putString("roomKey", roomInfo.getRoomId());
+ response.putInt("groupId", roomInfo.getGroupId());
+ response.putInt("wanfaId", roomInfo.getWanfaId());
+ response.putInt("robotId", robotId);
+ response.putString("server_ip", roomInfo.getServerIp());
+ response.putInt("server_port", roomInfo.getServerPort());
+
+ log.info("成功创建房间,房间ID: {}", roomInfo.getRoomId());
+ //使用Taurus框架方法发送响应
+ MainServer.instance.sendResponse(gid, 0, response, session);
+ } else {
+ log.error("创建房间失败,群组ID: {}, 玩法ID: {}", reqGroupId, wanfaId);
+ }
+ } catch (Exception e) {
+ log.error("处理创建房间请求时发生错误", e);
+ }
+ }
+
+ /**
+ * 接收来自robot_mgr的加入房间协议
+ */
+ @ActionKey(value = Config.JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER)
+ public void joinRoom(Session session, ITObject params, int gid) {
+ try {
+ String connecId = params.getString("connecId");
+ TaurusClient client = getCsMjGameServerConnection(connecId);
+ System.out.println("接收来自robot_mgr的加入房间协议 connecId: = "+connecId);
+ System.out.println("接收来自robot_mgr的加入房间协议 client: = "+client);
+ if (client == null) {
+ ITObject errorResponse = TObject.newInstance();
+ errorResponse.putString("status", "failed");
+ errorResponse.putString("message", "无法获取游戏服务器连接");
+ MainServer.instance.sendResponse(gid, 1, errorResponse, session);
+ return;
+ }
+
+ //设置session和token
+ String sessionToken = params.getString("session");
+ String robotSession = null;
+ String token = null;
+ if (sessionToken != null && sessionToken.contains(",")) {
+ String[] sessionParts = sessionToken.split(",");
+ if (sessionParts.length >= 2) {
+ robotSession = sessionParts[0];
+ token = sessionParts[1];
+ robotConnectionManager.setSessionAndToken(robotSession, token, connecId);
+ }
+ }
+
+ Integer groupId = params.getInt("groupId");
+ String roomId = params.getString("roomId");
+ String robotId = params.getString("robotId");
+
+ GroupRoomBusiness.joinRoom(groupId, roomId, robotSession, null);
+
+ Thread.sleep(5000);
+
+ params.del("groupId");
+ params.del("roomId");
+ params.del("connecId");
+ //发送加入房间请求到game_mj_cs
+ client.send(Config.JOIN_ROOM_CS, params, response -> {
+ System.out.println("joinRoomController: " + response);
+ RobotUser roomInfo = new RobotUser();
+ roomInfo.setCurrentRoomId(Integer.parseInt(roomId));
+ roomInfo.setConnecId(connecId);
+ roomInfo.setUserId(0);
+ //机器人房间映射关系
+ robotRoomMapping.put(robotId, roomInfo);
+ });
+
+ ITObject paramsReq = TObject.newInstance();
+ paramsReq.putString("status", "success");
+ MainServer.instance.sendResponse(gid, 0, paramsReq, session);
+
+ } catch (Exception e) {
+ log.error("处理加入房间请求时发生错误", e);
+ ITObject errorResponse = TObject.newInstance();
+ errorResponse.putString("status", "error");
+ errorResponse.putString("message", "处理加入房间请求时发生错误: " + e.getMessage());
+ MainServer.instance.sendResponse(gid, 1, errorResponse, session);
+ }
+ }
+
+ /**
+ * 接收来自robot_mgr的机器人准备协议
+ */
+ @ActionKey(value = Config.GAME_READY, validate = GameInterceptor.NOT_PLAYER)
+ public void robotReadyRoom(Session session, ITObject params, int gid) {
+ try {
+ String connecId = params.getString("connecId");
+ TaurusClient client = getCsMjGameServerConnection(connecId);
+ System.out.println("接收来自robot_mgr的机器人准备协议 connecId: = "+connecId);
+ System.out.println("接收来自robot_mgr的机器人准备协议 client: = "+client);
+ if (client == null) {
+ ITObject errorResponse = TObject.newInstance();
+ errorResponse.putString("status", "failed");
+ errorResponse.putString("message", "无法获取游戏服务器连接");
+ MainServer.instance.sendResponse(gid, 1, errorResponse, session);
+ return;
+ }
+
+ params.del("connecId");
+ Thread.sleep(1000);
+ //发送准备请求到game_mj_cs
+ client.send(Config.GAME_READY_CS, params, response -> {
+ System.out.println("robotReadyRoom: " + response);
+ });
+
+ ITObject paramsReq = TObject.newInstance();
+ paramsReq.putString("status", "success");
+ MainServer.instance.sendResponse(gid, 0, paramsReq, session);
+
+ } catch (Exception e) {
+ log.error("处理机器人准备请求时发生错误", e);
+ ITObject errorResponse = TObject.newInstance();
+ errorResponse.putString("status", "error");
+ errorResponse.putString("message", "服务器内部错误: " + e.getMessage());
+ MainServer.instance.sendResponse(gid, 1, errorResponse, session);
+ }
+ }
+
+ /**
+ * 接收来自web_group的加入房间协议
+ */
+ @ActionKey(value = "225", 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");
+
+ //防止玩家操作同一房间 导致其他机器人加入
+ List robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId));
+ if (!robotUsers.isEmpty()) {
+ synchronized (robotUsers) {
+ RobotUser robotUser = robotUsers.get(0);
+ if (robotId != Integer.parseInt(robotUser.getRobotId())) {
+ System.err.println("房间{"+ roomId +"}中已有机器人{"+robotUser.getRobotId()+"},当前机器人{"+robotId+"}不执行加入逻辑");
+ return;
+ }
+ }
+ }
+ System.err.println("225开始进房间: "+"room:"+ roomId +"robot:"+robotId);
+ //加入房间
+ joinRoomCommon(robotId, roomId, groupId, params);
+ System.err.println("225已进入房间准备成功: "+"room:"+ roomId +"robot:"+robotId);
+ }
+
+ /**
+ * 接收来自web_group的主动重连协议
+ */
+ @ActionKey(value = "226", validate = GameInterceptor.NOT_PLAYER)
+ public void webGroupActive(Session session, ITObject params, int gid) {
+ int robotId = params.getInt("robotid");
+ String roomId = params.getString("roomid");
+ System.err.println("226开始进房间: " + "room:" + roomId + "robot:" + robotId);
+ //加入房间
+ joinRoomCommon(params.getInt("robotid"), params.getString("roomid"), params.getInt("groupid"), params);
+ System.err.println("226已进入房间准备成功: " + "room:" + roomId + "robot:" + robotId);
+ }
+
+ /**
+ * 重启服务断线重连
+ * */
+ public void webGroupJoinRoom(RobotUser robotUser) {
+ String connecId = robotUser.getConnecId();
+ Jedis jedis0 = Redis.use("group1_db0").getJedis();
+ Jedis jedis2 = Redis.use("group1_db2").getJedis();
+ //重启检查
+ try {
+ Set robotTokens = jedis0.smembers("{user}:"+robotUser.getRobotId()+"_token");
+ String robotSession = null;
+
+ for (String token : robotTokens) {
+ if (jedis0.exists(token)) {
+ robotSession = token;
+ break;
+ }
+ }
+ String gallrobot = jedis2.hget("gallrobot", robotUser.getRobotId());
+ if (gallrobot.equals("0")) {
+ robotRoomMapping.remove(connecId);
+ return;
+ }
+
+ System.err.println("重启后开始进房间: " + "room:" + robotUser.getCurrentRoomId() + "robot:" + robotUser.getRobotId());
+ ITObject params = new TObject();
+ params.putString("session", "{user}:" + robotUser.getRobotId() + "," + robotSession);
+ //加入房间
+ joinRoomCommon(Integer.parseInt(robotUser.getRobotId()), String.valueOf(robotUser.getCurrentRoomId()), Integer.parseInt(robotUser.getRobotGroupid()), params);
+ System.err.println("重启后已进入房间准备成功: " + "room:" + robotUser.getCurrentRoomId() + "robot:" + robotUser.getRobotId());
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ jedis0.close();
+ jedis2.close();
+ }
+ }
+
+ /**
+ * 加入房间逻辑
+ */
+ private void joinRoomCommon(int robotId, String roomId, int groupId, ITObject params) {
+ Jedis jedis0 = Redis.use("group1_db0").getJedis();
+ Jedis jedis2 = Redis.use("group1_db2").getJedis();
+ try {
+ Set robotTokens = jedis0.smembers("{user}:" + robotId + "_token");
+ String robotSession = null;
+
+ for (String token : robotTokens) {
+ if (jedis0.exists(token)) {
+ robotSession = token;
+ break;
+ }
+ }
+
+ System.err.println("开始进房间: room:" + roomId);
+ System.err.println("开始进房间: {user}:" + robotId);
+
+ TaurusClient client = getCsMjGameServerConnection(roomId + "_" + robotId);
+ GroupRoomBusiness.joinRoom(groupId, "room:" + roomId, "{user}:" + robotId, null);
+
+ //机器人房间映射关系
+ RobotUser robotUser = getRobotRoomInfo(String.valueOf(robotId));
+ String connecId = roomId + "_" + robotId;
+ if (robotUser.getCurrentRoomId() == 0) {
+ robotUser.setCurrentRoomId(Integer.parseInt(roomId));
+ robotUser.setClient(client);
+ robotUser.setConnecId(connecId);
+ }
+ robotRoomMapping.put(robotUser.getConnecId(), robotUser);
+ robotRoomMapping.remove(robotUser.getRobotId());
+ Thread.sleep(2000);
+ params.putString("session", "{user}:" + robotId + "," + robotSession);
+
+ //发送加入房间请求到game_mj_cs
+ client.send(Config.JOIN_ROOM_CS, params, response -> {
+ robotConnectionManager.reconnectToGameServer(response, robotUser, client);
+ });
+ System.err.println("已进入房间成功: " + robotUser.getConnecId());
+ Thread.sleep(1000);
+ if (client.isConnected()) {
+ client.send(Config.GAME_READY_CS, params, response -> {
+ System.out.println("1003:" + response);
+ });
+ jedis2.hset("gallrobot", String.valueOf(robotUser.getRobotId()), "1");
+
+ robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_READY);
+ robotConnectionManager.setSessionAndToken("{user}:" + robotId, robotSession, robotUser.getConnecId());
+ }
+ robotUser.setIntoRoomTime(robotConnectionManager.getTime());
+ System.err.println("已进入房间准备成功: " + robotUser.getConnecId());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ jedis0.close();
+ jedis2.close();
+ }
+ }
+
+ /**
+ * 根据机器人ID获取其所在的房间信息
+ */
+ public static RobotUser getRobotRoomInfo(String robotId) {
+ RobotUser robotUser = robotRoomMapping.get(robotId);
+ if (robotUser ==null) {
+ RobotUser robotUserCopy = new RobotUser();
+ robotUserCopy.setRobotId(robotId);
+ robotUserCopy.setPassword("123456");
+ robotUserCopy.setGameHost("8.134.76.43");
+ robotUserCopy.setGamePort("6841");
+ robotUserCopy.setRobotGroupid("330800");
+ robotUserCopy.setRobotPid("66");
+ return robotUserCopy;
+ }
+ return robotRoomMapping.get(robotId);
+ }
+
+ /**
+ * 根据房间ID获取所有对应的RobotUser
+ */
+ public List getRobotUsersByRoomId(int roomId) {
+ String prefix = roomId + "_";
+ List result = new ArrayList<>();
+
+ for (Map.Entry entry : robotRoomMapping.entrySet()) {
+ if (entry.getKey().startsWith(prefix)) {
+ result.add(entry.getValue());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 根据机器人ID删除其所在的房间信息
+ */
+ public static void removeRobotRoomInfo(String robotId) {
+ robotRoomMapping.remove(robotId);
+ }
+
+ /**
+ * 根据机器人ID和连接ID获取跑得快游戏服务器连接
+ * 基于robotId和connectionId的组合复用连接
+ */
+ public static TaurusClient getCsMjGameServerConnection(String connecId) {
+ TaurusClient taurusClient = robotConnectionManager.getGameClient(connecId);
+ System.out.println("根据机器人ID和连接ID获取跑得快游戏服务器连接 client: = "+taurusClient);
+ if (taurusClient != null) {
+ log.debug("成功获取游戏服务器连接,connecId: {}", connecId);
+ return taurusClient;
+ }
+ taurusClient = robotConnectionManager.connectToGameServer(connecId);
+ return taurusClient;
+ }
+
+}
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXMainServer.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXMainServer.java
new file mode 100644
index 0000000..5301bd6
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXMainServer.java
@@ -0,0 +1,164 @@
+package robot.mj;
+
+import java.util.Map;
+
+import com.robot.GameController;
+import com.robot.MainServer;
+import com.robot.data.Player;
+import com.robot.data.Room;
+import com.taurus.core.entity.ITObject;
+import com.taurus.core.entity.TObject;
+import com.taurus.core.plugin.redis.Redis;
+import com.taurus.permanent.TPServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+import robot.mj.info.RobotUser;
+import taurus.client.NetManager;
+import taurus.client.TaurusClient;
+
+import java.util.concurrent.TimeUnit;
+
+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();
+ private static final EXGameController exGameController = new EXGameController();
+ private volatile boolean connectionCheckRunning = true;
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ // 1. 先启动独立的事件处理线程(只启动一次)
+ startNetEventThread();
+
+ // 2. 启动连接检查定时任务
+ //startConnectionCheckScheduler();
+ //测试
+ Jedis jedis2 = Redis.use("group1_db2").getJedis();
+ String robotskey = "g{"+762479+"}:play:"+66;
+ Map maprobot = jedis2.hgetAll(robotskey);
+ for(Map.Entry entry : maprobot.entrySet()) {
+ System.out.println(entry.getKey() + ":" + entry.getValue());
+ //是否创建
+ RobotUser robotUser = new RobotUser();
+ robotUser.setRobotId(entry.getKey());
+ robotUser.setPassword("123456");
+ robotUser.setGameHost("8.134.76.43");
+ robotUser.setGamePort("6841");
+ robotUser.setRobotGroupid("762479");
+ robotUser.setRobotPid("66");
+
+ robotRoomMapping.put(entry.getKey(), robotUser);
+ }
+
+ for(Map.Entry entry : robotRoomMapping.entrySet()) {
+ RobotUser robotUser = entry.getValue();
+ //1、登录
+ //判断是否登录
+ if(!robotUser.isLogin){
+ robotConnectionManager.login(robotUser);
+ }
+ }
+
+// TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() {
+// @Override
+// public void run() {
+//
+// for(Map.Entry entry : robotRoomMapping.entrySet()) {
+// RobotUser robotUser = entry.getValue();
+// //1、登录
+// //判断是否登录
+// if(!robotUser.isLogin){
+// robotConnectionManager.login(robotUser);
+// }
+// /*//2、链接
+// //判断是否链接
+// System.out.println("robotUser.isconnect"+robotUser.getIsconnect());
+// if(!robotUser.getIsconnect()){
+// robotConnectionManager.connectGame(robotUser);
+// }else{
+// robotConnectionManager.renconnect(robotUser);
+// }
+//
+//
+// //4、加入房间
+// if(robotUser.getStatus()==0){
+// //没状态时候进入加入房间
+// ITObject params = new TObject();
+// params.putString("connecId", robotUser.getRoomId()+"_"+robotUser.getRobotId());
+// params.putString("roomId", robotUser.getRoomId());
+// params.putString("groupId", robotUser.getRobotGroupid());
+// params.putString("session", "{user}:"+robotUser.getRobotId());
+// exGameController.joinRoom(null, params, robotUser.getClient().getId());
+// }
+// System.out.println("robotUser.getIntoRoomTime()"+robotUser.getIntoRoomTime());
+// System.out.println("robGetTiem"+robotConnectionManager.getTime());
+// if(robotUser.getIntoRoomTime()+6<=robotConnectionManager.getTime()){
+// //5、退出房间
+// robotConnectionManager.outoRoom(robotUser);
+// }*/
+//
+// }
+// }
+// }, 0, 5 ,TimeUnit.SECONDS);
+ //5、干活
+ log.info("跑得快机器人服务器已启动");
+ log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port);
+
+ jedis2.close();
+ }
+
+ /**
+ * 独立的事件处理线程
+ */
+ private void startNetEventThread() {
+ Thread eventThread = new Thread(() -> {
+ while (true) {
+ NetManager.processEvents();
+ try {
+ Thread.sleep(2);
+ } catch (InterruptedException e) {
+ break;
+ } catch (Exception e) {
+ }
+ }
+ }, "NetEvent-Thread");
+
+ eventThread.setDaemon(true); // 设置为守护线程
+ eventThread.start();
+ }
+
+
+
+ @Override
+ public Room newRoom(String roomid, Map redis_room_map) {
+ return new EXRoom(roomid, redis_room_map);
+ }
+
+ @Override
+ public Player newPlayer(int i, Room room, String s) {
+ return new EXPlayer(i, room, s);
+ }
+
+
+ protected GameController newController() {
+ return new EXGameController();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+
+ // 停止连接检查线程
+ connectionCheckRunning = false;
+ log.info("跑得快机器人服务器已停止");
+ }
+}
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXPlayer.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXPlayer.java
new file mode 100644
index 0000000..54b8039
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXPlayer.java
@@ -0,0 +1,31 @@
+package robot.mj;
+
+import com.robot.Util;
+import com.robot.data.Player;
+import com.robot.data.Room;
+import com.robot.data.Score;
+import com.taurus.core.entity.ITArray;
+import com.taurus.core.entity.ITObject;
+import com.taurus.core.entity.TArray;
+import com.taurus.core.entity.TObject;
+
+import java.util.*;
+
+/**
+ *
+ *
+ */
+public class EXPlayer extends Player {
+
+
+
+ public EXPlayer(int playerid, Room table, String session_id) {
+ super(playerid, table, session_id);
+ System.out.println("new robot ");
+ }
+
+ public EXRoom getRoom() {
+ return (EXRoom) room;
+ }
+
+}
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXRoom.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXRoom.java
new file mode 100644
index 0000000..84ea302
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/EXRoom.java
@@ -0,0 +1,53 @@
+package robot.mj;
+
+import com.robot.data.Room;
+
+
+import java.util.Map;
+
+public class EXRoom extends Room {
+
+ //
+
+
+
+ public EXRoom(String roomid, Map redis_room_map) {
+ super(roomid, redis_room_map);
+
+
+ }
+
+
+
+
+ public void checkAction() {
+
+ }
+
+
+
+
+
+
+
+ @Override
+ protected void roomResult() {
+
+ }
+
+ @Override
+ public void endGame() {
+ super.endGame();
+ }
+
+ @Override
+ public void saveMilitaryTotal(boolean dissmiss) {
+ super.saveMilitaryTotal(dissmiss);
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+ }
+
+}
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/RobotConnectionManager.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/RobotConnectionManager.java
new file mode 100644
index 0000000..7ac4235
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/RobotConnectionManager.java
@@ -0,0 +1,519 @@
+package robot.mj;
+
+import com.taurus.core.entity.ITArray;
+import com.taurus.core.entity.ITObject;
+import com.taurus.core.entity.TArray;
+import com.taurus.core.entity.TObject;
+import com.taurus.core.events.Event;
+import com.taurus.core.events.IEventListener;
+import com.taurus.core.plugin.database.DataBase;
+import com.taurus.core.plugin.redis.Redis;
+import com.taurus.core.util.ICallback;
+import com.taurus.core.util.StringUtil;
+import robot.mj.business.AccountBusiness;
+import robot.mj.handler.HuNanPaoDeKuai;
+import robot.mj.info.RobotUser;
+import taurus.client.Message;
+import taurus.client.MessageResponse;
+import taurus.client.TaurusClient;
+import taurus.client.SocketCode;
+import redis.clients.jedis.Jedis;
+
+import java.sql.SQLException;
+import java.util.*;
+import java.util.concurrent.*;
+
+import static robot.mj.EXGameController.robotRoomMapping;
+
+/**
+ * 机器人连接管理器 - 管理与游戏服务器的连接
+ */
+public class RobotConnectionManager {
+
+ private static final Map huNanPaoDeKuaiInstances = new ConcurrentHashMap<>();
+ private final EXGameController exGameController;
+
+ private final String host="8.134.76.43";
+ private final int port=6841;
+
+
+ public RobotConnectionManager() {
+ exGameController = new EXGameController();
+ }
+
+ /**
+ * 获取跑得快处理器实例
+ */
+ private HuNanPaoDeKuai getHuNanPaoDeKuaiInstance(String connecId) {
+ HuNanPaoDeKuai existingInstance = huNanPaoDeKuaiInstances.get(connecId);
+ if (existingInstance != null) {
+ return existingInstance;
+ }
+
+ HuNanPaoDeKuai newInstance = new HuNanPaoDeKuai();
+
+ //从Redis恢复状态
+ boolean restored = newInstance.restoreFromRedis(connecId);
+ if (restored) {
+ System.out.println("从Redis恢复HuNanPaoDeKuai实例: " + connecId);
+ } else {
+ System.out.println("创建新的HuNanPaoDeKuai实例: " + connecId);
+ }
+
+ huNanPaoDeKuaiInstances.put(connecId, newInstance);
+ System.out.println("当前HuNanPaoDeKuai实例总数: " + huNanPaoDeKuaiInstances.size());
+ return newInstance;
+ }
+
+ /**
+ * 设置会话和令牌
+ */
+ public void setSessionAndToken(String session, String token, String connecId) {
+ HuNanPaoDeKuai instance = getHuNanPaoDeKuaiInstance(connecId);
+ instance.session = session;
+ instance.token = token;
+ }
+
+ /**
+ * 连接到跑得快游戏服务器
+ */
+ public TaurusClient connectToGameServer(String connecId) {
+ try {
+ //创建Taurus客户端
+ TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);
+
+ //设置事件监听器
+ setupEventListeners(client, connecId);
+
+ client.connect();
+
+ return client;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 断开与游戏服务器的连接(主动断开)
+ */
+ public void disconnectFromGameServer(String connecId) {
+ System.out.println("开始主动断开连接: {"+connecId+"}");
+ RobotUser robotUser = robotRoomMapping.remove(connecId);
+
+ //清理连接数据
+ if (connecId != null) {
+ HuNanPaoDeKuai.removeFromRedis(connecId);
+
+ HuNanPaoDeKuai instance = huNanPaoDeKuaiInstances.get(connecId);
+ if (instance != null) {
+ instance.getPaoDekuaiCardInhand().clear();
+ instance.getSeatRemainHistory().clear();
+ System.out.println("清空HuNanPaoDeKuai集合数据: " + connecId);
+ }
+
+ huNanPaoDeKuaiInstances.remove(connecId);
+ }
+
+ if (robotUser != null) {
+ TaurusClient client = robotUser.getClient();
+ if (client != null) {
+ try {
+ if (client.isConnected()) {
+ client.killConnection();
+ }
+ System.out.println("客户端主动断开连接完成: {"+connecId+"}");
+ } catch (Exception e) {
+ System.out.println("断开客户端连接时发生异常: " + connecId + ", 错误: " + e.getMessage());
+ }
+ } else {
+ System.out.println("客户端连接不存在: {"+connecId+"}");
+ }
+ }
+ }
+
+ /**
+ * 设置事件监听器
+ */
+ public void setupEventListeners(TaurusClient client, String connecId) {
+ //添加消息事件监听器
+ IEventListener messageListener = new IEventListener() {
+ @Override
+ public void handleEvent(Event event) {
+ //获取 msg
+ Message message = (Message) event.getParameter("msg");
+
+ ITObject param = message.param;
+ //回调协议号
+ String command = message.command;
+ System.out.println("csmj OnEvent msg: " + command);
+
+ //根据玩法ID处理不同的回调
+ if (StringUtil.isNotEmpty(command)) {
+ //直接处理协议
+ handleProtocol(command, message, client, connecId);
+ }
+ }
+ };
+
+ //添加连接状态监听器
+ IEventListener connectListener = new IEventListener() {
+ @Override
+ public void handleEvent(Event event) {
+ Message message = (Message) event.getParameter("msg");
+ SocketCode code = (SocketCode) event.getParameter("code");
+
+ }
+ };
+
+ //注册事件监听器
+ client.addEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
+ client.addEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
+ }
+
+
+ /**
+ * 机器人断线重连
+ */
+ public void reconnectToGameServer(MessageResponse response, RobotUser robotUser, TaurusClient client) {
+ String connecId = robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId();
+ if(client.isConnected()){
+ ITObject obj = response.messageData.param.getTObject("tableInfo");
+ ITObject reloadInfo = response.messageData.param.getTObject("reloadInfo");
+ if (obj!=null) {
+ //处理 seat
+ //获取机器人的seat
+ ITArray playerData = obj.getTArray("playerData");
+ for (int i = 0; i < playerData.size(); i++) {
+ ITObject tms = playerData.getTObject(i);
+ Integer tmuserid = tms.getInt("aid");
+ if(tmuserid==Integer.parseInt(robotUser.getRobotId())){
+ Integer seat = tms.getInt("seat");
+ robotUser.setSeat(seat);
+ }
+ }
+ System.out.println("playerData:"+playerData);
+
+ System.out.println("obj:"+obj);
+ System.out.println("reloadInfo:"+reloadInfo);
+ if(reloadInfo!=null) {
+ //重连回来的
+ //同步手牌
+ ITArray hand_card = reloadInfo.getTArray("hand_card");
+ ITArray info_list = reloadInfo.getTArray("info_list");
+
+ List hcard = new ArrayList<>();
+ if(hand_card!=null) {
+ for (int i = 0; i < hand_card.size(); i++) {
+ hcard.add(hand_card.getInt(i));
+ }
+ }
+ ITArray outcard_list = new TArray();
+ if(info_list!=null) {
+ for (int i = 0; i < info_list.size(); i++) {
+ ITObject tms = info_list.getTObject(i);
+ Integer playerid = tms.getInt("playerid");
+ if(playerid==Integer.parseInt(robotUser.getRobotId())){
+ outcard_list = tms.getTArray("outcard_list");
+ }
+ }
+ }
+
+ System.out.println("hcard>0"+hcard);
+ if(hcard.size()>0){
+ //同步手牌
+ HuNanPaoDeKuai currentInstance = getHuNanPaoDeKuaiInstance(connecId);
+
+ //同步逻辑
+ if (hcard.size() > 0) {
+ //直接同步服务器手牌数据
+ currentInstance.updateHandCard(hcard);
+ System.out.println("断线重连:同步手牌数据,服务器手牌:" + hcard);
+ }
+
+ //同步最后出牌信息
+ /*if(info_list!=null) {
+ for (int i = 0; i < info_list.size(); i++) {
+ ITObject playerInfo = info_list.getTObject(i);
+ Integer playerid = playerInfo.getInt("playerid");
+
+ //找到最后出牌的玩家信息
+ if(playerid != null && playerid == Integer.parseInt(robotUser.getRobotId())) {
+ ITObject lastOutCard = playerInfo.getTObject("last_outcard");
+ if(lastOutCard != null) {
+ //提取最后出牌的关键信息
+ int minCard = lastOutCard.getInt("min_card");
+ int len = lastOutCard.getInt("len");
+ int type = lastOutCard.getInt("type");
+ ITArray cardList = lastOutCard.getTArray("card_list");
+
+ ITObject syncedCardList = TObject.newInstance();
+ syncedCardList.putTArray("card_list", cardList);
+ syncedCardList.putInt("min_card", minCard);
+ syncedCardList.putInt("len", len);
+ syncedCardList.putInt("type", type);
+
+ currentInstance.setCard_list(syncedCardList);
+ System.out.println("断线重连:同步最后出牌数据 - min_card:" + minCard + ", len:" + len + ", type:" + type + ", cards:" + cardList);
+ }
+ break;
+ }
+ }
+ }*/
+
+ sleepTime(2000);
+ currentInstance.outCard(client);
+ } else {
+ System.err.println("警告:重连时未获取到手牌数据");
+ }
+ }
+ }
+ }else {
+ renconnect(robotUser);
+ }
+ }
+
+ /**
+ * 处理接收到的游戏协议
+ */
+ private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
+ RobotUser robotUser = robotRoomMapping.get(connecId);
+ int robotId = Integer.parseInt(robotUser.getRobotId());
+ ITObject param = message.param;
+ HuNanPaoDeKuai huNanPaoDeKuai = getHuNanPaoDeKuaiInstance(connecId);
+ Jedis jedis0 = Redis.use().getJedis();
+ Jedis jedis2 = Redis.use("group1_db2").getJedis();
+ try {
+ //跑得快 机器人处理事件
+ //跑的快 初始化手牌
+ if ("2011".equalsIgnoreCase(command)) {
+ huNanPaoDeKuai.paoDeKuaiCardInHead(param, client);
+ //处理完协议后保存到Redis
+ HuNanPaoDeKuai currentInstance = huNanPaoDeKuaiInstances.get(connecId);
+ currentInstance.saveToRedis(connecId);
+ }
+ //出牌广播
+ else if ("2021".equalsIgnoreCase(command)) {
+ huNanPaoDeKuai.paoDekuaiChupaiGuangBo(param);
+ //处理完协议后保存到Redis
+ HuNanPaoDeKuai currentInstance = huNanPaoDeKuaiInstances.get(connecId);
+ currentInstance.saveToRedis(connecId);
+ }
+ //出牌提示事件,牌权
+ else if ("2004".equalsIgnoreCase(command)) {
+ Integer player = param.getInt("player");
+ Integer seat1 = param.getInt("seat");
+ System.out.println("跑的快seat1 77777777777777777777777777" + seat1);
+ System.out.println("跑的快palyer6666666666666666666666666" + player);
+ if (seat1 != null) {
+ huNanPaoDeKuai.seat = seat1;
+ }
+
+ //出牌
+ huNanPaoDeKuai.outCard(client);
+ //处理完协议后保存到Redis
+ HuNanPaoDeKuai currentInstance = huNanPaoDeKuaiInstances.get(connecId);
+ currentInstance.saveToRedis(connecId);
+ }
+ //结算准备
+ else if ("2007".equalsIgnoreCase(command)) {
+ //type为1 为大结算 type为0为小结算
+ Integer type = param.getInt("type");
+ System.out.println("type ++++++++++++++++++++++++" + type);
+ if (type == 0) {
+ huNanPaoDeKuai.getSeatRemainHistory().clear();
+ huNanPaoDeKuai.getPaoDekuaiCardInhand().clear();
+ ITArray card_list = huNanPaoDeKuai.getCard_list().getTArray("card_list");
+ card_list.clear();
+// ready();
+ }
+
+ if (type == 1) {
+ updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
+ }
+
+ }
+ else if ("2009".equalsIgnoreCase(command)) {
+ CompletableFuture.runAsync(() -> {
+ Integer paramRobotId = param.getInt("aid");
+ sleepTime(6000);
+
+ if (robotUser != null) {
+ String roomKey = String.valueOf(robotUser.getCurrentRoomId());
+
+ //查询该房间的玩家信息
+ String playersStr = jedis0.hget(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) {
+
+ String gpid = jedis0.hget(roomKey, "gpid");
+ String gpId = jedis0.hget(roomKey, "group");
+
+ //发送退出房间协议
+ ITObject params = TObject.newInstance();
+ client.send("1005", params, response -> {
+ EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId));
+ //断开连接
+ disconnectFromGameServer(connecId);
+ //更新机器人剩余数量
+ updateLeftoverRobot(paramRobotId);
+ System.out.println("2009发送退出房间协议1005,robotId: {"+paramRobotId+"}");
+ });
+ }
+ }
+ }
+ }
+ });
+ }
+ //解散房间时候恢复机器人账号可以使用
+ else if ("2008".equalsIgnoreCase(command)) {
+ updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
+ disconnectFromGameServer(connecId);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } 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");
+
+ System.out.println("机器人 {"+robotId+"} 退出房间,修改gallrobot为0");
+ } finally {
+ jedis2.close();
+ }
+ }
+
+ /**
+ * 机器人登录
+ */
+ public void login(RobotUser robotUser){
+ System.out.println("login:"+robotUser.getRobotId());
+ ITObject object = null;
+ AccountBusiness accountBusiness = null;
+ accountBusiness = new AccountBusiness();
+ try {
+ //先快速登录
+ object = accountBusiness.fastLogin(Integer.parseInt(robotUser.getRobotId()));
+ System.out.println("object:"+object);
+ 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());
+ System.err.println("重启获取的机器人还有当前房间,准备加入: "+robotUser.getConnecId());
+ exGameController.webGroupJoinRoom(robotUser);
+ }
+ }
+ }
+ });
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void connectGame(RobotUser robotUser){
+ if(robotUser.isLogin){
+ if(robotUser.getClient()==null){
+ TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "game", 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) {
+ throw new RuntimeException(e);
+ }
+ robotUser.setClient(client);
+ EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
+ }else{
+ System.out.println("reconnect");
+ System.out.println("client.isConnected()"+robotUser.getClient().isConnected());
+ if(robotUser.getClient().isConnected()){
+ robotUser.setIsconnect(true);
+ }else{
+ System.out.println("reconnect"+robotUser.getClient().getGameID());
+ TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "game", TaurusClient.ConnectionProtocol.Tcp);
+ client.setSession(robotUser.getLoginsession());
+ client.connect();
+ robotUser.setIsconnect(client.isConnected());
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ 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());
+ }
+ }
+ }
+
+ /**
+ * 根据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) {
+ e.printStackTrace();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/RoomCreator.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/RoomCreator.java
new file mode 100644
index 0000000..c3f0ecc
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/RoomCreator.java
@@ -0,0 +1,326 @@
+package robot.mj;
+
+import com.data.cache.BaseCache;
+import com.data.cache.GroupCache;
+import com.taurus.core.entity.ITObject;
+import com.taurus.core.entity.TObject;
+import com.taurus.core.plugin.redis.Redis;
+import com.taurus.core.util.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import redis.clients.jedis.Jedis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 房间创建器 - 统一处理房间创建逻辑
+ */
+public class RoomCreator {
+ private static final Logger log = LoggerFactory.getLogger(RoomCreator.class);
+
+ /**
+ * 在Redis中创建房间
+ *
+ * @param groupId 群组ID
+ * @param wanfaId 玩法ID
+ */
+ public static RoomInfo createRoomInRedis(int groupId, int wanfaId, int robotId) {
+ try {
+ Jedis jedis0 = Redis.use("group1_db0").getJedis();
+ Jedis jedis11 = Redis.use("group1_db11").getJedis();
+
+ try {
+ //从free_room队列获取房间ID
+ String newRoomId = Redis.use("group1_db1").rpop("free_room");
+ if (StringUtil.isEmpty(newRoomId)) {
+ log.error("没有可用的房间ID,free_room队列为空");
+ return null;
+ }
+ //Redis.use("group1_db1").lpush("free_room", newRoomId);
+
+ String roomKey = "room:" + newRoomId;
+
+ //获取群组信息
+ String groupKey = "group:" + groupId;
+ Map groupInfo = jedis11.hgetAll(groupKey);
+ //不存在则创建默认群组信息
+ if (groupInfo.isEmpty()) {
+ log.warn("群组信息不存在,群组ID: {},正在创建默认群组信息", groupId);
+ createDefaultGroupInfo(jedis11, groupId);
+ groupInfo = jedis11.hgetAll(groupKey);
+ }
+
+ //确保游戏配置存在
+ String gameConfigKey = "game:" + wanfaId;
+ Map gameInfo = jedis0.hgetAll(gameConfigKey);
+ //不存在则创建跑得快的默认游戏配置
+ if (gameInfo.isEmpty()) {
+ log.warn("游戏配置不存在,玩法ID: {},正在创建跑得快默认游戏配置", wanfaId);
+ createDefaultGameConfig(jedis0, wanfaId);
+ gameInfo = jedis0.hgetAll(gameConfigKey);
+ }
+
+ //获取玩法配置
+ String playKey = "g{" + groupId + "}:play:" + wanfaId;
+ Map playConfig = jedis11.hgetAll(playKey);
+ //不存在则创建跑得快的默认玩法配置
+ if (playConfig.isEmpty()) {
+ log.warn("玩法配置不存在,群组ID: {}, 玩法ID: {},正在创建跑得快默认配置", groupId, wanfaId);
+ createDefaultChangshaMajiangConfig(jedis11, groupId, wanfaId);
+ playConfig = jedis11.hgetAll(playKey);
+ }
+
+ //构建房间信息
+ Map roomMap = new HashMap<>();
+
+ //基础房间信息
+ roomMap.put("AA", "0"); //AA支付标志
+ roomMap.put("agent", "1"); //代理标志
+ roomMap.put("dismiss_time", "30"); //解散时间
+ roomMap.put("gpid", String.valueOf(wanfaId)); //玩法ID
+ roomMap.put("group", String.valueOf(groupId)); //群组ID
+ roomMap.put("hpOnOff", "1"); //体力开关
+ roomMap.put("hp_times", "1000"); //体力次数
+ roomMap.put("id", newRoomId); //房间ID
+ roomMap.put("kick_time", "30"); //踢出时间
+ roomMap.put("owner", "{user}:" + robotId); //房间所有者
+ roomMap.put("maxPlayers", "2"); //最大玩家数
+ roomMap.put("opt", "2"); //选项
+ roomMap.put("pay", "0"); //支付金额
+ roomMap.put("payer", String.valueOf(robotId)); //支付者ID
+ roomMap.put("rewardType", "0"); //奖励类型
+ roomMap.put("rewardValueType", "0"); //奖励值类型
+ roomMap.put("seats", "[1]"); //房间状态
+ roomMap.put("status", "0"); //房间状态
+ roomMap.put("times", "4"); //局数
+ roomMap.put("xipai_rewardType", "3"); //洗牌奖励类型
+ roomMap.put("xipai_rewardValueType", "1"); //洗牌奖励值类型
+
+ //如果有体力配置
+ String hpConfig = playConfig.get("hpConfig");
+ if (hpConfig != null) {
+ roomMap.put("limitInRoom", "1"); //房间内限制
+ }
+
+ //处理玩法选项配置
+ String playConfigJson = playConfig.getOrDefault("config", "{}");
+ ITObject configData = TObject.newFromJsonData(playConfigJson);
+
+ //原逻辑删除了字段
+ configData.del("opt");
+ configData.del("AA");
+
+ //将处理后的配置数据存储到options字段
+ roomMap.put("options", configData.toJson()); //选项配置
+ roomMap.put("game", String.valueOf(wanfaId)); //游戏ID
+ roomMap.put("open", "1"); //开放状态
+ roomMap.put("round", "0"); //回合数
+ roomMap.put("create_time", String.valueOf(System.currentTimeMillis() / 1000)); //创建时间
+ roomMap.put("cache_ver", "1"); //缓存版本
+ roomMap.put("players", "[]"); //玩家列表
+ roomMap.put("fake_existTime", "30"); //fake存在时间
+
+ //设置房间信息
+ jedis0.hmset(roomKey, roomMap);
+
+ //更新剩余机器人数量
+ String leftoverRobotStr = jedis11.hget(playKey, "leftover_robot");
+ int leftoverRobot = leftoverRobotStr != null ? Integer.parseInt(leftoverRobotStr) : 0;
+ if (leftoverRobot > 0) {
+ jedis11.hincrBy(playKey, "leftover_robot", -1);
+ }
+
+ //将房间添加到群组房间列表
+ String groomsKey = "g{" + groupId + "}:rooms";
+ jedis11.zadd(groomsKey, wanfaId * 10000 + 1101, roomKey);
+
+ //更新群组的缓存版本 确保客户端能够获取到最新的群组信息
+ String groupKeyForUpdate = GroupCache.genKey(groupId);
+ BaseCache.updateCacheVer(jedis11, groupKeyForUpdate);
+
+ //创建并返回房间信息
+ RoomInfo roomInfo = new RoomInfo();
+ roomInfo.setRoomId(roomKey);
+ roomInfo.setGroupId(groupId);
+ roomInfo.setWanfaId(wanfaId);
+ roomInfo.setServerIp("127.0.0.1");
+ roomInfo.setServerPort(getGamePortForWanfa(wanfaId));
+
+ log.info("成功创建机器人房间: {}, 群组: {}, 玩法: {}", roomKey, groupId, wanfaId);
+ return roomInfo;
+ } finally {
+ jedis0.close();
+ jedis11.close();
+ }
+ } catch (Exception e) {
+ log.error("创建房间时发生错误", e);
+ return null;
+ }
+ }
+
+ /**
+ * 根据玩法ID获取游戏服务器端口
+ */
+ private static int getGamePortForWanfa(int wanfaId) {
+ switch (wanfaId) {
+ case 10: //跑得快
+ return 6841;
+ default:
+ return 6841;
+ }
+ }
+
+ /**
+ * 为跑得快创建默认玩法配置
+ */
+ private static void createDefaultChangshaMajiangConfig(Jedis jedis11, int groupId, int wanfaId) {
+ try {
+ log.info("为群组 {} 和跑得快玩法 {} 创建默认玩法配置", groupId, wanfaId);
+
+ String playKey = "g{" + groupId + "}:play:" + wanfaId;
+
+ Map defaultConfig = new HashMap<>();
+ defaultConfig.put("opt", "1");
+ defaultConfig.put("groupId", String.valueOf(groupId));
+ defaultConfig.put("id", String.valueOf(wanfaId));
+ defaultConfig.put("gameId", String.valueOf(wanfaId));
+ defaultConfig.put("name", "跑得快-机器人专用");
+ defaultConfig.put("deskId", "0");
+ defaultConfig.put("maxPlayers", "4");
+ defaultConfig.put("hpOnOff", "0");
+ defaultConfig.put("rewardType", "0");
+ defaultConfig.put("rewardValueType", "0");
+ defaultConfig.put("xipai_rewardType", "0");
+ defaultConfig.put("xipai_rewardValueType", "0");
+ defaultConfig.put("hp_times", "0");
+ defaultConfig.put("ban", "0");
+ defaultConfig.put("robot_room", "1");
+ defaultConfig.put("shangxian_robot", "10"); //限制机器人数量
+ defaultConfig.put("leftover_robot", "10"); //设置剩余机器人数量
+ defaultConfig.put("reward", "0");
+ defaultConfig.put("xipai_reward", "100");
+ defaultConfig.put("anchou_reward", "1");
+ defaultConfig.put("mark", "0");
+ defaultConfig.put("cache_ver", "1");
+
+ //跑得快配置选项
+ defaultConfig.put("config", "{\"maxPlayers\":4,\"pid\":22,\"opt\":1,\"AA\":0,\"maxRound\":8,\"dianpao\":1,\"zimo\":1,\"haidi\":1,\"ting\":1,\"piao\":0,\"chongfeng\":1,\"queyimen\":0,\"hujia\":0,\"hongzhong\":1,\"qgh\":0,\"qgh_opt\":0,\"qgh_type\":0,\"qgh_score\":0,\"qgh_double\":0,\"qgh_double_opt\":0,\"qgh_double_type\":0,\"qgh_double_score\":0,\"qgh_double_score_opt\":0,\"qgh_double_score_type\":0,\"qgh_double_score_type_opt\":0}");
+ defaultConfig.put("hpConfig", "{\"times\":1,\"limitInRoom\":0,\"maxRound\":8}");
+
+ jedis11.hmset(playKey, defaultConfig);
+
+ //更新缓存版本
+ jedis11.hincrBy(playKey, "cache_ver", 1);
+
+ //更新群组玩法列表 将此玩法添加进去
+ String gpidsKey = "g{" + groupId + "}:pids";
+ jedis11.zadd(gpidsKey, 1 * 10 + 0, String.valueOf(wanfaId));
+
+ log.info("成功创建跑得快默认玩法配置 键名: {}", playKey);
+ } catch (Exception e) {
+ log.error("创建跑得快默认玩法配置时发生错误 群组ID: {}, 玩法ID: {}", groupId, wanfaId, e);
+ }
+ }
+
+ /**
+ * 创建默认群组信息
+ */
+ private static void createDefaultGroupInfo(Jedis jedis11, int groupId) {
+ try {
+ log.info("为群组 {} 创建默认群组信息", groupId);
+
+ String groupKey = "group:" + groupId;
+
+ Map defaultGroupInfo = new HashMap<>();
+ defaultGroupInfo.put("ban", "0"); //未禁用
+ defaultGroupInfo.put("ban_apply", "0"); //不禁止申请
+ defaultGroupInfo.put("ban_chat1", "false");
+ defaultGroupInfo.put("ban_chat2", "false");
+ defaultGroupInfo.put("create_time", String.valueOf(System.currentTimeMillis() / 1000));
+ defaultGroupInfo.put("dissolve_opt", "1"); //解散选项
+ defaultGroupInfo.put("exit_opt", "0");
+ defaultGroupInfo.put("gms", "19");
+ defaultGroupInfo.put("id", String.valueOf(groupId));
+ defaultGroupInfo.put("kick_opt", "1"); //踢人选项
+ defaultGroupInfo.put("name", "机器人专用群组-" + groupId);
+ defaultGroupInfo.put("notice", "");
+ defaultGroupInfo.put("opt", "1"); //开启状态
+ defaultGroupInfo.put("option", "0"); //选项
+ defaultGroupInfo.put("owner", "999999"); //使用机器人系统账户ID
+ defaultGroupInfo.put("pay_type", "1"); //房主支付
+ defaultGroupInfo.put("type", "2"); //普通群组类型
+
+ jedis11.hmset(groupKey, defaultGroupInfo);
+
+ log.info("成功创建默认群组信息,键名: {}", groupKey);
+ } catch (Exception e) {
+ log.error("创建默认群组信息时发生错误,群组ID: {}", groupId, e);
+ }
+ }
+
+ /**
+ * 创建默认游戏配置
+ */
+ private static void createDefaultGameConfig(Jedis jedis0, int wanfaId) {
+ try {
+ log.info("为玩法 {} 创建默认游戏配置", wanfaId);
+
+ String gameConfigKey = "game:" + wanfaId;
+
+ Map defaultGameInfo = new HashMap<>();
+ defaultGameInfo.put("id", String.valueOf(wanfaId));
+ defaultGameInfo.put("name", "跑得快");
+ defaultGameInfo.put("maxPlayers", "4"); //跑得快为4人游戏
+ defaultGameInfo.put("minPlayers", "2"); //最少2人
+ defaultGameInfo.put("type", "1"); //游戏类型
+ defaultGameInfo.put("status", "1"); //状态开启
+ defaultGameInfo.put("icon", ""); //图标
+ defaultGameInfo.put("desc", "跑得快游戏"); //描述
+ defaultGameInfo.put("version", "1.0"); //版本
+ defaultGameInfo.put("pay", "0"); //支付金额
+ defaultGameInfo.put("times", "8"); //局数
+ defaultGameInfo.put("hpType", "0"); // 体力值类型,必需字段
+ defaultGameInfo.put("gameType", "1"); // 游戏类型,必需字段
+ defaultGameInfo.put("isNonnegative", "0"); // 不可负分,必需字段
+
+ defaultGameInfo.put("opt1", "8");
+ defaultGameInfo.put("opt2", "16");
+ defaultGameInfo.put("opt3", "24");
+ defaultGameInfo.put("opt4", "32");
+ defaultGameInfo.put("opt5", "40");
+ //设置支付选项
+ defaultGameInfo.put("pay1_2", "10");
+ defaultGameInfo.put("pay1_3", "15");
+ defaultGameInfo.put("pay1_4", "20");
+
+ jedis0.hmset(gameConfigKey, defaultGameInfo);
+
+ log.info("成功创建默认游戏配置,键名: {}", gameConfigKey);
+ } catch (Exception e) {
+ log.error("创建默认游戏配置时发生错误,玩法ID: {}", wanfaId, e);
+ }
+ }
+
+ /**
+ * 房间信息类
+ */
+ public static class RoomInfo {
+ private String roomId;
+ private int groupId;
+ private int wanfaId;
+ private String serverIp;
+ private int serverPort;
+
+ public String getRoomId() { return roomId; }
+ public void setRoomId(String roomId) { this.roomId = roomId; }
+ public int getGroupId() { return groupId; }
+ public void setGroupId(int groupId) { this.groupId = groupId; }
+ public int getWanfaId() { return wanfaId; }
+ public void setWanfaId(int wanfaId) { this.wanfaId = wanfaId; }
+ public String getServerIp() { return serverIp; }
+ public void setServerIp(String serverIp) { this.serverIp = serverIp; }
+ public int getServerPort() { return serverPort; }
+ public void setServerPort(int serverPort) { this.serverPort = serverPort; }
+ }
+}
\ No newline at end of file
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/business/AccountBusiness.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/business/AccountBusiness.java
new file mode 100644
index 0000000..bdf1bfa
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/business/AccountBusiness.java
@@ -0,0 +1,380 @@
+package robot.mj.business;
+
+import com.data.bean.AccountBean;
+import com.data.bean.GameBean;
+import com.data.cache.AccountCache;
+import com.data.cache.BaseCache;
+import com.data.cache.GameCache;
+import com.data.util.ErrorCode;
+import com.data.util.Utility;
+import com.taurus.core.entity.ITArray;
+import com.taurus.core.entity.ITObject;
+import com.taurus.core.entity.TArray;
+import com.taurus.core.entity.TObject;
+import com.taurus.core.plugin.database.DataBase;
+import com.taurus.core.plugin.redis.Redis;
+import com.taurus.core.plugin.redis.RedisLock;
+import com.taurus.core.util.Logger;
+import com.taurus.core.util.StringUtil;
+import com.taurus.core.util.Utils;
+import com.taurus.web.Controller;
+import com.taurus.web.WebException;
+import redis.clients.jedis.Jedis;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class AccountBusiness extends Controller {
+ private static Logger logger = Logger.getLogger(AccountBusiness.class);
+
+ public static String request(String httpUrl, String httpArg) {
+ BufferedReader reader = null;
+ String result = null;
+ StringBuffer sbf = new StringBuffer();
+ httpUrl = httpUrl + "?" + httpArg;
+
+ try {
+ URL url = new URL(httpUrl);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+ InputStream is = connection.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ String strRead = reader.readLine();
+ if (strRead != null) {
+ sbf.append(strRead);
+ while ((strRead = reader.readLine()) != null) {
+ sbf.append("\n");
+ sbf.append(strRead);
+ }
+ }
+ reader.close();
+ result = sbf.toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ public static String md5(String plainText) {
+ StringBuffer buf = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(plainText.getBytes());
+ byte b[] = md.digest();
+ int i;
+ buf = new StringBuffer("");
+ for (int offset = 0; offset < b.length; offset++) {
+ i = b[offset];
+ if (i < 0)
+ i += 256;
+ if (i < 16)
+ buf.append("0");
+ buf.append(Integer.toHexString(i));
+ }
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return buf.toString();
+ }
+
+ public static String encodeUrlString(String str, String charset) {
+ String strret = null;
+ if (str == null)
+ return str;
+ try {
+ strret = java.net.URLEncoder.encode(str, charset);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ return strret;
+ }
+
+ private final ITObject fillLoginData(String session, int accountid) {
+ ITObject resData = TObject.newInstance();
+ ITObject userData = TObject.newInstance();
+ resData.putTObject("account", userData);
+ resData.putUtfString("session_id", session);
+ resData.putTArray("games", getOnlineGames());
+ Jedis jedis0 = Redis.use("group1_db0").getJedis();
+ try {
+ Map map = jedis0.hgetAll(session);
+ userData.putInt("id", accountid);
+ userData.putInt("diamo", Integer.parseInt(map.get("diamo")));
+ userData.putUtfString("nick", map.get("nick"));
+ userData.putUtfString("portrait", map.get("portrait"));
+ userData.putInt("sex", Integer.parseInt(map.get("sex")));
+ userData.putInt("type", Integer.parseInt(map.get("type")));
+ int mng = Integer.parseInt(map.get("mng"));
+ userData.putInt("mng", mng);
+
+ String phone = map.get("phone");
+ if (StringUtil.isNotEmpty(phone)) {
+ userData.putUtfString("phone", phone);
+ }
+
+ String address = map.get("address");
+ if (StringUtil.isNotEmpty(address)) {
+ userData.putUtfString("address", address);
+ }
+
+ String real_info = map.get("real_info");
+ if (StringUtil.isNotEmpty(real_info)) {
+ userData.putTObject("real_info", TObject.newFromJsonData(real_info));
+ }
+ String oldRoom = Utility.getOldRoomV2(jedis0, 0, session, accountid);
+ if (StringUtil.isNotEmpty(oldRoom)) {
+ String roomid = oldRoom.replace("room:", "");
+ String group = jedis0.hget(oldRoom, "group");
+ int groupId = 0;
+ if (StringUtil.isNotEmpty(group)) {
+ groupId = Integer.parseInt(group);
+ }
+ userData.putUtfString("roomid", roomid);
+ userData.putInt("groupId", groupId);
+ }
+ } finally {
+ jedis0.close();
+ }
+
+ resData.putUtfString("groupWeb", Redis.use("group1_db1").hget("web_requrl", "groupWeb_jefe"));
+ return resData;
+ }
+
+
+ public final ITObject fastLogin(int userid) throws Exception {
+ Jedis jedis = Redis.use("group1_db0").getJedis();
+ ITObject resData = null;
+ try {
+ Set usertoken = jedis.smembers("{user}:"+userid+"_token");
+ if (usertoken.size()<=0){
+ return null;
+ }
+ String token = "";
+ for (String item : usertoken) {
+ token = item;
+ }
+ String session ="{user}:"+userid;
+
+
+ AccountBean acc_bean = AccountCache.getAccount(session);
+ resData = fillLoginData(session, acc_bean.id);
+ String idPwdBan = Redis.use("group1_db0").get(acc_bean.id+"_login_ban");
+ if (StringUtil.isNotEmpty(idPwdBan))
+ {
+ logger.error("id:"+acc_bean.id+" ban login");
+ throw new WebException(ErrorCode.BAN_LOGIN);
+ }
+ resData.putString("token", token);
+ return resData;
+ }catch (Exception e){
+
+ }finally {
+ jedis.close();
+ }
+
+ return resData;
+
+ }
+
+
+ public final ITObject idPasswordLogin(int id, String password) throws Exception {
+
+ logger.info("id:" + id + " login");
+
+ Jedis jedis0 = Redis.use("group1_db0").getJedis();
+ RedisLock lock = new RedisLock("wx_" + id, jedis0);
+ try {
+
+ logger.info("==========> password111 = " + password);
+ String superPwd = Redis.use("group1_db1").get("superpwd2021");
+ String sql = "";
+ if (!StringUtil.isEmpty(superPwd)) {
+ if (!password.equals(superPwd)) {
+ password = Utils.getMD5Hash(password);
+ sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password);
+ } else {
+ logger.info("==========> password = " + password);
+
+ sql = String.format("SELECT * FROM account WHERE id ='%d' ", id);
+ }
+ } else {
+ password = Utils.getMD5Hash(password);
+ sql = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'", id, password);
+ }
+
+
+
+
+ String idPwdBan = Redis.use("group1_db0").get(id + "_login_ban");
+ if (StringUtil.isNotEmpty(idPwdBan)) {
+ System.out.println("进入了77777777777777777777");
+ logger.error("id:" + id + " ban login");
+ throw new WebException(ErrorCode.BAN_LOGIN);
+ }
+ System.out.println("进入了9999999999999");
+
+ ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
+ if (resultArray.size() == 0) {
+ if (Redis.use("group1_db0").exists(id + "_pwd_token")) {
+ Redis.use("group1_db0").incrBy(id + "_pwd_token", 1);
+ } else {
+ Redis.use("group1_db0").set(id + "_pwd_token", 1 + "");
+ Redis.use("group1_db0").expire(id + "_pwd_token", 300);
+ }
+
+ String idPwdToken = Redis.use("group1_db0").get(id + "_pwd_token");
+ if (StringUtil.isNotEmpty(idPwdToken)) {
+ long count = Long.parseLong(idPwdToken);
+ if (count >= 10) {
+ Redis.use("group1_db0").set(id + "_login_ban", "1");
+ Redis.use("group1_db0").expire(id + "_login_ban", 1800);
+ logger.error("pwd error count:" + count + " not login");
+ System.out.println("进入了00000000000");
+
+ throw new WebException(ErrorCode._NO_SESSION);
+
+ }
+ }
+ System.out.println("进入了111111111111");
+
+ throw new WebException(ErrorCode._FAILED);
+ }
+
+ ITObject userData = resultArray.getTObject(0);
+ int accountid = userData.getInt("id");
+ UpdateUserData(userData, accountid);
+
+ AccountBean acc_bean = AccountCache.getAccount(accountid);
+ String session = acc_bean.redis_key;
+ this.setSession(session);
+
+ if (resultArray.size() > 0) {
+ this.setSession(session);
+ String old_nick = acc_bean.nick;
+ String old_portrait = acc_bean.portrait;
+// String new_nick = reqData.getUtfString("nick");
+// String new_portrait = reqData.getUtfString("portrait");
+// if (!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) {
+// ITObject userData1 = TObject.newInstance();
+// userData1.putUtfString("nick", userData.getUtfString("nick"));
+// userData1.putUtfString("portrait", userData.getUtfString("portrait"));
+// userData1.putInt("sex", userData.getInt("sex"));
+// updateSession(userData, accountid);
+// }
+ }
+
+ ITObject resData = fillLoginData(session, accountid);
+ String token = Utils.getMD5Hash(id + "_" + password + "_" + System.currentTimeMillis() + "e4!Fesu]]{QyUuEA"
+ + Math.random() * 1000000);
+ Redis.use("group1_db0").sadd(session + "_token", token);
+
+ Redis.use("group1_db0").hset(token, "user", session);
+ Redis.use("group1_db0").hset(token, "create_time", "" + System.currentTimeMillis() / 1000);
+ Redis.use("group1_db0").expire(token, 172800);
+
+// Set allToken = Redis.use("group1_db0").smembers(session + "_token");
+// for (String temp : allToken) {
+// if (!Redis.use("group1_db0").exists(temp)) {
+// Redis.use("group1_db0").srem(session + "_token", temp);
+// logger.info("delte timeout token:" + temp);
+// }
+// }
+ System.out.println("进入了2222222222222");
+
+ long tokenNum = Redis.use("group1_db0").scard(session + "_token");
+ if (tokenNum >= 10) {
+ logger.warn("id:" + accountid + " repeat login, token count:" + tokenNum);
+ }
+ System.out.println("进入了33333333333333333332");
+
+ resData.putString("token", token);
+ return resData;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private static String updateSession(ITObject userData, int id) {
+ String session = AccountCache.genKey(id);
+ Map map = new HashMap();
+ Utils.objectToMap(userData, map);
+
+ Jedis jedis0 = Redis.use("group1_db0").getJedis();
+ try {
+ jedis0.hmset(session, map);
+ BaseCache.updateCacheVer(jedis0, session);
+ } finally {
+ jedis0.close();
+ }
+
+ return session;
+ }
+
+ /**
+ * 获取在线游戏
+ */
+ public static ITArray getOnlineGames() {
+ ITArray games = new TArray();
+ Jedis jedis1 = Redis.use("group1_db1").getJedis();
+ try {
+ Set list = jedis1.zrevrangeByScore("online_games", 1000, 1);
+ for (String game : list) {
+ int gameId = Integer.parseInt(game);
+ GameBean gb = GameCache.getGame(gameId);
+ if (gb == null)
+ continue;
+ ITObject gameObj = gb.getTObject();
+
+ for (Entry entry : gb.pay.entrySet()) {
+ gameObj.putInt(entry.getKey(), entry.getValue());
+ }
+ games.addTObject(gameObj);
+ }
+ } finally {
+ jedis1.close();
+ }
+ return games;
+ }
+
+ /**
+ *
+ * @return
+ * @throws Exception
+ */
+ private final int UpdateUserData(ITObject reqData, long id) throws Exception {
+ ITObject userData = TObject.newInstance();
+ userData.putInt("id", (int) id);
+
+ userData.putUtfString("acc", reqData.getUtfString("acc"));
+ userData.putUtfString("portrait", reqData.getUtfString("portrait"));
+ userData.putUtfString("nick", reqData.getUtfString("nick"));
+ int sex = reqData.getInt("sex");
+ if (sex == 0) {
+ sex = 1;
+ reqData.putInt("sex", sex);
+ }
+ userData.putInt("sex", sex);
+
+ userData.putInt("mng", 0);
+ userData.putInt("type", 0);
+ if (reqData.containsKey("diamo")) {
+ userData.putInt("diamo", reqData.getInt("diamo"));
+ }
+
+ userData.putInt("invitation", 1);
+ String session = updateSession(userData, (int) id);
+ this.setSession(session);
+ return (int) id;
+ }
+}
diff --git a/robots/puke/robot_pk_pdk/src/main/java/robot/mj/handler/HuNanPaoDeKuai.java b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/handler/HuNanPaoDeKuai.java
new file mode 100644
index 0000000..1a43cda
--- /dev/null
+++ b/robots/puke/robot_pk_pdk/src/main/java/robot/mj/handler/HuNanPaoDeKuai.java
@@ -0,0 +1,307 @@
+package robot.mj.handler;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+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 redis.clients.jedis.Jedis;
+import taurus.client.TaurusClient;
+import taurus.util.CardObj;
+import taurus.util.CardUtil;
+import taurus.util.test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class HuNanPaoDeKuai {
+
+ public int seat = 0;
+
+ //座位号 剩余牌数量
+ private final Map> seatRemainHistory = new HashMap<>();
+
+ // 跑的快玩家手牌
+ private final List paoDekuaiCardInhand = new ArrayList<>();
+
+ // 会话标识
+ public String session = "";
+ // 访问令牌
+ public String token = "";
+
+ //跑的快别人出的牌
+ private ITObject card_list = TObject.newInstance();
+
+ public int guangboseat = 0;
+
+ public int remain = 0;
+
+ public Map> getSeatRemainHistory() {
+ return seatRemainHistory;
+ }
+
+ public List getPaoDekuaiCardInhand() {
+ return paoDekuaiCardInhand;
+ }
+
+ public ITObject getCard_list() {
+ return card_list;
+ }
+
+ public void setCard_list(ITObject cardList) {
+ this.card_list = cardList;
+ }
+
+ private static final Gson gson = new Gson();
+
+
+ /**
+ * 将当前实例状态序列化为JSON字符串并保存到Redis
+ * @param connecId 连接ID
+ */
+ public void saveToRedis(String connecId) {
+ Jedis jedis = Redis.use("group1_db2").getJedis();
+ try {
+ Map stateMap = new HashMap<>();
+
+ stateMap.put("seatRemainHistory", gson.toJson(seatRemainHistory));
+ stateMap.put("paoDekuaiCardInhand", gson.toJson(paoDekuaiCardInhand));
+ stateMap.put("card_list", gson.toJson(card_list));
+
+ stateMap.put("seat", String.valueOf(seat));
+ stateMap.put("guangboseat", String.valueOf(guangboseat));
+ stateMap.put("remain", String.valueOf(remain));
+
+
+ stateMap.put("session", session);
+ stateMap.put("token", token);
+
+ String redisKey = "{pdk}:" + connecId;
+ jedis.hmset(redisKey, stateMap);
+ //1小时过期时间
+ jedis.expire(redisKey, 3600);
+
+ System.out.println("保存HuNanPaoDeKuai状态到Redis: " + connecId);
+ } catch (Exception e) {
+ System.err.println("保存HuNanPaoDeKuai状态到Redis失败: " + e.getMessage());
+ } finally {
+ jedis.close();
+ }
+ }
+
+ /**
+ * 从Redis恢复实例状态
+ * @param connecId 连接ID
+ * @return 是否成功恢复
+ */
+ public boolean restoreFromRedis(String connecId) {
+ Jedis jedis = Redis.use("group1_db2").getJedis();
+ try {
+ String redisKey = "{pdk}:" + connecId;
+ Map stateMap = jedis.hgetAll(redisKey);
+
+ if (stateMap == null || stateMap.isEmpty()) {
+ System.out.println("Redis中没有找到HuNanPaoDeKuai状态数据: " + connecId);
+ return false;
+ }
+
+ //反序列化集合
+ if (stateMap.containsKey("seatRemainHistory")) {
+ seatRemainHistory.clear();
+ Map> remainHistory = gson.fromJson(stateMap.get("seatRemainHistory"),
+ new TypeToken