Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当通讯发生异常时,如果发生的用户是玩家,此时用户所在游戏房房主仍为游戏中状态,实际应该是鱼 #73

Closed
smilesnake opened this issue Aug 26, 2022 · 0 comments

Comments

@smilesnake
Copy link

smilesnake commented Aug 26, 2022

XEChatServerHandler#

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    ChannelAction.cleanUser(ctx);
    ctx.close();
    log.error("error:", cause);
  }

ChannelAction#

/**
   * 清理指定用户
   * @param ctx 会话处理器上下文
   */
  public static void cleanUser(ChannelHandlerContext ctx) {
    cleanUser(getId(ctx));
  }

  /**
   * 通过id清理指定用户
   * @param id  用户id
   * @return 清理的用户信息
   */
  public static User cleanUser(String id) {
    log.debug("清理用户, id -> {}", id);

    User user = getUser(id);
    if (user == null) {
      return null;
    }

    log.debug("清理用户, username -> {}", user.getUsername());

    // 获取游戏房间号
    GameRoom gameRoom = GameRoomCache.getGameRoomByUserId(user.getId());
    if (gameRoom != null) {
      gameRoom.getUsers().forEach((k, v) -> {
        if (v.getId().equals(user.getId())) {
          return;
        }

        // 通知客户端玩家离开房间
        User player = UserCache.get(v.getId());
        if (player != null) {
          player.send(ResponseBuilder.build(user, new GameRoomMsgDTO(GameRoomMsgDTO.MsgType.PLAYER_LEFT, null), MessageType.GAME_ROOM));
        }
      });
      // 玩家离开房间
      GameRoomCache.leftRoom(gameRoom.getId(), user);
    }

    // 设置用户离线并移除相关缓存
    UserCache.remove(id);
    sendUserState(user, UserStateMsgDTO.State.OFFLINE);

    return user;
  }

GameRoomCache

  /**
     * 玩家离开房间
     *
     * @param roomId 房间ID
     * @param user   玩家
     * @return
     */
    public static boolean leftRoom(String roomId, User user) {
        // 查询游戏房间
        GameRoom gameRoom = GAME_ROOM_MAP.get(roomId);
        if (gameRoom == null) {
            return false;
        }

        // 从游戏房间移除玩家
        if (gameRoom.removeUser(user)) {
            // 从用户与房间的缓存中移除,即移除玩家与游戏房间的关联
            USER_ROOM_MAP.remove(user.getId());
            // 如果房间没人或者当前用户是房主
            if (gameRoom.getCurrentNums() == 0 || gameRoom.isHomeowner(user.getUsername())) {
                // 移除房间
                removeRoom(gameRoom.getId());
            }
            return true;
        }

        return false;
    }

    /**
     * 移除房间
     *
     * @param roomId 房间ID
     */
    public static void removeRoom(String roomId) {
        GameRoom gameRoom = getGameRoom(roomId);
        if (gameRoom == null) {
            return;
        }

        log.debug("游戏房间关闭 -> {}", gameRoom);

        // 先移除房间与房号的关联,再移除房间与玩家的关联
        GAME_ROOM_MAP.remove(roomId);
        if (gameRoom.getUsers().size() > 0) {
            gameRoom.getUsers().forEach((k, v) -> {
                USER_ROOM_MAP.remove(v.getId());
            });
        }

        //
        // 邀请的用户列表
        Set<User> userSet = new HashSet<>(gameRoom.getInviteUsers());
        // 房间内有玩家
        gameRoom.getUsers().forEach((k, v) -> {
            User user = UserCache.get(v.getId());
            if (user != null) {
                userSet.add(user);
            }
        });

        // 将非房主的玩家设置为“鱼”的状态
        if (userSet.size() > 0) {
            userSet.forEach(player -> {
                if (gameRoom.isHomeowner(player.getUsername())) {
                    return;
                }

                player.setStatus(UserStatus.FISHING);
                ChannelAction.updateUserStatus(player);
            });
        }
    }

removeRoom在这个方法中:

 if (gameRoom.isHomeowner(player.getUsername())) {
                    return;
 }

这里直接把房主过滤了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants