修改机器人登录连接需求
parent
9717f80bfb
commit
552620e486
|
|
@ -2,14 +2,14 @@ package com.group;
|
||||||
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.data.cache.AccountCache;
|
import com.data.cache.AccountCache;
|
||||||
import com.data.cache.GroupCache;
|
import com.data.cache.GroupCache;
|
||||||
import com.group.robot.RobotManager;
|
import com.group.robot.RobotManager;
|
||||||
|
import com.group.robot.info.RobotInfo;
|
||||||
import com.taurus.core.entity.ITArray;
|
import com.taurus.core.entity.ITArray;
|
||||||
import com.taurus.core.entity.ITObject;
|
import com.taurus.core.entity.ITObject;
|
||||||
import com.taurus.core.plugin.database.DataBase;
|
import com.taurus.core.plugin.database.DataBase;
|
||||||
|
|
@ -19,11 +19,9 @@ import com.taurus.core.routes.Routes;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
import taurus.client.NetManager;
|
import taurus.client.NetManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class MainServer extends Extension {
|
public class MainServer extends Extension {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MainServer.class);
|
private static final Logger log = LoggerFactory.getLogger(MainServer.class);
|
||||||
private ScheduledThreadPoolExecutor timeScheduler;
|
private ScheduledThreadPoolExecutor timeScheduler;
|
||||||
|
|
@ -32,8 +30,8 @@ public class MainServer extends Extension {
|
||||||
private static final String FORCE_VER_KEY = "force_ver";
|
private static final String FORCE_VER_KEY = "force_ver";
|
||||||
|
|
||||||
//机器人管理器
|
//机器人管理器
|
||||||
private RobotManager robotManager;
|
private RobotManager robotManager = new RobotManager();
|
||||||
|
|
||||||
public static Map<String,String> lua_map = new HashMap<>();
|
public static Map<String,String> lua_map = new HashMap<>();
|
||||||
public MainServer() {
|
public MainServer() {
|
||||||
super();
|
super();
|
||||||
|
|
@ -65,17 +63,26 @@ public class MainServer extends Extension {
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
System.out.println("开始创建机器人连接...");
|
System.out.println("开始创建机器人连接...");
|
||||||
|
|
||||||
|
//1.先启动独立的事件处理线程(只启动一次)
|
||||||
|
|
||||||
//初始化机器人管理器
|
|
||||||
robotManager = new RobotManager();
|
|
||||||
|
|
||||||
//0 加载机器人到redis 2
|
|
||||||
loadGroupRobot();
|
|
||||||
|
|
||||||
// 1. 先启动独立的事件处理线程(只启动一次)
|
|
||||||
startNetEventThread();
|
startNetEventThread();
|
||||||
|
|
||||||
|
//2.加载机器人到redis 2
|
||||||
|
loadGroupRobot();
|
||||||
|
|
||||||
|
//关闭时重置机器人状态
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(this::resetRobotStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置机器人状态为未使用
|
||||||
|
*/
|
||||||
|
private void resetRobotStatus() {
|
||||||
|
try {
|
||||||
|
String sql = "UPDATE account SET start = 0 WHERE jiqiren = 9998";
|
||||||
|
DataBase.use().executeUpdate(sql);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 独立的事件处理线程
|
// 独立的事件处理线程
|
||||||
|
|
@ -100,67 +107,60 @@ public class MainServer extends Extension {
|
||||||
* 把机器人加载到redis2
|
* 把机器人加载到redis2
|
||||||
*/
|
*/
|
||||||
private void loadGroupRobot(){
|
private void loadGroupRobot(){
|
||||||
Jedis jedis2 = Redis.use("group1_db2").getJedis();
|
String sql = "SELECT id,acc,nick,portrait,password FROM `account` WHERE jiqiren=9998 and start = 0";
|
||||||
|
ITArray robotIds = null;
|
||||||
try {
|
try {
|
||||||
String sql = String.format("SELECT id,acc,nick,portrait,password FROM `account` WHERE jiqiren=9998 and start = 0");
|
robotIds = DataBase.use().executeQueryByTArray(sql);
|
||||||
ITArray robotIds = DataBase.use().executeQueryByTArray(sql);
|
} catch (SQLException e) {
|
||||||
HashMap<String, String> robotMap = new HashMap<>();
|
|
||||||
|
|
||||||
//遍历机器人,
|
|
||||||
for(int i = 0; i < robotIds.size(); ++i) {
|
|
||||||
// //把机器人按group 分类好 存放到redis2
|
|
||||||
|
|
||||||
ITObject robot = robotIds.getTObject(i);
|
|
||||||
Integer robotId = robot.getInt("id");
|
|
||||||
String robotAcc = robot.getString("acc");
|
|
||||||
String robotNick = robot.getString("nick");
|
|
||||||
String robotPortrait = robot.getString("portrait");
|
|
||||||
String robotPassword = robot.getString("password");
|
|
||||||
|
|
||||||
robotMap.put("acc", robotAcc);
|
|
||||||
robotMap.put("nick", robotNick);
|
|
||||||
robotMap.put("portrait", robotPortrait);
|
|
||||||
robotMap.put("password", robotPassword);
|
|
||||||
jedis2.hmset("{robot}:" + robotId , robotMap);
|
|
||||||
|
|
||||||
// String sqls = String.format("UPDATE `account` SET start = %d WHERE id = %d", 1, robotId);
|
|
||||||
// DataBase.use().executeUpdate(sqls);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Map<String,String> gRobotMap = new HashMap<>();
|
|
||||||
gRobotMap.put("start", "0");
|
|
||||||
gRobotMap.put("pid", "66");
|
|
||||||
jedis2.hmset("{grobot}:"+101666, gRobotMap);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}finally {
|
}
|
||||||
jedis2.close();
|
|
||||||
|
Map<Integer, Integer> gameRobotConfig = new HashMap<>();
|
||||||
|
gameRobotConfig.put(10, 5);
|
||||||
|
gameRobotConfig.put(22, 3);
|
||||||
|
int robotIndex = 0;
|
||||||
|
|
||||||
|
//长沙麻将机器人
|
||||||
|
List<RobotInfo> csRobots = new ArrayList<>();
|
||||||
|
for (int i = 0; i < gameRobotConfig.get(10) && robotIndex < robotIds.size(); i++, robotIndex++) {
|
||||||
|
ITObject robot = robotIds.getTObject(robotIndex);
|
||||||
|
RobotInfo robotInfo = createRobotInfo(robot, 10);
|
||||||
|
csRobots.add(robotInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//红中麻将机器人
|
||||||
|
List<RobotInfo> hzRobots = new ArrayList<>();
|
||||||
|
for (int i = 0; i < gameRobotConfig.get(22) && robotIndex < robotIds.size(); i++, robotIndex++) {
|
||||||
|
ITObject robot = robotIds.getTObject(robotIndex);
|
||||||
|
RobotInfo robotInfo = createRobotInfo(robot, 22);
|
||||||
|
hzRobots.add(robotInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("机器人分配完成:长沙麻将{}个,红中麻将{}个", csRobots.size(), hzRobots.size());
|
||||||
|
|
||||||
|
//登录分配的机器人
|
||||||
|
//初始化机器人管理器
|
||||||
|
robotManager.loginRobots(csRobots, 10);
|
||||||
|
robotManager.loginRobots(hzRobots, 22);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建机器人信息对象
|
||||||
|
*/
|
||||||
|
private RobotInfo createRobotInfo(ITObject robotObj, int wanfaId) {
|
||||||
|
RobotInfo robot = new RobotInfo();
|
||||||
|
robot.setRobotId(robotObj.getInt("id"));
|
||||||
|
robot.setAccount(robotObj.getString("acc"));
|
||||||
|
robot.setNickName(robotObj.getString("nick"));
|
||||||
|
robot.setPortrait(robotObj.getString("portrait"));
|
||||||
|
robot.setPassword(robotObj.getString("password"));
|
||||||
|
robot.setWanfaId(wanfaId);
|
||||||
|
return robot;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configRoute(Routes me) {
|
public void configRoute(Routes me) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
if(timeScheduler!=null) {
|
|
||||||
timeScheduler.shutdownNow();
|
|
||||||
|
|
||||||
//关闭机器人管理器
|
|
||||||
if (robotManager != null) {
|
|
||||||
robotManager.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,26 +3,22 @@ package com.group.robot;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import com.group.robot.connect.RedisRoomListener;
|
|
||||||
import com.group.robot.connect.RobotDisconnect;
|
import com.group.robot.connect.RobotDisconnect;
|
||||||
|
import com.group.robot.handler.*;
|
||||||
import com.group.robot.info.RobotInfo;
|
import com.group.robot.info.RobotInfo;
|
||||||
import com.group.robot.info.RoomInfo;
|
import com.group.robot.matcher.RoomWanfaMatcher;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
import com.taurus.core.plugin.redis.Redis;
|
import com.taurus.core.plugin.redis.Redis;
|
||||||
import com.taurus.core.plugin.database.DataBase;
|
import com.taurus.core.plugin.database.DataBase;
|
||||||
import com.taurus.core.entity.ITArray;
|
|
||||||
import com.taurus.core.entity.ITObject;
|
import com.taurus.core.entity.ITObject;
|
||||||
import com.group.robot.handler.CSMJRobotHandler;
|
|
||||||
import com.group.robot.handler.HZMJRobotHandler;
|
|
||||||
import com.group.robot.handler.PokerRobotHandler;
|
|
||||||
import com.group.robot.handler.ZZMJRobotHandler;
|
|
||||||
import com.group.robot.matcher.majiang.CSMJRoomMatcher;
|
import com.group.robot.matcher.majiang.CSMJRoomMatcher;
|
||||||
import com.group.robot.matcher.majiang.HZMJRoomMatcher;
|
import com.group.robot.matcher.majiang.HZMJRoomMatcher;
|
||||||
import com.group.robot.matcher.poker.PokerRoomMatcher;
|
import com.group.robot.matcher.poker.PokerRoomMatcher;
|
||||||
import com.group.robot.matcher.majiang.ZZMJRoomMatcher;
|
import com.group.robot.matcher.majiang.ZZMJRoomMatcher;
|
||||||
import com.group.robot.matcher.GameRoomMatcherInterface;
|
import com.group.robot.matcher.GameRoomMatcherInterface;
|
||||||
|
import taurus.client.business.AccountBusiness;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机器人管理器 - 管理游戏机器人、游戏房间、监听
|
* 机器人管理器 - 管理游戏机器人、游戏房间、监听
|
||||||
|
|
@ -42,12 +38,12 @@ public class RobotManager {
|
||||||
//游戏特定的房间匹配器
|
//游戏特定的房间匹配器
|
||||||
private final Map<Integer, GameRoomMatcherInterface> gameRoomMatchers = new ConcurrentHashMap<>();
|
private final Map<Integer, GameRoomMatcherInterface> gameRoomMatchers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
//Redis房间监听器
|
|
||||||
private RedisRoomListener redisRoomListener;
|
|
||||||
|
|
||||||
//使用数量计数器 跟踪每种玩法的机器人使用数量
|
//使用数量计数器 跟踪每种玩法的机器人使用数量
|
||||||
private final Map<Integer, Integer> count = new ConcurrentHashMap<>();
|
private final Map<Integer, Integer> count = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
//玩法房间轮询器
|
||||||
|
private final Map<Integer, RoomWanfaMatcher> wanfaRoomPollers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
//定时任务调度器
|
//定时任务调度器
|
||||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
|
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
|
||||||
|
|
||||||
|
|
@ -61,9 +57,6 @@ public class RobotManager {
|
||||||
|
|
||||||
//1、启动 ==》2、登录,3、是否快捷登录 4、分配做什么工作(a:长麻,b:红中,c:跑得快)5、干活,6、销毁回收
|
//1、启动 ==》2、登录,3、是否快捷登录 4、分配做什么工作(a:长麻,b:红中,c:跑得快)5、干活,6、销毁回收
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//初始化游戏处理器
|
//初始化游戏处理器
|
||||||
initializeGameHandlers();
|
initializeGameHandlers();
|
||||||
//1、设定每个玩法多少机器人
|
//1、设定每个玩法多少机器人
|
||||||
|
|
@ -72,10 +65,7 @@ public class RobotManager {
|
||||||
//初始化游戏房间匹配器
|
//初始化游戏房间匹配器
|
||||||
initializeGameRoomMatchers();
|
initializeGameRoomMatchers();
|
||||||
|
|
||||||
//初始化Redis房间监听器
|
//定时任务
|
||||||
initializeRedisListener();
|
|
||||||
|
|
||||||
//定时清理任务
|
|
||||||
startCleanupTask();
|
startCleanupTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,32 +84,6 @@ public class RobotManager {
|
||||||
log.info("已初始化 {} 个游戏处理器", gameHandlers.size());
|
log.info("已初始化 {} 个游戏处理器", gameHandlers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加游戏处理器
|
|
||||||
*/
|
|
||||||
public void addGameHandler(int gameId, RobotManagerInterface handler) {
|
|
||||||
gameHandlers.put(gameId, handler);
|
|
||||||
log.info("添加游戏处理器: gameId={}, handler={}", gameId, handler.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取游戏处理器
|
|
||||||
*/
|
|
||||||
public RobotManagerInterface getGameHandler(int gameId) {
|
|
||||||
return gameHandlers.get(gameId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化Redis房间监听器
|
|
||||||
*/
|
|
||||||
private void initializeRedisListener() {
|
|
||||||
redisRoomListener = new RedisRoomListener(this);
|
|
||||||
//启动Redis实时监听
|
|
||||||
redisRoomListener.startListening();
|
|
||||||
|
|
||||||
log.info("房间监控已启动 - 实时监听模式,支持 {} 种游戏类型", gameHandlers.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化游戏房间匹配器
|
* 初始化游戏房间匹配器
|
||||||
*/
|
*/
|
||||||
|
|
@ -145,115 +109,146 @@ public class RobotManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时清理任务
|
* 登录单个机器人
|
||||||
*/
|
*/
|
||||||
private void startCleanupTask() {
|
public void loginRobots(List<RobotInfo> robots, int gameId) {
|
||||||
//每30秒检查一次不活跃的机器人连接
|
try (Jedis jedis0 = Redis.use().getJedis(); Jedis jedis2 = Redis.use("group1_db2").getJedis()){
|
||||||
scheduler.scheduleAtFixedRate(this::cleanupInactiveRobots, 30, 30, java.util.concurrent.TimeUnit.SECONDS);
|
for (RobotInfo robot : robots) {
|
||||||
|
AccountBusiness accountBusiness = new AccountBusiness();
|
||||||
|
//检查Redis中是否存在已有token
|
||||||
|
Set<String> tokenKeys = jedis0.keys("{user}:" + robot.getRobotId() + "_token");
|
||||||
|
ITObject loginResult;
|
||||||
|
|
||||||
log.info("定时清理任务已启动");
|
if (tokenKeys != null && !tokenKeys.isEmpty()) {
|
||||||
|
log.debug("机器人 {} 存在已有token,直接使用", robot.getRobotId());
|
||||||
|
Set<String> tokenSet = jedis0.smembers("{user}:" + robot.getRobotId() + "_token");
|
||||||
|
List<String> tokenList = new ArrayList<>(tokenSet);
|
||||||
|
|
||||||
|
robot.setSession("{user}:" + robot.getRobotId());
|
||||||
|
if (!tokenList.isEmpty()) {
|
||||||
|
robot.setToken(tokenList.get(0));
|
||||||
|
} else {
|
||||||
|
//如果没有token 则执行正常登录
|
||||||
|
loginResult = accountBusiness.idPasswordLogin(robot.getRobotId(), robot.getPassword());
|
||||||
|
robot.setToken(loginResult.getString("token"));
|
||||||
|
robot.setSession(accountBusiness.getSession());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("机器人 {} 执行常规登录", robot.getRobotId());
|
||||||
|
//执行正常登录流程
|
||||||
|
loginResult = accountBusiness.idPasswordLogin(robot.getRobotId(), robot.getPassword());
|
||||||
|
robot.setToken(loginResult.getString("token"));
|
||||||
|
robot.setSession(accountBusiness.getSession());
|
||||||
|
}
|
||||||
|
robot.setOnline(true);
|
||||||
|
robot.setWanfaId(gameId);
|
||||||
|
robot.setLastActiveTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
HashMap<String, String> robotMap = new HashMap<>();
|
||||||
|
robotMap.put("acc", robot.getAccount());
|
||||||
|
robotMap.put("nick", robot.getNickName());
|
||||||
|
robotMap.put("portrait", robot.getPortrait());
|
||||||
|
robotMap.put("password", robot.getPassword());
|
||||||
|
jedis2.hmset("{robot}:" + robot.getRobotId(), robotMap);
|
||||||
|
|
||||||
|
//todo 将机器人信息存储到grobot键中,用于按group分类
|
||||||
|
Map<String, String> gRobotMap = new HashMap<>();
|
||||||
|
gRobotMap.put("start", "0");
|
||||||
|
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);
|
||||||
|
log.info("机器人{}登录成功,分配到玩法{}", robot.getRobotId(), gameId);
|
||||||
|
|
||||||
|
//连接对应游戏服务器
|
||||||
|
RobotManagerInterface handler = getGameHandler(gameId);
|
||||||
|
handler.connectRobot(robot);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("机器人登录时发生错误", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理不活跃的机器人连接
|
* 添加游戏处理器
|
||||||
*/
|
*/
|
||||||
private void cleanupInactiveRobots() {
|
public void addGameHandler(int gameId, RobotManagerInterface handler) {
|
||||||
log.debug("开始清理不活跃的机器人连接...");
|
gameHandlers.put(gameId, handler);
|
||||||
|
log.info("添加游戏处理器: gameId={}, handler={}", gameId, handler.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
//已连接的机器人
|
/**
|
||||||
for (RobotInfo robot : new ArrayList<>(connectedRobots.values())) {
|
* 获取游戏处理器
|
||||||
//检查机器人是否仍然连接到房间
|
*/
|
||||||
try {
|
public RobotManagerInterface getGameHandler(int gameId) {
|
||||||
//检查房间状态
|
return gameHandlers.get(gameId);
|
||||||
try (Jedis jedis0 = Redis.use().getJedis()){
|
}
|
||||||
String roomKey = robot.getCurrentRoomId();
|
|
||||||
if (roomKey != null) {
|
|
||||||
//检查房间是否存在或是否已结束
|
|
||||||
String status = jedis0.hget(roomKey, "status");
|
|
||||||
if (status != null) {
|
|
||||||
int roomStatus = Integer.parseInt(status);
|
|
||||||
//如果房间已结束或已删除 断开机器人连接
|
|
||||||
if (roomStatus == 2 || roomStatus == 3) {
|
|
||||||
log.info("房间 {} 已结束,断开机器人 {} 连接", roomKey, robot.getRobotId());
|
|
||||||
disconnectRobot(robot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//检查房间玩家列表 确认机器人是否仍在房间中
|
/**
|
||||||
String players = jedis0.hget(roomKey, "players");
|
* 定时任务
|
||||||
if (players != null && !players.equals("[]")) {
|
*/
|
||||||
String playersStr = players.substring(1, players.length() - 1);
|
private void startCleanupTask() {
|
||||||
String[] playerIds = playersStr.split(",");
|
//每15秒检查一次玩法配置
|
||||||
boolean robotInRoom = false;
|
scheduler.scheduleAtFixedRate(this::manageWanfaPollers, 15, 15, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
for (String playerIdStr : playerIds) {
|
/**
|
||||||
int playerId = Integer.parseInt(playerIdStr.trim());
|
* 管理玩法轮询器
|
||||||
if (playerId == robot.getRobotId()) {
|
*/
|
||||||
robotInRoom = true;
|
private void manageWanfaPollers() {
|
||||||
break;
|
try (Jedis jedis11 = Redis.use("group1_db11").getJedis()) {
|
||||||
}
|
Set<String> playKeys = jedis11.keys("g{*}:play:*");
|
||||||
}
|
|
||||||
//如果机器人不在房间玩家列表中 断开连接
|
for (String playKey : playKeys) {
|
||||||
if (!robotInRoom) {
|
try {
|
||||||
log.info("机器人 {} 不在房间 {} 断开连接", robot.getRobotId(), roomKey);
|
String[] parts = playKey.split(":");
|
||||||
disconnectRobot(robot);
|
if (parts.length >= 3) {
|
||||||
|
String groupStr = parts[0];
|
||||||
|
int groupId = Integer.parseInt(groupStr.substring(2, groupStr.length() - 1));
|
||||||
|
int wanfaId = Integer.parseInt(parts[parts.length - 1]);
|
||||||
|
|
||||||
|
//检查是否配置了机器人
|
||||||
|
int shangxianRobot = Integer.parseInt(jedis11.hget(playKey, "shangxian_robot"));
|
||||||
|
int leftoverRobot = Integer.parseInt(jedis11.hget(playKey, "leftover_robot"));
|
||||||
|
|
||||||
|
if (shangxianRobot != 0 && leftoverRobot > 0) {
|
||||||
|
RoomWanfaMatcher poller = getWanfaRoomPoller(groupId, wanfaId);
|
||||||
|
if (!poller.isRunning()) {
|
||||||
|
poller.startPolling();
|
||||||
|
log.info("为玩法ID {} 启动房间轮询器", wanfaId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//如果房间玩家列表为空 但机器人连接到此房间 断开连接
|
//如果没有配置机器人 停止轮询器
|
||||||
if (roomKey.equals(robot.getCurrentRoomId())) {
|
RoomWanfaMatcher poller = wanfaRoomPollers.get(wanfaId);
|
||||||
log.info("房间 {} 玩家列表为空,断开机器人 {} 连接", roomKey, robot.getRobotId());
|
if (poller != null) {
|
||||||
disconnectRobot(robot);
|
poller.stopPolling();
|
||||||
|
log.info("为玩法ID {} 停止房间轮询器", wanfaId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.debug("无法解析玩法ID: {}", playKey);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("检查机器人 {} 连接状态时发生错误", robot.getRobotId(), e);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
log.debug("清理不活跃的机器人连接完成,当前连接机器人数量: {}", connectedRobots.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接机器人到指定房间
|
|
||||||
*/
|
|
||||||
public void connectRobotToRoom(RobotInfo robot, RoomInfo room) {
|
|
||||||
RobotManagerInterface handler = getGameHandler(room.getWanfaId());
|
|
||||||
if (handler == null) {
|
|
||||||
log.warn("未找到处理玩法ID {} 的处理器", room.getWanfaId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//增加对应玩法的机器人使用计数
|
|
||||||
increaseRobotUsageCount(room.getGroupId(), room.getWanfaId());
|
|
||||||
log.info("机器人 {} 加入房间前,减少leftover_robot数量,群组={}, 玩法ID={}", robot.getRobotId(), room.getGroupId(), room.getWanfaId());
|
|
||||||
|
|
||||||
try {
|
|
||||||
//通过处理器连接机器人
|
|
||||||
handler.connectRobot(robot, room);
|
|
||||||
connectedRobots.put(robot.getRobotId(), robot);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("连接机器人到房间时发生异常", e);
|
log.error("管理玩法轮询器时发生错误", e);
|
||||||
robot.setConnected(false);
|
|
||||||
//异常时回滚计数
|
|
||||||
rollbackRobotCounts(room.getGroupId(), room.getWanfaId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回滚机器人相关计数
|
* 获取玩法房间轮询器
|
||||||
*/
|
*/
|
||||||
private void rollbackRobotCounts(int groupId, int wanfaId) {
|
public RoomWanfaMatcher getWanfaRoomPoller(int groupId, int wanfaId) {
|
||||||
//减少的机器人使用计数回滚
|
return wanfaRoomPollers.computeIfAbsent(wanfaId, k -> {
|
||||||
decreaseRobotCount(wanfaId);
|
RoomWanfaMatcher poller = new RoomWanfaMatcher(this, groupId, wanfaId);
|
||||||
//增加leftover_robot数量
|
log.info("创建玩法ID {} 的房间轮询器", wanfaId);
|
||||||
try (Jedis jedis11 = Redis.use("group1_db11").getJedis()) {
|
return poller;
|
||||||
String playKey = "g{" + groupId + "}:play:" + wanfaId;
|
});
|
||||||
jedis11.hincrBy(playKey, "leftover_robot", 1);
|
|
||||||
log.info("回滚机器人计数,群组={}, 玩法ID={}", groupId, wanfaId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("回滚leftover_robot计数时发生异常", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -261,9 +256,9 @@ public class RobotManager {
|
||||||
*/
|
*/
|
||||||
public void disconnectRobot(RobotInfo robot) {
|
public void disconnectRobot(RobotInfo robot) {
|
||||||
int robotId = robot.getRobotId();
|
int robotId = robot.getRobotId();
|
||||||
int groupId = getGroupIdFromRoomId(robot.getCurrentRoomId());
|
int groupId = getGroupIdFromRoomId(robot.getRoomId());
|
||||||
int gameId = robot.getCurrentWanfaId();
|
int gameId = robot.getWanfaId();
|
||||||
String roomId = robot.getCurrentRoomId();
|
String roomId = robot.getRoomId();
|
||||||
|
|
||||||
//断开机器人服务
|
//断开机器人服务
|
||||||
safeDisconnectRobot(robotId, groupId, gameId, roomId);
|
safeDisconnectRobot(robotId, groupId, gameId, roomId);
|
||||||
|
|
@ -285,92 +280,17 @@ public class RobotManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取可用机器人列表
|
* 获取已登录的指定玩法的机器人
|
||||||
*/
|
*/
|
||||||
public List<RobotInfo> getAvailableRobots(int count) {
|
public RobotInfo getLoggedInRobotForWanfa(int wanfaId) {
|
||||||
List<RobotInfo> availableRobots = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
//获取可用机器人信息
|
|
||||||
String sql = String.format("SELECT id,acc,nick,portrait,password FROM `account` WHERE jiqiren=9998 and start = 0 LIMIT %d", count);
|
|
||||||
ITArray robotArray = DataBase.use().executeQueryByTArray(sql);
|
|
||||||
|
|
||||||
for (int i = 0; i < robotArray.size() && i < count; i++) {
|
|
||||||
ITObject robotObj = robotArray.getTObject(i);
|
|
||||||
|
|
||||||
RobotInfo robot = new RobotInfo();
|
|
||||||
robot.setRobotId(robotObj.getInt("id"));
|
|
||||||
robot.setAccount(robotObj.getString("acc"));
|
|
||||||
robot.setNickName(robotObj.getString("nick"));
|
|
||||||
robot.setPortrait(robotObj.getString("portrait"));
|
|
||||||
robot.setPassword(robotObj.getString("password"));
|
|
||||||
robot.setOnline(false);
|
|
||||||
robot.setConnected(false);
|
|
||||||
|
|
||||||
availableRobots.add(robot);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("获取可用机器人列表时发生错误", e);
|
|
||||||
} finally {
|
|
||||||
//更新机器人状态为已使用
|
|
||||||
if (!availableRobots.isEmpty()) {
|
|
||||||
for (RobotInfo robot : availableRobots) {
|
|
||||||
try {
|
|
||||||
String sql = String.format("UPDATE `account` SET start = %d WHERE id = %d", 1, robot.getRobotId());
|
|
||||||
DataBase.use().executeUpdate(sql);
|
|
||||||
log.debug("机器人 {} 状态已更新为已使用", robot.getRobotId());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("更新机器人 {} 状态失败", robot.getRobotId(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return availableRobots;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定玩法类型的房间匹配器
|
|
||||||
*/
|
|
||||||
public GameRoomMatcherInterface getGameRoomMatcher(int wanfaId) {
|
|
||||||
return gameRoomMatchers.get(wanfaId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭机器人管理器
|
|
||||||
*/
|
|
||||||
public void shutdown() {
|
|
||||||
//停止Redis监听
|
|
||||||
if (redisRoomListener != null) {
|
|
||||||
redisRoomListener.stopListening();
|
|
||||||
}
|
|
||||||
|
|
||||||
//断开所有机器人连接
|
|
||||||
for (RobotInfo robot : connectedRobots.values()) {
|
for (RobotInfo robot : connectedRobots.values()) {
|
||||||
disconnectRobot(robot);
|
if (robot.getWanfaId() == wanfaId && robot.isOnline() && robot.isConnected()) {
|
||||||
}
|
//更新最后活跃时间
|
||||||
|
robot.setLastActiveTime(System.currentTimeMillis());
|
||||||
//恢复所有机器人状态为可用
|
return robot;
|
||||||
try {
|
|
||||||
String sql = "UPDATE `account` SET start = 0 WHERE jiqiren = 9998";
|
|
||||||
DataBase.use().executeUpdate(sql);
|
|
||||||
log.info("所有机器人状态已重置为可用");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("重置机器人状态时发生错误", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
//关闭定时任务调度器
|
|
||||||
try {
|
|
||||||
scheduler.shutdown();
|
|
||||||
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
|
|
||||||
scheduler.shutdownNow();
|
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
|
||||||
scheduler.shutdownNow();
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
log.info("机器人管理器已关闭,断开了 {} 个机器人连接", connectedRobots.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -380,21 +300,6 @@ public class RobotManager {
|
||||||
return robotManager;
|
return robotManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 增加指定玩法ID的机器人使用计数
|
|
||||||
*/
|
|
||||||
public void increaseRobotUsageCount(int groupId, int wanfaId) {
|
|
||||||
count.put(wanfaId, count.getOrDefault(wanfaId, 0) + 1);
|
|
||||||
|
|
||||||
try (Jedis jedis11 = Redis.use("group1_db11").getJedis()) {
|
|
||||||
String playKey = "g{" + groupId + "}:play:" + wanfaId;
|
|
||||||
jedis11.hincrBy(playKey, "leftover_robot", -1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
decreaseRobotCount(wanfaId);
|
|
||||||
}
|
|
||||||
log.debug("玩法ID {} 的机器人使用计数增加到: {}", wanfaId, count.get(wanfaId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 减少指定玩法ID的机器人使用计数
|
* 减少指定玩法ID的机器人使用计数
|
||||||
*/
|
*/
|
||||||
|
|
@ -406,13 +311,6 @@ public class RobotManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定玩法ID的机器人使用计数
|
|
||||||
*/
|
|
||||||
public int getRobotUsageCount(int wanfaId) {
|
|
||||||
return count.getOrDefault(wanfaId, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取已连接的机器人
|
* 获取已连接的机器人
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ import com.group.robot.info.RoomInfo;
|
||||||
*/
|
*/
|
||||||
public interface RobotManagerInterface {
|
public interface RobotManagerInterface {
|
||||||
/**
|
/**
|
||||||
* 连接机器人到房间
|
* 连接机器人到游戏服务器
|
||||||
*/
|
*/
|
||||||
void connectRobot(RobotInfo robot, RoomInfo room);
|
void connectRobot(RobotInfo robot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 断开机器人连接
|
* 断开机器人连接
|
||||||
|
|
|
||||||
|
|
@ -1,451 +0,0 @@
|
||||||
package com.group.robot.connect;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import com.group.robot.RobotManager;
|
|
||||||
import com.group.robot.info.RobotInfo;
|
|
||||||
import com.group.robot.info.RoomInfo;
|
|
||||||
import com.taurus.core.entity.ITArray;
|
|
||||||
import com.taurus.core.entity.ITObject;
|
|
||||||
import com.taurus.core.plugin.database.DataBase;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
import redis.clients.jedis.JedisPubSub;
|
|
||||||
import com.taurus.core.plugin.redis.Redis;
|
|
||||||
import com.group.robot.matcher.GameRoomMatcherInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redis房间监听器 - 实时监听房间的游戏类型 触发对应游戏类型匹配器
|
|
||||||
*/
|
|
||||||
public class RedisRoomListener extends JedisPubSub {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(RedisRoomListener.class);
|
|
||||||
private final ExecutorService executorService = Executors.newFixedThreadPool(4);
|
|
||||||
//机器人管理器
|
|
||||||
private final RobotManager robotManager;
|
|
||||||
|
|
||||||
public RedisRoomListener(RobotManager robotManager) {
|
|
||||||
this.robotManager = robotManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始监听房间变化
|
|
||||||
*/
|
|
||||||
public void startListening() {
|
|
||||||
// 启动db0监听线程(房间变化)
|
|
||||||
Thread db0ListenerThread = new Thread(() -> {
|
|
||||||
Jedis jedis0 = Redis.use().getJedis(); // 默认db0
|
|
||||||
try {
|
|
||||||
log.info("开始监听db0的房间键空间变化...");
|
|
||||||
|
|
||||||
//订阅键空间通知 - db0中的房间变化
|
|
||||||
//注意:Redis需要开启键空间通知:config set notify-keyspace-events Ex
|
|
||||||
jedis0.psubscribe(this, "__keyspace@0__:room:*");
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("监听db0房间变化时发生错误", e);
|
|
||||||
} finally {
|
|
||||||
if (jedis0 != null) {
|
|
||||||
jedis0.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
db0ListenerThread.setDaemon(true);
|
|
||||||
db0ListenerThread.setName("RedisRoomListener-db0");
|
|
||||||
db0ListenerThread.start();
|
|
||||||
|
|
||||||
//启动db11监听线程(玩法配置变化)
|
|
||||||
Thread db11ListenerThread = new Thread(() -> {
|
|
||||||
Jedis jedis11 = Redis.use("group1_db11").getJedis();
|
|
||||||
try {
|
|
||||||
log.info("开始监听db11的玩法配置变化...");
|
|
||||||
|
|
||||||
//订阅键空间通知 - db11中的玩法配置变化
|
|
||||||
//注意:需要订阅正确的模式
|
|
||||||
jedis11.psubscribe(this, "__keyspace@11__:g{*}:play:*");
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("监听db11玩法配置变化时发生错误", e);
|
|
||||||
} finally {
|
|
||||||
if (jedis11 != null) {
|
|
||||||
jedis11.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
db11ListenerThread.setDaemon(true);
|
|
||||||
db11ListenerThread.setName("RedisRoomListener-db11");
|
|
||||||
db11ListenerThread.start();
|
|
||||||
|
|
||||||
log.info("Redis房间监听器已启动,正在监听db0的房间变化和db11的玩法配置变化");
|
|
||||||
|
|
||||||
//等待监听线程启动
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
if (db0ListenerThread.isAlive() && db11ListenerThread.isAlive()) {
|
|
||||||
log.info("两个监听线程都已成功启动");
|
|
||||||
System.out.println("Redis房间监听器已启动,正在监听db0的房间变化和db11的玩法配置变化");
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(String channel, String message) {
|
|
||||||
log.debug("收到Redis频道消息: channel={}, message={}", channel, message);
|
|
||||||
System.out.println("收到Redis频道消息: channel=" + channel + ", message=" + message);
|
|
||||||
//根据订阅类型处理
|
|
||||||
if (channel.startsWith("__keyspace@0__:room:")) {
|
|
||||||
//处理房间人员进出或状态变化
|
|
||||||
handleRoomEvent(channel, message);
|
|
||||||
} else if (channel.startsWith("g{") && channel.contains("}:play:")) {
|
|
||||||
//群组玩法配置变化事件
|
|
||||||
handleGroupPlayChange(channel, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理房间变化事件
|
|
||||||
*/
|
|
||||||
private void handleRoomEvent(String channel, String message) {
|
|
||||||
executorService.submit(() -> {
|
|
||||||
try (Jedis jedis0 = Redis.use().getJedis(); Jedis jedis11 = Redis.use("group1_db11").getJedis()) {
|
|
||||||
//获取房间ID
|
|
||||||
String roomId = getRedisChannelRoomId(channel);
|
|
||||||
|
|
||||||
int wanfaId = Integer.parseInt(jedis0.hget(roomId, "game"));
|
|
||||||
int groupId = Integer.parseInt(jedis0.hget(roomId, "group"));
|
|
||||||
int status = Integer.parseInt(jedis0.hget(roomId, "status"));
|
|
||||||
int maxPlayers = Integer.parseInt(jedis0.hget(roomId, "maxPlayers"));
|
|
||||||
|
|
||||||
if (maxPlayers != 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//房间已结束或已删除
|
|
||||||
if (status == 2 || status == 3) {
|
|
||||||
String playersStr = jedis0.hget(roomId, "players");
|
|
||||||
if (playersStr != null && !playersStr.equals("[]")) {
|
|
||||||
//房间结束后 如果房间中有机器人 恢复剩余机器人数量
|
|
||||||
restoreLeftoverRobotOnRoomEnd(roomId, groupId, wanfaId, playersStr, jedis11);
|
|
||||||
|
|
||||||
//房间结束后 立即检查是否需要创建新房间
|
|
||||||
checkCreateRobotRoomTCP(wanfaId, groupId, jedis0, jedis11);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 匹配机器人机制 */
|
|
||||||
//检查玩法配置中的机器人设置
|
|
||||||
String playKey = "g{" + groupId + "}:play:" + wanfaId;
|
|
||||||
int shangxianRobot = Integer.parseInt(jedis11.hget(playKey, "shangxian_robot"));
|
|
||||||
|
|
||||||
//玩法配置了机器人上限
|
|
||||||
if (shangxianRobot > 0) {
|
|
||||||
String playersStr = jedis0.hget(roomId, "players");
|
|
||||||
|
|
||||||
//房间中当前人数
|
|
||||||
int currentPlayers = 0;
|
|
||||||
if (playersStr != null && !playersStr.equals("[]")) {
|
|
||||||
String playersClean = playersStr.substring(1, playersStr.length() - 1);
|
|
||||||
if (!playersClean.isEmpty()) {
|
|
||||||
String[] playerIds = playersClean.split(",");
|
|
||||||
currentPlayers = playerIds.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//检查房间中是否已有机器人
|
|
||||||
boolean hasRobot = hasRobotInRoom(roomId, jedis0);
|
|
||||||
|
|
||||||
//触发对应游戏类型的房间匹配器
|
|
||||||
GameRoomMatcherInterface matcher = robotManager.getGameRoomMatcher(wanfaId);
|
|
||||||
if (matcher != null && !hasRobot && currentPlayers < maxPlayers) {
|
|
||||||
log.info("触发玩法ID {} 的房间匹配", wanfaId);
|
|
||||||
|
|
||||||
//获取玩法配置中的剩余机器人数量
|
|
||||||
int leftoverRobot = Integer.parseInt(jedis11.hget(playKey, "leftover_robot"));
|
|
||||||
if (leftoverRobot > 0) {
|
|
||||||
int currentUsage = robotManager.getRobotUsageCount(wanfaId);
|
|
||||||
//当前机器人使用数量小于上限
|
|
||||||
if (currentUsage < shangxianRobot) {
|
|
||||||
//获取可用机器人
|
|
||||||
List<RobotInfo> availableRobots = robotManager.getAvailableRobots(1);
|
|
||||||
if (!availableRobots.isEmpty()) {
|
|
||||||
RobotInfo robot = availableRobots.get(0);
|
|
||||||
|
|
||||||
//创建房间信息对象
|
|
||||||
RoomInfo roomInfo = new RoomInfo();
|
|
||||||
roomInfo.setRoomId(roomId);
|
|
||||||
roomInfo.setWanfaId(wanfaId);
|
|
||||||
roomInfo.setGroupId(groupId);
|
|
||||||
roomInfo.setCurrentPlayers(currentPlayers);
|
|
||||||
roomInfo.setMaxPlayers(maxPlayers);
|
|
||||||
roomInfo.setGame(String.valueOf(wanfaId));
|
|
||||||
|
|
||||||
//连接机器人到房间
|
|
||||||
robotManager.connectRobotToRoom(robot, roomInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.debug("玩法ID {} 房间已有机器人或房间已满", wanfaId);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.debug("玩法ID {} 没有配置机器人上限或上限为0 跳过处理", wanfaId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 对2人房间进行检查 当房间状态发生变化时 检查是否需要创建新房间 */
|
|
||||||
checkCreateRobotRoomTCP(wanfaId, groupId, jedis0, jedis11);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("处理房间变化事件时发生错误", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理群组玩法配置变化
|
|
||||||
*/
|
|
||||||
private void handleGroupPlayChange(String channel, String message) {
|
|
||||||
executorService.submit(() -> {
|
|
||||||
try (Jedis jedis0 = Redis.use().getJedis(); Jedis jedis11 = Redis.use("group1_db11").getJedis()){
|
|
||||||
log.info("监听到群组玩法配置变化: {}", channel);
|
|
||||||
|
|
||||||
int braceIndex = channel.indexOf('}');
|
|
||||||
if (braceIndex > 1) {
|
|
||||||
String groupIdStr = channel.substring(2, braceIndex);
|
|
||||||
String remaining = channel.substring(braceIndex + 1);
|
|
||||||
|
|
||||||
if (remaining.startsWith(":play:") && remaining.length() > 6) {
|
|
||||||
String wanfaIdStr = remaining.substring(6);
|
|
||||||
int groupId = Integer.parseInt(groupIdStr);
|
|
||||||
int wanfaId = Integer.parseInt(wanfaIdStr);
|
|
||||||
|
|
||||||
//当玩法配置发生变化时 立即检查是否需要创建房间
|
|
||||||
checkCreateRobotRoomTCP(wanfaId, groupId, jedis0, jedis11);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("处理群组玩法配置变化时发生错误", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取房间ID
|
|
||||||
*/
|
|
||||||
private String getRedisChannelRoomId(String channel) {
|
|
||||||
if (channel.startsWith("__keyspace@0__:room:")) {
|
|
||||||
return "room:" + channel.substring("__keyspace@0__:room:".length());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 停止监听
|
|
||||||
*/
|
|
||||||
public void stopListening() {
|
|
||||||
try {
|
|
||||||
this.unsubscribe();
|
|
||||||
executorService.shutdown();
|
|
||||||
try {
|
|
||||||
//等待现有任务完成
|
|
||||||
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
//再次等待
|
|
||||||
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
|
|
||||||
log.error("线程池未能正常关闭");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// 重新中断当前线程
|
|
||||||
executorService.shutdownNow();
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
log.info("Redis房间监听器已停止");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("停止Redis房间监听器时发生错误", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查房间中是否已有机器人
|
|
||||||
*/
|
|
||||||
private boolean hasRobotInRoom(String roomId, Jedis jedis0) {
|
|
||||||
String players = jedis0.hget(roomId, "players");
|
|
||||||
Integer playerId = hasRobotInPlayerList(players);
|
|
||||||
return playerId != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查玩家列表中是否包含机器人
|
|
||||||
*/
|
|
||||||
public static Integer hasRobotInPlayerList(String playersStr) {
|
|
||||||
if (playersStr == null || playersStr.equals("[]")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String playersClean = playersStr.substring(1, playersStr.length() - 1);
|
|
||||||
String[] playerIds = playersClean.split(",");
|
|
||||||
|
|
||||||
for (String playerIdStr : playerIds) {
|
|
||||||
try {
|
|
||||||
int playerId = Integer.parseInt(playerIdStr.trim());
|
|
||||||
//检查是否为机器人账户(jiqiren=9998)
|
|
||||||
String checkSql = String.format("SELECT jiqiren FROM `account` WHERE id = %d", playerId);
|
|
||||||
ITArray checkArray = DataBase.use().executeQueryByTArray(checkSql);
|
|
||||||
|
|
||||||
if (checkArray.size() > 0) {
|
|
||||||
ITObject checkObj = checkArray.getTObject(0);
|
|
||||||
int jiqiren = checkObj.getInt("jiqiren");
|
|
||||||
if (jiqiren == 9998) { //是机器人
|
|
||||||
return playerId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("检查玩家是否为机器人时发生错误: {}", playerIdStr, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查是否需要为指定玩法和群组创建新房间 通过TCP服务
|
|
||||||
*/
|
|
||||||
private void checkCreateRobotRoomTCP(int wanfaId, int groupId, Jedis jedis0, Jedis jedis11) {
|
|
||||||
try {
|
|
||||||
//获取玩法配置中是否允许机器人创建房间
|
|
||||||
String playKey = "g{" + groupId + "}:play:" + wanfaId;
|
|
||||||
String leftoverRobotValue = jedis11.hget(playKey, "leftover_robot");
|
|
||||||
String shangxianRobotValue = jedis11.hget(playKey, "shangxian_robot");
|
|
||||||
|
|
||||||
if (leftoverRobotValue == null || shangxianRobotValue == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int leftoverRobot = Integer.parseInt(leftoverRobotValue);
|
|
||||||
int shangxianRobot = Integer.parseInt(shangxianRobotValue);
|
|
||||||
|
|
||||||
//检查当前玩法的机器人使用数量
|
|
||||||
int currentUsage = robotManager.getRobotUsageCount(wanfaId);
|
|
||||||
if (leftoverRobot > 0 && currentUsage < shangxianRobot) {
|
|
||||||
Set<String> roomIds = jedis0.keys("room:*");
|
|
||||||
//有效房间数量
|
|
||||||
int validRoomCount = 0;
|
|
||||||
|
|
||||||
for (String roomId : roomIds) {
|
|
||||||
String groupValue = jedis0.hget(roomId, "group");
|
|
||||||
String gameValue = jedis0.hget(roomId, "game");
|
|
||||||
|
|
||||||
if (groupValue == null || gameValue == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int roomGroup = Integer.parseInt(groupValue);
|
|
||||||
int roomWanfa = Integer.parseInt(gameValue);
|
|
||||||
|
|
||||||
//检查玩法和群组是否匹配
|
|
||||||
if (roomGroup == groupId && roomWanfa == wanfaId) {
|
|
||||||
int status = Integer.parseInt(jedis0.hget(roomId, "status"));
|
|
||||||
int maxPlayers = Integer.parseInt(jedis0.hget(roomId, "maxPlayers"));
|
|
||||||
|
|
||||||
//只考虑2人房间 未开始或进行中
|
|
||||||
if (maxPlayers == 2 && status < 2) {
|
|
||||||
String playersStr = jedis0.hget(roomId, "players");
|
|
||||||
if (!playersStr.equals("[]")) {
|
|
||||||
String playersClean = playersStr.substring(1, playersStr.length() - 1);
|
|
||||||
int currentPlayers = 0;
|
|
||||||
if (!playersClean.isEmpty()) {
|
|
||||||
String[] playerIds = playersClean.split(",");
|
|
||||||
currentPlayers = playerIds.length;
|
|
||||||
}
|
|
||||||
if (currentPlayers < maxPlayers) {
|
|
||||||
validRoomCount++; //未满员的有效房间
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//如果没有有效房间(空房间或未满员房间)则通过TCP创建新房间
|
|
||||||
if (validRoomCount == 0) {
|
|
||||||
log.info("检测到群组 {} 和玩法ID {} 没有效房间,通过TCP创建房间: 剩余机器人={}, 当前使用={}, 上限={}",groupId, wanfaId, leftoverRobot, currentUsage, shangxianRobot);
|
|
||||||
//通过TCP创建新房间
|
|
||||||
createRoomForWanfaTCP(groupId, wanfaId, jedis11);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("检查是否需要通过TCP创建房间时发生错误", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过TCP服务为指定群组和玩法创建房间
|
|
||||||
*/
|
|
||||||
private void createRoomForWanfaTCP(int groupId, int wanfaId, Jedis jedis11) {
|
|
||||||
//检查玩法配置中的机器人设置
|
|
||||||
try {
|
|
||||||
String playKey = "g{" + groupId + "}:play:" + wanfaId;
|
|
||||||
String shangxianRobotValue = jedis11.hget(playKey, "shangxian_robot");
|
|
||||||
|
|
||||||
if (shangxianRobotValue == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int shangxianRobot = Integer.parseInt(shangxianRobotValue);
|
|
||||||
|
|
||||||
if (shangxianRobot != 0) {
|
|
||||||
int currentUsage = robotManager.getRobotUsageCount(wanfaId);
|
|
||||||
|
|
||||||
if (currentUsage < shangxianRobot) {
|
|
||||||
RobotMgrTcpClient tcpClient = new RobotMgrTcpClient("127.0.0.1", 8701);
|
|
||||||
|
|
||||||
//获取可用机器人
|
|
||||||
List<RobotInfo> availableRobots = robotManager.getAvailableRobots(1);
|
|
||||||
if (!availableRobots.isEmpty()) {
|
|
||||||
RobotInfo robot = availableRobots.get(0);
|
|
||||||
|
|
||||||
//TCP客户端连接到robot_mj_cs
|
|
||||||
int attempts = 0;
|
|
||||||
while (!tcpClient.isConnected() && attempts < 10) {
|
|
||||||
Thread.sleep(100);
|
|
||||||
attempts++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送创建房间请求
|
|
||||||
CompletableFuture<RoomInfo> future = tcpClient.sendCreateRoomForRobot(groupId, wanfaId, robot.getRobotId());
|
|
||||||
|
|
||||||
RoomInfo roomInfo = future.get();
|
|
||||||
if (roomInfo != null) {
|
|
||||||
log.info("收到创建房间{}响应:", roomInfo.getRoomId());
|
|
||||||
robotManager.connectRobotToRoom(robot, roomInfo);
|
|
||||||
log.info("成功为玩法ID {} 的房间 {} 添加机器人 {}", wanfaId, roomInfo.getRoomId(), robot.getRobotId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("玩法ID {} 已达到机器人使用上限: 当前={}, 上限={}", wanfaId, currentUsage, shangxianRobot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("通过TCP为群组 {} 和玩法ID {} 创建房间时发生错误", groupId, wanfaId, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 房间结束时恢复leftover_robot数量
|
|
||||||
*/
|
|
||||||
private void restoreLeftoverRobotOnRoomEnd(String roomId, int groupId, int wanfaId, String playersStr, Jedis jedis11) {
|
|
||||||
Integer robotId = hasRobotInPlayerList(playersStr);
|
|
||||||
if (robotId != null) {
|
|
||||||
log.info("房间 {} 结束,检测到机器人 {},调用统一断开服务", roomId, robotId);
|
|
||||||
//调用RobotManager的统一断开服务
|
|
||||||
robotManager.safeDisconnectRobot(robotId, groupId, wanfaId, roomId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -56,7 +56,7 @@ public class RobotDisconnect {
|
||||||
|
|
||||||
//处理对应游戏处理器断开连接
|
//处理对应游戏处理器断开连接
|
||||||
if (robot != null) {
|
if (robot != null) {
|
||||||
RobotManagerInterface handler = robotManager.getGameHandler(robot.getCurrentWanfaId());
|
RobotManagerInterface handler = robotManager.getGameHandler(robot.getWanfaId());
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
handler.disconnectRobot(robot);
|
handler.disconnectRobot(robot);
|
||||||
log.debug("游戏处理器已断开机器人 {} 连接", robotId);
|
log.debug("游戏处理器已断开机器人 {} 连接", robotId);
|
||||||
|
|
|
||||||
|
|
@ -1,240 +0,0 @@
|
||||||
package com.group.robot.connect;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import com.group.Protocol;
|
|
||||||
import com.group.robot.info.RoomInfo;
|
|
||||||
import com.taurus.core.entity.ITObject;
|
|
||||||
import com.taurus.core.entity.TObject;
|
|
||||||
import com.taurus.core.util.ICallback;
|
|
||||||
import com.taurus.core.util.Logger;
|
|
||||||
import taurus.client.MessageResponse;
|
|
||||||
import taurus.client.NetManager;
|
|
||||||
import taurus.client.TaurusClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TCP客户端 - 与robot_mj_cs服务端通信
|
|
||||||
*/
|
|
||||||
public class RobotMgrTcpClient {
|
|
||||||
|
|
||||||
private Logger log = Logger.getLogger(RobotMgrTcpClient.class);
|
|
||||||
private TaurusClient client;
|
|
||||||
private volatile boolean isConnected = false;
|
|
||||||
private volatile boolean isInitialized = false;
|
|
||||||
private volatile boolean isLoginCompleted = false;
|
|
||||||
private Thread eventThread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造函数
|
|
||||||
* @param host 服务器主机地址
|
|
||||||
* @param port 服务器端口
|
|
||||||
*/
|
|
||||||
public RobotMgrTcpClient(String host, int port) {
|
|
||||||
try {
|
|
||||||
//创建TCP客户端
|
|
||||||
this.client = new TaurusClient(host + ":" + port, "10", TaurusClient.ConnectionProtocol.Tcp);
|
|
||||||
|
|
||||||
//启动网络事件处理线程
|
|
||||||
startNetEventThread();
|
|
||||||
|
|
||||||
//连接到服务器 异步
|
|
||||||
client.connect();
|
|
||||||
|
|
||||||
int attempts = 0;
|
|
||||||
while (!client.isConnected() && attempts < 100) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(200);
|
|
||||||
attempts++;
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
System.err.println("等待连接建立时被中断: " + e.getMessage());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//连接成功 发送握手协议
|
|
||||||
if (client.isConnected()) {
|
|
||||||
log.info("TCP连接已建立 发送握手协议");
|
|
||||||
isConnected = true;
|
|
||||||
isInitialized = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(500);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送初始化协议 完成握手过程 防止服务端超时断开连接
|
|
||||||
sendInitializationProtocol();
|
|
||||||
|
|
||||||
attempts = 0;
|
|
||||||
while (!isLoginCompleted && attempts < 50) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(200);
|
|
||||||
attempts++;
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
log.error("等待握手完成被中断: " + e.getMessage());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 启动网络事件处理线程
|
|
||||||
*/
|
|
||||||
private void startNetEventThread() {
|
|
||||||
eventThread = new Thread(() -> {
|
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
|
||||||
NetManager.processEvents();
|
|
||||||
try {
|
|
||||||
Thread.sleep(2);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
break;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("网络事件处理错误: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "RobotMgrTcpClient-NetEventThread");
|
|
||||||
|
|
||||||
eventThread.setDaemon(true);
|
|
||||||
eventThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送初始化协议到robot_mj_cs服务器
|
|
||||||
*/
|
|
||||||
private void sendInitializationProtocol() {
|
|
||||||
try {
|
|
||||||
log.info("发送初始化协议到robot_mj_cs服务器");
|
|
||||||
|
|
||||||
//构建初始化参数
|
|
||||||
ITObject params = TObject.newInstance();
|
|
||||||
params.putString("type", "manager_connection");
|
|
||||||
params.putString("client", "robot_mgr");
|
|
||||||
|
|
||||||
//发送初始化协议
|
|
||||||
client.send("init_connection", params, new ICallback<MessageResponse>() {
|
|
||||||
@Override
|
|
||||||
public void action(MessageResponse response) {
|
|
||||||
if (response.returnCode == 0) {
|
|
||||||
isLoginCompleted = true;
|
|
||||||
} else {
|
|
||||||
isLoginCompleted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
isLoginCompleted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查连接状态
|
|
||||||
*/
|
|
||||||
public boolean isConnected() {
|
|
||||||
return isConnected && isInitialized && isLoginCompleted && client != null && client.isConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送创建房间协议到robot_mj_cs
|
|
||||||
* @param groupId 群组ID
|
|
||||||
* @param wanfaId 玩法ID
|
|
||||||
* @return CompletableFuture<RoomInfo> 异步返回房间信息
|
|
||||||
*/
|
|
||||||
public CompletableFuture<RoomInfo> sendCreateRoomForRobot(int groupId, int wanfaId, int robotId) {
|
|
||||||
CompletableFuture<RoomInfo> future = new CompletableFuture<>();
|
|
||||||
|
|
||||||
if (!isConnected()) {
|
|
||||||
future.completeExceptionally(new RuntimeException("未连接到robot_mj_cs服务器"));
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
//构建请求参数
|
|
||||||
ITObject params = TObject.newInstance();
|
|
||||||
params.putInt("groupId", groupId);
|
|
||||||
params.putInt("wanfaId", wanfaId);
|
|
||||||
params.putInt("robotId", robotId);
|
|
||||||
|
|
||||||
//发送创建房间请求
|
|
||||||
client.send(Protocol.CREATE_ROOM_FOR_ROBOT, params, new ICallback<MessageResponse>() {
|
|
||||||
@Override
|
|
||||||
public void action(MessageResponse response) {
|
|
||||||
if (response.returnCode == 0 && response.messageData != null &&
|
|
||||||
response.messageData.param != null) {
|
|
||||||
//解析响应数据
|
|
||||||
ITObject responseData = response.messageData.param;
|
|
||||||
RoomInfo roomInfo = new RoomInfo();
|
|
||||||
|
|
||||||
//设置房间信息
|
|
||||||
roomInfo.setRoomId(responseData.getString("roomKey"));
|
|
||||||
roomInfo.setGroupId(responseData.getInt("groupId"));
|
|
||||||
roomInfo.setWanfaId(responseData.getInt("wanfaId"));
|
|
||||||
|
|
||||||
//获取游戏服务器地址和端口
|
|
||||||
if (responseData.containsKey("server_ip")) {
|
|
||||||
roomInfo.setGameServerHost(responseData.getString("server_ip"));
|
|
||||||
}
|
|
||||||
if (responseData.containsKey("server_port")) {
|
|
||||||
roomInfo.setGameServerPort(responseData.getInt("server_port"));
|
|
||||||
}
|
|
||||||
|
|
||||||
future.complete(roomInfo);
|
|
||||||
log.info("robot_mj_cs创建房间成功: " + roomInfo.getRoomId());
|
|
||||||
} else {
|
|
||||||
future.completeExceptionally(new RuntimeException("创建房间失败,错误码: " + response.returnCode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("发送创建房间协议时发生错误: " + e.getMessage());
|
|
||||||
future.completeExceptionally(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭连接
|
|
||||||
*/
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
//停止网络事件处理线程
|
|
||||||
if (eventThread != null) {
|
|
||||||
eventThread.interrupt();
|
|
||||||
try {
|
|
||||||
eventThread.join(2000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
log.warn("等待事件线程结束时被中断", e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
eventThread = null;
|
|
||||||
}
|
|
||||||
//关闭客户端连接
|
|
||||||
if (client != null) {
|
|
||||||
try {
|
|
||||||
client.killConnection();
|
|
||||||
log.debug("已关闭TCP客户端连接");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("关闭TCP客户端连接时发生异常", e);
|
|
||||||
} finally {
|
|
||||||
client = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//重置状态
|
|
||||||
isConnected = false;
|
|
||||||
isInitialized = false;
|
|
||||||
isLoginCompleted = false;
|
|
||||||
log.info("RobotMgrTcpClient连接已关闭");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("关闭RobotMgrTcpClient时发生异常", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,6 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.group.robot.info.RobotInfo;
|
import com.group.robot.info.RobotInfo;
|
||||||
import com.group.robot.info.RoomInfo;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,17 +16,19 @@ public class MaJiangRobotHandler implements RobotManagerInterface {
|
||||||
private final RobotConnectionHandler robotConnectionHandler;
|
private final RobotConnectionHandler robotConnectionHandler;
|
||||||
|
|
||||||
public MaJiangRobotHandler() {
|
public MaJiangRobotHandler() {
|
||||||
this.robotConnectionHandler = new RobotConnectionHandler();
|
this.robotConnectionHandler = RobotConnectionHandler.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connectRobot(RobotInfo robot, RoomInfo room) {
|
public void connectRobot(RobotInfo robot) {
|
||||||
try {
|
try {
|
||||||
log.info("麻将机器人 {} 正在连接到房间 {}", robot.getRobotId(), room.getRoomId());
|
|
||||||
//连接处理器进行连接
|
//连接处理器进行连接
|
||||||
robotConnectionHandler.connectRobot(robot, room);
|
robotConnectionHandler.connectRobot(robot);
|
||||||
|
|
||||||
|
//设置机器人连接状态
|
||||||
|
robot.setConnected(true);
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
log.error("麻将机器人 {} 连接房间 {} 时发生异常", robot.getRobotId(), room.getRoomId(), e);
|
log.error("麻将机器人 {} 连接游戏服务器时发生异常", robot.getRobotId(), e);
|
||||||
robot.setConnected(false);
|
robot.setConnected(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -41,9 +42,7 @@ public class MaJiangRobotHandler implements RobotManagerInterface {
|
||||||
robotConnectionHandler.disconnectRobot(robot.getRobotId());
|
robotConnectionHandler.disconnectRobot(robot.getRobotId());
|
||||||
|
|
||||||
robot.setConnected(false);
|
robot.setConnected(false);
|
||||||
robot.setCurrentRoomId(null);
|
|
||||||
robot.setCurrentWanfaId(0);
|
|
||||||
|
|
||||||
log.info("麻将机器人 {} 连接已断开", robot.getRobotId());
|
log.info("麻将机器人 {} 连接已断开", robot.getRobotId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("断开麻将机器人连接时发生错误: " + robot.getRobotId(), e);
|
log.error("断开麻将机器人连接时发生错误: " + robot.getRobotId(), e);
|
||||||
|
|
|
||||||
|
|
@ -17,24 +17,21 @@ public class PokerRobotHandler implements RobotManagerInterface {
|
||||||
private final RobotConnectionHandler connectionHandler;
|
private final RobotConnectionHandler connectionHandler;
|
||||||
|
|
||||||
public PokerRobotHandler() {
|
public PokerRobotHandler() {
|
||||||
this.connectionHandler = new RobotConnectionHandler();
|
this.connectionHandler = RobotConnectionHandler.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connectRobot(RobotInfo robot, RoomInfo room) {
|
public void connectRobot(RobotInfo robot) {
|
||||||
try {
|
try {
|
||||||
log.info("扑克机器人 {} 正在连接到房间 {}", robot.getRobotId(), room.getRoomId());
|
log.info("扑克机器人 {} 正在连接到房间 {}", robot.getRobotId(), robot.getRoomId());
|
||||||
|
|
||||||
//使用连接处理器进行连接
|
//使用连接处理器进行连接
|
||||||
connectionHandler.connectRobot(robot, room);
|
connectionHandler.connectRobot(robot);
|
||||||
|
|
||||||
// 设置机器人连接状态和房间信息
|
// 设置机器人连接状态和房间信息
|
||||||
robot.setConnected(true);
|
robot.setConnected(true);
|
||||||
robot.setCurrentWanfaId(room.getWanfaId());
|
|
||||||
robot.setCurrentRoomId(room.getRoomId());
|
log.info("扑克机器人 {} 开始连接到房间 {}, 玩法ID: {}", robot.getRobotId(), robot.getRoomId(), robot.getWanfaId());
|
||||||
|
|
||||||
log.info("扑克机器人 {} 开始连接到房间 {}, 玩法ID: {}",
|
|
||||||
robot.getRobotId(), room.getRoomId(), room.getWanfaId());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("扑克机器人连接失败: " + robot.getRobotId(), e);
|
log.error("扑克机器人连接失败: " + robot.getRobotId(), e);
|
||||||
}
|
}
|
||||||
|
|
@ -49,9 +46,6 @@ public class PokerRobotHandler implements RobotManagerInterface {
|
||||||
connectionHandler.disconnectRobot(robot.getRobotId());
|
connectionHandler.disconnectRobot(robot.getRobotId());
|
||||||
|
|
||||||
robot.setConnected(false);
|
robot.setConnected(false);
|
||||||
robot.setCurrentRoomId(null);
|
|
||||||
robot.setCurrentWanfaId(0);
|
|
||||||
|
|
||||||
log.info("扑克机器人 {} 连接已断开", robot.getRobotId());
|
log.info("扑克机器人 {} 连接已断开", robot.getRobotId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("断开扑克机器人连接时发生错误: " + robot.getRobotId(), e);
|
log.error("断开扑克机器人连接时发生错误: " + robot.getRobotId(), e);
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,31 @@
|
||||||
package com.group.robot.handler;
|
package com.group.robot.handler;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.group.robot.connect.RedisRoomListener;
|
import com.group.Protocol;
|
||||||
import com.group.robot.info.RobotInfo;
|
import com.group.robot.info.RobotInfo;
|
||||||
import com.group.robot.RobotManager;
|
import com.group.robot.RobotManager;
|
||||||
import com.group.robot.info.RoomInfo;
|
import com.group.robot.info.RoomInfo;
|
||||||
import com.taurus.core.entity.ITArray;
|
import com.group.robot.matcher.RoomWanfaMatcher;
|
||||||
import com.taurus.core.entity.TObject;
|
import com.taurus.core.entity.TObject;
|
||||||
import com.taurus.core.plugin.database.DataBase;
|
import com.taurus.core.util.ICallback;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import taurus.client.MessageResponse;
|
||||||
import taurus.client.SocketCode;
|
import taurus.client.SocketCode;
|
||||||
import taurus.client.TaurusClient;
|
import taurus.client.TaurusClient;
|
||||||
import taurus.client.Message;
|
import taurus.client.Message;
|
||||||
import taurus.client.business.AccountBusiness;
|
|
||||||
import taurus.client.business.GroupRoomBusiness;
|
|
||||||
import com.taurus.core.entity.ITObject;
|
import com.taurus.core.entity.ITObject;
|
||||||
import com.taurus.core.events.Event;
|
import com.taurus.core.events.Event;
|
||||||
import com.taurus.core.events.IEventListener;
|
import com.taurus.core.events.IEventListener;
|
||||||
import com.taurus.core.plugin.redis.Redis;
|
|
||||||
import com.taurus.core.util.StringUtil;
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机器人连接处理器 - 将机器人连接到游戏服务器并准备
|
* 机器人连接处理器 - 将机器人连接到游戏服务器并准备
|
||||||
*/
|
*/
|
||||||
public class RobotConnectionHandler {
|
public class RobotConnectionHandler {
|
||||||
|
private static volatile RobotConnectionHandler instance;
|
||||||
private static final Logger log = LoggerFactory.getLogger(RobotConnectionHandler.class);
|
private static final Logger log = LoggerFactory.getLogger(RobotConnectionHandler.class);
|
||||||
|
|
||||||
//机器人ID到客户端连接的映射
|
//机器人ID到客户端连接的映射
|
||||||
|
|
@ -81,54 +75,44 @@ public class RobotConnectionHandler {
|
||||||
public void setGameId(int gameId) { this.gameId = gameId; }
|
public void setGameId(int gameId) { this.gameId = gameId; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public RobotConnectionHandler() {
|
private RobotConnectionHandler() {
|
||||||
this.robotManager = RobotManager.getRobotManager();
|
this.robotManager = RobotManager.getRobotManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RobotConnectionHandler getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
synchronized (RobotConnectionHandler.class) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new RobotConnectionHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接机器人到指定房间并准备
|
* 连接机器人到游戏服务器
|
||||||
*/
|
*/
|
||||||
public void connectRobot(RobotInfo robot, RoomInfo room) {
|
public void connectRobot(RobotInfo robot) {
|
||||||
//异步执行连接逻辑
|
//异步执行连接逻辑
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
log.info("开始连接机器人 {} 到房间 {}, 玩法ID: {}", robot.getRobotId(), room.getRoomId(), room.getWanfaId());
|
log.info("开始连接机器人 {} 到游戏服务器,玩法ID: {}", robot.getRobotId(), robot.getWanfaId());
|
||||||
|
//TCP客户端连接
|
||||||
//获取机器人账户信息
|
TaurusClient client = new TaurusClient(getGameServerAddress(robot.getWanfaId()), "game", TaurusClient.ConnectionProtocol.Tcp);
|
||||||
RobotAccountInfo accountInfo = getRobotAccountInfo(robot.getRobotId(), room.getGroupId());
|
|
||||||
if (accountInfo == null) {
|
|
||||||
log.error("无法获取机器人 {} 的账户信息", robot.getRobotId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//根据玩法ID获取服务器地址
|
|
||||||
String serverAddress = getGameServerAddress(room.getWanfaId());
|
|
||||||
//创建TCP客户端连接
|
|
||||||
TaurusClient client = new TaurusClient(serverAddress, "game", TaurusClient.ConnectionProtocol.Tcp);
|
|
||||||
client.connect();
|
client.connect();
|
||||||
|
|
||||||
//保存客户端连接
|
//保存客户端连接
|
||||||
robotClients.put(robot.getRobotId(), client);
|
robotClients.put(robot.getRobotId(), client);
|
||||||
|
|
||||||
//设置事件监听器
|
//设置事件监听器
|
||||||
setupInitializationEventListeners(client, robot, room);
|
setupInitializationEventListeners(client, robot);
|
||||||
|
|
||||||
//登录并加入房间
|
//连接成功后发送初始化协议
|
||||||
Thread.sleep(5000);
|
sendInitializationProtocol(client, robot);
|
||||||
loginAndJoinRoom(accountInfo, room);
|
log.info("机器人 {} 成功连接到游戏服务器", robot.getRobotId());
|
||||||
|
|
||||||
//登录成功后
|
|
||||||
robotAccounts.put(robot.getRobotId(), accountInfo);
|
|
||||||
|
|
||||||
//发送准备请求
|
|
||||||
Thread.sleep(1000);
|
|
||||||
sendReadyRequest(client, accountInfo.getRobotId());
|
|
||||||
log.info("机器人 {} 成功连接到房间 {}", robot.getRobotId(), room.getRoomId());
|
|
||||||
|
|
||||||
//6秒没有玩家加入 则退出房间
|
|
||||||
readyTimeRobotExit(accountInfo.getRobotId(), room);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("连接机器人时发生异常: " + robot.getRobotId(), e);
|
log.error("连接机器人到游戏服务器时发生异常: " + robot.getRobotId(), e);
|
||||||
//清理已经建立的连接
|
//清理已经建立的连接
|
||||||
disconnectRobot(robot.getRobotId());
|
disconnectRobot(robot.getRobotId());
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +122,7 @@ public class RobotConnectionHandler {
|
||||||
/**
|
/**
|
||||||
* 设置初始化阶段的事件监听器
|
* 设置初始化阶段的事件监听器
|
||||||
*/
|
*/
|
||||||
private void setupInitializationEventListeners(TaurusClient client, RobotInfo robot, RoomInfo room) {
|
private void setupInitializationEventListeners(TaurusClient client, RobotInfo robot) {
|
||||||
//添加连接状态监听器
|
//添加连接状态监听器
|
||||||
client.addEventListener(TaurusClient.NetClientEvent.Connect, new IEventListener() {
|
client.addEventListener(TaurusClient.NetClientEvent.Connect, new IEventListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -175,74 +159,6 @@ public class RobotConnectionHandler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录并加入房间
|
|
||||||
*/
|
|
||||||
private void loginAndJoinRoom(RobotAccountInfo accountInfo, RoomInfo room) {
|
|
||||||
try {
|
|
||||||
//登录获取session和token
|
|
||||||
AccountBusiness accountBusiness = new AccountBusiness();
|
|
||||||
|
|
||||||
try (Jedis jedis0 = Redis.use().getJedis()){
|
|
||||||
//检查Redis中是否存在已有token
|
|
||||||
Set<String> tokenKeys = jedis0.keys("{user}:" + accountInfo.getRobotId() + "_token");
|
|
||||||
ITObject loginResult;
|
|
||||||
|
|
||||||
if (tokenKeys != null && !tokenKeys.isEmpty()) {
|
|
||||||
log.debug("机器人 {} 存在已有token,直接使用", accountInfo.getRobotId());
|
|
||||||
Set<String> tokenSet = jedis0.smembers("{user}:" + accountInfo.getRobotId() + "_token");
|
|
||||||
List<String> tokenList = new ArrayList<>(tokenSet);
|
|
||||||
|
|
||||||
accountInfo.setSession("{user}:" + accountInfo.getRobotId());
|
|
||||||
if (!tokenList.isEmpty()) {
|
|
||||||
accountInfo.setToken(tokenList.get(0));
|
|
||||||
} else {
|
|
||||||
//如果没有token 则执行正常登录
|
|
||||||
loginResult = accountBusiness.idPasswordLogin(accountInfo.getRobotId(), accountInfo.getPassword());
|
|
||||||
accountInfo.setToken(loginResult.getString("token"));
|
|
||||||
accountInfo.setSession(accountBusiness.getSession());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.debug("机器人 {} 执行常规登录", accountInfo.getRobotId());
|
|
||||||
//执行正常登录流程
|
|
||||||
loginResult = accountBusiness.idPasswordLogin(accountInfo.getRobotId(), accountInfo.getPassword());
|
|
||||||
accountInfo.setToken(loginResult.getString("token"));
|
|
||||||
accountInfo.setSession(accountBusiness.getSession());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//加入房间
|
|
||||||
GroupRoomBusiness.joinRoom(accountInfo.getGroupId(), room.getRoomId(), accountInfo.getSession(), null);
|
|
||||||
log.info("机器人 {} 已成功加入房间 {}", accountInfo.getRobotId(), room.getRoomId());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("登录并加入房间时发生异常", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送准备请求
|
|
||||||
*/
|
|
||||||
private void sendReadyRequest(TaurusClient client, int robotId) {
|
|
||||||
try {
|
|
||||||
//获取机器人的账户信息以获取session和token
|
|
||||||
RobotAccountInfo accountInfo = robotAccounts.get(robotId);
|
|
||||||
if (accountInfo == null) {
|
|
||||||
log.error("机器人 {} 的账户信息不存在,无法发送准备请求", robotId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (StringUtil.isEmpty(accountInfo.getSession()) || StringUtil.isEmpty(accountInfo.getToken())) {
|
|
||||||
log.error("机器人 {} 的session或token为空,无法发送准备请求", robotId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ITObject readyParam = new TObject();
|
|
||||||
readyParam.putString("session", accountInfo.getSession() + "," + accountInfo.getToken());
|
|
||||||
client.send("1003", readyParam, response -> {
|
|
||||||
log.debug("机器人 {} 发送准备请求响应: {}", robotId, response);
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("发送准备请求时发生异常", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据游戏ID获取服务器地址
|
* 根据游戏ID获取服务器地址
|
||||||
*/
|
*/
|
||||||
|
|
@ -250,11 +166,9 @@ public class RobotConnectionHandler {
|
||||||
//根据玩法ID返回对应的服务器地址
|
//根据玩法ID返回对应的服务器地址
|
||||||
switch (wanfaId) {
|
switch (wanfaId) {
|
||||||
case 10: //长沙麻将
|
case 10: //长沙麻将
|
||||||
return "127.0.0.1:6311";
|
return "127.0.0.1:8701";
|
||||||
case 22: //红中麻将
|
case 22: //红中麻将
|
||||||
return "8.138.242.190:6421";
|
return "8.138.242.190:6421";
|
||||||
case 108: //转转麻将
|
|
||||||
return "8.138.242.190:6841";
|
|
||||||
case 66: //跑得快
|
case 66: //跑得快
|
||||||
return "8.138.242.190:6841";
|
return "8.138.242.190:6841";
|
||||||
default:
|
default:
|
||||||
|
|
@ -263,53 +177,6 @@ public class RobotConnectionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取机器人信息
|
|
||||||
*/
|
|
||||||
private RobotAccountInfo getRobotAccountInfo(int robotId, int groupId) {
|
|
||||||
try {
|
|
||||||
//获取机器人信息
|
|
||||||
String sql = String.format("SELECT id,acc,nick,portrait,password FROM `account` WHERE id = %d", robotId);
|
|
||||||
ITArray robotArray = DataBase.use().executeQueryByTArray(sql);
|
|
||||||
|
|
||||||
if (robotArray.size() == 0) {
|
|
||||||
//数据库中没有 从Redis获取信息
|
|
||||||
Jedis jedis = Redis.use("group1_db2").getJedis();
|
|
||||||
try {
|
|
||||||
Map<String, String> robotData = jedis.hgetAll("{robot}:" + robotId);
|
|
||||||
if (robotData.isEmpty()) {
|
|
||||||
log.error("未找到机器人ID {} 的信息", robotId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String account = robotData.get("acc");
|
|
||||||
String password = robotData.get("password");
|
|
||||||
|
|
||||||
if (StringUtil.isEmpty(account) || StringUtil.isEmpty(password)) {
|
|
||||||
log.error("机器人 {} 的信息不完整", robotId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RobotAccountInfo(robotId, account, password, groupId);
|
|
||||||
} finally {
|
|
||||||
jedis.close();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//数据库获取信息
|
|
||||||
ITObject robotObj = robotArray.getTObject(0);
|
|
||||||
|
|
||||||
int id = robotObj.getInt("id");
|
|
||||||
String account = robotObj.getString("acc");
|
|
||||||
String password = robotObj.getString("password");
|
|
||||||
|
|
||||||
return new RobotAccountInfo(id, account, password, groupId);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("获取机器人账户时发生异常: " + robotId, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 断开机器人连接
|
* 断开机器人连接
|
||||||
*/
|
*/
|
||||||
|
|
@ -339,68 +206,128 @@ public class RobotConnectionHandler {
|
||||||
/**
|
/**
|
||||||
* 超时检查 6秒没有玩家加入 则退出房间
|
* 超时检查 6秒没有玩家加入 则退出房间
|
||||||
*/
|
*/
|
||||||
private void readyTimeRobotExit(int robotId, RoomInfo room) {
|
public void readyTimeRobotExit(RobotInfo robot) {
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(6000);
|
Thread.sleep(6000);
|
||||||
//检查房间内是否只有机器人
|
log.info("机器人 {} 准备时间超过6秒且房间人数不足,退出房间", robot.getRobotId());
|
||||||
if (ifExitRoom(room)) {
|
TaurusClient client = robotClients.get(robot.getRobotId());
|
||||||
log.info("机器人 {} 准备时间超过6秒且房间人数不足,退出房间", robotId);
|
|
||||||
//获取客户端连接
|
if (client != null && client.isConnected()) {
|
||||||
TaurusClient client = robotClients.remove(robotId);
|
//发送离开房间协议
|
||||||
if (client != null) {
|
ITObject param = new TObject();
|
||||||
//发送离开房间协议
|
client.send("1005", param, response -> {
|
||||||
ITObject param = new TObject();
|
log.debug("机器人 {} 发送离开房间请求", robot.getRobotId());
|
||||||
client.send("1005", param, response -> {
|
});
|
||||||
log.debug("机器人 {} 发送离开房间请求", robotId);
|
} else {
|
||||||
});
|
log.warn("机器人 {} 连接不存在或未激活,跳过离开房间操作", robot.getRobotId());
|
||||||
//关闭连接
|
|
||||||
client.clearResponse();
|
|
||||||
}
|
|
||||||
//延迟后断开连接
|
|
||||||
Thread.sleep(1000);
|
|
||||||
disconnectRobot(robotId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//延迟后断开连接
|
||||||
|
Thread.sleep(1000);
|
||||||
|
disconnectRobot(robot.getRobotId());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
log.debug("超时检查线程被中断: {}", robotId);
|
log.debug("超时检查线程被中断: {}", robot.getRobotId());
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("超时检查过程中发生异常", e);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否退出房间
|
* 发送初始化协议
|
||||||
*/
|
*/
|
||||||
private boolean ifExitRoom(RoomInfo room) {
|
private void sendInitializationProtocol(TaurusClient client, RobotInfo robot) {
|
||||||
try {
|
if (client == null || !client.isConnected()) {
|
||||||
Jedis jedis0 = Redis.use().getJedis();
|
log.warn("机器人 {} 没有有效的TCP连接,无法发送初始化协议", robot.getRobotId());
|
||||||
try {
|
return;
|
||||||
String players = jedis0.hget(room.getRoomId(), "players");
|
|
||||||
if (players != null && !players.equals("[]")) {
|
|
||||||
Integer robotInRoom = RedisRoomListener.hasRobotInPlayerList(players);
|
|
||||||
|
|
||||||
//计算房间总人数
|
|
||||||
String playersClean = players.substring(1, players.length() - 1);
|
|
||||||
String[] playerIds = playersClean.split(",");
|
|
||||||
int totalPlayers = 0;
|
|
||||||
for (String playerIdStr : playerIds) {
|
|
||||||
playerIdStr = playerIdStr.trim();
|
|
||||||
if (!playerIdStr.isEmpty()) {
|
|
||||||
totalPlayers++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//如果机器人在房间中 且房间总人数小于2人 则退出房间
|
|
||||||
return robotInRoom != null && totalPlayers < 2;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
jedis0.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("检查房间玩家数量时发生异常", e);
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
ITObject param = new TObject();
|
||||||
|
param.putString("type", "manager_connection");
|
||||||
|
param.putString("client", "robot_mgr");
|
||||||
|
param.putString("session", robot.getSession() + "," + robot.getToken());
|
||||||
|
client.send("init_connection", param, response -> {
|
||||||
|
if (response != null && response.returnCode == 0) {
|
||||||
|
log.info("机器人 {} 初始化协议发送成功", robot.getRobotId());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送准备消息给指定机器人
|
||||||
|
*/
|
||||||
|
public void sendReadyMessage(RobotInfo robot) {
|
||||||
|
TaurusClient client = robotClients.get(robot.getRobotId());
|
||||||
|
|
||||||
|
if (client == null || !client.isConnected()) {
|
||||||
|
log.warn("机器人 {} 没有有效的TCP连接,无法发送准备消息", robot.getRobotId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ITObject readyParam = new TObject();
|
||||||
|
readyParam.putString("session", robot.getSession() + "," + robot.getToken());
|
||||||
|
client.send("1003", readyParam, response -> {
|
||||||
|
log.debug("机器人 {} 发送准备请求响应: {}", robot.getRobotId(), response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调接口
|
||||||
|
*/
|
||||||
|
public interface RoomCreatedCallback {
|
||||||
|
void onRoomCreated(RobotInfo robot, int groupId, String roomId, int wanfaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RoomCreatedCallback roomCreatedCallback;
|
||||||
|
|
||||||
|
public void setRoomCreatedCallback(RoomCreatedCallback callback) {
|
||||||
|
this.roomCreatedCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送创建房间请求
|
||||||
|
*/
|
||||||
|
public void sendCreateRoom(RobotInfo robot, int groupId, int wanfaId) {
|
||||||
|
CompletableFuture<RoomInfo> future = new CompletableFuture<>();
|
||||||
|
TaurusClient client = robotClients.get(robot.getRobotId());
|
||||||
|
if (!client.isConnected()) {
|
||||||
|
log.warn("机器人 {} 的TCP连接未激活,无法发送创建房间请求", robot.getRobotId());
|
||||||
|
robotClients.remove(robot.getRobotId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ITObject param = new TObject();
|
||||||
|
param.putInt("groupId", groupId);
|
||||||
|
param.putInt("wanfaId", wanfaId);
|
||||||
|
param.putInt("robotId", robot.getRobotId());
|
||||||
|
param.putString("session", robot.getSession() + "," + robot.getToken());
|
||||||
|
client.send(Protocol.CREATE_ROOM_FOR_ROBOT, param, response -> {
|
||||||
|
if (response != null && response.returnCode == 0) {
|
||||||
|
ITObject responseData = response.messageData.param;
|
||||||
|
String roomId = responseData.getString("roomKey");
|
||||||
|
log.info("机器人 {} 成功创建房间 {}", robot.getRobotId(), roomId);
|
||||||
|
if (roomCreatedCallback != null) {
|
||||||
|
roomCreatedCallback.onRoomCreated(robot, groupId, roomId, wanfaId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*client.send(Protocol.CREATE_ROOM_FOR_ROBOT, param, new ICallback<MessageResponse>() {
|
||||||
|
@Override
|
||||||
|
public void action(MessageResponse response) {
|
||||||
|
if (response.returnCode == 0) {
|
||||||
|
//解析响应数据
|
||||||
|
ITObject responseData = response.messageData.param;
|
||||||
|
RoomInfo roomInfo = new RoomInfo();
|
||||||
|
|
||||||
|
//RoomWanfaMatcher.robotJoinRoom(groupId, responseData.getString("roomKey"), wanfaId, true);
|
||||||
|
|
||||||
|
future.complete(roomInfo);
|
||||||
|
log.info("robot_mj_cs创建房间成功: " + roomInfo.getRoomId());
|
||||||
|
} else {
|
||||||
|
future.completeExceptionally(new RuntimeException("创建房间失败,错误码: " + response.returnCode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -12,9 +12,11 @@ public class RobotInfo {
|
||||||
private boolean isOnline; //是否在线
|
private boolean isOnline; //是否在线
|
||||||
private boolean isConnected; //是否已连接到游戏服务器
|
private boolean isConnected; //是否已连接到游戏服务器
|
||||||
private boolean isConnecting; //是否正在连接
|
private boolean isConnecting; //是否正在连接
|
||||||
private String currentRoomId; //当前所在房间ID
|
private String roomId; //当前所在房间ID
|
||||||
private int currentWanfaId; //当前玩法ID
|
private int wanfaId; //当前玩法ID
|
||||||
private long lastActiveTime; //最后活跃时间
|
private long lastActiveTime; //最后活跃时间
|
||||||
|
private String session;
|
||||||
|
private String token;
|
||||||
|
|
||||||
public RobotInfo() {
|
public RobotInfo() {
|
||||||
this.lastActiveTime = System.currentTimeMillis();
|
this.lastActiveTime = System.currentTimeMillis();
|
||||||
|
|
@ -83,23 +85,23 @@ public class RobotInfo {
|
||||||
public void setConnecting(boolean connecting) {
|
public void setConnecting(boolean connecting) {
|
||||||
isConnecting = connecting;
|
isConnecting = connecting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrentRoomId() {
|
public String getRoomId() {
|
||||||
return currentRoomId;
|
return roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentRoomId(String currentRoomId) {
|
public void setRoomId(String roomId) {
|
||||||
this.currentRoomId = currentRoomId;
|
this.roomId = roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentWanfaId() {
|
public int getWanfaId() {
|
||||||
return currentWanfaId;
|
return wanfaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentWanfaId(int currentWanfaId) {
|
public void setWanfaId(int wanfaId) {
|
||||||
this.currentWanfaId = currentWanfaId;
|
this.wanfaId = wanfaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastActiveTime() {
|
public long getLastActiveTime() {
|
||||||
return lastActiveTime;
|
return lastActiveTime;
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +109,24 @@ public class RobotInfo {
|
||||||
public void setLastActiveTime(long lastActiveTime) {
|
public void setLastActiveTime(long lastActiveTime) {
|
||||||
this.lastActiveTime = lastActiveTime;
|
this.lastActiveTime = lastActiveTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RobotInfo{" +
|
return "RobotInfo{" +
|
||||||
|
|
@ -115,8 +134,11 @@ public class RobotInfo {
|
||||||
", account='" + account + '\'' +
|
", account='" + account + '\'' +
|
||||||
", isOnline=" + isOnline +
|
", isOnline=" + isOnline +
|
||||||
", isConnected=" + isConnected +
|
", isConnected=" + isConnected +
|
||||||
", currentRoomId='" + currentRoomId + '\'' +
|
", roomId='" + roomId + '\'' +
|
||||||
", currentWanfaId=" + currentWanfaId +
|
", wanfaId=" + wanfaId +
|
||||||
|
", lastActiveTime=" + lastActiveTime +
|
||||||
|
", session='" + session + '\'' +
|
||||||
|
", token='" + token + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,271 @@
|
||||||
|
package com.group.robot.matcher;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.group.robot.RobotManager;
|
||||||
|
import com.group.robot.handler.RobotConnectionHandler;
|
||||||
|
import com.group.robot.info.RobotInfo;
|
||||||
|
import com.taurus.core.entity.ITArray;
|
||||||
|
import com.taurus.core.entity.ITObject;
|
||||||
|
import com.taurus.core.plugin.database.DataBase;
|
||||||
|
import com.taurus.core.plugin.redis.Redis;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
import taurus.client.business.GroupRoomBusiness;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 玩法房间轮询器 - 按玩法定期查询房间
|
||||||
|
*/
|
||||||
|
public class RoomWanfaMatcher {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RoomWanfaMatcher.class);
|
||||||
|
|
||||||
|
private final RobotManager robotManager;
|
||||||
|
private final int groupId;
|
||||||
|
private final int wanfaId;
|
||||||
|
private final Object lock = new Object();
|
||||||
|
private volatile ScheduledExecutorService scheduler;
|
||||||
|
private volatile boolean isRunning = false;
|
||||||
|
//机器人连接处理器
|
||||||
|
private final RobotConnectionHandler robotConnectionHandler;
|
||||||
|
|
||||||
|
public RoomWanfaMatcher(RobotManager robotManager, int groupId, int wanfaId) {
|
||||||
|
this.robotManager = robotManager;
|
||||||
|
this.groupId = groupId;
|
||||||
|
this.wanfaId = wanfaId;
|
||||||
|
this.scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
this.robotConnectionHandler = RobotConnectionHandler.getInstance();
|
||||||
|
|
||||||
|
//设置房间创建回调
|
||||||
|
this.robotConnectionHandler.setRoomCreatedCallback(this::onRoomCreated);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动轮询
|
||||||
|
*/
|
||||||
|
public void startPolling() {
|
||||||
|
synchronized(lock) {
|
||||||
|
if (isRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheduler == null || scheduler.isShutdown()) {
|
||||||
|
scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
isRunning = true;
|
||||||
|
log.info("开始为玩法ID {} 启动房间轮询", wanfaId);
|
||||||
|
|
||||||
|
//10秒轮询一次
|
||||||
|
scheduler.scheduleWithFixedDelay(this::pollRooms, 0, 10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮询房间
|
||||||
|
*/
|
||||||
|
private void pollRooms() {
|
||||||
|
try {
|
||||||
|
if (!isRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Jedis jedis0 = Redis.use().getJedis(); Jedis jedis11 = Redis.use("group1_db11").getJedis()) {
|
||||||
|
Set<String> roomIds = jedis0.keys("room:*");
|
||||||
|
if (roomIds.isEmpty()) {
|
||||||
|
createRobotWanfaRoomTCP(groupId, this.wanfaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
int groupId = -1;
|
||||||
|
|
||||||
|
for (String roomId : roomIds) {
|
||||||
|
int wanfaId = Integer.parseInt(jedis0.hget(roomId, "gpid"));
|
||||||
|
if (wanfaId == this.wanfaId) {
|
||||||
|
groupId = Integer.parseInt(jedis0.hget(roomId, "group"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupId != -1) {
|
||||||
|
//检查该玩法是否配置了机器人
|
||||||
|
String playKey = "g{" + groupId + "}:play:" + this.wanfaId;
|
||||||
|
int leftoverRobot = Integer.parseInt(jedis11.hget(playKey, "leftover_robot"));
|
||||||
|
|
||||||
|
if (leftoverRobot > 0) {
|
||||||
|
//满人房间
|
||||||
|
int fullRooms = 0;
|
||||||
|
//所有房间
|
||||||
|
int totalRooms = 0;
|
||||||
|
List<String> roomsList = new ArrayList<>();
|
||||||
|
|
||||||
|
//统计所有2人房间
|
||||||
|
for (String roomId : roomIds) {
|
||||||
|
int currentWanfaId = Integer.parseInt(jedis0.hget(roomId, "gpid"));
|
||||||
|
int status = Integer.parseInt(jedis0.hget(roomId, "status"));
|
||||||
|
int maxPlayers = Integer.parseInt(jedis0.hget(roomId, "maxPlayers"));
|
||||||
|
|
||||||
|
//处理当前玩法maxPlayers为2的房间
|
||||||
|
if (maxPlayers == 2 && currentWanfaId == this.wanfaId && status == 0) {
|
||||||
|
totalRooms++;
|
||||||
|
|
||||||
|
String playersStr = jedis0.hget(roomId, "players");
|
||||||
|
int currentPlayers = 0;
|
||||||
|
if (!playersStr.equals("[]")) {
|
||||||
|
String playersClean = playersStr.substring(1, playersStr.length() - 1);
|
||||||
|
if (!playersClean.isEmpty()) {
|
||||||
|
String[] playerIds = playersClean.split(",");
|
||||||
|
currentPlayers = playerIds.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentPlayers == maxPlayers) {
|
||||||
|
fullRooms++;
|
||||||
|
} else {
|
||||||
|
roomsList.add(roomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//该玩法机器人房间满了 创建新房间
|
||||||
|
if (fullRooms == totalRooms && totalRooms > 0) {
|
||||||
|
createRobotWanfaRoomTCP(groupId, this.wanfaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String roomId : roomsList) {
|
||||||
|
int group = Integer.parseInt(jedis0.hget(roomId, "group"));
|
||||||
|
int status = Integer.parseInt(jedis0.hget(roomId, "status"));
|
||||||
|
|
||||||
|
//处理未开始的陪打房间
|
||||||
|
if (status == 0) {
|
||||||
|
String playersStr = jedis0.hget(roomId, "players");
|
||||||
|
|
||||||
|
//房间没人 加入房间
|
||||||
|
if (playersStr.equals("[]")) {
|
||||||
|
robotJoinRoom(group, roomId, this.wanfaId, true);
|
||||||
|
} else {
|
||||||
|
//房间有人 不是机器人则加入房间
|
||||||
|
Integer robotInRoom = playerIsRobotRedis(playersStr);
|
||||||
|
if (robotInRoom == null) {
|
||||||
|
robotJoinRoom(group, roomId, this.wanfaId, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) { // 捕获所有Throwable,包括Error
|
||||||
|
log.error("轮询玩法ID {} 的房间时发生严重错误", wanfaId, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机器人加入房间
|
||||||
|
* */
|
||||||
|
private void robotJoinRoom(int group, String roomId, int wanfaId, boolean isRobot) {
|
||||||
|
//检查调度器是否可用
|
||||||
|
if (!scheduler.isShutdown()) {
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
RobotInfo robot = robotManager.getLoggedInRobotForWanfa(wanfaId);
|
||||||
|
//加入房间
|
||||||
|
GroupRoomBusiness.joinRoom(group, roomId, robot.getSession(), null);
|
||||||
|
|
||||||
|
//准备
|
||||||
|
Thread.sleep(1000);
|
||||||
|
robotConnectionHandler.sendReadyMessage(robot);
|
||||||
|
|
||||||
|
if (isRobot) {
|
||||||
|
//6秒没有玩家加入 则退出房间
|
||||||
|
robotConnectionHandler.readyTimeRobotExit(robot);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("机器人加入房间时发生错误: groupId={}, roomId={}, wanfaId={}, isRobot={}", group, roomId, wanfaId, isRobot, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过TCP服务为指定群组和玩法创建房间
|
||||||
|
*/
|
||||||
|
private void createRobotWanfaRoomTCP(int groupId, int wanfaId) {
|
||||||
|
try {
|
||||||
|
RobotInfo robot = robotManager.getLoggedInRobotForWanfa(wanfaId);
|
||||||
|
if (robot == null) {
|
||||||
|
log.warn("未能获取到玩法ID {} 的已登录机器人", wanfaId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//使用机器人连接处理器发送创建房间请求
|
||||||
|
robotConnectionHandler.sendCreateRoom(robot, groupId, wanfaId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建玩法ID {} 的房间时发生错误", wanfaId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 房间创建成功后的回调方法
|
||||||
|
*/
|
||||||
|
private void onRoomCreated(RobotInfo robot, int groupId, String roomId, int wanfaId) {
|
||||||
|
//加入新创建的房间
|
||||||
|
robotJoinRoom(groupId, roomId, wanfaId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家列表中是否包含机器人
|
||||||
|
*/
|
||||||
|
public static Integer playerIsRobotRedis(String playersStr) {
|
||||||
|
String playersClean = playersStr.substring(1, playersStr.length() - 1);
|
||||||
|
String[] playerIds = playersClean.split(",");
|
||||||
|
|
||||||
|
for (String playerIdStr : playerIds) {
|
||||||
|
try {
|
||||||
|
int playerId = Integer.parseInt(playerIdStr.trim());
|
||||||
|
//检查是否为机器人账户(jiqiren=9998)
|
||||||
|
String checkSql = String.format("SELECT jiqiren FROM `account` WHERE id = %d", playerId);
|
||||||
|
ITArray checkArray = DataBase.use().executeQueryByTArray(checkSql);
|
||||||
|
|
||||||
|
if (checkArray.size() > 0) {
|
||||||
|
ITObject checkObj = checkArray.getTObject(0);
|
||||||
|
int jiqiren = checkObj.getInt("jiqiren");
|
||||||
|
if (jiqiren == 9998) { //是机器人
|
||||||
|
return playerId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("检查玩家是否为机器人时发生错误: {}", playerIdStr, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止轮询
|
||||||
|
*/
|
||||||
|
public void stopPolling() {
|
||||||
|
synchronized(lock) {
|
||||||
|
isRunning = false;
|
||||||
|
if (scheduler != null && !scheduler.isShutdown()) {
|
||||||
|
scheduler.shutdown();
|
||||||
|
try {
|
||||||
|
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("玩法ID {} 的房间轮询已停止", wanfaId);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -75,27 +75,27 @@ public class RoomCreator {
|
||||||
Map<String, String> roomMap = new HashMap<>();
|
Map<String, String> roomMap = new HashMap<>();
|
||||||
|
|
||||||
//基础房间信息
|
//基础房间信息
|
||||||
roomMap.put("id", newRoomId); //房间ID
|
|
||||||
roomMap.put("owner", "{user}:" + robotId); //房间所有者
|
|
||||||
roomMap.put("AA", "0"); //AA支付标志
|
roomMap.put("AA", "0"); //AA支付标志
|
||||||
roomMap.put("pay", gameInfo.getOrDefault("pay", "0")); //支付金额
|
|
||||||
roomMap.put("agent", "1"); //代理标志
|
roomMap.put("agent", "1"); //代理标志
|
||||||
roomMap.put("group", String.valueOf(groupId)); //群组ID
|
|
||||||
roomMap.put("gpid", String.valueOf(wanfaId)); //玩法ID
|
|
||||||
roomMap.put("payer", String.valueOf(robotId)); //支付者ID
|
|
||||||
roomMap.put("maxPlayers", gameInfo.getOrDefault("maxPlayers", "4")); //最大玩家数
|
|
||||||
roomMap.put("times", gameInfo.getOrDefault("times", "8")); //局数
|
|
||||||
roomMap.put("opt", playConfig.getOrDefault("opt", "1")); //选项
|
|
||||||
roomMap.put("status", "0"); //房间状态
|
|
||||||
roomMap.put("hpOnOff", playConfig.getOrDefault("hpOnOff", "0")); //体力开关
|
|
||||||
roomMap.put("rewardType", playConfig.getOrDefault("rewardType", "0")); //奖励类型
|
|
||||||
roomMap.put("rewardValueType", playConfig.getOrDefault("rewardValueType", "0")); //奖励值类型
|
|
||||||
roomMap.put("xipai_rewardType", playConfig.getOrDefault("xipai_rewardType", "0")); //洗牌奖励类型
|
|
||||||
roomMap.put("xipai_rewardValueType", playConfig.getOrDefault("xipai_rewardValueType", "0")); //洗牌奖励值类型
|
|
||||||
roomMap.put("dismiss_time", "30"); //解散时间
|
roomMap.put("dismiss_time", "30"); //解散时间
|
||||||
roomMap.put("kick_time", "60"); //踢出时间
|
roomMap.put("gpid", String.valueOf(wanfaId)); //玩法ID
|
||||||
roomMap.put("hp_times", playConfig.getOrDefault("hp_times", "1")); //体力次数
|
roomMap.put("group", String.valueOf(groupId)); //群组ID
|
||||||
|
roomMap.put("hpOnOff", "1"); //体力开关
|
||||||
|
roomMap.put("hp_times", "1000"); //体力次数
|
||||||
|
roomMap.put("id", newRoomId); //房间ID
|
||||||
|
roomMap.put("kick_time", "30"); //踢出时间
|
||||||
|
roomMap.put("owner", "{user}:" + robotId); //房间所有者
|
||||||
|
roomMap.put("maxPlayers", "2"); //最大玩家数
|
||||||
|
roomMap.put("opt", "2"); //选项
|
||||||
|
roomMap.put("pay", "0"); //支付金额
|
||||||
|
roomMap.put("payer", String.valueOf(robotId)); //支付者ID
|
||||||
|
roomMap.put("rewardType", "0"); //奖励类型
|
||||||
|
roomMap.put("rewardValueType", "0"); //奖励值类型
|
||||||
|
roomMap.put("status", "0"); //房间状态
|
||||||
|
roomMap.put("times", "4"); //局数
|
||||||
|
roomMap.put("xipai_rewardType", "3"); //洗牌奖励类型
|
||||||
|
roomMap.put("xipai_rewardValueType", "1"); //洗牌奖励值类型
|
||||||
|
|
||||||
//如果有体力配置
|
//如果有体力配置
|
||||||
String hpConfig = playConfig.get("hpConfig");
|
String hpConfig = playConfig.get("hpConfig");
|
||||||
if (hpConfig != null) {
|
if (hpConfig != null) {
|
||||||
|
|
@ -236,20 +236,24 @@ public class RoomCreator {
|
||||||
String groupKey = "group:" + groupId;
|
String groupKey = "group:" + groupId;
|
||||||
|
|
||||||
Map<String, String> defaultGroupInfo = new HashMap<>();
|
Map<String, String> defaultGroupInfo = new HashMap<>();
|
||||||
defaultGroupInfo.put("id", String.valueOf(groupId));
|
|
||||||
defaultGroupInfo.put("name", "机器人专用群组-" + groupId);
|
|
||||||
defaultGroupInfo.put("owner", "999999"); //使用机器人系统账户ID
|
|
||||||
defaultGroupInfo.put("type", "1"); //普通群组类型
|
|
||||||
defaultGroupInfo.put("pay_type", "1"); //房主支付
|
|
||||||
defaultGroupInfo.put("opt", "1"); //开启状态
|
|
||||||
defaultGroupInfo.put("ban", "0"); //未禁用
|
defaultGroupInfo.put("ban", "0"); //未禁用
|
||||||
defaultGroupInfo.put("dissolve_opt", "1"); //解散选项
|
|
||||||
defaultGroupInfo.put("kick_opt", "1"); //踢人选项
|
|
||||||
defaultGroupInfo.put("ban_apply", "0"); //不禁止申请
|
defaultGroupInfo.put("ban_apply", "0"); //不禁止申请
|
||||||
|
defaultGroupInfo.put("ban_chat1", "false");
|
||||||
|
defaultGroupInfo.put("ban_chat2", "false");
|
||||||
defaultGroupInfo.put("create_time", String.valueOf(System.currentTimeMillis() / 1000));
|
defaultGroupInfo.put("create_time", String.valueOf(System.currentTimeMillis() / 1000));
|
||||||
defaultGroupInfo.put("gms", "1"); //成员数
|
defaultGroupInfo.put("dissolve_opt", "1"); //解散选项
|
||||||
|
defaultGroupInfo.put("exit_opt", "0");
|
||||||
|
defaultGroupInfo.put("gms", "19");
|
||||||
|
defaultGroupInfo.put("id", String.valueOf(groupId));
|
||||||
|
defaultGroupInfo.put("kick_opt", "1"); //踢人选项
|
||||||
|
defaultGroupInfo.put("name", "机器人专用群组-" + groupId);
|
||||||
|
defaultGroupInfo.put("notice", "");
|
||||||
|
defaultGroupInfo.put("opt", "1"); //开启状态
|
||||||
defaultGroupInfo.put("option", "0"); //选项
|
defaultGroupInfo.put("option", "0"); //选项
|
||||||
|
defaultGroupInfo.put("owner", "999999"); //使用机器人系统账户ID
|
||||||
|
defaultGroupInfo.put("pay_type", "1"); //房主支付
|
||||||
|
defaultGroupInfo.put("type", "2"); //普通群组类型
|
||||||
|
|
||||||
jedis11.hmset(groupKey, defaultGroupInfo);
|
jedis11.hmset(groupKey, defaultGroupInfo);
|
||||||
|
|
||||||
log.info("成功创建默认群组信息,键名: {}", groupKey);
|
log.info("成功创建默认群组信息,键名: {}", groupKey);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue