master
zhouwei 2026-02-04 19:19:56 +08:00
parent 9b18a28747
commit f6b9e7c875
36 changed files with 1361 additions and 746 deletions

26
.idea/compiler.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="game_mj_changsha" />
<module name="robot_mj_changsha" />
<module name="pack_tools" />
<module name="taurus-core" />
<module name="robot_common" />
<module name="game_mj_hongzhong" />
<module name="web_group" />
<module name="robot_mgr" />
<module name="web_login" />
<module name="taurus-permanent" />
<module name="event_mgr" />
<module name="group_mgr" />
<module name="game_common" />
<module name="taurus-web" />
</profile>
</annotationProcessing>
</component>
</project>

35
.idea/encodings.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/game_web/event_mgr/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/event_mgr/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/group_room_mgr/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/group_room_mgr/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/pack_tools/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/pack_tools/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/robot_mgr/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/robot_mgr/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/web_group/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/web_group/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/web_login20/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/game_web/web_login20/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/game_common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/game_common/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/robot_common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/robot_common/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/taurus-core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/taurus-core/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/taurus-permanent/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/taurus-permanent/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/taurus-web/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libs/taurus-server/taurus-web/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/majiang/changsha/game_mj_cs/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/majiang/changsha/game_mj_cs/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/majiang/hongzhong/game_mj_hz/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/majiang/hongzhong/game_mj_hz/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/robots/majiang/robot_mj_cs/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/robots/majiang/robot_mj_cs/src/main/resources" charset="UTF-8" />
</component>
</project>

20
.idea/jarRepositories.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/nexus/content/groups/public" />
</remote-repository>
</component>
</project>

View File

@ -1,5 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/game_web/event_mgr/pom.xml" />
<option value="$PROJECT_DIR$/game_web/group_room_mgr/pom.xml" />
<option value="$PROJECT_DIR$/game_web/pack_tools/pom.xml" />
<option value="$PROJECT_DIR$/game_web/robot_mgr/pom.xml" />
<option value="$PROJECT_DIR$/game_web/web_group/pom.xml" />
<option value="$PROJECT_DIR$/game_web/web_login20/pom.xml" />
<option value="$PROJECT_DIR$/libs/game_common/pom.xml" />
<option value="$PROJECT_DIR$/libs/robot_common/pom.xml" />
<option value="$PROJECT_DIR$/libs/taurus-server/pom.xml" />
<option value="$PROJECT_DIR$/majiang/changsha/game_mj_cs/pom.xml" />
<option value="$PROJECT_DIR$/majiang/hongzhong/game_mj_hz/pom.xml" />
<option value="$PROJECT_DIR$/robots/majiang/robot_mj_cs/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>

View File

@ -16,5 +16,10 @@
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/nexus/content/groups/public" />
</remote-repository>
</component>
</project>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/pom.xml" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -116,7 +116,7 @@ public class MainServer extends Extension {
}
Map<Integer, Integer> gameRobotConfig = new HashMap<>();
gameRobotConfig.put(10, 1);
gameRobotConfig.put(10, 10);
gameRobotConfig.put(22, 0);
int robotIndex = 0;

View File

@ -83,10 +83,8 @@ public class RobotDisconnect {
}
//更新Redis2中的机器人start状态为0
updateRedis2StartStatus(robotId, 0);
updateRobotDB(robotId, 0);
//更新机器人状态为可用
updateDatabaseStatus(robotId);
log.info("机器人 {} 断开连接流程完成", robotId);
} catch (Exception e) {
log.error("统一断开机器人 {} 连接时发生异常", robotId, e);
@ -109,27 +107,20 @@ public class RobotDisconnect {
}
}
/**
*
*/
private void updateDatabaseStatus(int robotId) {
try {
String sql = String.format("UPDATE `account` SET start = %d WHERE id = %d", 0, robotId);
DataBase.use().executeUpdate(sql);
log.debug("数据库已更新机器人 {} 状态为可用", robotId);
} catch (Exception e) {
log.error("更新机器人 {} 数据库状态失败", robotId, e);
}
}
/**
* Redis2start
* redis
*/
private void updateRedis2StartStatus(int robotId, int startValue) {
private void updateRobotDB(int robotId, int startValue) {
try (Jedis jedis2 = Redis.use("group1_db2").getJedis()) {
String gRobotKey = "{grobot}:" + robotId;
jedis2.hset(gRobotKey, "start", String.valueOf(startValue));
log.debug("Redis2已更新机器人 {} 的start状态为 {}", robotId, startValue);
String sql = String.format("UPDATE `account` SET start = %d WHERE id = %d", startValue, robotId);
DataBase.use().executeUpdate(sql);
log.debug("数据库已更新机器人 {} 状态为可用", robotId);
} catch (Exception e) {
log.error("更新机器人 {} Redis2 start状态失败", robotId, e);
}

View File

@ -221,64 +221,6 @@ public class RobotConnectionHandler {
}
}
/**
* 6 退
* @param robot
*/
public void readyTimeRobotExit(RobotInfo robot, Object joinRoomLock) {
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(6000);
log.info("机器人 {} 准备时间超过6秒且房间人数不足退出房间", robot.getRobotId());
TaurusClient client = robotClients.get(robot.getRobotId());
if (client != null) {
//发送离开房间协议
ITObject param = new TObject();
param.putString("robotId", String.valueOf(robot.getRobotId()));
param.putString("connecId", robotConnectionIds.get(robot.getRobotId()));
System.out.println("readyTimeRobotExit 2005 client: "+ robotConnectionIds.get(robot.getRobotId()));
client.send("2005", param, response -> {
log.debug("机器人 {} 发送离开房间请求", robot.getRobotId());
});
} else {
log.warn("机器人 {} 连接不存在或未激活,跳过离开房间操作", robot.getRobotId());
}
//机器人退出空房间 增加leftover_robot数量
if (joinRoomLock != null) {
synchronized (joinRoomLock) {
increaseLeftoverRobot(robot);
}
} else {
increaseLeftoverRobot(robot);
}
} catch (InterruptedException e) {
log.debug("超时检查线程被中断: {}", robot.getRobotId());
Thread.currentThread().interrupt();
}
});
}
/**
* leftover_robot 退
*/
private void increaseLeftoverRobot(RobotInfo robot) {
try (Jedis jedis11 = Redis.use("group1_db11").getJedis();Jedis jedis2 = Redis.use("group1_db2").getJedis()) {
String playKey = "g{" + robot.getGroupId() + "}:play:" + robot.getWanfaId();
jedis11.hincrBy(playKey, "leftover_robot", 1);
jedis2.hset("{grobot}:" + robot.getRobotId(), "start", "0");
robotManager.markLeftoverRobotRecovered(robot.getRobotId());
robotManager.roomProcessingFinish(robot.getRoomId());
log.debug("机器人 {} 退出空房间增加leftover_robot群组={}, 玩法={}", robot.getRobotId(), robot.getGroupId(), robot.getWanfaId());
} catch (Exception e) {
log.error("增加Redis leftover_robot时异常群组={}, 玩法={}", robot.getGroupId(), robot.getWanfaId(), e);
}
}
/**
*
*/
@ -328,7 +270,7 @@ public class RobotConnectionHandler {
}
}, 10000);
client.send("2002", readyParam, response -> {
client.send("1002", readyParam, response -> {
boolean success = response != null && response.returnCode == 0;
if (!future.isDone()) {
future.complete(success);
@ -340,9 +282,9 @@ public class RobotConnectionHandler {
}
/**
* CompletableFuture
*
*/
public CompletableFuture<Boolean> sendReadyMessageAsyncCompletable(RobotInfo robot) {
public CompletableFuture<Boolean> sendReadyMessage(RobotInfo robot) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
TaurusClient client = robotClients.get(robot.getRobotId());
@ -356,7 +298,7 @@ public class RobotConnectionHandler {
readyParam.putString("robotId", String.valueOf(robot.getRobotId()));
readyParam.putString("connecId", robotConnectionIds.get(robot.getRobotId()));
// 设置超时机制
//超时机制
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
@ -365,9 +307,9 @@ public class RobotConnectionHandler {
future.completeExceptionally(new RuntimeException("Ready message timeout"));
}
}
}, 10000); // 10秒超时
}, 10000);
client.send("2003", readyParam, response -> {
client.send("1003", readyParam, response -> {
boolean success = response != null && response.returnCode == 0;
if (!future.isDone()) {
future.complete(success);

View File

@ -164,7 +164,7 @@ public class RoomWanfaMatcher {
synchronized (roomSpecificLock) {
if (!processingRooms.contains(roomId)) {
processingRooms.add(roomId);
robotJoinRoom(robot, true);
robotJoinRoom(robot);
}
}
} else {
@ -175,7 +175,7 @@ public class RoomWanfaMatcher {
synchronized (roomSpecificLock) {
if (!processingRooms.contains(roomId)) {
processingRooms.add(roomId);
robotJoinRoom(robot, false);
robotJoinRoom(robot);
}
}
}
@ -191,10 +191,9 @@ public class RoomWanfaMatcher {
/**
*
* @param isRobot
* @param robot
* */
private void robotJoinRoom(RobotInfo robot, boolean isRobot) {
private void robotJoinRoom(RobotInfo robot) {
String roomId = robot != null ? robot.getRoomId() : null;
Object roomSpecificLock = robotManager.getRoomLock(roomId);
synchronized (roomSpecificLock) {
@ -225,7 +224,7 @@ public class RoomWanfaMatcher {
if (joinSuccess) {
System.out.println("机器人"+robot.getRobotId()+" 加入了房间 机器人状态 :" + robot.isConnecting());
//准备阶段
return robotConnectionHandler.sendReadyMessageAsyncCompletable(finalRobotInfo);
return robotConnectionHandler.sendReadyMessage(finalRobotInfo);
} else {
System.out.println("robotJoinRoomInternal机器人加入了房间 失败 :" + robot.isConnecting());
//加入失败 释放机器人
@ -237,10 +236,6 @@ public class RoomWanfaMatcher {
System.out.println("robotJoinRoomInternal机器人准备 房间 机器人状态 :" + robot.isConnecting());
roomToRobotMap.put(roomId, finalRobotInfo.getRobotId());
updateRobotStatusRedis(finalRobotInfo);
if (isRobot) {
//6秒没有玩家加入 则退出房间
//robotConnectionHandler.readyTimeRobotExit(finalRobotInfo, robotManager.getRoomLock(roomId));
}
} else {
System.out.println("robotJoinRoomInternal机器人准备 房间 失败 :" + robot.isConnecting());
//准备失败时释放机器人
@ -284,7 +279,7 @@ public class RoomWanfaMatcher {
*/
private void onRoomCreated(RobotInfo robot) {
try {
robotJoinRoom(robot, true);
robotJoinRoom(robot);
} catch (Exception e) {
if (robot != null) {
robotConnectionHandler.disconnectRobot(robot.getRobotId());

View File

@ -43,14 +43,14 @@
<!--<db>
<name>db1</name>
<driverName>com.mysql.cj.jdbc.Driver</driverName>
<jdbcUrl>jdbc:mysql://8.134.76.43:8060/wb_game</jdbcUrl>
<jdbcUrl>jdbc:mysql://8.138.242.190:8060/wb_game</jdbcUrl>
<userName>root</userName>
<password>6KYnXJjGhxNceF8e</password>
</db>-->
<db>
<name>db1</name>
<driverName>com.mysql.cj.jdbc.Driver</driverName>
<jdbcUrl>jdbc:mysql://8.134.76.43:8060/wb_game</jdbcUrl>
<jdbcUrl>jdbc:mysql://8.138.242.190:8060/wb_game</jdbcUrl>
<userName>root</userName>
<password>6KYnXJjGhxNceF8e</password>
</db>
@ -93,15 +93,15 @@
</poolConfig>
<infos>
<info name="group1_db0" host="8.134.76.43" password="cssq@2020" port="6379" database="0" timeout="5000"/>
<info name="group1_db1" host="8.134.76.43" password="cssq@2020" port="6379" database="1" timeout="5000"/>
<info name="group1_db2" host="8.134.76.43" password="cssq@2020" port="6379" database="2" timeout="5000"/>
<info name="group1_db5" host="8.134.76.43" password="cssq@2020" port="6379" database="5" timeout="5000"/>
<info name="group1_db8" host="8.134.76.43" password="cssq@2020" port="6379" database="8" timeout="5000"/>
<info name="group1_db9" host="8.134.76.43" password="cssq@2020" port="6379" database="9" timeout="5000"/>
<info name="group1_db10" host="8.134.76.43" password="cssq@2020" port="6379" database="10" timeout="5000"/>
<info name="group1_db11" host="8.134.76.43" password="cssq@2020" port="6379" database="11" timeout="5000"/>
<info name="tmp_group1_db9" host="8.134.76.43" password="654sads" port="6479" database="9" timeout="5000"/>
<info name="group1_db0" host="8.138.242.190" password="cssq@2020" port="6379" database="0" timeout="5000"/>
<info name="group1_db1" host="8.138.242.190" password="cssq@2020" port="6379" database="1" timeout="5000"/>
<info name="group1_db2" host="8.138.242.190" password="cssq@2020" port="6379" database="2" timeout="5000"/>
<info name="group1_db5" host="8.138.242.190" password="cssq@2020" port="6379" database="5" timeout="5000"/>
<info name="group1_db8" host="8.138.242.190" password="cssq@2020" port="6379" database="8" timeout="5000"/>
<info name="group1_db9" host="8.138.242.190" password="cssq@2020" port="6379" database="9" timeout="5000"/>
<info name="group1_db10" host="8.138.242.190" password="cssq@2020" port="6379" database="10" timeout="5000"/>
<info name="group1_db11" host="8.138.242.190" password="cssq@2020" port="6379" database="11" timeout="5000"/>
<info name="tmp_group1_db9" host="8.138.242.190" password="654sads" port="6479" database="9" timeout="5000"/>
</infos>
</plugin>
</serivce-core>

View File

@ -8,3 +8,27 @@ taurus.client.io.TSocketException
at taurus.client.io.SocketTcp$2.run(SocketTcp.java:70)
at java.lang.Thread.run(Thread.java:750)
04 二月 2026 | 12:58:54,539 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : ExceptionOnReceive
04 二月 2026 | 15:17:53,519 | INFO | main | core.plugin.PluginService | | plugin[database] load success!
04 二月 2026 | 15:17:53,705 | INFO | main | core.plugin.PluginService | | plugin[redis] load success!
04 二月 2026 | 15:17:54,557 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 15:21:54,810 | INFO | main | core.plugin.PluginService | | plugin[database] load success!
04 二月 2026 | 15:21:54,969 | INFO | main | core.plugin.PluginService | | plugin[redis] load success!
04 二月 2026 | 15:21:55,825 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 15:22:52,765 | INFO | main | core.plugin.PluginService | | plugin[database] load success!
04 二月 2026 | 15:22:52,925 | INFO | main | core.plugin.PluginService | | plugin[redis] load success!
04 二月 2026 | 15:22:53,492 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 16:09:30,082 | INFO | main | core.plugin.PluginService | | plugin[database] load success!
04 二月 2026 | 16:09:30,332 | INFO | main | core.plugin.PluginService | | plugin[redis] load success!
04 二月 2026 | 16:09:39,482 | INFO | main | core.plugin.PluginService | | plugin[database] load success!
04 二月 2026 | 16:09:39,659 | INFO | main | core.plugin.PluginService | | plugin[redis] load success!
04 二月 2026 | 16:09:40,020 | INFO | main | client.business.AccountBusiness | | id:101777 login
04 二月 2026 | 16:09:40,240 | INFO | main | client.business.AccountBusiness | | ==========> password111 = 123456
04 二月 2026 | 16:09:42,684 | INFO | main | client.business.AccountBusiness | | id:101999 login
04 二月 2026 | 16:09:42,691 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 16:09:42,696 | INFO | main | client.business.AccountBusiness | | ==========> password111 = 123456
04 二月 2026 | 16:09:44,507 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 16:09:44,647 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 16:09:44,806 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect
04 二月 2026 | 16:09:44,817 | INFO | main | client.business.AccountBusiness | | id:104637 login
04 二月 2026 | 16:09:44,830 | INFO | main | client.business.AccountBusiness | | ==========> password111 = 123456
04 二月 2026 | 16:09:46,408 | INFO | NetEvent-Thread | client.io.SocketEngine | | status : Connect

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<gameSetting>
<host>8.134.76.43</host>
<intranet>8.134.76.43</intranet>
<host>8.138.242.190</host>
<intranet>8.138.242.190</intranet>
<port>8701</port>
<serverId>7701</serverId>
<gameId>10</gameId>

View File

@ -38,15 +38,15 @@
</poolConfig>
<infos>
<info name="group1_db0" host="8.134.76.43" password="cssq@2020" port="6379" database="0" timeout="5000"/>
<info name="group1_db1" host="8.134.76.43" password="cssq@2020" port="6379" database="1" timeout="5000"/>
<info name="group1_db2" host="8.134.76.43" password="cssq@2020" port="6379" database="2" timeout="5000"/>
<info name="group1_db5" host="8.134.76.43" password="cssq@2020" port="6379" database="5" timeout="5000"/>
<info name="group1_db8" host="8.134.76.43" password="cssq@2020" port="6379" database="8" timeout="5000"/>
<info name="group1_db9" host="8.134.76.43" password="cssq@2020" port="6379" database="9" timeout="5000"/>
<info name="group1_db10" host="8.134.76.43" password="cssq@2020" port="6379" database="10" timeout="5000"/>
<info name="group1_db11" host="8.134.76.43" password="cssq@2020" port="6379" database="11" timeout="5000"/>
<info name="tmp_group1_db9" host="8.134.76.43" password="654sads" port="6479" database="9" timeout="5000"/>
<info name="group1_db0" host="8.138.242.190" password="cssq@2020" port="6379" database="0" timeout="5000"/>
<info name="group1_db1" host="8.138.242.190" password="cssq@2020" port="6379" database="1" timeout="5000"/>
<info name="group1_db2" host="8.138.242.190" password="cssq@2020" port="6379" database="2" timeout="5000"/>
<info name="group1_db5" host="8.138.242.190" password="cssq@2020" port="6379" database="5" timeout="5000"/>
<info name="group1_db8" host="8.138.242.190" password="cssq@2020" port="6379" database="8" timeout="5000"/>
<info name="group1_db9" host="8.138.242.190" password="cssq@2020" port="6379" database="9" timeout="5000"/>
<info name="group1_db10" host="8.138.242.190" password="cssq@2020" port="6379" database="10" timeout="5000"/>
<info name="group1_db11" host="8.138.242.190" password="cssq@2020" port="6379" database="11" timeout="5000"/>
<info name="tmp_group1_db9" host="8.138.242.190" password="654sads" port="6479" database="9" timeout="5000"/>
</infos>
<!--<infos>
<info name="group1_db0" host="127.0.0.1" port="6379" database="0" timeout="5000"/>

View File

@ -5,15 +5,19 @@ 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 robot.mj.info.RobotRoomInfo;
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.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
@ -22,10 +26,10 @@ import java.util.concurrent.ConcurrentHashMap;
public class EXGameController extends GameController {
private static final Logger log = LoggerFactory.getLogger(EXGameController.class);
private static RobotConnectionManager connectionManager = new RobotConnectionManager();
private static RobotConnectionManager robotConnectionManager = new RobotConnectionManager();
//机器人房间
private static final Map<String, RobotRoomInfo> robotRoomMapping = new ConcurrentHashMap<>();
protected static final Map<String, RobotUser> robotRoomMapping = new ConcurrentHashMap<>();
public EXGameController() {
super();
@ -117,7 +121,6 @@ public class EXGameController extends GameController {
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", "无法获取游戏服务器连接");
@ -133,7 +136,7 @@ public class EXGameController extends GameController {
if (sessionParts.length >= 2) {
robotSession = sessionParts[0];
String token = sessionParts[1];
connectionManager.setSessionAndToken(robotSession, token);
robotConnectionManager.setSessionAndToken(robotSession, token);
}
}
@ -151,7 +154,7 @@ public class EXGameController extends GameController {
//发送加入房间请求到game_mj_cs
client.send(Config.JOIN_ROOM_CS, params, response -> {
System.out.println("joinRoomController: " + response);
RobotRoomInfo roomInfo = new RobotRoomInfo();
RobotUser roomInfo = new RobotUser();
roomInfo.setRoomId(roomId);
roomInfo.setConnecId(connecId);
roomInfo.setUserId(0);
@ -159,7 +162,6 @@ public class EXGameController extends GameController {
robotRoomMapping.put(robotId, roomInfo);
});
// 发送成功响应
ITObject paramsReq = TObject.newInstance();
paramsReq.putString("status", "success");
MainServer.instance.sendResponse(gid, 0, paramsReq, session);
@ -198,7 +200,6 @@ public class EXGameController extends GameController {
System.out.println("robotReadyRoom: " + response);
});
// 发送成功响应
ITObject paramsReq = TObject.newInstance();
paramsReq.putString("status", "success");
MainServer.instance.sendResponse(gid, 0, paramsReq, session);
@ -212,56 +213,58 @@ public class EXGameController extends GameController {
}
}
/**
* robot_mgr退
* game_mj_csTCP
*/
@ActionKey(value = Config.EXIT_ROOM, validate = GameInterceptor.NOT_PLAYER)
public void exitRoom(Session session, ITObject params, int gid) {
try {
String connecId = params.getString("connecId");
Integer robotId = params.getInt("robotId"); // 获取机器人ID
log.info("处理退出房间请求connecId: {}, robotId: {}", connecId, robotId);
@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");
try (Jedis jedis0 = Redis.use("group1_db0").getJedis()){
Set<String> robotTokens = jedis0.smembers("{user}:"+robotId+"_token");
String robotSession = null;
// 清理机器人房间映射
if (robotId != null && robotId > 0) {
RobotRoomInfo removedInfo = robotRoomMapping.remove(robotId);
if (removedInfo != null) {
log.info("清理机器人房间映射: robotId={}, 映射信息={}", robotId, removedInfo);
for (String token : robotTokens) {
if (jedis0.exists(token)) {
robotSession = token;
break;
}
}
TaurusClient client = getCsMjGameServerConnection(connecId);
if (client == null) {
log.error("无法获取到游戏服务器连接connecId: {}", connecId);
return;
}
System.out.println("进房间: "+robotId);
System.out.println("进房间: "+roomId);
System.out.println("进房间: "+"room:"+ roomId);
System.out.println("进房间: "+"{user}:"+robotId);
//发送退出房间请求
client.send(Config.EXIT_ROOM_CS, params, response -> {
log.info("退出房间请求发送结果: returnCode={} for connecId={}", response.returnCode, connecId);
TaurusClient client = getCsMjGameServerConnection(roomId+"_"+robotId);
GroupRoomBusiness.joinRoom(groupId, "room:"+ roomId, "{user}:"+robotId, null);
//机器人房间映射关系
RobotUser robotUser = getRobotRoomInfo(String.valueOf(robotId));
Thread.sleep(5000);
params.putString("session","{user}:"+robotId+ "," + robotSession);
//发送加入房间请求到game_mj_cs
client.send(Config.JOIN_ROOM_CS, params, response -> {
System.out.println("joinRoomController: " + response);
robotConnectionManager.reconnectToGameServer(response, robotUser, client);
});
//断开与游戏服务器的连接
//connectionManager.disconnectFromGameServer(connecId);
} catch (Exception e) {
log.error("处理退出房间请求时发生错误", e);
String connecId = params.getString("connecId");
Integer robotId = params.getInt("robotId");
//出错时也要清理映射
if (robotId != null && robotId > 0) {
robotRoomMapping.remove(robotId);
Thread.sleep(1000);
if(client.isConnected()){
client.send(Config.GAME_READY_CS, params, response -> {
System.out.println("1003:"+response);
});
robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_READY);
}
//connectionManager.disconnectFromGameServer(connecId);
robotUser.setIntoRoomTime(robotConnectionManager.getTime());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* ID
*/
public static RobotRoomInfo getRobotRoomInfo(String robotId) {
public static RobotUser getRobotRoomInfo(String robotId) {
return robotRoomMapping.get(robotId);
}
@ -277,15 +280,13 @@ public class EXGameController extends GameController {
* robotIdconnectionId
*/
public static TaurusClient getCsMjGameServerConnection(String connecId) {
TaurusClient taurusClient = connectionManager.getGameClient(connecId);
TaurusClient taurusClient = robotConnectionManager.getGameClient(connecId);
System.out.println("根据机器人ID和连接ID获取长沙麻将游戏服务器连接 client: = "+taurusClient);
if (taurusClient != null) {
log.debug("成功获取游戏服务器连接connecId: {}", connecId);
// 快速检测连接状态
connectionManager.quickCheckAndReconnect(connecId);
return taurusClient;
}
taurusClient = connectionManager.connectToGameServer(connecId);
taurusClient = robotConnectionManager.connectToGameServer(connecId);
return taurusClient;
}

View File

@ -6,12 +6,21 @@ 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;
/**
*
* TCProbot_mgr game_mj_csAI
@ -19,6 +28,10 @@ import java.util.concurrent.TimeUnit;
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();
@ -26,11 +39,100 @@ public class EXMainServer extends MainServer{
// 1. 先启动独立的事件处理线程(只启动一次)
startNetEventThread();
// 2. 启动连接检查定时任务
startConnectionCheckScheduler();
//测试
Jedis jedis2 = Redis.use("group1_db2").getJedis();
String robotskey = "g{"+330800+"}:play:"+10;
Map<String, String> maprobot = jedis2.hgetAll(robotskey);
for(Map.Entry<String, String> entry : maprobot.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
//是否创建
RobotUser robotUser = new RobotUser();
robotUser.setRobotId(entry.getKey());
robotUser.setPassword("123456");
robotUser.setGameHost("8.138.242.190");
robotUser.setGamePort("6311");
robotUser.setRobotGroupid("330800");
robotUser.setRobotPid("10");
robotRoomMapping.put(entry.getKey(), robotUser);
}
TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
for(Map.Entry<String, RobotUser> 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);
}
/**
*
*/
private void startConnectionCheckScheduler() {
Thread connectionCheckThread = new Thread(() -> {
while (connectionCheckRunning) {
try {
for(Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
RobotUser robotUser = entry.getValue();
robotConnectionManager.checkIsConnect(robotUser);
}
Thread.sleep(2000);
} catch (InterruptedException e) {
break;
} catch (Exception e) {
log.error("连接检查线程异常", e);
}
}
}, "Connection-Check-Thread");
connectionCheckThread.setDaemon(true);
connectionCheckThread.start();
}
/**
* 线
*/
@ -72,6 +174,8 @@ public class EXMainServer extends MainServer{
public void onStop() {
super.onStop();
// 停止连接检查线程
connectionCheckRunning = false;
log.info("长沙麻将机器人服务器已停止");
}
}

View File

@ -2,6 +2,7 @@ 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;
@ -9,9 +10,8 @@ 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 redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import robot.mj.info.RobotRoomInfo;
import robot.mj.business.AccountBusiness;
import robot.mj.info.RobotUser;
import taurus.client.Message;
import taurus.client.MessageResponse;
import taurus.client.TaurusClient;
@ -19,6 +19,7 @@ import taurus.client.SocketCode;
import redis.clients.jedis.Jedis;
import robot.mj.handler.HuNanChangSha;
import taurus.util.ChangShaSuanFaTest;
import taurus.util.ROBOTEventType;
import taurus.util.TinHuChi;
import java.util.*;
@ -33,25 +34,11 @@ public class RobotConnectionManager {
private Map<String, TaurusClient> gameClients;
//存储全局的长沙麻将AI处理器
private HuNanChangSha huNanChangSha;
private EXGameController exGameController;
private final String host="8.134.76.43";
private final String host="8.138.242.190";
private final int port=6311;
// 自动重连相关
private final ScheduledExecutorService reconnectScheduler = Executors.newScheduledThreadPool(2);
private final Map<String, Boolean> activeConnections = new ConcurrentHashMap<>();//记录活跃连接
private final Map<String, Integer> reconnectAttempts = new ConcurrentHashMap<>();//重连尝试次数
private final Map<String, Long> lastActivityTime = new ConcurrentHashMap<>();//记录最后活动时间
private final Map<String, ScheduledFuture<?>> connectionWatchers = new ConcurrentHashMap<>();//连接监视器
private final Map<String, Long> lastDisconnectTime = new ConcurrentHashMap<>();//记录最后断开时间
private final Map<String, IEventListener> connectEventListeners = new ConcurrentHashMap<>();//连接事件监听器
private final Map<String, IEventListener> messageEventListeners = new ConcurrentHashMap<>();//消息事件监听器
private final int MAX_RECONNECT_ATTEMPTS = 3;//最大重连次数(减少重试)
private final int RECONNECT_DELAY_SECONDS = 5;//重连间隔秒数(增加延迟)
private final int CONNECTION_WATCH_INTERVAL = 15;//连接监视间隔秒数(延长检测间隔)
private final int CONNECTION_TIMEOUT_SECONDS = 45;//连接超时检测秒数(延长超时时间)
private final int MIN_RECONNECT_INTERVAL = 60;//最小重连间隔秒数(防止频繁重连)
/*长沙麻将游戏算法相关 start*/
private Map<Integer, List<Integer>> playerOutcardsMap = new HashMap<>();
private Map<Integer, List<Integer>> playerchisMap = new HashMap<>();
@ -66,108 +53,12 @@ public class RobotConnectionManager {
/*长沙麻将游戏算法相关 end*/
public RobotConnectionManager() {
gameClients = new HashMap<>();
huNanChangSha = new HuNanChangSha();
}
/**
*
*/
private void startConnectionWatcher(String connecId) {
//检查是否有运行中的监视器
ScheduledFuture<?> existingWatcher = connectionWatchers.get(connecId);
if (existingWatcher != null && !existingWatcher.isDone()) {
existingWatcher.cancel(false);
}
TaurusClient client = gameClients.get(connecId);
if (client == null || !client.isConnected()) {
System.out.println("连接不存在或未激活,不启动监视器: {"+connecId+"}");
return;
}
//启动监视器
ScheduledFuture<?> watcher = reconnectScheduler.scheduleAtFixedRate(() -> {
try {
monitorConnection(connecId);
} catch (Exception e) {
System.out.println("连接监视器执行异常: {"+connecId+"} " + e.getMessage());
}
}, CONNECTION_WATCH_INTERVAL, CONNECTION_WATCH_INTERVAL, TimeUnit.SECONDS);
connectionWatchers.put(connecId, watcher);
System.out.println("启动连接监视器: {"+connecId+"}, 检测间隔: {"+CONNECTION_WATCH_INTERVAL+"}秒");
}
/**
*
*/
private void monitorConnection(String connecId) {
TaurusClient client = gameClients.get(connecId);
if (client == null) {
System.out.println("监视器找不到客户端连接: {"+connecId+"}");
stopConnectionWatcher(connecId);
return;
}
// 检查连接状态
if (!client.isConnected()) {
System.out.println("监视器检测到连接断开: {"+connecId+"}");
handleConnectionFailure(connecId, SocketCode.Disconnect);
return;
}
// 检查是否超时(基于最后活动时间)
Long lastActivity = lastActivityTime.get(connecId);
if (lastActivity != null) {
long elapsed = System.currentTimeMillis() - lastActivity;
if (elapsed > CONNECTION_TIMEOUT_SECONDS * 1000) {
System.out.println("连接超时检测: {"+connecId+"}, elapsed: {"+elapsed+"}ms");
// 尝试发送验证消息
try {
ITObject params = TObject.newInstance();
params.putString("pos", "10,10");
client.send("1001", params, response -> {
// 更新活动时间
lastActivityTime.put(connecId, System.currentTimeMillis());
});
} catch (Exception e) {
System.out.println("连接验证失败,触发重连: {"+connecId+"}");
handleConnectionFailure(connecId, SocketCode.NetworkException);
}
}
}
}
/**
*
*/
private void removeEventListeners(String connecId) {
TaurusClient client = gameClients.get(connecId);
if (client != null) {
IEventListener messageListener = messageEventListeners.remove(connecId);
IEventListener connectListener = connectEventListeners.remove(connecId);
if (messageListener != null) {
client.removeEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
}
if (connectListener != null) {
client.removeEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
}
}
System.out.println("移除事件监听器: {"+connecId+"}");
}
/**
*
*/
private void stopConnectionWatcher(String connecId) {
ScheduledFuture<?> watcher = connectionWatchers.remove(connecId);
if (watcher != null && !watcher.isDone()) {
watcher.cancel(false);
}
System.out.println("停止连接监视器定时任务: {"+connecId+"}");
exGameController = new EXGameController();
}
/**
@ -190,10 +81,6 @@ public class RobotConnectionManager {
return existingClient;
}
//todo: 断线重连
/*else {
//连接断开 移除旧的客户端
disconnectFromGameServer(connecId);
}*/
}
//创建Taurus客户端
@ -205,9 +92,6 @@ public class RobotConnectionManager {
client.connect();
gameClients.put(connecId, client);
activeConnections.put(connecId, true);
reconnectAttempts.remove(connecId);
lastActivityTime.put(connecId, System.currentTimeMillis()); // 记录连接建立时间
return client;
} catch (Exception e) {
@ -222,18 +106,6 @@ public class RobotConnectionManager {
public void disconnectFromGameServer(String connecId) {
System.out.println("开始主动断开连接: {"+connecId+"}");
//主动断开 标记为非活跃连接
activeConnections.put(connecId, false);
reconnectAttempts.remove(connecId);
lastActivityTime.remove(connecId);
lastDisconnectTime.put(connecId, System.currentTimeMillis());
//停止连接监视器
stopConnectionWatcher(connecId);
//移除事件监听器
removeEventListeners(connecId);
TaurusClient client = gameClients.remove(connecId);
if (client != null) {
try {
@ -263,132 +135,18 @@ public class RobotConnectionManager {
}
}
/**
*
*/
private void handleConnectionFailure(String connecId, SocketCode code) {
System.out.println("处理连接失败或断开事件: {"+connecId+"}, 错误码: {"+code+"}");
//非主动断开才进行重连
if (activeConnections.getOrDefault(connecId, false)) {
scheduleReconnect(connecId);
}
}
/**
*
*/
private void scheduleReconnect(String connecId) {
//检查是否仍然是活跃连接
if (!activeConnections.getOrDefault(connecId, false)) {
System.out.println("连接已非活跃,取消重连安排: {"+connecId+"}");
return;
}
Integer attempts = reconnectAttempts.getOrDefault(connecId, 0);
//最大重连次数
if (attempts >= 5) {
System.out.println("达到最大重连次数,停止重连: {"+connecId+"}");
activeConnections.put(connecId, false);
return;
}
reconnectAttempts.put(connecId, attempts + 1);
System.out.println("安排重连任务: {"+connecId+"}, 第{"+(attempts + 1)+"}次尝试");
reconnectScheduler.schedule(() -> {
try {
//再次检查连接状态
if (activeConnections.getOrDefault(connecId, false)) {
System.out.println("开始重连: {"+connecId+"}");
reconnectToGameServer(connecId);
} else {
System.out.println("重连前检查发现连接已非活跃,取消重连: {"+connecId+"}");
}
} catch (Exception e) {
System.out.println("重连失败: {"+connecId+"}, 错误: " + e.getMessage());
}
}, 1, TimeUnit.SECONDS);//重连间隔秒
}
/**
*
*/
private void reconnectToGameServer(String connecId) {
//检查是否仍然是活跃连接
if (!activeConnections.getOrDefault(connecId, false)) {
System.out.println("连接已标记为非活跃,取消重连: {"+connecId+"}");
return;
}
try {
//检查是否已经有连接
TaurusClient existingClient = gameClients.get(connecId);
if (existingClient != null && existingClient.isConnected()) {
System.out.println("连接已恢复,取消重连: {"+connecId+"}");
reconnectAttempts.remove(connecId);
return;
}
//移除旧的客户端和事件监听器
if (existingClient != null) {
try {
existingClient.killConnection();
} catch (Exception e) {
System.out.println("关闭旧连接时发生异常: {"+connecId+"}");
}
gameClients.remove(connecId);
}
//清理旧的事件监听器
removeEventListeners(connecId);
//创建新连接
TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);
//设置新的事件监听器
setupEventListeners(client, connecId);
client.connect();
gameClients.put(connecId, client);
lastActivityTime.put(connecId, System.currentTimeMillis());
System.out.println("重连成功: {"+connecId+"}");
reconnectAttempts.remove(connecId);
//重连成功后重新启动监视器
startConnectionWatcher(connecId);
} catch (Exception e) {
log.error("重连过程中发生异常: " + connecId, e);
//检查是否仍然是活跃连接后再安排下次重连
if (activeConnections.getOrDefault(connecId, false)) {
scheduleReconnect(connecId);
}
}
}
/**
*
*/
private void setupEventListeners(TaurusClient client, String connecId) {
// 先移除可能存在的旧监听器
removeEventListeners(connecId);
public void setupEventListeners(TaurusClient client, String connecId) {
//添加消息事件监听器
IEventListener messageListener = new IEventListener() {
@Override
public void handleEvent(Event event) {
//检查连接是否仍然有效
if (!activeConnections.getOrDefault(connecId, false)) {
System.out.println("消息监听器: 连接已非活跃,忽略消息: {"+connecId+"}");
return;
}
//获取 msg
Message message = (Message) event.getParameter("msg");
// 更新最后活动时间
lastActivityTime.put(connecId, System.currentTimeMillis());
ITObject param = message.param;
//回调协议号
String command = message.command;
@ -406,80 +164,87 @@ public class RobotConnectionManager {
IEventListener connectListener = new IEventListener() {
@Override
public void handleEvent(Event event) {
//检查连接是否仍然应该处理事件
if (!activeConnections.getOrDefault(connecId, false)) {
System.out.println("连接监听器: 连接已标记为非活跃,忽略状态变更: {"+connecId+"}");
return;
}
Message message = (Message) event.getParameter("msg");
SocketCode code = (SocketCode) event.getParameter("code");
if (code == SocketCode.Connect) {
System.out.println("csmj Connect connecId: " + connecId);
//连接成功 标记为活跃连接并重置重连次数
activeConnections.put(connecId, true);
reconnectAttempts.remove(connecId);
lastActivityTime.put(connecId, System.currentTimeMillis());
lastDisconnectTime.remove(connecId);
System.out.println("连接成功: {"+connecId+"} ");
//启动该连接的监视器
if (!connectionWatchers.containsKey(connecId)) {
startConnectionWatcher(connecId);
}
} else {
//连接失败或断开
System.out.println("连接状态异常: {"+connecId+"}, code: {"+code+"}");
if (activeConnections.getOrDefault(connecId, false)) {
//断开活跃连接
handleConnectionFailure(connecId, code);
}
}
}
};
//注册事件监听器
client.addEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
client.addEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
//保存监听器引用以便后续移除
messageEventListeners.put(connecId, messageListener);
connectEventListeners.put(connecId, connectListener);
}
/**
*
* 线
*/
public void quickCheckAndReconnect(String connecId) {
TaurusClient client = gameClients.get(connecId);
if (client != null) {
//检查连接状态和超时
if (!client.isConnected()) {
System.out.println("快速检测到连接断开: {"+connecId+"} ");
handleConnectionFailure(connecId, SocketCode.Disconnect);
public void reconnectToGameServer(MessageResponse response, RobotUser robotUser, TaurusClient client) {
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) {
//重连回来的
int curren_outcard_seat = reloadInfo.getInt("curren_outcard_seat");
if(curren_outcard_seat== robotUser.getSeat()){
//同步手牌
ITArray hand_card = reloadInfo.getTArray("hand_card");
ITArray info_list = reloadInfo.getTArray("info_list");
List<Integer> 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");
}
}
}
if(hcard.size()>0){
//同步手牌
huNanChangSha.updateHandCard(hcard);
if(outcard_list.size()>0){
List<Integer> outcards = new ArrayList<>();
for (int i = 0; i < outcard_list.size(); i++) {
outcards.add(outcard_list.getInt(i));
}
huNanChangSha.updateOutCard(outcards);
}
sleepTime(2000);
huNanChangSha.outCard(client,playerOutcardsMap, playerchisMap, playerpengsMap, playermingsMap, playerzisMap);
}
}
}
}
}else {
//检查是否超时(基于最后活动时间)
Long lastActivity = lastActivityTime.get(connecId);
if (lastActivity != null) {
long elapsed = System.currentTimeMillis() - lastActivity;
if (elapsed > CONNECTION_TIMEOUT_SECONDS * 1000) {
System.out.println("连接超时检测: {"+connecId+"} , elapsed: {"+elapsed+"}ms");
//尝试发送一个简单消息来验证连接
try {
ITObject params = TObject.newInstance();
params.putString("pos", "10,10");
client.send("1001", params, response -> {
//更新活动时间
lastActivityTime.put(connecId, System.currentTimeMillis());
});
} catch (Exception e) {
System.out.println("连接验证失败,触发重连: : {"+connecId+"}");
handleConnectionFailure(connecId, SocketCode.NetworkException);
}
}
}
}
renconnect(robotUser);
}
}
@ -487,16 +252,38 @@ public class RobotConnectionManager {
*
*/
private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
String[] robotIds= connecId.split("_", 2);
int robotId = Integer.parseInt(robotIds[0]);
RobotUser robotUser = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
ITObject param = message.param;
try (Jedis jedis0 = Redis.use().getJedis()){
try (Jedis jedis0 = Redis.use().getJedis();Jedis jedis2 = Redis.use("group1_db2").getJedis();){
//长沙麻将 机器人处理事件
//[TCP->822] data:{"tip_list":[{"type":8,"id":1,"opcard":[],"weight":8,"card":0}],"types":[{"type":21,"value":1}]}
//板胡Event [TCP->823] data:{"type":8,"seat":1,"data":[{"opcard":[204,204,204,108,108,108],"type":21,"value":1}]}
if ("811".equalsIgnoreCase(command)) {//初始化收手牌
//初始化收手牌
if ("811".equalsIgnoreCase(command)) {
robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_WORKING);
//初始化收手牌
// System.out.println("初始化手牌" + session);
String key = robotId+"";
log.info("key+++++++++++++++++++++++++++++++++++" + key);
if (jedis2.hget("{robortInfo}:" + key, "circleId") != null && jedis2.hget("{robortInfo}:" + key, "pid") != null) {
String circleId = jedis2.hget("{robortInfo}:" + key, "circleId");
log.info("circleId +++++++++++++++++++++++++"+circleId);
String pid = jedis2.hget("{robortInfo}:" + key, "pid");
log.info("pid +++++++++++++++++++++++++"+pid);
String getStart = "g{" + circleId + "}:play:" + pid;
if (!pid.equals("0")){
log.info("getStart +++++++++++++++++++++++++"+getStart);
jedis2.hset(getStart, key, "2");
}
}
huNanChangSha.cardInHead(command, message, client);
} else if ("812".equalsIgnoreCase(command)) {//出牌广播
}
//出牌广播
else if ("812".equalsIgnoreCase(command)) {
//{"opzicards":[{"opzicards":[],"playerId":101555}],"opmingcards":[{"opmingcards":[],"playerId":101555}],"outcard_map":[{"outcards":[209,205],"playerId":101555},{"outcards":[],"playerId":112233}],"card":205,"opchicards":[{"opchicards":[105,103],"playerId":101555}],"oppengcards":[{"oppengcards":[],"playerId":101555}],"seat":1}
ITArray outcard_map = param.getTArray("outcard_map");
ITArray opchicards = param.getTArray("opchicards");
@ -590,11 +377,13 @@ public class RobotConnectionManager {
}
HuNanChangSha.drawCard(command, message);
} else if ("819".equalsIgnoreCase(command)) {
}
//摸牌
huNanChangSha.getCard(command, message,null,null);
} else if ("813".equalsIgnoreCase(command)) {//出牌提示
else if ("819".equalsIgnoreCase(command)) {
huNanChangSha.getCard(command, message, client);
}
//出牌提示
else if ("813".equalsIgnoreCase(command)) {
huNanChangSha.outCard(client,playerOutcardsMap,playerchisMap,playerpengsMap,playermingsMap,playerzisMap);
}
//放招提示
@ -603,24 +392,18 @@ public class RobotConnectionManager {
}
//2026.02.03修改 玩家加入房间
else if ("2001".equalsIgnoreCase(command)) {
String[] robotId = connecId.split("_", 2);
RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(robotId[0]);
Integer userId = param.getInt("aid");
robotRoomInfo.setUserId(userId);
System.out.println("玩家{"+robotRoomInfo.getRoomId()+"}加入房间:"+ param);
robotUser.setUserId(userId);
System.out.println("玩家{"+ robotUser.getRoomId()+"}加入房间:"+ param);
}
//2026.02.03修改 玩家退出房间也要检查
else if ("2002".equalsIgnoreCase(command)) {
/*else if ("2002".equalsIgnoreCase(command)) {
CompletableFuture.runAsync(() -> {
try {
Integer userId = param.getInt("aid");
String[] robotIds= connecId.split("_", 2);
int robotId = Integer.parseInt(robotIds[0]);
RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(robotIds[0]);
Thread.sleep(6000);
sleepTime(6000);
if (userId.equals(robotRoomInfo.getUserId())) {
String roomKey = robotRoomInfo.getRoomId();
if (userId.equals(robotUser.getUserId())) {
String roomKey = robotUser.getRoomId();
//查询该房间的玩家信息
String playersStr = jedis0.hget(roomKey, "players");
@ -656,30 +439,48 @@ public class RobotConnectionManager {
}
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}*/
else if("2002".equalsIgnoreCase(command)) {
System.out.println("comds:2002");
ITObject params = TObject.newInstance();
String aid = client.getGameID();
String getKey = "{robortInfo}:" + aid;
Jedis jedis20 = Redis.use("group1_db2").getJedis();
String circleId1 = jedis20.hget(getKey, "circleId");
String pid = jedis20.hget(getKey, "pid");
String key = "g{" + circleId1 + "}:play:" + pid;
client.send("1005", params, response -> {
log.info("退出状态1---------"+response);
log.info("退出状态1getKey---------"+getKey);
log.info("退出状态1key---------"+key);
log.info("退出状态1aid---------"+aid);
jedis20.hset(getKey, "circleId", "0");
jedis20.hset(getKey, "pid", "0");
jedis20.hset(getKey, "room_id", "0");
//退出修改机器人状态
jedis20.hset(key,aid, "0");
});
jedis20.close();
}
//2026.02.03修改 玩家解散房间
else if ("2005".equalsIgnoreCase(command)) {
CompletableFuture.runAsync(() -> {
String[] robotIds= connecId.split("_", 2);
int robotId = Integer.parseInt(robotIds[0]);
RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
ITArray playsList = param.getTArray("list");
for (int i = 0; i < playsList.size(); i++) {
ITObject playerData = playsList.getTObject(i);
Integer userId = playerData.getInt("aid");
if (userId.equals(robotId)) {
String roomKey = robotRoomInfo.getRoomId();
String roomKey = robotUser.getRoomId();
String gpid = jedis0.hget(roomKey, "gpid");
String gpId = jedis0.hget(roomKey, "group");
try {
Thread.sleep(25000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
sleepTime(25000);
//更新机器人剩余数量
if (count != null && count.containsKey(Integer.parseInt(gpid))) {
Integer currentValue = count.get(Integer.parseInt(gpid));
@ -698,10 +499,7 @@ public class RobotConnectionManager {
}
//2026.02.03修改 解散房间时候恢复机器人账号可以使用
else if ("2008".equalsIgnoreCase(command)) {
String[] robotIds= connecId.split("_", 2);
int robotId = Integer.parseInt(robotIds[0]);
RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
String roomKey = robotRoomInfo.getRoomId();
String roomKey = robotUser.getRoomId();
if (jedis0.exists(roomKey)) {
String gpid = jedis0.hget(roomKey, "gpid");
@ -717,13 +515,11 @@ public class RobotConnectionManager {
//2026.02.03修改 通过机器人房间映射直接获取房间信息
else if ("2009".equalsIgnoreCase(command)) {
CompletableFuture.runAsync(() -> {
try {
Integer robotId = param.getInt("aid");
Thread.sleep(6000);
Integer paramRobotId = param.getInt("aid");
sleepTime(6000);
RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
if (robotRoomInfo != null) {
String roomKey = robotRoomInfo.getRoomId();
if (robotUser != null) {
String roomKey = robotUser.getRoomId();
//查询该房间的玩家信息
String playersStr = jedis0.hget(roomKey, "players");
@ -734,7 +530,7 @@ public class RobotConnectionManager {
//判断只有当前机器人一个玩家
if (playerIds.length == 1) {
int playerId = Integer.parseInt(playerIds[0].trim());
if (playerId == robotId) {
if (playerId == paramRobotId) {
String gpid = jedis0.hget(roomKey, "gpid");
String gpId = jedis0.hget(roomKey, "group");
@ -750,20 +546,17 @@ public class RobotConnectionManager {
//发送退出房间协议
ITObject params = TObject.newInstance();
client.send("1005", params, response -> {
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId));
//断开连接
disconnectFromGameServer(connecId);
//更新机器人剩余数量
updateLeftoverRobot(gpId, gpid, robotId);
System.out.println("2009发送退出房间协议1005robotId: {"+robotId+"}");
updateLeftoverRobot(gpId, gpid, paramRobotId);
System.out.println("2009发送退出房间协议1005robotId: {"+paramRobotId+"}");
});
}
}
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
//结算
@ -828,7 +621,7 @@ public class RobotConnectionManager {
// playerState.gangGroups.clear();;
Thread.sleep(1000);
sleepTime(1000);
ITObject params = TObject.newInstance();
params.putString("session", client.getSession());
@ -881,24 +674,169 @@ public class RobotConnectionManager {
});
}
} catch (InterruptedException e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Set<String> scanRooms(Jedis jedis, String pattern) {
Set<String> keys = new HashSet<>();
String cursor = "0";
ScanParams scanParams = new ScanParams().match(pattern).count(100);
do {
ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
keys.addAll(scanResult.getResult());
cursor = String.valueOf(scanResult.getCursor());
} while (!cursor.equals("0"));
return keys;
public static void sleepTime(int time) {
try {
// 添加延迟
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
*
*/
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());
}
if (object != null) {
//判断是否有房间
if(object.getTObject("account")!=null){
ITObject validate = TObject.newInstance();
validate.putString("token", object.getString("token"));
robotUser.setToken(object.getString("token"));;
robotUser.setLoginsession("{user}:"+robotUser.getRobotId());
if (robotUser.getLoginsession() != null) {
robotUser.setIsLogin(true);
}
if(object.getTObject("account").get("roomid")!=null){
String roomid = object.getTObject("account").get("roomid").toString();
robotUser.setCurrentRoomId(Integer.parseInt(roomid));
connectGame(robotUser);
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());
}
}
}
} 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(), String.valueOf(robotUser.getRobotId()), TaurusClient.ConnectionProtocol.Tcp);
client.setSession(robotUser.getLoginsession());
client.connect();
setupEventListeners(client, robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId());
robotUser.setIsconnect(client.isConnected());
robotUser.setClient(client);
}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(), String.valueOf(robotUser.getRobotId()), TaurusClient.ConnectionProtocol.Tcp);
client.setSession(robotUser.getLoginsession());
client.connect();
robotUser.setIsconnect(client.isConnected());
}
}
}
}
public void checkIsConnect(RobotUser robotUser){
System.out.println("checkIsConnect:"+robotUser.getRobotId()+"==="+robotUser.getStatus());
System.out.println("checkIsConnectgetId:"+robotUser.getRobotId()+"==="+robotUser.getClient().getId());
System.out.println("checkIsConnectgetGameID:"+robotUser.getRobotId()+"==="+robotUser.getClient().getGameID());
if(robotUser.getIsLogin()&&robotUser.getClient()!=null){
System.out.println("connectid:"+robotUser.getClient().getId());
robotUser.setIsconnect(robotUser.getClient().isConnected());
}
}
/**
* 退
*/
public void outoRoom(RobotUser robotUser) {
//判断当前状态是否在工作
System.out.println("outoRoom:"+ROBOTEventType.ROBOT_INTOROOM_READY);
if (robotUser.getStatus() == ROBOTEventType.ROBOT_INTOROOM_READY) {
//判断房间是否有人
//room:197276
Jedis jedis0 = Redis.use("group1_db0").getJedis();
try {
System.out.println("getCurrentRoomId:"+robotUser.getCurrentRoomId());
if(robotUser.getCurrentRoomId()!=0){
System.out.println("getCurrentRoomId:"+ROBOTEventType.ROBOT_INTOROOM_READY);
String roomkey="room:"+robotUser.getCurrentRoomId();
List<String> room_list = jedis0.hmget(roomkey, "fake", "status", "round", "id", "times", "players", "create_time", "fake_existTime");
System.out.println("room_list:"+room_list);
String roomId = room_list.get(3);
if(room_list.get(5)==null){
ITObject params = TObject.newInstance();
params.putString("session", robotUser.getLoginsession() + "," + robotUser.getToken());
System.out.println("logoutroom:"+params);
if(robotUser.getClient().isConnected()){
robotUser.getClient().send("1005", params,response -> {
});
robotUser.setStatus(ROBOTEventType.ROBOT_UNUSE);
}
}
ITArray players = TArray.newFromJsonData(room_list.get(5));
System.out.println("players:"+players);
if(players.size()<2){
ITObject params = TObject.newInstance();
params.putString("session", robotUser.getLoginsession() + "," + robotUser.getToken());
System.out.println("logoutroom:"+params);
if(robotUser.getClient().isConnected()){
robotUser.getClient().send("1005", params,response -> {
});
robotUser.setStatus(ROBOTEventType.ROBOT_UNUSE);
}
}
}
}catch (Exception e){
}finally {
jedis0.close();
}
}
}
public int getTime(){
return Integer.parseInt((System.currentTimeMillis() + "").substring(0, 10));
}
/**
*
*/
public void renconnect(RobotUser robotUser){
TaurusClient client = robotUser.getClient();
if(client!=null){
if(client.isConnected()){
client.connect();
robotUser.setIsconnect(client.isConnected());
}
}
}
/**
* connecId
@ -907,49 +845,4 @@ public class RobotConnectionManager {
return gameClients.get(connecId);
}
/**
*
*/
public void cleanupAllConnections() {
System.out.println("开始清理所有连接和资源...");
//标记所有连接为非活跃
for (String connecId : activeConnections.keySet()) {
activeConnections.put(connecId, false);
}
//断开所有连接
for (String connecId : new ArrayList<>(gameClients.keySet())) {
disconnectFromGameServer(connecId);
}
//停止所有监视器
for (String connecId : new ArrayList<>(connectionWatchers.keySet())) {
stopConnectionWatcher(connecId);
}
//关闭调度器
reconnectScheduler.shutdown();
try {
if (!reconnectScheduler.awaitTermination(5, TimeUnit.SECONDS)) {
reconnectScheduler.shutdownNow();
}
} catch (InterruptedException e) {
reconnectScheduler.shutdownNow();
Thread.currentThread().interrupt();
}
//清理所有缓存数据
activeConnections.clear();
reconnectAttempts.clear();
lastActivityTime.clear();
lastDisconnectTime.clear();
connectionWatchers.clear();
connectEventListeners.clear();
messageEventListeners.clear();
gameClients.clear();
System.out.println("所有连接和资源清理完成");
}
}

View File

@ -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<String, String> 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<String> 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<String> 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<String, String> map = new HashMap<String, String>();
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<String> 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<String, Integer> 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;
}
}

View File

@ -16,6 +16,7 @@ import taurus.util.*;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
public class HuNanChangSha {
@ -24,6 +25,14 @@ public class HuNanChangSha {
public static boolean isTinChi = false;
public static boolean isTinPeng = false;
private int robotid=0;
public void setRobotid(int robotid) {
this.robotid = robotid;
}
public int getRobotid() {
return robotid;
}
// private static final Logger log = Logger.getLogger(DoTest.class);
@ -35,6 +44,10 @@ public class HuNanChangSha {
private List<Integer> changShaCardInhand = new ArrayList<>();
public List<Integer> getChangShaCardInhand() {
return changShaCardInhand;
}
private Map<Integer, Integer> chuGuoPainum = new HashMap<>();
@ -81,9 +94,6 @@ public class HuNanChangSha {
return chowGroup;
}
public List<Integer> getChangShaCardInhand() {
return changShaCardInhand;
}
public List<Integer> getChuGuoCardInhand() {
return changShachuguopai;
@ -121,7 +131,7 @@ public class HuNanChangSha {
* @param message
* @return
*/
public String getCard(String command, Message message, TaurusClient client, Map<String, Object> mapclient) {
public String getCard(String command, Message message, TaurusClient client) {
if (command.equalsIgnoreCase("819")) {
ITObject param = message.param;
if (param == null) {
@ -135,7 +145,8 @@ public class HuNanChangSha {
int drawnCard = param.getInt("card");
changShaSuanFaTest.drawnCards = drawnCard;//存储摸到的牌
changShaCardInhand.add(drawnCard);
System.out.println("param.getInt(player)" + param.getInt("player") );
System.out.println("摸到的牌 +++++++++ " + drawnCard);
if (jedis222.hget("{robortInfo}:" + player, "circleId") != null && jedis222.hget("{robortInfo}:" + player, "pid") != null) {
String circleId = jedis222.hget("{robortInfo}:" + player, "circleId");
String pid = jedis222.hget("{robortInfo}:" + player, "pid");
@ -204,6 +215,20 @@ public class HuNanChangSha {
return null;
}
/**
*
* @param handCard
*/
public void updateHandCard(List<Integer> handCard) {
changShaCardInhand.clear();
changShaCardInhand.addAll(handCard);
}
public void updateOutCard(List<Integer> outCard) {
changShachuguopai.clear();
changShachuguopai.addAll(outCard);
}
public static int[][] countTiles(List<Integer> cardInHand) {
int[][] counts = new int[5][10]; // 类型×值
@ -297,7 +322,7 @@ public class HuNanChangSha {
// log.info("tipList" +tipList);
ITObject params = TObject.newInstance();
int card = 0;
getChangShaCardInhand();
//循环
List<Integer> yupanhandcard = new ArrayList<>();
yupanhandcard.addAll(changShaCardInhand);
@ -1789,8 +1814,10 @@ public class HuNanChangSha {
// 将当前出的牌添加到历史出牌列表
changShachuguopai.add(cardToOut);
System.out.println("changShachuguopai ++++ :"+changShachuguopai);
// 从手牌中移除
changShaCardInhand.remove(Integer.valueOf(cardToOut));
System.out.println("打过后的手牌 +++ " + changShaCardInhand);
params.putString("session", session + "," + token);
client.send("611", params, response -> {
@ -1819,24 +1846,13 @@ public class HuNanChangSha {
Integer playerid = param.getInt("playerid");
// 从Redis中获取机器人ID列表 - 使用当前连接的机器人列表
String sql2 = String.format("SELECT id FROM `account` WHERE jiqiren=9998");
try {
ITArray robotId2 = DataBase.use().executeQueryByTArray(sql2);
List<Integer> robotIdsList = new ArrayList<>();
// 从Redis中获取当前活跃的机器人连接信息
try (Jedis jedis = Redis.use().getJedis()) {
// 从Redis中获取所有在线的机器人ID
java.util.Set<String> allKeys = jedis.keys("{user}:*");
for (String key : allKeys) {
if (key.contains("_token")) {
String playerIdStr = key.replace("{user}:", "").replace("_token", "");
try {
int playerId = Integer.parseInt(playerIdStr);
robotIdsList.add(playerId);
} catch (NumberFormatException ex) {
// 忽略无法解析的ID
}
}
}
for (int j = 0; j < robotId2.size(); j++) {
robotIdsList.add(robotId2.getTObject(j).getInt("id"));
}
if (!robotIdsList.contains(playerid)) {
@ -1845,11 +1861,22 @@ public class HuNanChangSha {
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
HuNanChangSha huNanChangSha = new HuNanChangSha();
String str = "[107, 202, 204, 103, 109, 101, 108, 201, 109, 105, 207, 209, 202]";
String cleanedStr = str.substring(1, str.length() - 1);
List<Integer> list = Arrays.stream(cleanedStr.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
System.out.println(list);
/*HuNanChangSha huNanChangSha = new HuNanChangSha();
ITObject params = TObject.newInstance();
TaurusClient tc = new TaurusClient("47.109.55.7", "10", TaurusClient.ConnectionProtocol.Tcp);
List<Integer> hands1 = new ArrayList<>();
@ -1925,6 +1952,8 @@ public class HuNanChangSha {
//huNanChangSha.chowGroup.add(205);
String res = huNanChangSha.actionCard(params, tc);
System.out.println(res);
*/
}
}

View File

@ -1,66 +0,0 @@
package robot.mj.info;
/**
*
*/
public class RobotRoomInfo {
private String roomId;
private String connecId;
private int userId;
private String groupId;
private String wanfaId;
private String robotId;
public String getRoomId() {
return roomId;
}
public void setRoomId(String roomId) {
this.roomId = roomId;
}
public String getConnecId() {
return connecId;
}
public void setConnecId(String connecId) {
this.connecId = connecId;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getWanfaId() {
return wanfaId;
}
public void setWanfaId(String wanfaId) {
this.wanfaId = wanfaId;
}
public String getRobotId() {
return robotId;
}
public void setRobotId(String robotId) {
this.robotId = robotId;
}
@Override
public String toString() {
return "RobotRoomInfo{roomId='" + roomId + "', connecId='" + connecId + "'}";
}
}

View File

@ -0,0 +1,195 @@
package robot.mj.info;
import taurus.client.TaurusClient;
/**
*
*/
public class RobotUser {
private String roomId;
private String connecId;
private int userId;
private String groupId;
private String wanfaId;
private String robotId;
private int seat;
public int status; //工作状态 0,1:等待2:干活
public boolean isconnect = false; //是否连接上
public int intoRoomTime; //进入房间时间戳
public String password;
public String gameHost;
public String gamePort;
public String robotGroupid;
public String robotPid;
public boolean isLogin = false;
private String token;
private String loginsession;
public int currentRoomId;//当前房间id
public TaurusClient client = null;
public TaurusClient getClient() {
return client;
}
public void setClient(TaurusClient client) {
this.client = client;
}
public int getCurrentRoomId() {
return currentRoomId;
}
public void setCurrentRoomId(int currentRoomId) {
this.currentRoomId = currentRoomId;
}
public String getLoginsession() {
return loginsession;
}
public void setLoginsession(String loginsession) {
this.loginsession = loginsession;
}
public boolean getIsLogin() {
return isLogin;
}
public void setIsLogin(boolean login) {
isLogin = login;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getGameHost() {
return gameHost;
}
public void setGameHost(String gameHost) {
this.gameHost = gameHost;
}
public String getGamePort() {
return gamePort;
}
public void setGamePort(String gamePort) {
this.gamePort = gamePort;
}
public String getRobotGroupid() {
return robotGroupid;
}
public void setRobotGroupid(String robotGroupid) {
this.robotGroupid = robotGroupid;
}
public String getRobotPid() {
return robotPid;
}
public void setRobotPid(String robotPid) {
this.robotPid = robotPid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getIntoRoomTime() {
return intoRoomTime;
}
public void setIntoRoomTime(int intoRoomTime) {
this.intoRoomTime = intoRoomTime;
}
public boolean getIsconnect() {
return isconnect;
}
public void setIsconnect(boolean isconnect) {
this.isconnect = isconnect;
}
public int getSeat() {
return seat;
}
public void setSeat(int seat) {
this.seat = seat;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getRoomId() {
return roomId;
}
public void setRoomId(String roomId) {
this.roomId = roomId;
}
public String getConnecId() {
return connecId;
}
public void setConnecId(String connecId) {
this.connecId = connecId;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getWanfaId() {
return wanfaId;
}
public void setWanfaId(String wanfaId) {
this.wanfaId = wanfaId;
}
public String getRobotId() {
return robotId;
}
public void setRobotId(String robotId) {
this.robotId = robotId;
}
@Override
public String toString() {
return "RobotRoomInfo{roomId='" + roomId + "', connecId='" + connecId + "'}";
}
}

View File

@ -0,0 +1,13 @@
package taurus.util;
public class ROBOTEventType {
/**
*
*/
public static final int ROBOT_INTOROOM_READY = 1;//等待状态
public static final int ROBOT_INTOROOM_WORKING = 2;//工作状态
public static final int ROBOT_UNUSE = 0;//未使用状态
}