diff --git a/web_group/src/main/java/com/group/service/GroupRoomService.java b/web_group/src/main/java/com/group/service/GroupRoomService.java index 7abecb2..0d1851c 100644 --- a/web_group/src/main/java/com/group/service/GroupRoomService.java +++ b/web_group/src/main/java/com/group/service/GroupRoomService.java @@ -604,7 +604,18 @@ public class GroupRoomService { } } if(StringUtil.isNotEmpty(robot_host)) { - sendRobotData(resData.getString("room_id"),groupId,robot_host,gameId1); + String roomId = resData.getString("room_id"); + + //异步执行机器人分配不阻塞玩家进入房间 + final String finalRobotHost = robot_host; + final int finalGameId = gameId1; + CompletableFuture.runAsync(() -> { + try { + sendRobotData(roomId, groupId, finalRobotHost, finalGameId); + } catch (Exception e) { + log.error("joinRoom ==> 异步分配机器人失败(不影响玩家进入) roomid:" + roomId, e); + } + }); } @@ -1086,7 +1097,6 @@ public class GroupRoomService { //检查玩家今天是否已经与机器人对打过 if (!isPlayerRobotToday(acc.id)) { - log.info("matchRoom() ==> 玩家今天和机器人对打过了isPlayerRobotToday = " + isPlayerRobotToday(acc.id)); //匹配 Jedis jedis11 = Redis.use("group1_db11").getJedis(); Jedis jedis0 = Redis.use("group1_db0").getJedis(); @@ -1103,14 +1113,21 @@ public class GroupRoomService { if (Integer.parseInt(gameId1) == 22) { robot_host = "8.138.120.132:8722"; } - - log.info("StringUtil.isNotEmpty(gameId1) && StringUtil.isNotEmpty(robot_host)" + gameId1 + " " +robot_host); if (StringUtil.isNotEmpty(gameId1) && StringUtil.isNotEmpty(robot_host)) { String roomid = resData.getString("room_id"); log.info("room_idroom_idroom_id" + roomid); - sendRobotData(roomid, groupId,robot_host,Integer.parseInt(gameId1)); - } + //异步执行机器人分配 不阻塞玩家进入房间 + final String finalRobotHost = robot_host; + final int finalGameId = Integer.parseInt(gameId1); + CompletableFuture.runAsync(() -> { + try { + sendRobotData(roomid, groupId, finalRobotHost, finalGameId); + } catch (Exception e) { + log.error("matchRoom ==> 异步分配机器人失败(不影响玩家进入) roomid:" + roomid, e); + } + }); + } } } finally { @@ -1198,21 +1215,73 @@ public class GroupRoomService { * @return */ public static ITObject sendRobotData(String roomid,int groupid,String robot_host,int gameId){ - - //Jedis js1 = Redis.use("group1_db3").getJedis(); - - log.info("sendRobotData :"+roomid+"groupid:"+groupid+"robot_host:"+robot_host); + Jedis js0 = Redis.use("group1_db0").getJedis(); Jedis js3 = Redis.use("group1_db3").getJedis(); try { String flag = js3.get("roomsend" + roomid); if (flag != null) { + log.info("sendRobotData ==> 房间已分配过机器人,跳过 roomid:" + roomid); return null; } js3.set("roomsend" + roomid, 1 + ""); - js3.expire("roomsend" + roomid, 5); + js3.expire("roomsend" + roomid, 37); + //最多等待800ms (4 x 200ms) + //players由游戏服异步写入 若超时则本次不分配机器人 + String roomKey = "room:" + roomid; + String playersJson = js0.hget(roomKey, "players"); + int maxRetry = 4; + for (int i = 0; i < maxRetry && StringUtil.isEmpty(playersJson); i++) { + sleep(200); + playersJson = js0.hget(roomKey, "players"); + } + + if (StringUtil.isEmpty(playersJson)) { + log.warn("sendRobotData ==> 800ms内未获取到players数据,跳过本次机器人分配 roomid:" + roomid + " (玩家可正常进入,仅无机器人)"); + return null; + } else { + //检查是否有真人 + ITArray players = TArray.newFromJsonData(playersJson); + Set robotSet = js3.smembers("robots"); + String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + + //检查房间内的真人玩家是否都已对打过了 + List realPlayersInRoom = new ArrayList<>(); + boolean allRealMatchedToday = true; + for (int i = 0; i < players.size(); i++) { + int playerId = players.getInt(i); + if (robotSet == null || !robotSet.contains(String.valueOf(playerId))) { + realPlayersInRoom.add(playerId); + //检查该真人今天是否已和机器人对打过 + String matchedDate = js3.get("player_user:" + playerId); + if (matchedDate == null || !matchedDate.equals(today)) { + allRealMatchedToday = false; + log.info("sendRobotData ==> 真人玩家今天未对打 roomid:" + roomid + " realPlayerId:" + playerId); + } else { + log.info("sendRobotData ==> 真人玩家今天已对打过 roomid:" + roomid + " realPlayerId:" + playerId); + } + } + } + + if (realPlayersInRoom.isEmpty()) { + log.info("sendRobotData ==> 房间内没有真人玩家,取消发机器人 roomid:" + roomid + " players:" + playersJson); + return null; + } + + if (allRealMatchedToday) { + log.info("sendRobotData ==> 房间内所有真人今天都已与机器人对打过,取消发机器人 roomid:" + roomid + " realPlayers:" + realPlayersInRoom); + return null; + } + + if (players.size() >= 2) { + log.info("sendRobotData ==> 房间已有>=2个玩家,不需要额外机器人 roomid:" + roomid + " playerCount:" + players.size()); + return null; + } + } + + //找可用机器人 int robotid = 0; Set jsRobot = js3.smembers("robots"); log.info("jsRobot" + jsRobot); @@ -1221,21 +1290,10 @@ public class GroupRoomService { String tmp = js3.get(wokelock + key); if (StringUtil.isEmpty(tmp)) { robotid = Integer.parseInt(key); + break; } } - -// int robotid = 0; -// Map jsRobot = js1.hgetAll("{robot426149}" + gameId); -// String wokelock = "wokelock"; -// for (String key : jsRobot.keySet()) { -// String tmp = js1.get(wokelock + key); -// if (StringUtil.isEmpty(tmp)) { -// robotid = Integer.parseInt(key); -// break; -// } -// } - if (robotid == 0) { log.info("sendRobotData 没有可用机器人 roomid:" + roomid); return null; @@ -1245,8 +1303,6 @@ public class GroupRoomService { js3.set(wokelock + robotid, String.valueOf(1)); js3.expire(wokelock + robotid, 35); -// js1.expire(wokelock + robotid, 900); - //通过 HTTP 同步调用机器人服务的 225 协议入口 sleep(1000); String url = buildRobotHttpUrl(robot_host); @@ -1256,6 +1312,7 @@ public class GroupRoomService { } catch (Exception e) { log.error("sendRobotData 异常 roomid:" + roomid, e); } finally { + js0.close(); js3.close(); } //client.killConnection();