5. 服务端 - 创建房间#

本文介绍玩家创建房间以及启动房间时服务端的行为,可能与“进行游玩”这章有重合的地方。 该模块需要实现的功能有:

  • 用户能够创建自己的房间。

  • 当房间没有人类时,应释放相关资源。

  • 房主离开时,选出新的房主。

  • 需要决定房间在哪个线程中运行游戏逻辑代码。

  • 自动封禁机制相关的功能。

  • 处理玩家断线与逃跑的相关功能。

  • 房主踢人相关功能。

  • 服务端热更新相关功能。

此外涉及的其他相关功能主要是关于玩家的掉线处理,以及相关的内存与多线程考虑。

首先是与房间管理相关的类图,算了懒得画完:

@startuml

!theme plain
hide empty methods
class Room {
  -RoomThread *thread
  -int id
  -string name
  -int capacity
  -bytes settings
  -bool m_abandoned
  -ServerPlayer *owner
  -QList<ServerPlayer *> players
  -QList<ServerPlayer *> observers
  -QList<int> runned_players
  -QList<int> rejected_players
  -int robot_id
  -bool gameStarted
  -bool m_ready

}

class Lobby {
}

Lobby --|> Room
@enduml

5.1. 房间的创建与清除#

这需要从服务器的创建开始说明。服务器启动之初,服务器便创建好大厅,而成功建立连接 的玩家也是先进入大厅。一个玩家要么在大厅中,要么就在某个房间中。

房间的创建动作是通过玩家向服务器发起创建房间请求后才执行的。玩家在客户端通过 操作后向服务端传递数据后,最终进入 Server::createRoom 。这样一来就创建了 新的房间。

房间的清除则是自动进行的。当房间内已没有任何人类玩家存在时,会触发其 abandoned() 信号,进而由 Server::onRoomAbandoned() 处理。房间清除时并没有直接delete掉, 而是放入一个栈中,这样下次创建房间时不需要申请新内存。

备注

idle_rooms的设计目前看来似乎必要性不大。在项目早期阶段,每个Room都持有一个 Lua虚拟机并占用一个线程,这样创建新房间的开销便十分大,因此设计了这样的循环 利用功能。现在的Room已经相当精简,但这个功能还是保留了下来。

5.2. 玩家的网络状态分析#

既然房间需要在房中无人时自动清除,那么自然需要检测玩家在线的功能。