Files
OnlineRpg/src/server/GameServer.cpp
2025-10-26 20:44:58 +08:00

161 lines
4.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "server/GameServer.h"
#include "server/ClientHandler.h"
#include "server/GameLobby.h"
#include "server/BattleRoomManager.h"
#include <iostream>
GameServer::GameServer(int port, const std::string& dbPath)
: m_port(port), m_nextClientId(1), m_isRunning(false) {
// 初始化数据库
m_database = std::make_shared<Database>(dbPath);
// 初始化游戏模块
m_lobby = std::make_shared<GameLobby>(this);
m_battleManager = std::make_shared<BattleRoomManager>(this);
}
GameServer::~GameServer() {
stop();
}
bool GameServer::start() {
if (!m_database->isOpen()) {
std::cerr << "无法打开数据库" << std::endl;
return false;
}
// 创建并绑定服务器socket
if (!m_serverSocket.create()) {
std::cerr << "创建服务器socket失败" << std::endl;
return false;
}
if (!m_serverSocket.bind("0.0.0.0", m_port)) {
std::cerr << "绑定端口失败:" << m_port << std::endl;
return false;
}
if (!m_serverSocket.listen(10)) {
std::cerr << "监听端口失败:" << m_port << std::endl;
return false;
}
m_isRunning = true;
std::cout << "服务器启动成功" << std::endl;
std::cout << "监听端口:" << m_port << std::endl;
std::cout << "数据库:" << (m_database->isOpen() ? "已连接" : "失败") << std::endl;
return true;
}
void GameServer::stop() {
if (!m_isRunning) {
return;
}
m_isRunning = false;
std::cout << "正在停止服务器..." << std::endl;
// 停止所有客户端
{
std::lock_guard<std::mutex> lock(m_clientsMutex);
for (auto& pair : m_clients) {
pair.second->stop();
}
m_clients.clear();
}
// 关闭服务器socket
m_serverSocket.close();
std::cout << "服务器已停止" << std::endl;
}
void GameServer::run() {
std::cout << "服务器正在接受连接..." << std::endl;
while (m_isRunning) {
std::string clientAddr;
int clientPort;
SocketFd clientFd = m_serverSocket.accept(clientAddr, clientPort);
if (clientFd < 0) {
if (m_isRunning) {
std::cerr << "接受客户端连接失败" << std::endl;
}
continue;
}
std::cout << "客户端已连接,来自 " << clientAddr << ":" << clientPort << std::endl;
// 创建ClientHandler
int clientId = m_nextClientId++;
auto handler = std::make_shared<ClientHandler>(clientId, clientFd, this);
// 添加到客户端列表
{
std::lock_guard<std::mutex> lock(m_clientsMutex);
m_clients[clientId] = handler;
}
// 启动处理线程
handler->start();
std::cout << "新客户端已连接ID=" << clientId << "FD=" << clientFd << std::endl;
}
}
int GameServer::addClient(std::shared_ptr<ClientHandler> client) {
std::lock_guard<std::mutex> lock(m_clientsMutex);
int clientId = m_nextClientId++;
m_clients[clientId] = client;
return clientId;
}
void GameServer::removeClient(int clientId) {
std::lock_guard<std::mutex> lock(m_clientsMutex);
auto it = m_clients.find(clientId);
if (it != m_clients.end()) {
std::cout << "Removing client: ID=" << clientId << std::endl;
m_clients.erase(it);
}
}
std::shared_ptr<ClientHandler> GameServer::getClientByUsername(const std::string& username) {
std::lock_guard<std::mutex> lock(m_clientsMutex);
for (auto& pair : m_clients) {
if (pair.second->getUsername() == username) {
return pair.second;
}
}
return nullptr;
}
std::vector<std::string> GameServer::getOnlinePlayers() {
std::vector<std::string> players;
std::lock_guard<std::mutex> lock(m_clientsMutex);
for (const auto& pair : m_clients) {
const std::string& username = pair.second->getUsername();
if (!username.empty() && pair.second->getState() == ClientState::Lobby) {
players.push_back(username);
}
}
return players;
}
void GameServer::broadcastToLobby(const std::string& message, int excludeClientId) {
std::lock_guard<std::mutex> lock(m_clientsMutex);
for (auto& pair : m_clients) {
if (pair.first != excludeClientId &&
pair.second->getState() == ClientState::Lobby) {
pair.second->sendMessage(message);
}
}
}