This commit is contained in:
ChuXun
2025-10-26 16:37:22 +08:00
parent fba64f7100
commit e287aadd3c
5 changed files with 408 additions and 0 deletions

111
系统架构设计.md Normal file
View File

@@ -0,0 +1,111 @@
# **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\]**:接收线程收到 logcout 打印战报。