机器人连接0201(修复部分连接问题)

1.待完成:机器人无法出牌
master
zhouwei 2026-02-01 14:43:02 +08:00
parent accdf5e4d6
commit 84bb216bb9
11 changed files with 542 additions and 492 deletions

View File

@ -56,6 +56,9 @@ public class RobotManager {
//跟踪已经恢复leftover_robot的机器人
private final Set<Integer> leftoverRobotRecovered = ConcurrentHashMap.newKeySet();
//房间级别的锁,用于细粒度的同步控制
private final Map<String, Object> roomLocks = new ConcurrentHashMap<>();
public RobotManager() {
this.robotDisconnect = new RobotDisconnect(this);
@ -164,9 +167,6 @@ public class RobotManager {
gRobotMap.put("pid", String.valueOf(gameId));
jedis2.hmset("{grobot}:" + robot.getRobotId(), gRobotMap);
//将登录后的机器人添加到已连接列表中 等待连接服务器
connectedRobots.put(robot.getRobotId(), robot);
//更新数据库状态为已使用
String sql = String.format("UPDATE `account` SET start = %d WHERE id = %d", 1, robot.getRobotId());
DataBase.use().executeUpdate(sql);
@ -175,6 +175,8 @@ public class RobotManager {
//连接对应游戏服务器
RobotManagerInterface handler = getGameHandler(gameId);
handler.connectRobot(robot);
//将登录后的机器人添加到已连接列表中 等待连接服务器
connectedRobots.put(robot.getRobotId(), robot);
}
} catch (Exception e) {
log.error("机器人登录时发生错误", e);
@ -253,7 +255,7 @@ public class RobotManager {
/**
*
*/
public void disconnectExcessRobots(int wanfaId, int requiredCount) {
public void disconnectExcessRobots(int wanfaId) {
List<RobotInfo> allWanfaRobots = new ArrayList<>();
for (RobotInfo robot : connectedRobots.values()) {
if (robot.getWanfaId() == wanfaId) {
@ -261,38 +263,23 @@ public class RobotManager {
}
}
//该玩法已连接的机器人
int currentlyConnected = 0;
for (RobotInfo robot : allWanfaRobots) {
if (robot.isConnected()) {
currentlyConnected++;
}
}
//需要断开的机器人
int toDisconnect = Math.max(0, currentlyConnected - requiredCount);
if (toDisconnect > 0) {
//断开该玩法下未使用的机器人
int disconnectedCount = 0;
for (int i = 0; i < allWanfaRobots.size() && disconnectedCount < toDisconnect; i++) {
RobotInfo robot = allWanfaRobots.get(i);
//不在使用断开连接
if (!robot.isUsing() && robot.isConnected()) {
for (RobotInfo robot : allWanfaRobots) {
synchronized(robot) {
if (!robot.isUsing() && robot.isConnected()) {
RobotManagerInterface handler = getGameHandler(robot.getWanfaId());
if (handler != null) {
handler.disconnectRobot(robot);
log.debug("断开机器人 {} TCP连接玩法ID: {}", robot.getRobotId(), wanfaId);
log.debug("断开未使用机器人 {} TCP连接玩法ID: {}", robot.getRobotId(), wanfaId);
}
disconnectedCount++;
}
}
}
}
if (disconnectedCount > 0) {
log.debug("玩法 {} 成功断开 {} 个机器人的TCP连接目标连接数: {}", wanfaId, disconnectedCount, requiredCount);
}
log.debug("玩法 {} 成功断开 {} 个未使用机器人的TCP连接", wanfaId, disconnectedCount);
}
}
@ -307,36 +294,46 @@ public class RobotManager {
}
}
//该玩法已连接的机器人
int currentConnected = 0;
//空闲机器人
int availableCount = 0;
for (RobotInfo robot : allWanfaRobots) {
if (robot.isConnected()) {
currentConnected++;
if (robot.isConnected() && !robot.isUsing()) {
availableCount++;
}
}
//当前连接数小于所需数量 则连接更多机器人
if (currentConnected < requiredCount) {
int reconnectedCount = 0;
//可用机器人数量少于需求 连接更多机器人
if (availableCount < requiredCount) {
int needToConnect = requiredCount - availableCount;
int connectedCount = 0;
for (RobotInfo robot : allWanfaRobots) {
if (!robot.isConnected() && !robot.isUsing() && reconnectedCount < (requiredCount - currentConnected)) {
if (connectedCount >= needToConnect) {
break;
}
if (!robot.isConnected() && !robot.isUsing()) {
RobotManagerInterface handler = getGameHandler(robot.getWanfaId());
if (handler != null) {
if (shouldConnectRobot(robot)) {
synchronized(robot) {
if (!robot.isConnected() && !robot.isUsing()) {
handler.connectRobot(robot);
log.debug("重新连接玩法 {} 的机器人: {}", wanfaId, robot.getRobotId());
log.debug("连接玩法 {} 的空闲机器人: {}", wanfaId, robot.getRobotId());
connectedCount++;
}
}
} else {
log.debug("玩法 {} 的leftover_robot为0跳过连接机器人: {}", wanfaId, robot.getRobotId());
}
reconnectedCount++;
log.debug("玩法 {} 当前不允许连接机器人: {}", wanfaId, robot.getRobotId());
}
}
}
}
if (connectedCount > 0) {
log.debug("玩法 {} 新连接了 {} 个机器人以满足需求", wanfaId, connectedCount);
}
}
}
/**
@ -386,7 +383,7 @@ public class RobotManager {
//获取指定玩法的所有可用机器人
List<RobotInfo> availableRobots = new ArrayList<>();
for (RobotInfo robot : connectedRobots.values()) {
if (robot.getWanfaId() == wanfaId && robot.isOnline() && robot.isConnected() && !robot.isUsing()) {
if (robot.getWanfaId() == wanfaId && robot.isOnline() && !robot.isUsing()) {
availableRobots.add(robot);
}
}
@ -399,17 +396,20 @@ public class RobotManager {
RobotInfo selectedRobot = availableRobots.get(currentIndex);
synchronized (selectedRobot) {
if (!selectedRobot.isUsing()) {
selectedRobot.setLastActiveTime(System.currentTimeMillis());
selectedRobot.setUsing(true);
int nextIndex = (currentIndex + 1) % availableRobots.size();
wanfaRobotIndex.put(wanfaId, nextIndex);
return selectedRobot;
}
}
}
//如果没有连接的可用机器人,检查是否有未连接的机器人并尝试连接
List<RobotInfo> allWanfaRobots = new ArrayList<>();
for (RobotInfo robot : connectedRobots.values()) {
if (robot.getWanfaId() == wanfaId && robot.isOnline() && robot.isConnected()) {
if (robot.getWanfaId() == wanfaId && robot.isOnline()) {
allWanfaRobots.add(robot);
}
}
@ -422,13 +422,27 @@ public class RobotManager {
RobotInfo selectedRobot = allWanfaRobots.get(currentIndex);
selectedRobot.setLastActiveTime(System.currentTimeMillis());
//机器人未连接 尝试重新连接
if (!selectedRobot.isConnected()) {
selectedRobot.setUsing(false);
RobotManagerInterface handler = getGameHandler(selectedRobot.getWanfaId());
if (handler != null) {
handler.connectRobot(selectedRobot);
}
}
selectedRobot.setUsing(true);
if (!selectedRobot.isUsing()) {
//使用同步块确保原子操作
synchronized (selectedRobot) {
if (!selectedRobot.isUsing()) {
selectedRobot.setLastActiveTime(System.currentTimeMillis());
int nextIndex = (currentIndex + 1) % allWanfaRobots.size();
wanfaRobotIndex.put(wanfaId, nextIndex);
return selectedRobot;
}
}
}
}
return null;
}
@ -538,4 +552,11 @@ public class RobotManager {
return false;
}
}
/**
*
*/
public Object getRoomLock(String roomId) {
return roomLocks.computeIfAbsent(roomId, k -> new Object());
}
}

View File

@ -1,7 +1,6 @@
package com.group.robot;
import com.group.robot.info.RobotInfo;
import com.group.robot.info.RoomInfo;
/**
* -

View File

@ -24,9 +24,6 @@ public class MaJiangRobotHandler implements RobotManagerInterface {
try {
//连接处理器进行连接
robotConnectionHandler.connectRobot(robot);
//设置机器人连接状态
robot.setConnected(true);
}catch (Exception e) {
log.error("麻将机器人 {} 连接游戏服务器时发生异常", robot.getRobotId(), e);
robot.setConnected(false);

View File

@ -2,11 +2,10 @@ package com.group.robot.handler;
import java.util.Map;
import java.util.UUID;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@ -35,58 +34,15 @@ public class RobotConnectionHandler {
//机器人ID到客户端连接的映射
private final Map<Integer, TaurusClient> robotClients = new ConcurrentHashMap<>();
//机器人ID到账户信息的映射
private final Map<Integer, RobotAccountInfo> robotAccounts = new ConcurrentHashMap<>();
//机器人ID到连接ID的映射用于标识每个机器人连接的唯一性
//机器人ID到连接ID的映射 用于标识每个机器人连接的唯一性
private final Map<Integer, String> robotConnectionIds = new ConcurrentHashMap<>();
//机器人连接锁,防止重复连接
private final Map<Integer, Object> robotConnectionLocks = new ConcurrentHashMap<>();
//机器人管理器引用
private final RobotManager robotManager;
//心跳和重连
private final Map<Integer, ScheduledFuture<?>> heartbeatTasks = new ConcurrentHashMap<>();
private final Map<Integer, String> robotServerAddresses = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
/**
*
*/
public static class RobotAccountInfo {
private int robotId;
private String account;
private String password;
private String session;
private String token;
private int groupId;
private String roomId;
private int gameId;
public RobotAccountInfo(int robotId, String account, String password, int groupId) {
this.robotId = robotId;
this.account = account;
this.password = password;
this.groupId = groupId;
}
public int getRobotId() { return robotId; }
public void setRobotId(int robotId) { this.robotId = robotId; }
public String getAccount() { return account; }
public void setAccount(String account) { this.account = account; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getSession() { return session; }
public void setSession(String session) { this.session = session; }
public String getToken() { return token; }
public void setToken(String token) { this.token = token; }
public int getGroupId() { return groupId; }
public void setGroupId(int groupId) { this.groupId = groupId; }
public String getRoomId() { return roomId; }
public void setRoomId(String roomId) { this.roomId = roomId; }
public int getGameId() { return gameId; }
public void setGameId(int gameId) { this.gameId = gameId; }
}
private RobotConnectionHandler() {
this.robotManager = RobotManager.getRobotManager();
}
@ -111,6 +67,17 @@ public class RobotConnectionHandler {
return;
}
//机器人锁 防止重复连接
Object lock = robotConnectionLocks.computeIfAbsent(robot.getRobotId(), k -> new Object());
synchronized (lock) {
//再次检查是否已经存在有效连接
TaurusClient existingClient = robotClients.get(robot.getRobotId());
if (existingClient != null && existingClient.isConnected()) {
log.debug("机器人 {} 已存在有效连接,跳过重复连接", robot.getRobotId());
robot.setConnected(true);
return;
}
//异步执行连接逻辑
CompletableFuture.runAsync(() -> {
try {
@ -125,6 +92,12 @@ public class RobotConnectionHandler {
TaurusClient client = new TaurusClient(serverAddress, "game", TaurusClient.ConnectionProtocol.Tcp);
client.connect();
//连接成功后发送初始化协议
sendInitializationProtocol(client, robot);
//设置事件监听器
setupInitializationEventListeners(client, robot);
//生成唯一的connecId
String connecId = generateConnectionId(robot.getRobotId());
@ -136,29 +109,27 @@ public class RobotConnectionHandler {
//保存客户端连接
robotClients.put(robot.getRobotId(), client);
robotServerAddresses.put(robot.getRobotId(), serverAddress);
//保存connecId
robotConnectionIds.put(robot.getRobotId(), connecId);
//设置事件监听器
setupInitializationEventListeners(client, robot);
//连接成功后发送初始化协议
sendInitializationProtocol(client, robot);
//设置机器人连接状态
robot.setConnected(true);
log.info("机器人 {} 成功连接到游戏服务器, ConnectionId: {}", robot.getRobotId(), connecId);
System.out.println("connectRobot机器人尝试连接游戏服务器, client状态 :" + client.isConnected() + "机器人状态 :" + robot.isConnected());
//启动心跳
startHeartTask(robot.getRobotId(), client, robot.getWanfaId());
} catch (Exception e) {
log.error("连接机器人到游戏服务器时发生异常: " + robot.getRobotId(), e);
System.out.println("连接机器人到游戏服务器时发生异常: " + robot.getRobotId());
robotClients.remove(robot.getRobotId());
robotConnectionIds.remove(robot.getRobotId());
robot.setConnected(false);
disconnectRobot(robot.getRobotId());
} finally {
if (!robotClients.containsKey(robot.getRobotId())) {
robotConnectionLocks.remove(robot.getRobotId());
}
}
});
}
}
/**
* ID
@ -210,77 +181,6 @@ public class RobotConnectionHandler {
});
}
/**
*
*/
private void startHeartTask(int robotId, TaurusClient client, int wanfaId) {
stopHeartTask(robotId);
ScheduledFuture<?> heartbeatTask = scheduler.scheduleWithFixedDelay(() -> {
try {
if (client != null && client.isConnected()) {
//发送心跳包
ITObject heartbeatParam = new TObject();
heartbeatParam.putString("type", "heartbeat");
heartbeatParam.putInt("robot_id", robotId);
heartbeatParam.putInt("wanfa_id", wanfaId);
heartbeatParam.putString("connecId", robotConnectionIds.get(robotId));
heartbeatParam.putLong("timestamp", System.currentTimeMillis());
client.send("ping", heartbeatParam, response -> {
if (response != null) {
log.debug("机器人 {} 心跳响应成功", robotId);
} else {
log.warn("机器人 {} 心跳响应失败", robotId);
}
});
} else {
log.warn("机器人 {} 连接已断开,无法发送心跳", robotId);
//连接断开 尝试重连
RobotInfo robot = robotManager.getConnectedRobot(robotId);
if (robot != null) {
scheduleReconnection(robot);
}
}
} catch (Exception e) {
log.error("发送心跳时发生异常,机器人: " + robotId, e);
}
}, 30, 30, TimeUnit.SECONDS);//30秒发送一次心跳
heartbeatTasks.put(robotId, heartbeatTask);
log.info("已启动机器人 {} 的心跳任务", robotId);
}
/**
*
*/
private void stopHeartTask(int robotId) {
ScheduledFuture<?> task = heartbeatTasks.remove(robotId);
if (task != null && !task.isCancelled()) {
robotConnectionIds.remove(robotId);
task.cancel(false);
log.info("已停止机器人 {} 的心跳任务", robotId);
}
}
/**
*
*/
private void scheduleReconnection(RobotInfo robot) {
scheduler.schedule(() -> {
try {
log.info("开始重连机器人: {}", robot.getRobotId());
//清理可能存在的旧连接
robot.setConnected(false);
disconnectRobot(robot.getRobotId());
//重新连接
connectRobot(robot);
} catch (Exception e) {
log.error("重连机器人失败: {}", robot.getRobotId(), e);
}
}, 2, TimeUnit.SECONDS);
}
/**
* ID
*/
@ -295,7 +195,7 @@ public class RobotConnectionHandler {
return "8.138.242.190:6841";
default:
log.warn("未知的玩法ID: {}, 使用默认服务器地址", wanfaId);
return "192.168.0.32:6311"; //默认地址
return "127.0.0.1:6311"; //默认地址
}
}
@ -305,21 +205,25 @@ public class RobotConnectionHandler {
public void disconnectRobot(int robotId) {
try {
log.info("清理机器人 {} 的连接资源", robotId);
stopHeartTask(robotId);
Object lock = robotConnectionLocks.computeIfAbsent(robotId, k -> new Object());
synchronized (lock) {
//移除机器人TCP客户端连接
TaurusClient client = robotClients.remove(robotId);
if (client != null) {
client.killConnection();
log.debug("已清理机器人 {} 的客户端连接", robotId);
}
//移除机器人信息
RobotAccountInfo robotAccountInfo = robotAccounts.remove(robotId);
if (robotAccountInfo != null && robotManager != null) {
//调用RobotManager的统一断开服务
robotManager.safeDisconnectRobot(robotId,
robotAccountInfo.getGroupId(),
robotAccountInfo.getGameId(),
robotAccountInfo.getRoomId());
//移除连接ID
robotConnectionIds.remove(robotId);
//清理锁对象
robotConnectionLocks.remove(robotId);
}
//从RobotManager中获取机器人信息并断开连接
RobotInfo robot = robotManager.getConnectedRobot(robotId);
if (robot != null) {
robotManager.safeDisconnectRobot(robotId, robot.getGroupId(), robot.getWanfaId(), robot.getRoomId());
}
} catch (Exception e) {
log.error("断开机器人连接时发生异常: " + robotId, e);
@ -342,7 +246,8 @@ public class RobotConnectionHandler {
//发送离开房间协议
ITObject param = new TObject();
param.putString("robotId", String.valueOf(robot.getRobotId()));
param.putString("connecId", robotConnectionIds.get(robot.getRobotId())); // 添加connecId
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());
});
@ -407,20 +312,24 @@ public class RobotConnectionHandler {
/**
*
*/
public void sendJoinRoomMessage(RobotInfo robot) {
public void sendJoinRoomMessageAsync(RobotInfo robot, Consumer<Boolean> callback) {
TaurusClient client = robotClients.get(robot.getRobotId());
if (client == null) {
log.warn("机器人 {} 没有有效的TCP连接无法发送加入房间消息", robot.getRobotId());
callback.accept(false);
return;
}
ITObject readyParam = new TObject();
readyParam.putInt("groupId", robot.getGroupId());
readyParam.putString("roomId", robot.getRoomId());
readyParam.putString("session", robot.getSession() + "," + robot.getToken());
readyParam.putString("robotId", String.valueOf(robot.getRobotId()));
readyParam.putString("connecId", robotConnectionIds.get(robot.getRobotId()));
System.out.println("sendJoinRoomMessageAsync 2002 client: "+ robotConnectionIds.get(robot.getRobotId()));
client.send("2002", readyParam, response -> {
log.debug("机器人 {} 发送加入房间请求响应: {}", robot.getRobotId(), response);
boolean success = response != null && response.returnCode == 0;
callback.accept(success);
});
}
@ -486,13 +395,95 @@ public class RobotConnectionHandler {
readyParam.putString("session", robot.getSession() + "," + robot.getToken());
readyParam.putString("robotId", String.valueOf(robot.getRobotId()));
readyParam.putString("connecId", robotConnectionIds.get(robot.getRobotId()));
System.out.println("sendReadyMessage 2003 client: "+ robotConnectionIds.get(robot.getRobotId()));
client.send("2003", readyParam, response -> {
boolean success = response != null && response.returnCode == 0;
callback.accept(success);
});
}
/**
* CompletableFuture
*/
public CompletableFuture<Boolean> sendJoinRoomMessageAsyncCompletable(RobotInfo robot) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
TaurusClient client = robotClients.get(robot.getRobotId());
if (client == null) {
future.complete(false);
return future;
}
ITObject readyParam = new TObject();
readyParam.putInt("groupId", robot.getGroupId());
readyParam.putString("roomId", robot.getRoomId());
readyParam.putString("session", robot.getSession() + "," + robot.getToken());
readyParam.putString("robotId", String.valueOf(robot.getRobotId()));
readyParam.putString("connecId", robotConnectionIds.get(robot.getRobotId()));
System.out.println("sendJoinRoomMessageAsync 2002 client: " + robotConnectionIds.get(robot.getRobotId()));
// 设置超时机制
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!future.isDone()) {
future.completeExceptionally(new RuntimeException("Join room timeout"));
}
}
}, 10000); // 10秒超时
client.send("2002", readyParam, response -> {
boolean success = response != null && response.returnCode == 0;
if (!future.isDone()) {
future.complete(success);
}
timer.cancel();
});
return future;
}
/**
* CompletableFuture
*/
public CompletableFuture<Boolean> sendReadyMessageAsyncCompletable(RobotInfo robot) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
TaurusClient client = robotClients.get(robot.getRobotId());
if (client == null) {
future.complete(false);
return future;
}
ITObject readyParam = new TObject();
readyParam.putString("session", robot.getSession() + "," + robot.getToken());
readyParam.putString("robotId", String.valueOf(robot.getRobotId()));
readyParam.putString("connecId", robotConnectionIds.get(robot.getRobotId()));
// 设置超时机制
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!future.isDone()) {
future.completeExceptionally(new RuntimeException("Ready message timeout"));
}
}
}, 10000); // 10秒超时
client.send("2003", readyParam, response -> {
boolean success = response != null && response.returnCode == 0;
if (!future.isDone()) {
future.complete(success);
}
timer.cancel();
});
return future;
}
/**
*
*/
@ -511,7 +502,8 @@ public class RobotConnectionHandler {
*/
public void sendCreateRoom(RobotInfo robot, int groupId, int wanfaId) {
TaurusClient client = robotClients.get(robot.getRobotId());
if (client == null ) {
//todo !client.isConnected()
if (client == null || !client.isConnected()) {
connectRobot(robot);
return;
}

View File

@ -4,10 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import com.group.robot.RobotManager;
import com.group.robot.handler.RobotConnectionHandler;
@ -79,7 +76,7 @@ public class RoomWanfaMatcher {
log.info("开始为群组 {} 玩法ID {} 启动房间轮询", groupId, wanfaId);
//10秒轮询一次
scheduler.scheduleWithFixedDelay(this::pollRooms, 0, 10, TimeUnit.SECONDS);
scheduler.scheduleWithFixedDelay(this::pollRooms, 0, 20, TimeUnit.SECONDS);
}
}
@ -163,18 +160,23 @@ public class RoomWanfaMatcher {
//房间没人 加入房间
if (playersStr.equals("[]")) {
//房间是否正在被加入
Object roomSpecificLock = robotManager.getRoomLock(roomId);
synchronized (roomSpecificLock) {
if (!processingRooms.contains(roomId)) {
processingRooms.add(roomId);
robotJoinRoom(robot, true);
robotJoinRoomInternal(robot, true);
}
}
} else {
//房间有人 不是机器人则加入房间
Integer robotInRoom = playerIsRobotRedis(playersStr);
if (robotInRoom == null) {
Object roomSpecificLock = robotManager.getRoomLock(roomId);
synchronized (roomSpecificLock) {
if (!processingRooms.contains(roomId)) {
processingRooms.add(roomId);
robotJoinRoom(robot, false);
robotJoinRoomInternal(robot, false);
}
}
}
}
@ -188,70 +190,92 @@ public class RoomWanfaMatcher {
}
/**
*
*
* @param isRobot
* @param robot
* */
private void robotJoinRoom(RobotInfo robot, boolean isRobot) {
synchronized (joinRoomLock) {
RobotInfo robotInfo = robot;
private void robotJoinRoomInternal(RobotInfo robot, boolean isRobot) {
String roomId = robot != null ? robot.getRoomId() : null;
RobotInfo robotInfo = robot;
int groupId = robot.getGroupId();
try {
if (robotInfo.getRobotId() == -1) {
robotInfo = robotManager.getLoggedInRobotForWanfa(wanfaId);
robotInfo.setGroupId(groupId);
robotInfo.setRoomId(roomId);
}
//加入房间
try {
GroupRoomBusiness.joinRoom(robotInfo.getGroupId(), robotInfo.getRoomId(), robotInfo.getSession(), null);
Thread.sleep(5000);
robotConnectionHandler.sendJoinRoomMessage(robotInfo);
Thread.sleep(1000);
}catch (Exception e) {
log.error("加入房间失败", e);
processingRooms.remove(roomId);
System.out.println("robotJoinRoom机器人加入房间 机器人状态 :" + robot.isConnecting());
if (robotInfo == null) {
return;
}
robotInfo.setGroupId(groupId);
robotInfo.setRoomId(roomId);
//准备
//验证机器人连接状态
if (robotInfo.isUsing()) {
robotManager.releaseRobot(robotInfo.getRobotId());
return;
}
}
// 使用CompletableFuture替代嵌套回调提高可读性和可控性
RobotInfo finalRobotInfo = robotInfo;
robotConnectionHandler.sendReadyMessageAsync(robotInfo, readySuccess -> {
// 创建一个完整的加入房间流程
CompletableFuture<Boolean> joinFuture = robotConnectionHandler.sendJoinRoomMessageAsyncCompletable(finalRobotInfo);
joinFuture.thenCompose(joinSuccess -> {
if (joinSuccess) {
System.out.println("robotJoinRoomInternal机器人加入了房间 机器人状态 :" + robot.isConnecting());
// 准备阶段
return robotConnectionHandler.sendReadyMessageAsyncCompletable(finalRobotInfo);
} else {
System.out.println("robotJoinRoomInternal机器人加入了房间 失败 :" + robot.isConnecting());
// 加入失败,释放机器人
robotManager.releaseRobot(finalRobotInfo.getRobotId());
return CompletableFuture.completedFuture(false);
}
}).thenAccept(readySuccess -> {
if (readySuccess) {
System.out.println("robotJoinRoomInternal机器人准备 房间 机器人状态 :" + robot.isConnecting());
roomToRobotMap.put(roomId, finalRobotInfo.getRobotId());
updateRobotStatusRedis(finalRobotInfo);
if (isRobot) {
//6秒没有玩家加入 则退出房间
robotConnectionHandler.readyTimeRobotExit(finalRobotInfo, joinRoomLock);
robotConnectionHandler.readyTimeRobotExit(finalRobotInfo, robotManager.getRoomLock(roomId));
}
} else {
System.out.println("机器人准备失败");
}
if (roomId != null) {
processingRooms.remove(roomId);
System.out.println("robotJoinRoomInternal机器人准备 房间 失败 :" + robot.isConnecting());
// 准备失败时释放机器人
robotManager.releaseRobot(finalRobotInfo.getRobotId());
}
}).exceptionally(throwable -> {
log.error("机器人加入房间流程异常", throwable);
robotManager.releaseRobot(finalRobotInfo.getRobotId());
return null;
});
/*boolean readySuccess = robotConnectionHandler.sendReadyMessageSync(robotInfo);
if (readySuccess) {
//记录机器人和房间的关联
roomToRobotMap.put(roomId, robotInfo.getRobotId());
updateRobotStatusRedis(robotInfo);
if (isRobot) {
//6秒没有玩家加入 则退出房间
robotConnectionHandler.readyTimeRobotExit(robotInfo, joinRoomLock);
}
} else {
//robotConnectionHandler.disconnectRobot(robotInfo.getRobotId());
}*/
} catch (Exception e) {
if (robotInfo != null) {
//robotConnectionHandler.disconnectRobot(robotInfo.getRobotId());
//释放机器人
robotManager.releaseRobot(robotInfo.getRobotId());
}
} finally {
// 从处理队列中移除房间 - 这个操作是必要的,无论是在哪种情况下
processingRooms.remove(roomId);
}
}
/**
* -
* @param isRobot
* @param robot
* */
private void robotJoinRoom(RobotInfo robot, boolean isRobot) {
String roomId = robot != null ? robot.getRoomId() : null;
// 使用房间级别的细粒度锁,而不是全局锁
Object roomSpecificLock = robotManager.getRoomLock(roomId);
synchronized (roomSpecificLock) {
robotJoinRoomInternal(robot, isRobot);
}
}
@ -321,15 +345,16 @@ public class RoomWanfaMatcher {
private void manageRobotConnections(int currentLeftoverRobot) {
if (lastLeftoverRobot != currentLeftoverRobot) {
if (currentLeftoverRobot <= 0 && lastLeftoverRobot > 0) {
//leftover_robot变为0 断开该玩法与robot_mj_cs的连接
robotManager.disconnectExcessRobots(wanfaId, 0);
//leftover_robot变为0 断开该玩法下未使用的机器人连接
robotManager.disconnectExcessRobots(wanfaId);
lastLeftoverRobot = 0;
} else if (currentLeftoverRobot > 0 && lastLeftoverRobot <= 0) {
//leftover_robot变为正数 重新连接机器人到robot_mj_cs
//leftover_robot变为正数 检查是否有可用的空闲机器人 没有则连接新的
robotManager.connectRequiredRobots(wanfaId, currentLeftoverRobot);
}
lastLeftoverRobot = currentLeftoverRobot;
}
}
}
/**
*

View File

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

View File

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

View File

@ -98,33 +98,36 @@ public class Config {
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";
// 创建房间机器人协议
public static final String CREATE_ROOM_ROBOT = "create_room_for_robot";
// 加入房间协议
/**
* - robot_mgr to robot_mj_cs
*/
public static final String JOIN_ROOM = "2002";
// 加入房间CS协议
public static final String JOIN_ROOM_CS = "1002";
// 游戏准备协议
/**
* - robot_mgr to robot_mj_cs
*/
public static final String GAME_READY = "2003";
// 游戏准备CS协议
/**
* 退 - robot_mgr to robot_mj_cs
*/
public static final String EXIT_ROOM = "2005";
/**
* - robot_mj_cs to game_mj_cs
*/
public static final String GAME_READY_CS = "1003";
// 退出房间协议
public static final String EXIT_ROOM = "2004";
/**
* - robot_mgr to game_mj_cs
*/
public static final String JOIN_ROOM_CS = "1002";
// 退出房间CS协议
public static final String EXIT_ROOM_CS = "1004";
// 其他可能的游戏相关协议
public static final String GAME_CHAT = "1006";
// 心跳协议
public static final String HEARTBEAT = "9000";
/**
* 退 - robot_mgr to game_mj_cs
*/
public static final String EXIT_ROOM_CS = "1005";
}

View File

@ -5,18 +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.events.Event;
import com.taurus.core.events.IEventListener;
import com.taurus.core.routes.ActionKey;
import com.taurus.core.util.ICallback;
import com.taurus.core.util.StringUtil;
import com.taurus.permanent.data.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import robot.mj.handler.HuNanChangSha;
import taurus.client.Message;
import taurus.client.MessageResponse;
import taurus.client.TaurusClient;
import taurus.client.business.GroupRoomBusiness;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
/**
* -
@ -113,40 +114,56 @@ public class EXGameController extends GameController {
@ActionKey(value = Config.JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER)
public void joinRoom(Session session, ITObject params, int gid) {
try {
System.out.println("收到加入房间请求Session: {}, GID: {}, 参数: {}");
String connecId = params.getString("connecId");
TaurusClient client = null;// getCsMjGameServerConnection(connecId);
client = new TaurusClient("8.134.76.43" + ":" + "6311", "game", TaurusClient.ConnectionProtocol.Tcp);
client.connect();
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;
if (sessionToken != null && sessionToken.contains(",")) {
String[] sessionParts = sessionToken.split(",");
if (sessionParts.length >= 2) {
String actualSessionFromParams = sessionParts[0];
robotSession = sessionParts[0];
String token = sessionParts[1];
connectionManager.setSessionAndToken(actualSessionFromParams, token);
connectionManager.setSessionAndToken(robotSession, token);
}
}
//发送加入房间请求
Integer groupId = params.getInt("groupId");
String roomId = params.getString("roomId");
// 在当前线程中同步执行阻塞操作
GroupRoomBusiness.joinRoom(groupId, roomId, robotSession, null);
Thread.sleep(5000); // 等待100毫秒后再次检查
// 发送加入房间请求到game_mj_cs
client.send(Config.JOIN_ROOM_CS, params, response -> {
System.out.println("csmj OnEvent " + response.returnCode);
log.info("加入房间请求发送结果: returnCode={}", response.returnCode);
});
client.addEventListener(TaurusClient.NetClientEvent.OnEvent, new IEventListener() {
@Override
public void handleEvent(Event event) {
System.out.println("csmj OnEvent 能监听jefe " );
}
System.out.println("joinRoom: " + 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);
}
}
@ -158,20 +175,34 @@ public class EXGameController extends GameController {
try {
String connecId = params.getString("connecId");
TaurusClient client = getCsMjGameServerConnection(connecId);
System.out.println("session: " + session);
System.out.println("client: " + client);
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");
client.send(Config.GAME_READY_CS, params, null);
Thread.sleep(1000); // 等待100毫秒后再次检查
// 发送准备请求到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);
}
}
@ -183,18 +214,21 @@ public class EXGameController extends GameController {
public void exitRoom(Session session, ITObject params, int gid) {
try {
String connecId = params.getString("connecId");
TaurusClient client = getCsMjGameServerConnection(connecId);
log.info("处理退出房间请求connecId: {}", connecId);
TaurusClient client = getCsMjGameServerConnection(connecId);
if (client == null) {
log.error("无法获取到游戏服务器连接connecId: {}", connecId);
return;
}
//发送退出房间请求
client.send(Config.EXIT_ROOM_CS, params, response -> {
log.info("退出房间请求发送结果: returnCode={} for connecId={}", response.returnCode, connecId);
});
//断开与游戏服务器的连接
//connectionManager.disconnectFromGameServer(connecId);
connectionManager.disconnectFromGameServer(connecId);
} catch (Exception e) {
log.error("处理退出房间请求时发生错误", e);
String connecId = params.getString("connecId");
@ -204,21 +238,17 @@ public class EXGameController extends GameController {
/**
* IDID
* robotIdconnectionId
*/
public static TaurusClient getCsMjGameServerConnection(String connecId) {
TaurusClient taurusClient = connectionManager.getGameServerConnection(connecId);
TaurusClient taurusClient = connectionManager.getGameClient(connecId);
System.out.println("根据机器人ID和连接ID获取长沙麻将游戏服务器连接 client: = "+taurusClient);
if (taurusClient != null) {
log.debug("成功获取游戏服务器连接connecId: {}", connecId);
return taurusClient;
}
boolean connected = connectionManager.connectToGameServer(connecId);
if (connected) {
taurusClient = connectionManager.getGameServerConnection(connecId);
if (taurusClient != null) {
taurusClient = connectionManager.connectToGameServer(connecId);
return taurusClient;
}
}
return null;
}
}

View File

@ -28,16 +28,6 @@ import robot.mj.handler.HuNanChangSha;
public class EXMainServer extends MainServer{
private static final Logger log = LoggerFactory.getLogger(EXMainServer.class);
//机器人连接管理器
private static RobotConnectionManager robotConnectionManager;
//长沙麻将AI处理器
private static HuNanChangSha huNanChangSha;
//心跳和重连
private final Map<String, ScheduledFuture<?>> serverHeartbeatTasks = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
@Override
public void onStart() {
super.onStart();
@ -67,9 +57,6 @@ public class EXMainServer extends MainServer{
*
*/
private void initializeComponents() {
robotConnectionManager = new RobotConnectionManager();
//长沙麻将AI处理器
huNanChangSha = new HuNanChangSha();
log.info("长沙麻将机器人服务器组件初始化完成");
}

View File

@ -13,7 +13,6 @@ import taurus.client.Message;
import taurus.client.TaurusClient;
import redis.clients.jedis.Jedis;
import robot.mj.handler.HuNanChangSha;
import taurus.client.business.GroupRoomBusiness;
import taurus.util.ChangShaSuanFaTest;
import taurus.util.TinHuChi;
@ -21,8 +20,6 @@ import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.*;
import static java.lang.Thread.sleep;
/**
* -
*/
@ -33,10 +30,12 @@ public class RobotConnectionManager {
//存储全局的长沙麻将AI处理器
private HuNanChangSha huNanChangSha;
private final String host="8.134.76.43";
private final String host="192.168.0.32";
private final int port=6311;
private TaurusClient client = null;
// 连接状态管理
private Map<String, Long> lastActivityTime = new ConcurrentHashMap<>();
private Map<String, Boolean> connectionRegistered = new ConcurrentHashMap<>();
private Map<Integer, List<Integer>> playerOutcardsMap = new HashMap<>();
@ -59,8 +58,12 @@ public class RobotConnectionManager {
public RobotConnectionManager() {
gameClients = new HashMap<>();
huNanChangSha = new HuNanChangSha();
}
/**
* session
*/
@ -79,13 +82,18 @@ public class RobotConnectionManager {
/**
*
*/
public boolean connectToGameServer(String connecId) {
public TaurusClient connectToGameServer(String connecId) {
try {
//检查是否已经连接
if (gameClients.containsKey(connecId)) {
TaurusClient existingClient = gameClients.get(connecId);
if (existingClient.isConnected()) {
return true;
//检查是否已注册
if (!connectionRegistered.getOrDefault(connecId, false)) {
//如果连接存在但未注册 尝试重新注册
reRegisterConnection(connecId, existingClient);
}
return existingClient;
} else {
//连接断开 移除旧的客户端
disconnectFromGameServer(connecId);
@ -93,22 +101,9 @@ public class RobotConnectionManager {
}
//创建Taurus客户端
client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);
client.connect();
TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);
System.out.println("csmj OnEvent " + client.getSession());
/// GroupRoomBusiness.joinRoom(383709, "room:592473", "{user}:101555", null);
//Thread.sleep(5000);
System.out.println("csmj OnEvent2 " + client.getSession());
System.out.println("client.getSession()1111" +client.getSession());
System.out.println("client.getId()1111" +client.getId());
//添加事件监听器处理网络消息和连接断开
//添加事件监听器处理网络消息和连接断开 - 必须在连接之前添加监听器
client.addEventListener(TaurusClient.NetClientEvent.OnEvent, new IEventListener() {
@Override
public void handleEvent(Event event) {
@ -117,7 +112,6 @@ public class RobotConnectionManager {
//获取 msg
Message message = (Message) event.getParameter("msg");
if (message == null) {
System.out.println("在OnEvent中收到空消息");
return;
}
@ -126,8 +120,8 @@ public class RobotConnectionManager {
String command = message.command;
System.out.println("csmj OnEvent msg " + command);
// 添加更详细的日志
System.out.println("收到协议命令: " + command + " params: " + param);
//更新最后活动时间
lastActivityTime.put(connecId, System.currentTimeMillis());
//根据玩法ID处理不同的回调
if (StringUtil.isNotEmpty(command)) {
@ -143,43 +137,72 @@ public class RobotConnectionManager {
public void handleEvent(Event event) {
System.out.println("Connect");
System.out.println("csmj Connect connecId: " + connecId);
//连接成功后立即尝试注册连接
registerConnection(connecId, client);
}
});
// 添加连接断开监听器
/* client.addEventListener(TaurusClient.NetClientEvent.Disconnect, new IEventListener() {
@Override
public void handleEvent(Event event) {
System.out.println("Connection disconnected for connecId: " + connecId);
connectionRegistered.put(connecId, false);
}
});*/
ITObject readyParam = new TObject();
readyParam.putString("session","{user}:101555,c739ec6c3e93e9655e507397f78d857f");
readyParam.putString("pos", "10,10");
//readyParam.putString("connecId", "1");
//pos
client.send(Config.JOIN_ROOM_CS, readyParam, response -> {
System.out.println("csmj OnEvent " + response.returnCode);
log.info("加入房间请求发送结果: returnCode={}", response.returnCode);
});
client.connect();
//连接成功后立即尝试注册连接
//registerConnection(connecId, client);
readyParam.del("connecId");
sleep(5000);
client.send(Config.GAME_READY_CS, readyParam, null);
System.out.println(client);
System.out.println("client.getSession()2222" +client.getSession());
System.out.println("client.getId()2222" +client.getId());
gameClients.put(connecId, client);
System.out.println("gameClients" + gameClients.get(connecId));
return true;
return client;
} catch (Exception e) {
log.error("连接到游戏服务器时发生异常", e);
return false;
return null;
}
}
/**
*
*/
private void registerConnection(String connecId, TaurusClient client) {
ITObject authParam = new TObject();
authParam.putString("type", "robot_auth");
authParam.putString("connecId", connecId);
authParam.putInt("playerId", 0); // 机器人ID占位符
client.send("1000", authParam, response -> {
System.out.println("Robot authentication sent for connecId: " + connecId + ", response: " + response.returnCode);
if (response.returnCode == 0) {
connectionRegistered.put(connecId, true);
System.out.println("Successfully registered connection for connecId: " + connecId);
} else {
System.out.println("Failed to register connection for connecId: " + connecId);
connectionRegistered.put(connecId, false);
}
});
}
/**
*
*/
private void reRegisterConnection(String connecId, TaurusClient client) {
System.out.println("Re-registering connection for connecId: " + connecId);
registerConnection(connecId, client);
}
/**
*
*/
public void disconnectFromGameServer(String compositeKey) {
TaurusClient client = gameClients.remove(compositeKey);
connectionRegistered.remove(compositeKey);
lastActivityTime.remove(compositeKey);
if (client != null && client.isConnected()) {
try {
client.killConnection();
@ -189,26 +212,11 @@ public class RobotConnectionManager {
}
}
public static void main(String[] args) {
RobotConnectionManager rb=new RobotConnectionManager();
boolean i = rb.connectToGameServer("1");
System.out.println(i);
}
/**
* connecId
*/
public TaurusClient getGameServerConnection(String connecId) {
TaurusClient client = gameClients.get(connecId);
if (client == null) {
System.out.println("Attempting to reconnect: " + connecId);
// 尝试重新连接
connectToGameServer(connecId);
client = gameClients.get(connecId);
}
return client;
public TaurusClient getGameClient(String connecId) {
return gameClients.get(connecId);
}
/**
@ -315,24 +323,20 @@ public class RobotConnectionManager {
HuNanChangSha.drawCard(command, message);
break;
case "819": //摸牌
System.out.println("Handling 819 - Draw card");
huNanChangSha.getCard(command, message);
break;
case "813": //出牌提示
System.out.println("Handling 813 - Discard card tip received!");
huNanChangSha.outCard(client,playerOutcardsMap,playerchisMap,playerpengsMap,playermingsMap,playerzisMap);
break;
case "814": //操作提示(吃碰杠胡)
System.out.println("Handling 814 - Action tips (Chi, Peng, Gang, Hu)");
huNanChangSha.actionCard(param, client);
break;
case "2009": //其他操作 - 房间检查和踢人逻辑
System.out.println("Handling 2009 - Other operations");
try {
Jedis jedis22 = Redis.use().getJedis();
// 使用JiQiRens的sleepTime方法
try {
sleep(3000);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@ -479,16 +483,13 @@ public class RobotConnectionManager {
});
break;
case "815": //服务器通知客户端有玩家执行了操作
System.out.println("Handling 815 - Server notifies client of player action");
//[TCP->815] data:{"playerid":101555,"card":104,"opcard":[105,103],"from_seat":2,"type":1,"opengang":false}
huNanChangSha.shanchuchuguopai(param);
break;
case "820": //换牌提示
System.out.println("Handling 820 - Change card tips");
HuNanChangSha.changePlayer(command, message);
break;
case "825":
System.out.println("Handling 825");
ITObject params25 = TObject.newInstance();
params25.putInt("qi", 0);
params25.putInt("id", 1);
@ -498,7 +499,6 @@ public class RobotConnectionManager {
});
break;
case "822":
System.out.println("Handling 822");
ITObject params22 = TObject.newInstance();
//params.putInt("qi", 0);
params22.putInt("id", 1);
@ -510,7 +510,6 @@ public class RobotConnectionManager {
});
break;
case "2008": //解散房间时候恢复机器人账号可以使用
System.out.println("Handling 2008 - Restore robot accounts when room is dismissed");
// Jedis jedis11s = Redis.use("group1_db11").getJedis();
// String key = "g{" + groupId + "}:play:" + pid;
//
@ -542,7 +541,6 @@ public class RobotConnectionManager {
}
break;
case "838": //补杠事件
System.out.println("Handling 838 - Bu Gang event");
int card838 = param.getInt("card");
ITObject params838 = new TObject();
params838.putInt("card", card838);
@ -552,7 +550,6 @@ public class RobotConnectionManager {
});
break;
case "816": //抢杠胡
System.out.println("Handling 816 - Qiang Gang Hu");
int card816 = param.getInt("card");
ITObject params816 = new TObject();
params816.putInt("type", 21); //胡牌类型
@ -563,7 +560,6 @@ public class RobotConnectionManager {
});
break;
case "821": //吃牌
System.out.println("Handling 821 - Chi Pai");
int card821 = param.getInt("card");
ITObject params821 = new TObject();
params821.putInt("type", 21); //吃牌类型
@ -574,14 +570,12 @@ public class RobotConnectionManager {
});
break;
case "823": //杠后补牌
System.out.println("Handling 823 - Gang after draw card");
//处理杠后补牌逻辑
int card823 = param.getInt("card");
huNanChangSha.getChangShaCardInhand().add(card823);
log.info("杠后补牌: " + card823 + ", 当前手牌: " + huNanChangSha.getChangShaCardInhand());
break;
case "835": //听牌相关
System.out.println("Handling 835 - Ting Pai related");
ITObject params835 = new TObject();
params835.putInt("qi", 0);
params835.putInt("id", 1);
@ -591,9 +585,11 @@ public class RobotConnectionManager {
});
break;
default:
System.out.println("Received unknown protocol command: " + command + ", params: " + param);
System.out.println("收到未知协议命令: " + command + ", 参数: " + param);
break;
}
}
}
}