Files
Embalming_Girl_Client/src/network/NetworkManager.cpp
T
2026-06-18 17:29:28 +08:00

170 lines
5.1 KiB
C++

#include "NetworkManager.h"
#include <QJsonArray>
#include <QDateTime>
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);
}
}