# **1\. 系统架构图 (C/S 架构)**

\+-------------------------------------------------------------------------+  
| \[ 客户端 A (Console) \]                                                  |  
|   \+--------------------+   \+--------------------+                       |  
|   |   GameClient       |   |   主线程 (Input)   |                       |  
|   | (负责网络通信)     |   | (发送聊天/指令)  |                       |  
|   \+--------------------+   \+--------------------+                       |  
|   | SocketWrapper      |   |   接收线程 (Recv)  |                       |  
|   | (封装Socket API)   |   | (打印聊天/战报)  |                       |  
|   \+--------------------+   \+--------------------+                       |  
\+-------------^----------------------------------+                        |  
              | (TCP/IP)                                                  |  
              |                                                           |  
\+-------------v----------------------------------+                        |  
| \[ 客户端 B (Console) \]                                                  |  
|   (结构同 A)                                                              |  
\+-------------^----------------------------------+                        |  
              | (TCP/IP)                                                  |  
              |                                                           |  
\+-------------v-----------------------------------------------------------+  
| \[ 服务器 (GameServer Console) \]                                           |  
|                                                                         |  
|   \+---------------------+   \+-----------------------------------------+ |  
|   |  GameServer (主线程)  |   | \[ 线程池 / 并发管理 \]                       | |  
|   | (Socket, Bind, Listen)|   |                                         | |  
|   | (Loop: Accept)      |   | \+-----------------+ \+-----------------+ | |  
|   |                     |   | | ClientHandler A | | ClientHandler B | | |  
|   | (管理所有 Client)   |   | | (Thread A)      | | (Thread B)      | | |  
|   | (std::map\<fd, Ptr\>)|   | \+-----------------+ \+-----------------+ | |  
|   \+----------^----------+   \+---------^---------------+---------^-----+ |  
|              |                        | (Lobby/Battle)        |         |  
|              |                        |                       |         |  
|   \+----------v----------+   \+---------v---------------+         |         |  
|   |  GameLobby (单例)   |   |  BattleRoomManager    |         |         |  
|   | (std::map\<name, Ptr\>)|   | (管理所有战斗房间)  |         |         |  
|   | (负责聊天/邀请)     |   | (std::map\<id, Ptr\>) |         |         |  
|   \+---------------------+   \+-----------------------+         |         |  
|                                                               |         |  
|                               \+-------------------------------v-------+ |  
|                               | \[ 数据库接口 (Database) \]               | |  
|                               | (封装 SQLite API)                     | |  
|                               | (使用 Mutex 保证线程安全)             | |  
|                               \+-------------------^-------------------+ |  
|                                                   |                     |  
\+---------------------------------------------------+---------------------+  
                                                    |  
                                                \+---v---+  
                                                | DB    |  
                                                | (users.db)|  
                                                \+-------+

# **2\. 关键组件职责**

1. **GameClient (客户端)**  
   * 负责连接服务器。  
   * **必须**使用多线程：一个线程（主线程）负责捕获用户输入 (cin) 并 send；另一个线程（子线程）负责阻塞 recv 并打印服务器消息 (cout)。  
   * 负责提供控制台的菜单和界面。  
2. **GameServer (服务器)**  
   * 负责监听端口 (listen) 和接受新连接 (accept)。  
   * 每接受一个新连接，**必须**创建一个 ClientHandler 实例，并在一个**新线程 (std::thread)** 中运行它。  
   * **必须**使用 std::map (STL) 来存储所有 ClientHandler 的指针或引用，以便管理。  
   * **必须**使用 std::mutex (STL) 来保护这个 map，防止多线程冲突。  
3. **ClientHandler (服务器)**  
   * 在独立的线程中运行，代表一个已连接的客户端。  
   * 负责该客户端的 recv 循环，解析客户端发来的命令 (使用 Protocol.h)。  
   * 根据命令，调用 GameLobby (聊天/邀请) 或 BattleRoomManager (战斗) 的功能。  
   * 负责处理该客户端的异常掉线，并通知 GameServer 将自己从 map 中移除。  
4. **GameLobby (服务器)**  
   * 管理所有处于“大厅”状态的玩家。  
   * 实现 broadcastMessage() (广播聊天)，需要加锁 (std::mutex) 遍历 GameServer 的客户端 map 并发送。  
   * 实现 handleInvite() (处理邀请逻辑)。  
5. **BattleRoom (服务器)**  
   * 负责处理一场 1v1 战斗。  
   * 持有**多态**的 ICharacter\* 指针。  
   * 持有**模板+链表**实现的 HistoryLog\<string\> 实例，用于记录战报。  
   * 实现 runTurn() 战斗循环逻辑，调用 ISkill 的 execute 方法。  
6. **Database (服务器)**  
   * 封装 SQLite3 的 C API。  
   * 提供上层易用的接口：bool registerUser(user, pass)等。  
   * **必须**保证是线程安全的（例如，对所有数据库写操作使用一个全局 std::mutex）。

# **3\. 关键数据流**

## **3.1. 数据流：玩家A 发送大厅聊天**

1. **\[Client A\]**：主线程 cin 捕获输入 "Hello"。  
2. **\[Client A\]**：GameClient 将其打包为 "CHAT|Hello"，通过 SocketWrapper::send() 发出。  
3. **\[Server\]**：ClientHandler A (线程A) 的 recv() 循环收到数据。  
4. **\[Server\]**：ClientHandler A 解析出是 CHAT 命令。  
5. **\[Server\]**：ClientHandler A 调用 GameLobby::broadcastMessage("A: Hello")。  
6. **\[Server\]**：GameLobby **加锁**访问 GameServer 的客户端 map。  
7. **\[Server\]**：GameLobby 遍历 map，对所有**非战斗中**的 ClientHandler (如 B, C, D) 调用 send("MSG|A: Hello")。  
8. **\[Client B,C,D\]**：接收线程 (子线程) 的 recv() 收到消息，cout 打印 "A: Hello" 到控制台。

## **3.2. 数据流：玩家A 攻击 玩家B (战斗中)**

1. **\[Server\]**：BattleRoom (线程C) 判定轮到 A 行动。  
2. **\[Server\]**：BattleRoom 向 ClientHandler A (线程A) 发送 "TURN|YOUR\_TURN"。  
3. **\[Client A\]**：接收线程收到 "TURN|YOUR\_TURN"，cout 打印 "轮到你行动"。  
4. **\[Client A\]**：主线程 cin 捕获输入 "attack B"。  
5. **\[Client A\]**：GameClient 打包为 "BATTLE|USE\_SKILL|Fireball|B"，send() 发出。  
6. **\[Server\]**：ClientHandler A (线程A) 收到数据，解析后调用 BattleRoom::handleAction("A", "Fireball", "B")。  
7. \[Server\]：BattleRoom (线程C) 加锁（防止多线程同时修改战斗状态），执行战斗逻辑：  
   a. ICharacter\* charA \= ...;  
   b. ISkill\* skill \= charA-\>getSkill("Fireball");  
   c. skill-\>execute(charA, charB); (多态调用)  
   d. string log \= "A 对 B 使用了\[火球\]...";  
   e. m\_historyLog.add(log); (模板+链表调用)  
8. **\[Server\]**：BattleRoom (线程C) 将战报 log 广播给 ClientHandler A 和 ClientHandler B。  
9. **\[Client A, B\]**：接收线程收到 log，cout 打印战报。