mirror of
https://github.com/ChuXunYu/OnlineRpg.git
synced 2026-01-31 10:21:26 +00:00
2
This commit is contained in:
171
include/common/Database.h
Normal file
171
include/common/Database.h
Normal file
@@ -0,0 +1,171 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
// 前向声明 SQLite 结构
|
||||
struct sqlite3;
|
||||
|
||||
/**
|
||||
* @brief 用户数据结构
|
||||
*/
|
||||
struct UserData {
|
||||
int userId;
|
||||
std::string username;
|
||||
std::string passwordHash;
|
||||
std::string createdAt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 角色数据结构
|
||||
*/
|
||||
struct CharacterData {
|
||||
int characterId;
|
||||
int userId;
|
||||
std::string className;
|
||||
int level;
|
||||
int hp;
|
||||
int mp;
|
||||
int attack;
|
||||
int speed;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 数据库管理类
|
||||
*
|
||||
* 技术点: 数据库 (Database) - SQLite3
|
||||
* 线程安全: 使用 std::mutex 保护所有数据库操作
|
||||
*/
|
||||
class Database {
|
||||
private:
|
||||
sqlite3* m_db;
|
||||
std::string m_dbPath;
|
||||
mutable std::mutex m_mutex; // 保证线程安全 (STL)
|
||||
bool m_isOpen;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
* @param dbPath 数据库文件路径
|
||||
*/
|
||||
explicit Database(const std::string& dbPath);
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~Database();
|
||||
|
||||
// 禁止拷贝
|
||||
Database(const Database&) = delete;
|
||||
Database& operator=(const Database&) = delete;
|
||||
|
||||
/**
|
||||
* @brief 打开数据库连接
|
||||
*/
|
||||
bool open();
|
||||
|
||||
/**
|
||||
* @brief 关闭数据库连接
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* @brief 初始化数据库表结构
|
||||
*/
|
||||
bool initializeTables();
|
||||
|
||||
/**
|
||||
* @brief 检查数据库是否已打开
|
||||
*/
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
|
||||
// ===== 用户相关操作 =====
|
||||
|
||||
/**
|
||||
* @brief 注册新用户
|
||||
* @param username 用户名
|
||||
* @param password 密码 (将被哈希)
|
||||
* @return bool 是否成功
|
||||
*/
|
||||
bool registerUser(const std::string& username, const std::string& password);
|
||||
|
||||
/**
|
||||
* @brief 验证用户登录
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return bool 是否验证成功
|
||||
*/
|
||||
bool verifyUser(const std::string& username, const std::string& password);
|
||||
|
||||
/**
|
||||
* @brief 检查用户名是否存在
|
||||
*/
|
||||
bool userExists(const std::string& username);
|
||||
|
||||
/**
|
||||
* @brief 获取用户ID
|
||||
*/
|
||||
int getUserId(const std::string& username);
|
||||
|
||||
/**
|
||||
* @brief 获取用户数据
|
||||
*/
|
||||
bool getUserData(const std::string& username, UserData& userData);
|
||||
|
||||
// ===== 角色相关操作 =====
|
||||
|
||||
/**
|
||||
* @brief 创建角色
|
||||
* @param userId 用户ID
|
||||
* @param className 职业名称
|
||||
* @return bool 是否成功
|
||||
*/
|
||||
bool createCharacter(int userId, const std::string& className);
|
||||
|
||||
/**
|
||||
* @brief 获取用户的角色数据
|
||||
*/
|
||||
bool getCharacterData(int userId, CharacterData& charData);
|
||||
|
||||
/**
|
||||
* @brief 更新角色数据
|
||||
*/
|
||||
bool updateCharacter(const CharacterData& charData);
|
||||
|
||||
/**
|
||||
* @brief 检查用户是否有角色
|
||||
*/
|
||||
bool hasCharacter(int userId);
|
||||
|
||||
// ===== 工具函数 =====
|
||||
|
||||
/**
|
||||
* @brief 执行 SQL 语句
|
||||
* @param sql SQL 语句
|
||||
* @return bool 是否成功
|
||||
*/
|
||||
bool executeSql(const std::string& sql);
|
||||
|
||||
/**
|
||||
* @brief 获取最后插入的行 ID
|
||||
*/
|
||||
int getLastInsertId();
|
||||
|
||||
/**
|
||||
* @brief 获取最后的错误信息
|
||||
*/
|
||||
std::string getLastError();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 密码哈希函数 (简单实现)
|
||||
* 注意: 生产环境应使用更安全的哈希算法 (如 bcrypt, argon2)
|
||||
*/
|
||||
std::string hashPassword(const std::string& password);
|
||||
|
||||
/**
|
||||
* @brief 验证密码
|
||||
*/
|
||||
bool verifyPassword(const std::string& password, const std::string& hash);
|
||||
};
|
||||
98
include/common/Protocol.h
Normal file
98
include/common/Protocol.h
Normal file
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* @brief 网络通信协议定义
|
||||
*
|
||||
* 协议格式: COMMAND|param1|param2|...\n
|
||||
* 所有消息以换行符 \n 结尾
|
||||
*/
|
||||
|
||||
namespace Protocol {
|
||||
// ===== 协议命令定义 =====
|
||||
|
||||
// === 客户端 -> 服务器 (C2S) ===
|
||||
const std::string C2S_REGISTER = "C2S_REG"; // 注册: C2S_REG|username|password
|
||||
const std::string C2S_LOGIN = "C2S_LOGIN"; // 登录: C2S_LOGIN|username|password
|
||||
const std::string C2S_CHAT = "C2S_CHAT"; // 聊天: C2S_CHAT|message
|
||||
const std::string C2S_LIST_PLAYERS = "C2S_LIST"; // 玩家列表: C2S_LIST
|
||||
const std::string C2S_INVITE = "C2S_INVITE"; // 邀请: C2S_INVITE|target_username
|
||||
const std::string C2S_INVITE_RSP = "C2S_INVITE_RSP"; // 邀请响应: C2S_INVITE_RSP|inviter|accept/reject
|
||||
const std::string C2S_BATTLE_ACTION = "C2S_ACTION"; // 战斗行动: C2S_ACTION|skill_index|target
|
||||
const std::string C2S_LOGOUT = "C2S_LOGOUT"; // 登出: C2S_LOGOUT
|
||||
|
||||
// === 服务器 -> 客户端 (S2C) ===
|
||||
const std::string S2C_RESPONSE = "S2C_RESPONSE"; // 通用响应: S2C_RESPONSE|OK/ERROR|message
|
||||
const std::string S2C_LOGIN_OK = "S2C_LOGIN_OK"; // 登录成功: S2C_LOGIN_OK|username|class|level|hp|mp
|
||||
const std::string S2C_MSG = "S2C_MSG"; // 大厅消息: S2C_MSG|sender|message
|
||||
const std::string S2C_LIST_PLAYERS = "S2C_LIST"; // 玩家列表: S2C_LIST|user1,user2,user3
|
||||
const std::string S2C_INVITE = "S2C_INVITE"; // 收到邀请: S2C_INVITE|inviter_username
|
||||
const std::string S2C_INVITE_RESULT = "S2C_INV_RES"; // 邀请结果: S2C_INV_RES|target|accepted/rejected
|
||||
const std::string S2C_BATTLE_START = "S2C_BAT_START"; // 战斗开始: S2C_BAT_START|opponent|class
|
||||
const std::string S2C_BATTLE_TURN = "S2C_BAT_TURN"; // 回合通知: S2C_BAT_TURN|YOUR_TURN/OPP_TURN
|
||||
const std::string S2C_BATTLE_LOG = "S2C_BAT_LOG"; // 战斗日志: S2C_BAT_LOG|log_message
|
||||
const std::string S2C_BATTLE_END = "S2C_BAT_END"; // 战斗结束: S2C_BAT_END|WIN/LOSE
|
||||
const std::string S2C_SYSTEM = "S2C_SYSTEM"; // 系统消息: S2C_SYSTEM|message
|
||||
|
||||
// ===== 协议工具函数 =====
|
||||
|
||||
/**
|
||||
* @brief 构建协议消息
|
||||
* @param command 命令
|
||||
* @param params 参数列表
|
||||
* @return std::string 完整的协议消息 (包含换行符)
|
||||
*/
|
||||
std::string buildMessage(const std::string& command,
|
||||
const std::vector<std::string>& params = {});
|
||||
|
||||
/**
|
||||
* @brief 解析协议消息
|
||||
* @param message 原始消息
|
||||
* @param command 输出参数: 命令
|
||||
* @param params 输出参数: 参数列表
|
||||
* @return bool 解析是否成功
|
||||
*/
|
||||
bool parseMessage(const std::string& message,
|
||||
std::string& command,
|
||||
std::vector<std::string>& params);
|
||||
|
||||
/**
|
||||
* @brief 构建响应消息
|
||||
*/
|
||||
std::string buildResponse(bool success, const std::string& message);
|
||||
|
||||
/**
|
||||
* @brief 构建登录成功消息
|
||||
*/
|
||||
std::string buildLoginOk(const std::string& username,
|
||||
const std::string& className,
|
||||
int level, int hp, int mp);
|
||||
|
||||
/**
|
||||
* @brief 构建聊天消息
|
||||
*/
|
||||
std::string buildChatMessage(const std::string& sender,
|
||||
const std::string& message);
|
||||
|
||||
/**
|
||||
* @brief 构建玩家列表消息
|
||||
*/
|
||||
std::string buildPlayerList(const std::vector<std::string>& players);
|
||||
|
||||
/**
|
||||
* @brief 构建邀请消息
|
||||
*/
|
||||
std::string buildInvite(const std::string& inviter);
|
||||
|
||||
/**
|
||||
* @brief 构建战斗日志消息
|
||||
*/
|
||||
std::string buildBattleLog(const std::string& logMessage);
|
||||
|
||||
/**
|
||||
* @brief 构建系统消息
|
||||
*/
|
||||
std::string buildSystemMessage(const std::string& message);
|
||||
}
|
||||
139
include/common/SocketWrapper.h
Normal file
139
include/common/SocketWrapper.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
typedef SOCKET SocketFd;
|
||||
#define INVALID_SOCKET_FD INVALID_SOCKET
|
||||
#define SOCKET_ERROR_CODE WSAGetLastError()
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
typedef int SocketFd;
|
||||
#define INVALID_SOCKET_FD -1
|
||||
#define SOCKET_ERROR_CODE errno
|
||||
#define closesocket close
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Socket 封装类
|
||||
*
|
||||
* 技术点: 网络编程 (Network Programming) - 原生 Socket API 封装
|
||||
* 跨平台支持: Windows (Winsock) 和 Linux (POSIX Sockets)
|
||||
*/
|
||||
class SocketWrapper {
|
||||
private:
|
||||
SocketFd m_socket;
|
||||
bool m_isValid;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
*/
|
||||
SocketWrapper();
|
||||
|
||||
/**
|
||||
* @brief 构造函数 (使用现有socket)
|
||||
*/
|
||||
explicit SocketWrapper(SocketFd socket);
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~SocketWrapper();
|
||||
|
||||
// 禁止拷贝
|
||||
SocketWrapper(const SocketWrapper&) = delete;
|
||||
SocketWrapper& operator=(const SocketWrapper&) = delete;
|
||||
|
||||
/**
|
||||
* @brief 初始化 Winsock (仅 Windows)
|
||||
*/
|
||||
static bool initializeWinsock();
|
||||
|
||||
/**
|
||||
* @brief 清理 Winsock (仅 Windows)
|
||||
*/
|
||||
static void cleanupWinsock();
|
||||
|
||||
/**
|
||||
* @brief 创建 Socket
|
||||
*/
|
||||
bool create();
|
||||
|
||||
/**
|
||||
* @brief 绑定地址和端口
|
||||
*/
|
||||
bool bind(const std::string& address, int port);
|
||||
|
||||
/**
|
||||
* @brief 监听连接
|
||||
*/
|
||||
bool listen(int backlog = 10);
|
||||
|
||||
/**
|
||||
* @brief 接受客户端连接
|
||||
*/
|
||||
SocketFd accept(std::string& clientAddress, int& clientPort);
|
||||
|
||||
/**
|
||||
* @brief 连接到服务器
|
||||
*/
|
||||
bool connect(const std::string& address, int port);
|
||||
|
||||
/**
|
||||
* @brief 发送数据
|
||||
*/
|
||||
int send(const char* data, int length);
|
||||
|
||||
/**
|
||||
* @brief 发送字符串
|
||||
*/
|
||||
int send(const std::string& message);
|
||||
|
||||
/**
|
||||
* @brief 接收数据
|
||||
*/
|
||||
int recv(char* buffer, int length);
|
||||
|
||||
/**
|
||||
* @brief 接收一行数据 (以 \n 结尾)
|
||||
*/
|
||||
std::string recvLine();
|
||||
|
||||
/**
|
||||
* @brief 设置为非阻塞模式
|
||||
*/
|
||||
bool setNonBlocking(bool nonBlocking);
|
||||
|
||||
/**
|
||||
* @brief 设置 Socket 选项
|
||||
*/
|
||||
bool setReuseAddr(bool reuse);
|
||||
|
||||
/**
|
||||
* @brief 关闭 Socket
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* @brief 检查 Socket 是否有效
|
||||
*/
|
||||
bool isValid() const { return m_isValid; }
|
||||
|
||||
/**
|
||||
* @brief 获取原始 Socket 描述符
|
||||
*/
|
||||
SocketFd getSocket() const { return m_socket; }
|
||||
|
||||
/**
|
||||
* @brief 获取最后的错误信息
|
||||
*/
|
||||
static std::string getLastError();
|
||||
};
|
||||
Reference in New Issue
Block a user