This commit is contained in:
2025-10-26 20:44:58 +08:00
parent e287aadd3c
commit e73c08abf7
45 changed files with 280774 additions and 0 deletions

134
include/server/BattleRoom.h Normal file
View File

@@ -0,0 +1,134 @@
#pragma once
#include "ICharacter.h"
#include "HistoryLog.h"
#include <memory>
#include <string>
#include <vector>
#include <mutex>
// 前向声明
class ClientHandler;
/**
* @brief 战斗房间
*
* 技术点:
* 1. 多态 - ICharacter* 和 ISkill*
* 2. 模板+链表 - HistoryLog<string>
* 3. STL - std::vector, std::mutex
*/
class BattleRoom {
private:
int m_roomId;
// 战斗双方
std::shared_ptr<ClientHandler> m_player1;
std::shared_ptr<ClientHandler> m_player2;
// 角色 (多态)
std::shared_ptr<ICharacter> m_char1;
std::shared_ptr<ICharacter> m_char2;
// 战斗日志 (模板+链表)
HistoryLog<std::string> m_historyLog;
// 战斗状态
bool m_isRunning;
int m_currentTurn; // 0 = player1, 1 = player2
int m_turnCount;
std::mutex m_mutex;
public:
/**
* @brief 构造函数
*/
BattleRoom(int roomId,
std::shared_ptr<ClientHandler> player1,
std::shared_ptr<ClientHandler> player2,
std::shared_ptr<ICharacter> char1,
std::shared_ptr<ICharacter> char2);
/**
* @brief 析构函数
*/
~BattleRoom();
/**
* @brief 启动战斗
*/
void start();
/**
* @brief 处理玩家行动
*/
bool handleAction(const std::string& username,
int skillIndex,
const std::string& targetName);
/**
* @brief 检查战斗是否结束
*/
bool isFinished() const;
/**
* @brief 获取胜利者
*/
std::string getWinner() const;
/**
* @brief 获取战斗日志
*/
std::vector<std::string> getBattleLog() const;
/**
* @brief 获取房间ID
*/
int getRoomId() const { return m_roomId; }
/**
* @brief 检查是否轮到某玩家
*/
bool isPlayerTurn(const std::string& username) const;
private:
/**
* @brief 执行一回合
*/
void executeTurn();
/**
* @brief 广播给双方玩家
*/
void broadcastToBoth(const std::string& message);
/**
* @brief 发送给玩家1
*/
void sendToPlayer1(const std::string& message);
/**
* @brief 发送给玩家2
*/
void sendToPlayer2(const std::string& message);
/**
* @brief 添加战斗日志
*/
void addLog(const std::string& log);
/**
* @brief 结束战斗
*/
void endBattle();
/**
* @brief 发送回合通知
*/
void notifyTurn();
/**
* @brief 发送战斗状态
*/
void sendBattleStatus();
};

View File

@@ -0,0 +1,71 @@
#pragma once
#include "BattleRoom.h"
#include <map>
#include <mutex>
#include <memory>
// 前向声明
class GameServer;
/**
* @brief 战斗房间管理器
*
* 技术点: STL - std::map, std::mutex
*/
class BattleRoomManager {
private:
GameServer* m_server;
std::map<int, std::shared_ptr<BattleRoom>> m_rooms; // STL
std::mutex m_mutex; // STL
int m_nextRoomId;
public:
/**
* @brief 构造函数
*/
explicit BattleRoomManager(GameServer* server);
/**
* @brief 析构函数
*/
~BattleRoomManager();
/**
* @brief 创建战斗房间
* @param player1 玩家1用户名
* @param player2 玩家2用户名
* @return int 房间ID失败返回 -1
*/
int createBattle(const std::string& player1, const std::string& player2);
/**
* @brief 获取战斗房间
*/
std::shared_ptr<BattleRoom> getBattleRoom(int roomId);
/**
* @brief 处理战斗行动
*/
bool handleBattleAction(int roomId,
const std::string& username,
int skillIndex,
const std::string& targetName);
/**
* @brief 移除战斗房间
*/
void removeBattleRoom(int roomId);
/**
* @brief 检查玩家是否在战斗中
*/
bool isPlayerInBattle(const std::string& username);
private:
/**
* @brief 创建角色实例
*/
std::shared_ptr<ICharacter> createCharacter(const std::string& className,
const std::string& name,
int level = 1);
};

View File

@@ -0,0 +1,172 @@
#pragma once
#include "SocketWrapper.h"
#include <string>
#include <thread>
#include <atomic>
#include <memory>
#include <vector>
// 前向声明
class GameServer;
/**
* @brief 客户端状态枚举
*/
enum class ClientState {
Unauthenticated, // 未认证
Lobby, // 大厅中
InBattle // 战斗中
};
/**
* @brief 客户端处理器
*
* 技术点:
* 1. STL - std::thread (多线程)
* 2. 网络编程 - Socket 通信
*/
class ClientHandler : public std::enable_shared_from_this<ClientHandler> {
private:
int m_clientId;
SocketFd m_socketFd;
GameServer* m_server;
std::thread m_thread;
std::atomic<bool> m_isRunning;
// 客户端状态
ClientState m_state;
std::string m_username;
int m_userId;
// 战斗相关
std::string m_pendingInviter; // 待处理的邀请者
int m_battleRoomId; // 所在战斗房间ID
public:
/**
* @brief 构造函数
*/
ClientHandler(int clientId, SocketFd socketFd, GameServer* server);
/**
* @brief 析构函数
*/
~ClientHandler();
// 禁止拷贝
ClientHandler(const ClientHandler&) = delete;
ClientHandler& operator=(const ClientHandler&) = delete;
/**
* @brief 启动处理线程
*/
void start();
/**
* @brief 停止处理
*/
void stop();
/**
* @brief 发送消息
*/
bool sendMessage(const std::string& message);
/**
* @brief 获取客户端ID
*/
int getClientId() const { return m_clientId; }
/**
* @brief 获取用户名
*/
std::string getUsername() const { return m_username; }
/**
* @brief 获取用户ID
*/
int getUserId() const { return m_userId; }
/**
* @brief 获取状态
*/
ClientState getState() const { return m_state; }
/**
* @brief 设置状态
*/
void setState(ClientState state) { m_state = state; }
/**
* @brief 设置战斗房间ID
*/
void setBattleRoomId(int roomId) { m_battleRoomId = roomId; }
/**
* @brief 获取战斗房间ID
*/
int getBattleRoomId() const { return m_battleRoomId; }
/**
* @brief 设置待处理邀请
*/
void setPendingInviter(const std::string& inviter) { m_pendingInviter = inviter; }
/**
* @brief 获取待处理邀请
*/
std::string getPendingInviter() const { return m_pendingInviter; }
private:
/**
* @brief 线程主循环
*/
void run();
/**
* @brief 处理客户端命令
*/
void handleCommand(const std::string& command,
const std::vector<std::string>& params);
/**
* @brief 处理注册
*/
void handleRegister(const std::vector<std::string>& params);
/**
* @brief 处理登录
*/
void handleLogin(const std::vector<std::string>& params);
/**
* @brief 处理聊天
*/
void handleChat(const std::vector<std::string>& params);
/**
* @brief 处理玩家列表请求
*/
void handleListPlayers();
/**
* @brief 处理邀请
*/
void handleInvite(const std::vector<std::string>& params);
/**
* @brief 处理邀请响应
*/
void handleInviteResponse(const std::vector<std::string>& params);
/**
* @brief 处理战斗行动
*/
void handleBattleAction(const std::vector<std::string>& params);
/**
* @brief 处理登出
*/
void handleLogout();
};

View File

@@ -0,0 +1,59 @@
#pragma once
#include <string>
#include <memory>
// 前向声明
class GameServer;
/**
* @brief 游戏大厅管理类
*
* 功能:
* 1. 管理大厅聊天
* 2. 处理玩家列表
* 3. 处理对战邀请
*/
class GameLobby {
private:
GameServer* m_server;
public:
/**
* @brief 构造函数
*/
explicit GameLobby(GameServer* server);
/**
* @brief 析构函数
*/
~GameLobby();
/**
* @brief 广播聊天消息
* @param sender 发送者用户名
* @param message 消息内容
* @param excludeClientId 排除的客户端ID (不发送给自己)
*/
void broadcastMessage(const std::string& sender,
const std::string& message,
int excludeClientId = -1);
/**
* @brief 处理对战邀请
* @param inviter 邀请者用户名
* @param target 被邀请者用户名
* @return bool 是否成功发送邀请
*/
bool handleInvite(const std::string& inviter, const std::string& target);
/**
* @brief 处理邀请响应
* @param inviter 邀请者用户名
* @param target 被邀请者用户名
* @param accept 是否接受
* @return bool 是否成功处理
*/
bool handleInviteResponse(const std::string& inviter,
const std::string& target,
bool accept);
};

111
include/server/GameServer.h Normal file
View File

@@ -0,0 +1,111 @@
#pragma once
#include "SocketWrapper.h"
#include "Database.h"
#include <string>
#include <map>
#include <mutex>
#include <memory>
#include <vector>
// 前向声明
class ClientHandler;
class GameLobby;
class BattleRoomManager;
/**
* @brief 游戏服务器主类
*
* 技术点:
* 1. STL - std::map, std::mutex, std::thread
* 2. 网络编程 - Socket Server
*/
class GameServer {
private:
int m_port;
SocketWrapper m_serverSocket;
std::shared_ptr<Database> m_database;
// 客户端管理 (STL)
std::map<int, std::shared_ptr<ClientHandler>> m_clients;
std::mutex m_clientsMutex;
int m_nextClientId;
// 游戏模块
std::shared_ptr<GameLobby> m_lobby;
std::shared_ptr<BattleRoomManager> m_battleManager;
bool m_isRunning;
public:
/**
* @brief 构造函数
* @param port 监听端口
* @param dbPath 数据库文件路径
*/
GameServer(int port, const std::string& dbPath);
/**
* @brief 析构函数
*/
~GameServer();
/**
* @brief 启动服务器
*/
bool start();
/**
* @brief 停止服务器
*/
void stop();
/**
* @brief 服务器主循环 (接受连接)
*/
void run();
/**
* @brief 添加客户端
*/
int addClient(std::shared_ptr<ClientHandler> client);
/**
* @brief 移除客户端
*/
void removeClient(int clientId);
/**
* @brief 根据用户名获取客户端
*/
std::shared_ptr<ClientHandler> getClientByUsername(const std::string& username);
/**
* @brief 获取所有在线玩家列表
*/
std::vector<std::string> getOnlinePlayers();
/**
* @brief 广播消息给所有在大厅的客户端
*/
void broadcastToLobby(const std::string& message, int excludeClientId = -1);
/**
* @brief 获取数据库
*/
std::shared_ptr<Database> getDatabase() { return m_database; }
/**
* @brief 获取大厅
*/
std::shared_ptr<GameLobby> getLobby() { return m_lobby; }
/**
* @brief 获取战斗管理器
*/
std::shared_ptr<BattleRoomManager> getBattleManager() { return m_battleManager; }
/**
* @brief 检查服务器是否运行中
*/
bool isRunning() const { return m_isRunning; }
};