package robot.mj;

import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.events.Event;
import com.taurus.core.events.IEventListener;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.ICallback;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import robot.mj.business.AccountBusiness;
import robot.mj.info.RobotUser;
import robot.mj.thread.ThreadPoolConfig;
import taurus.client.Message;
import taurus.client.MessageResponse;
import taurus.client.TaurusClient;
import taurus.client.SocketCode;
import redis.clients.jedis.Jedis;
import robot.mj.handler.HuNanChangSha;
import taurus.util.ROBOTEventType;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static robot.mj.thread.ThreadPoolConfig.getBusinessThreadPool;
import static robot.mj.thread.ThreadPoolConfig.scheduleDelay;

import static robot.mj.EXGameController.robotRoomMapping;

/**
 * 机器人连接管理器 - 管理与游戏服务器的连接
 */
public class RobotConnectionManager {

    private Logger log = Logger.getLogger(RobotConnectionManager.class);
    private static final Map<String, HuNanChangSha> huNanChangShaInstances = new ConcurrentHashMap<>();
    private final EXGameController exGameController;

    private final String host= Config.GAME_SERVER_HOST;
    private final int port= Integer.parseInt(Config.GAME_SERVER_PORT);

    /*长沙麻将游戏算法相关 start*/
    private final Map<String, Map<Integer, List<Integer>>> playerOutcardsMapByConn = new ConcurrentHashMap<>();
    private final Map<String, Map<Integer, List<Integer>>> playerchisMapByConn = new ConcurrentHashMap<>();
    private final Map<String, Map<Integer, List<Integer>>> playerpengsMapByConn = new ConcurrentHashMap<>();
    private final Map<String, Map<Integer, List<Integer>>> playermingsMapByConn = new ConcurrentHashMap<>();
    private final Map<String, Map<Integer, List<Integer>>> playerzisMapByConn = new ConcurrentHashMap<>();

    private Map<Integer, List<Integer>> getPlayerOutcardsMap(String connecId) {
        return playerOutcardsMapByConn.computeIfAbsent(connecId, k -> new ConcurrentHashMap<>());
    }
    private Map<Integer, List<Integer>> getPlayerchisMap(String connecId) {
        return playerchisMapByConn.computeIfAbsent(connecId, k -> new ConcurrentHashMap<>());
    }
    private Map<Integer, List<Integer>> getPlayerpengsMap(String connecId) {
        return playerpengsMapByConn.computeIfAbsent(connecId, k -> new ConcurrentHashMap<>());
    }
    private Map<Integer, List<Integer>> getPlayermingsMap(String connecId) {
        return playermingsMapByConn.computeIfAbsent(connecId, k -> new ConcurrentHashMap<>());
    }
    private Map<Integer, List<Integer>> getPlayerzisMap(String connecId) {
        return playerzisMapByConn.computeIfAbsent(connecId, k -> new ConcurrentHashMap<>());
    }
    private int pid = 0;
    private Map<Integer, Integer> count = new HashMap<Integer, Integer>();
    /*长沙麻将游戏算法相关 end*/




    public RobotConnectionManager() {
        exGameController = new EXGameController();
    }

    /**
     * 获取长沙麻将处理器实例
     */
    private HuNanChangSha getHuNanChangShaInstance(String connecId) {
        HuNanChangSha existingInstance = huNanChangShaInstances.get(connecId);
        if (existingInstance != null) {
            return existingInstance;
        }

        HuNanChangSha newInstance = new HuNanChangSha();
        
        //从Redis恢复状态
        boolean restored = newInstance.restoreFromRedis(connecId);
        if (restored) {
            System.out.println("从Redis恢复HuNanChangSha实例: " + connecId);
        } else {
            System.out.println("创建新的HuNanChangSha实例: " + connecId);
        }
        
        huNanChangShaInstances.put(connecId, newInstance);
        System.out.println("当前HuNanChangSha实例总数: " + huNanChangShaInstances.size());
        return newInstance;
    }

    /**
     * 设置会话和令牌
     */
    public void setSessionAndToken(String session, String token, String connecId) {
        HuNanChangSha instance = getHuNanChangShaInstance(connecId);
        instance.session = session;
        instance.token = token;
    }

    /**
     * 连接到长沙麻将游戏服务器
     */
    public TaurusClient connectToGameServer(String connecId) {
        try {
            //创建Taurus客户端
            TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);

            //设置事件监听器
            setupEventListeners(client, connecId);

            client.connect();

            return client;
        } catch (Exception e) {
            log.error("连接到游戏服务器时发生异常", e);
            return null;
        }
    }

    /**
     * 断开与游戏服务器的连接（主动断开）
     */
    public void disconnectFromGameServer(String connecId) {
        System.out.println("开始主动断开连接: {"+connecId+"}");
        RobotUser robotUser = robotRoomMapping.remove(connecId);

        //清理连接数据
        if (connecId != null) {
            HuNanChangSha.removeFromRedis(connecId);
            
            HuNanChangSha instance = huNanChangShaInstances.get(connecId);
            if (instance != null) {
                instance.getChangShaCardInhand().clear();
                instance.getChuGuoCardInhand().clear();
                instance.getgangdepai().clear();
                instance.getpongGroup().clear();
                instance.getchowGroup().clear();
                instance.getchangShaCardInhandgang().clear();
                instance.getChuGuoPainum().clear();
                System.out.println("清空HuNanChangSha集合数据: " + connecId);
            }
            
            huNanChangShaInstances.remove(connecId);
            playerOutcardsMapByConn.remove(connecId);
            playerchisMapByConn.remove(connecId);
            playerpengsMapByConn.remove(connecId);
            playermingsMapByConn.remove(connecId);
            playerzisMapByConn.remove(connecId);
        }

        if (robotUser != null) {
            TaurusClient client = robotUser.getClient();
            if (client != null) {
                try {
                    if (client.isConnected()) {
                        client.killConnection();
                    }
                    System.out.println("客户端主动断开连接完成: {"+connecId+"}");
                } catch (Exception e) {
                    System.out.println("断开客户端连接时发生异常: " + connecId + ", 错误: " + e.getMessage());
                }
            } else {
                System.out.println("客户端连接不存在: {"+connecId+"}");
            }
        }
    }

    /**
     * 设置事件监听器
     */
    public void setupEventListeners(TaurusClient client, String connecId) {
        //添加消息事件监听器
        IEventListener messageListener = new IEventListener() {
            @Override
            public void handleEvent(Event event) {
                //获取 msg
                Message message = (Message) event.getParameter("msg");

                ITObject param = message.param;
                //回调协议号
                String command = message.command;
                System.out.println("csmj OnEvent msg： " + command);

                //根据玩法ID处理不同的回调
                if (StringUtil.isNotEmpty(command)) {
                    //直接处理协议
                    handleProtocol(command, message, client, connecId);
                }
            }
        };

        //添加连接状态监听器
        IEventListener connectListener = new IEventListener() {
            @Override
            public void handleEvent(Event event) {
                Message message = (Message) event.getParameter("msg");
                SocketCode code = (SocketCode) event.getParameter("code");

            }
        };

        //注册事件监听器
        client.addEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
        client.addEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
    }


    /**
     * 机器人断线重连
     */
    public void reconnectToGameServer(MessageResponse response, RobotUser robotUser, TaurusClient client) {
        String connecId = robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId();
        if(client.isConnected()){
            try {
                ITObject obj = response.messageData.param.getTObject("tableInfo");
                ITObject reloadInfo = response.messageData.param.getTObject("reloadInfo");
                if (obj != null) {
                    //处理 seat
                    //获取机器人的seat
                    ITArray playerData = obj.getTArray("playerData");
                    for (int i = 0; i < playerData.size(); i++) {
                        ITObject tms = playerData.getTObject(i);
                        Integer tmuserid = tms.getInt("aid");
                        if (tmuserid == Integer.parseInt(robotUser.getRobotId())) {
                            Integer seat = tms.getInt("seat");
                            robotUser.setSeat(seat);
                        }
                    }
                    System.out.println("playerData:" + playerData);

                    System.out.println("obj:" + obj);
                    System.out.println("reloadInfo:" + reloadInfo);
                    if (reloadInfo != null) {
                        //重连回来的
                        int curren_outcard_seat = reloadInfo.getInt("curren_outcard_seat");
                        if (curren_outcard_seat == robotUser.getSeat()) {
                            //同步手牌
                            ITArray hand_card = reloadInfo.getTArray("hand_card");
                            ITArray info_list = reloadInfo.getTArray("info_list");

                            List<Integer> hcard = new ArrayList<>();
                            if (hand_card != null) {
                                for (int i = 0; i < hand_card.size(); i++) {
                                    hcard.add(hand_card.getInt(i));
                                }
                            }
                            ITArray outcard_list = new TArray();
                            if (info_list != null) {
                                for (int i = 0; i < info_list.size(); i++) {
                                    ITObject tms = info_list.getTObject(i);
                                    Integer playerid = tms.getInt("playerid");
                                    if (playerid == Integer.parseInt(robotUser.getRobotId())) {
                                        outcard_list = tms.getTArray("outcard_list");
                                    }
                                }
                            }

                            System.out.println("hcard>0" + hcard);
                            if (hcard.size() > 0) {
                                //同步手牌
                                HuNanChangSha currentInstance = getHuNanChangShaInstance(connecId);

                                //同步逻辑比较手牌数量
                                List<Integer> currentHand = currentInstance.getChangShaCardInhand();
                                if (currentHand.isEmpty() || hcard.size() > currentHand.size()) {
                                    //手牌集合为空 或者 玩家出牌了
                                    currentInstance.updateHandCard(hcard);
                                    System.out.println("断线重连：同步手牌数据，服务器手牌:" + hcard);
                                } else {
                                    System.out.println("断线重连：使用Redis恢复的手牌数据，数量:" + currentHand.size());
                                }

                                if (outcard_list.size() > 0) {
                                    List<Integer> outcards = new ArrayList<>();
                                    for (int i = 0; i < outcard_list.size(); i++) {
                                        outcards.add(outcard_list.getInt(i));
                                    }

                                    //检查出牌记录是否需要同步
                                    List<Integer> currentOutCards = currentInstance.getChuGuoCardInhand();
                                    if (currentOutCards.isEmpty() || outcards.size() > currentOutCards.size()) {
                                        currentInstance.updateOutCard(outcards);
                                        System.out.println("断线重连：同步出牌数据，服务器出牌:" + outcards);
                                    } else {
                                        System.out.println("断线重连：使用Redis恢复的出牌数据，数量:" + currentOutCards.size());
                                    }
                                }

                                //非阻塞的延迟执行，增加更完善的异常处理
                                scheduleDelay(() -> {
                                    try {
                                        //重新获取当前实例，确保数据一致性
                                        HuNanChangSha reconnectedInstance = getHuNanChangShaInstance(connecId);
                                        Map<Integer, List<Integer>> currentPlayerOutcardsMap = getPlayerOutcardsMap(connecId);
                                        Map<Integer, List<Integer>> currentPlayerchisMap = getPlayerchisMap(connecId);
                                        Map<Integer, List<Integer>> currentPlayerpengsMap = getPlayerpengsMap(connecId);
                                        Map<Integer, List<Integer>> currentPlayermingsMap = getPlayermingsMap(connecId);
                                        Map<Integer, List<Integer>> currentPlayerzisMap = getPlayerzisMap(connecId);

                                        reconnectedInstance.outCard(client, currentPlayerOutcardsMap, currentPlayerchisMap, currentPlayerpengsMap, currentPlayermingsMap, currentPlayerzisMap);
                                        System.out.println("断线重连后成功执行出牌操作");
                                    } catch (Exception e) {
                                        log.error("断线重连后执行出牌操作时发生异常", e);
                                        //即使出牌失败，也要确保连接状态正确
                                        try {
                                            if (robotUser != null) {
                                                robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_READY);
                                            }
                                        } catch (Exception statusEx) {
                                            log.error("更新机器人状态时发生异常", statusEx);
                                        }
                                    }
                                }, 2, TimeUnit.SECONDS);
                            } else {
                                System.err.println("警告：重连时未获取到手牌数据");
                            }
                        }
                    }
                }
            }catch (Exception e) {
                log.error("机器人断线重连异常");
            }
        }else {
            renconnect(robotUser);
        }
    }

    /**
     * 处理接收到的游戏协议
     */
    private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
        RobotUser robotUser = robotRoomMapping.get(connecId);
        int robotId = Integer.parseInt(robotUser.getRobotId());
        ITObject param = message.param;
        HuNanChangSha huNanChangSha = getHuNanChangShaInstance(connecId);
        Jedis jedis0 = Redis.use().getJedis();
        Jedis jedis2 = Redis.use("group1_db2").getJedis();
        try {
            //长沙麻将 机器人处理事件
            //初始化收手牌
            if ("811".equalsIgnoreCase(command)) {
                robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_WORKING);
                //初始化收手牌
                String key = robotId+"";
                log.info("key+++++++++++++++++++++++++++++++++++" + key);
                if (jedis2.hget("{robortInfo}:" + key, "circleId") != null && jedis2.hget("{robortInfo}:" + key, "pid") != null) {
                    String circleId = jedis2.hget("{robortInfo}:" + key, "circleId");
                    log.info("circleId +++++++++++++++++++++++++"+circleId);
                    String pid = jedis2.hget("{robortInfo}:" + key, "pid");
                    log.info("pid +++++++++++++++++++++++++"+pid);
                    String getStart = "g{" + circleId + "}:play:" + pid;
                    if (!pid.equals("0")){
                        log.info("getStart +++++++++++++++++++++++++"+getStart);
                        jedis2.hset(getStart, key, "2");
                    }
                }
                huNanChangSha.cardInHead(command, message);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            //出牌广播
            else if ("812".equalsIgnoreCase(command)) {
                ITArray outcard_map = param.getTArray("outcard_map");
                ITArray opchicards = param.getTArray("opchicards");
                ITArray oppengcards = param.getTArray("oppengcards");
                ITArray opmingcards = param.getTArray("opmingcards");
                ITArray opzicards = param.getTArray("opzicards");

                //获取当前连接专用的Maps
                Map<Integer, List<Integer>> currentPlayerOutcardsMap = getPlayerOutcardsMap(connecId);
                Map<Integer, List<Integer>> currentPlayerchisMap = getPlayerchisMap(connecId);
                Map<Integer, List<Integer>> currentPlayerpengsMap = getPlayerpengsMap(connecId);
                Map<Integer, List<Integer>> currentPlayermingsMap = getPlayermingsMap(connecId);
                Map<Integer, List<Integer>> currentPlayerzisMap = getPlayerzisMap(connecId);

                //清空旧数据 用新数据完全覆盖
                currentPlayerOutcardsMap.clear();
                currentPlayerchisMap.clear();
                currentPlayerpengsMap.clear();
                currentPlayermingsMap.clear();
                currentPlayerzisMap.clear();
                //出过的牌
                if (outcard_map != null) {
                    for (int i = 0; i < outcard_map.size(); i++) {
                        ITObject playerData = outcard_map.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outcardsArray = playerData.getTArray("outcards");

                        List<Integer> outcardsList = new ArrayList<>();
                        for (int j = 0; j < outcardsArray.size(); j++) {
                            outcardsList.add(outcardsArray.getInt(j));
                        }

                        //存储到当前连接的Map中（覆盖旧数据）
                        currentPlayerOutcardsMap.put(playerId, outcardsList);
                    }
                }

                //吃的牌
                if (opchicards != null) {
                    for (int i = 0; i < opchicards.size(); i++) {
                        ITObject playerData = opchicards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outchiArray = playerData.getTArray("opchicards");

                        List<Integer> outchiList = new ArrayList<>();
                        for (int j = 0; j < outchiArray.size(); j++) {
                            outchiList.add(outchiArray.getInt(j));
                        }
                        currentPlayerchisMap.put(playerId, outchiList);
                    }
                }

                //碰的牌
                if (oppengcards != null) {
                    for (int i = 0; i < oppengcards.size(); i++) {
                        ITObject playerData = oppengcards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outpengArray = playerData.getTArray("oppengcards");

                        List<Integer> outpengList = new ArrayList<>();
                        for (int j = 0; j < outpengArray.size(); j++) {
                            outpengList.add(outpengArray.getInt(j));
                        }
                        currentPlayerpengsMap.put(playerId, outpengList);
                    }
                }

                //明杠的牌
                if (opmingcards != null) {
                    for (int i = 0; i < opmingcards.size(); i++) {
                        ITObject playerData = opmingcards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outmingArray = playerData.getTArray("opmingcards");

                        List<Integer> outmingList = new ArrayList<>();
                        for (int j = 0; j < outmingArray.size(); j++) {
                            outmingList.add(outmingArray.getInt(j));
                        }
                        currentPlayermingsMap.put(playerId, outmingList);
                    }
                }

                //暗杠的牌
                if (opzicards != null) {
                    for (int i = 0; i < opzicards.size(); i++) {
                        ITObject playerData = opzicards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outziArray = playerData.getTArray("opzicards");

                        List<Integer> outziList = new ArrayList<>();
                        for (int j = 0; j < outziArray.size(); j++) {
                            outziList.add(outziArray.getInt(j));
                        }
                        currentPlayerzisMap.put(playerId, outziList);
                    }
                }

                huNanChangSha.drawCard(command, message);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            //摸牌
            else if ("819".equalsIgnoreCase(command)) {
                huNanChangSha.getCard(command, message);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            //出牌提示
            else if ("813".equalsIgnoreCase(command)) {
                //获取当前连接的Maps
                Map<Integer, List<Integer>> currentPlayerOutcardsMap = getPlayerOutcardsMap(connecId);
                Map<Integer, List<Integer>> currentPlayerchisMap = getPlayerchisMap(connecId);
                Map<Integer, List<Integer>> currentPlayerpengsMap = getPlayerpengsMap(connecId);
                Map<Integer, List<Integer>> currentPlayermingsMap = getPlayermingsMap(connecId);
                Map<Integer, List<Integer>> currentPlayerzisMap = getPlayerzisMap(connecId);

                huNanChangSha.outCard(client, currentPlayerOutcardsMap, currentPlayerchisMap, currentPlayerpengsMap, currentPlayermingsMap, currentPlayerzisMap);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            //放招提示
            else if ("814".equalsIgnoreCase(command)) {
                huNanChangSha.actionCard(param, client);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            //2026.02.03修改 玩家加入房间
            else if ("2001".equalsIgnoreCase(command)) {
                //直接使用定时任务替代Thread.sleep，避免嵌套异步调用
                scheduleDelay(() -> {
                    Jedis jedis = Redis.use().getJedis();
                    try {
                        String roomKey = String.valueOf(robotUser.getCurrentRoomId());

                        //查询该房间的玩家信息
                        String playersStr = jedis.hget("room:"+roomKey, "players");
                        if (playersStr != null && !playersStr.equals("[]")) {
                            String players = playersStr.substring(1, playersStr.length() - 1);
                            String[] playerIds = players.split(",");

                            //判断只有当前机器人一个玩家
                            if (playerIds.length == 1) {
                                int playerId = Integer.parseInt(playerIds[0].trim());
                                if (playerId == robotId) {
                                    //发送退出房间协议
                                    ITObject params = TObject.newInstance();
                                    client.send("1005", params, response -> {
                                        EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                                        //更新机器人剩余数量
                                        updateLeftoverRobot(robotId);
                                        disconnectFromGameServer(connecId);
                                        System.out.println("2001发送退出房间协议1005，robotId: {"+robotId+"}");
                                    });
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理玩家加入房间检查时发生异常", e);
                    } finally {
                        // 确保Jedis连接关闭
                        if (jedis != null) {
                            jedis.close();
                        }
                    }
                }, 6, TimeUnit.SECONDS);
                System.out.println("玩家{"+ robotUser.getCurrentRoomId()+"}加入房间:"+ param);
            }
            //2026.02.03修改 玩家退出房间也要检查
            else if ("2002".equalsIgnoreCase(command)) {
                //直接使用定时任务替代Thread.sleep，避免嵌套异步调用
                scheduleDelay(() -> {
                    Jedis jedis = Redis.use().getJedis();
                    try {
                        String roomKey = String.valueOf(robotUser.getCurrentRoomId());

                        //查询该房间的玩家信息
                        String playersStr = jedis.hget("room:"+roomKey, "players");
                        if (playersStr != null && !playersStr.equals("[]")) {
                            String players = playersStr.substring(1, playersStr.length() - 1);
                            String[] playerIds = players.split(",");

                            //判断只有当前机器人一个玩家
                            if (playerIds.length == 1) {
                                int playerId = Integer.parseInt(playerIds[0].trim());
                                if (playerId == robotId) {
                                    //发送退出房间协议
                                    ITObject params = TObject.newInstance();
                                    client.send("1005", params, response -> {
                                        EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                                        //更新机器人剩余数量
                                        updateLeftoverRobot(robotId);
                                        disconnectFromGameServer(connecId);
                                        System.out.println("2002发送退出房间协议1005，robotId: {"+robotId+"}");
                                    });
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理玩家退出房间检查时发生异常", e);
                    } finally {
                        if (jedis != null) {
                            jedis.close();
                        }
                    }
                }, 6, TimeUnit.SECONDS);
            }
            //2026.02.05修改 玩家解散房间
            else if ("2005".equalsIgnoreCase(command)) {
                EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                //更新机器人剩余数量
                updateLeftoverRobot(robotId);
                disconnectFromGameServer(connecId);
                System.out.println("2005玩家发送解散房间协议，robotId: {"+robotId+"}");
            }
            //2026.02.03修改 解散房间时候恢复机器人账号可以使用
            else if ("2008".equalsIgnoreCase(command)) {
                updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
                disconnectFromGameServer(connecId);
            }
            //2026.02.03修改 通过机器人房间映射直接获取房间信息
            else if ("2009".equalsIgnoreCase(command)) {
                //直接使用定时任务替代Thread.sleep，避免嵌套异步调用
                scheduleDelay(() -> {
                    Jedis localJedis = Redis.use().getJedis();
                    try {
                        Integer paramRobotId = param.getInt("aid");
                        if (robotUser != null) {
                            String roomKey = String.valueOf(robotUser.getCurrentRoomId());

                            //查询该房间的玩家信息
                            String playersStr = localJedis.hget(roomKey, "players");
                            if (playersStr != null && !playersStr.equals("[]")) {
                                String players = playersStr.substring(1, playersStr.length() - 1);
                                String[] playerIds = players.split(",");

                                //判断只有当前机器人一个玩家
                                if (playerIds.length == 1) {
                                    int playerId = Integer.parseInt(playerIds[0].trim());
                                    if (playerId == paramRobotId) {
                                        String gpid = localJedis.hget(roomKey, "gpid");

                                        //更新机器人剩余数量
                                        if (count != null && count.containsKey(Integer.parseInt(gpid))) {
                                            Integer currentValue = count.get(Integer.parseInt(gpid));
                                            if (currentValue > 0) {
                                                count.put(Integer.parseInt(gpid), currentValue - 1);
                                            }
                                        }

                                        //发送退出房间协议
                                        ITObject params = TObject.newInstance();
                                        client.send("1005", params, response -> {
                                            EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId));
                                            //断开连接
                                            disconnectFromGameServer(connecId);
                                            //更新机器人剩余数量
                                            updateLeftoverRobot(paramRobotId);
                                            System.out.println("2009发送退出房间协议1005，robotId: {"+paramRobotId+"}");
                                        });
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理机器人房间映射检查时发生异常", e);
                    } finally {
                        if (localJedis != null) {
                            localJedis.close();
                        }
                    }
                }, 6, TimeUnit.SECONDS);
            }
            //结算
            else if ("817".equalsIgnoreCase(command)) {
                //清空所有HuNanChangSha相关的集合数据
                huNanChangSha.getChangShaCardInhand().clear();
                huNanChangSha.getChuGuoCardInhand().clear();
                huNanChangSha.getgangdepai().clear();
                huNanChangSha.getpongGroup().clear();
                huNanChangSha.getchowGroup().clear();
                huNanChangSha.getchangShaCardInhandgang().clear();
                huNanChangSha.getChuGuoPainum().clear();
                Integer type = param.getInt("type");
                if (type == 1 || type == 2) { //为1为大结算 为2为解散
                    if (count != null && count.containsKey(pid)) {
                        Integer currentValue = count.get(pid);
                        if (currentValue > 0) {
                            count.put(pid, currentValue - 1);
                        }
                    }
                    //更新机器人剩余数量
                    updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
                }
                ITObject params = TObject.newInstance();
                params.putString("session", client.getSession());
                client.send("1003", params, new ICallback<MessageResponse>() {
                    @Override
                    public void action(MessageResponse messageResponse) {

                    }
                });
            }
            //服务器通知客户端有玩家执行了操作
            else if ("815".equalsIgnoreCase(command)) {
                huNanChangSha.shanchuchuguopai(param);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            //换牌提示
            else if ("820".equalsIgnoreCase(command)) {
                huNanChangSha.changePlayer(command, message);
                //处理完协议后保存到Redis
                HuNanChangSha currentInstance = huNanChangShaInstances.get(connecId);
                currentInstance.saveToRedis(connecId);
            }
            else if ("825".equalsIgnoreCase(command)) {
                ITObject params = TObject.newInstance();
                params.putInt("qi", 0);
                params.putInt("id", 1);
                client.send("612", params, response -> {

                });
            }
            else if ("822".equalsIgnoreCase(command)) {
                ITObject params = TObject.newInstance();
                params.putInt("id", 1);
                client.send("612", params, response -> {

                });
            }
            //听牌天听
            else if ("835".equalsIgnoreCase(command)) {
                ITObject params = TObject.newInstance();
                params.putInt("qi", 0);
                params.putInt("id", 1);
                client.send("612", params, response -> {

                });
            }
        } catch (Exception e) {
            log.error("处理接收到的游戏协议");
        } finally {
            jedis0.close();
            jedis2.close();
        }
    }

    /**
     * 增加leftover_robot数量 机器人退出房间
     */
    private void updateLeftoverRobot(int robotId) {
        Jedis jedis2 = Redis.use("group1_db2").getJedis();
        try {

            jedis2.hset("gallrobot", String.valueOf(robotId), "0");

            jedis2.hset("{grobot}:" + robotId, "start", "0");

            System.out.println("机器人 {"+robotId+"} 退出房间，修改gallrobot为0");
        } finally {
            jedis2.close();
        }
    }

    /**
     * 机器人登录
     */
    public void login(RobotUser robotUser){
        System.out.println("login:"+robotUser.getRobotId());
        ITObject object = null;
        AccountBusiness accountBusiness = null;
        accountBusiness = new AccountBusiness();
        try {
            //先快速登录
            object = accountBusiness.fastLogin(Integer.parseInt(robotUser.getRobotId()));
            System.out.println("object:"+object);
            if(object==null){
                object = accountBusiness.idPasswordLogin(Integer.parseInt(robotUser.getRobotId()), robotUser.getPassword());
            }
            ITObject finalObject = object;
            CompletableFuture.runAsync(() -> {
                if (finalObject != null) {
                    //判断是否有房间
                    if(finalObject.getTObject("account")!=null){
                        ITObject validate = TObject.newInstance();
                        validate.putString("token", finalObject.getString("token"));
                        robotUser.setToken(finalObject.getString("token"));;
                        robotUser.setLoginsession("{user}:"+robotUser.getRobotId());
                        if (robotUser.getLoginsession() != null) {
                            robotUser.setIsLogin(true);
                        }
                        if(finalObject.getTObject("account").get("roomid")!=null){
                            String roomid = finalObject.getTObject("account").get("roomid").toString();
                            robotUser.setCurrentRoomId(Integer.parseInt(roomid));
                            connectGame(robotUser);

                            robotUser.setConnecId(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId());
                            System.err.println("重启获取的机器人还有当前房间，准备加入: "+robotUser.getConnecId());
                            exGameController.webGroupJoinRoom(robotUser);
                        }
                    }
                }
            });
        } catch (Exception e) {
            log.error("机器人登录异常");
        }
    }

    public void connectGame(RobotUser robotUser){
        if(robotUser.isLogin){
            if(robotUser.getClient()==null){
                TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "cm"+robotUser.getRobotId(), TaurusClient.ConnectionProtocol.Tcp);
                client.setSession(robotUser.getLoginsession());
                client.connect();
                setupEventListeners(client, robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId());
                robotUser.setIsconnect(client.isConnected());
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    log.error("连接游戏服务器时发生异常", e);
                }
                robotUser.setClient(client);
                EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
            }else{
                System.out.println("reconnect");
                System.out.println("client.isConnected()"+robotUser.getClient().isConnected());
                if(robotUser.getClient().isConnected()){
                    robotUser.setIsconnect(true);
                }else{
                    System.out.println("reconnect"+robotUser.getClient().getGameID());
                    TaurusClient client = new TaurusClient(robotUser.getGameHost()+":"+robotUser.getGamePort(), "cm"+robotUser.getRobotId(), TaurusClient.ConnectionProtocol.Tcp);
                    client.setSession(robotUser.getLoginsession());
                    client.connect();
                    robotUser.setIsconnect(client.isConnected());
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        log.error("重新连接游戏服务器时发生异常", e);
                    }
                    robotUser.setClient(client);
                    EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
                }
            }
        }
    }

    /**
     * 重连
     */
    public void renconnect(RobotUser robotUser){
        TaurusClient client = robotUser.getClient();
        if(client!=null){
            if(client.isConnected()){
                client.connect();
                robotUser.setIsconnect(client.isConnected());
            }
        }
    }

    /**
     * 根据connecId获取游戏服务器连接
     */
    public TaurusClient getGameClient(String connecId) {
        return robotRoomMapping.get(connecId) != null ? robotRoomMapping.get(connecId).getClient() : null;
    }


    public int getTime(){
        return Integer.parseInt((System.currentTimeMillis() + "").substring(0, 10));
    }

    public static void sleepTime(int time) {
        try {
            //添加延迟
            Thread.sleep(time);
        } catch (InterruptedException e) {
            System.out.println(e);
        }
    }

}