#include "NetworkManager.h" #include #include NetworkManager::NetworkManager(QObject* parent) : QObject(parent) { connect(&_socket, &QWebSocket::connected, this, &NetworkManager::onConnected); connect(&_socket, &QWebSocket::disconnected, this, &NetworkManager::onDisconnected); connect(&_socket, &QWebSocket::textMessageReceived, this, &NetworkManager::onTextMessageReceived); connect(&_socket, &QWebSocket::errorOccurred, this, &NetworkManager::onError); connect(&_socket, &QWebSocket::binaryMessageReceived, this, [this](const QByteArray& msg) { emit binaryFrameReceived(msg); }); connect(&_heartbeatTimer, &QTimer::timeout, this, &NetworkManager::onHeartbeat); } void NetworkManager::connectToServer(const QString& url) { _serverUrl = url; _socket.open(QUrl(url)); } void NetworkManager::disconnect() { _heartbeatTimer.stop(); _socket.close(); } bool NetworkManager::isConnected() const { return _socket.state() == QAbstractSocket::ConnectedState; } void NetworkManager::sendMessage(const QString& type, const QJsonObject& payload) { QJsonObject msg; msg["type"] = type; msg["seq"] = ++_seqNum; msg["timestamp"] = QDateTime::currentMSecsSinceEpoch(); if (!payload.isEmpty()) msg["payload"] = payload; _socket.sendTextMessage(QJsonDocument(msg).toJson(QJsonDocument::Compact)); } void NetworkManager::joinRoom(const QString& roomId, const QString& nickname) { QJsonObject payload; payload["room_id"] = roomId; payload["nickname"] = nickname; sendMessage("join_room", payload); } void NetworkManager::createRoom(const QString& nickname, int maxPlayers) { QJsonObject payload; payload["nickname"] = nickname; payload["max_players"] = maxPlayers; sendMessage("create_room", payload); } void NetworkManager::leaveRoom() { sendMessage("leave_room"); } void NetworkManager::setReady(bool ready) { QJsonObject payload; payload["ready"] = ready; sendMessage("set_ready", payload); } void NetworkManager::startGame() { sendMessage("start_game"); } void NetworkManager::selectCard(const QString& cardUid) { QJsonObject payload; payload["card_uid"] = cardUid; sendMessage("select_card", payload); } void NetworkManager::confirmAction(const QString& action, const QJsonObject& extra) { QJsonObject payload; payload["action"] = action; if (!extra.isEmpty()) { for (auto it = extra.begin(); it != extra.end(); ++it) payload[it.key()] = it.value(); } sendMessage("confirm_action", payload); } void NetworkManager::effectResponse(const QJsonObject& response) { sendMessage("effect_response", response); } void NetworkManager::listRooms() { sendMessage("list_rooms"); } void NetworkManager::sendChat(const QString& text) { QJsonObject payload; payload["text"] = text; sendMessage("send_chat", payload); } void NetworkManager::sendBinaryFrame(const QByteArray& data) { if (_socket.state() == QAbstractSocket::ConnectedState) _socket.sendBinaryMessage(data); } void NetworkManager::onConnected() { _heartbeatTimer.start(15000); emit connected(); } void NetworkManager::onDisconnected() { _heartbeatTimer.stop(); emit disconnected(); } void NetworkManager::onTextMessageReceived(const QString& message) { auto doc = QJsonDocument::fromJson(message.toUtf8()); if (doc.isNull()) return; handleServerMessage(doc.object()); } void NetworkManager::onError(QAbstractSocket::SocketError error) { Q_UNUSED(error) emit connectionError(_socket.errorString()); } void NetworkManager::onHeartbeat() { sendMessage("heartbeat"); } void NetworkManager::handleServerMessage(const QJsonObject& msg) { auto type = msg["type"].toString(); auto payload = msg["payload"].toObject(); if (type == "room_state") { emit roomStateUpdated(payload); } else if (type == "game_start") { emit gameStarted(payload); } else if (type == "state_snapshot") { emit gameStateSnapshot(payload); } else if (type == "card_move") { emit cardMoveEvent(payload); } else if (type == "card_flip") { emit cardFlipEvent(payload); } else if (type == "effect_trigger") { emit effectTriggered(payload); } else if (type == "request_choice") { emit requestChoice(payload); } else if (type == "player_exit") { emit playerExited(payload); } else if (type == "settlement") { emit settlementNotify(payload); } else if (type == "game_end") { emit gameEnded(payload); } else if (type == "error") { emit errorNotify(payload); } else if (type == "chat") { emit chatMessage(payload); } else if (type == "room_created") { emit roomCreated(payload["room_id"].toString()); } else if (type == "room_joined") { emit roomJoined(payload); } else if (type == "room_left") { emit roomLeft(); } else if (type == "room_list") { emit roomListReceived(payload["rooms"].toArray()); } else if (type == "settlement_result") { emit settlementResult(payload); } }