From 04665e4dd80d9f60dcdd35e0712f26e3aa8dbd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Sun, 5 Apr 2026 21:46:58 +0200 Subject: [PATCH] Rework Took 30 minutes --- cockatrice/src/main.cpp | 2 +- cockatrice/src/single_instance_manager.cpp | 89 ++++++++++++++++++++++ cockatrice/src/single_instance_manager.h | 46 +---------- 3 files changed, 94 insertions(+), 43 deletions(-) diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index c9866b508..6b20fd0a5 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -348,5 +348,5 @@ int main(int argc, char *argv[]) CountryPixmapGenerator::clear(); UserLevelPixmapGenerator::clear(); - return 0; + return ret; } diff --git a/cockatrice/src/single_instance_manager.cpp b/cockatrice/src/single_instance_manager.cpp index 9f5b5af38..d0be29eb3 100644 --- a/cockatrice/src/single_instance_manager.cpp +++ b/cockatrice/src/single_instance_manager.cpp @@ -1 +1,90 @@ #include "single_instance_manager.h" + +SingleInstanceManager::SingleInstanceManager(QObject *parent) : QObject(parent) +{ +} + +bool SingleInstanceManager::tryRun(const QStringList &initialFiles) +{ + serverName = "CockatriceSingleInstance"; + + QLocalSocket socket; + socket.connectToServer(serverName); + + if (socket.waitForConnected(200)) { + // Serialize into buffer first + QByteArray payload; + QDataStream out(&payload, QIODevice::WriteOnly); + out << initialFiles; + + // Prefix with size + QByteArray message; + QDataStream msgStream(&message, QIODevice::WriteOnly); + msgStream << quint32(payload.size()); + message.append(payload); + + socket.write(message); + socket.flush(); + socket.waitForBytesWritten(1000); + + return false; // Another instance is running + } + + // No other instance → start server + server = new QLocalServer(this); + + connect(server, &QLocalServer::newConnection, this, &SingleInstanceManager::handleNewConnection); + + if (!server->listen(serverName)) { + QLocalServer::removeServer(serverName); + server->listen(serverName); + } + + return true; +} +void SingleInstanceManager::handleNewConnection() +{ + QLocalSocket *socket = server->nextPendingConnection(); + + // Per-connection state + auto buffer = new QByteArray(); + auto expectedSize = new quint32(0); + + connect(socket, &QLocalSocket::readyRead, this, [this, socket, buffer, expectedSize]() { + buffer->append(socket->readAll()); + + QDataStream stream(buffer, QIODevice::ReadOnly); + + while (true) { + // Step 1: read size + if (*expectedSize == 0) { + if (buffer->size() < static_cast(sizeof(quint32))) + return; + + stream >> *expectedSize; + } + + // Step 2: wait for full payload + if (buffer->size() < static_cast(sizeof(quint32) + *expectedSize)) + return; + + // Step 3: extract payload + QByteArray payload = buffer->mid(sizeof(quint32), *expectedSize); + + QDataStream payloadStream(&payload, QIODevice::ReadOnly); + QStringList files; + payloadStream >> files; + + emit filesReceived(files); + + // Reset buffer (single message use-case) + buffer->clear(); + *expectedSize = 0; + + socket->disconnectFromServer(); + return; + } + }); + + connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater); +} \ No newline at end of file diff --git a/cockatrice/src/single_instance_manager.h b/cockatrice/src/single_instance_manager.h index 812f8d2aa..9f0e54d32 100644 --- a/cockatrice/src/single_instance_manager.h +++ b/cockatrice/src/single_instance_manager.h @@ -10,57 +10,19 @@ class SingleInstanceManager : public QObject { Q_OBJECT public: - explicit SingleInstanceManager(QObject *parent = nullptr) : QObject(parent) - { - } + explicit SingleInstanceManager(QObject *parent = nullptr); - bool tryRun(const QStringList &initialFiles) - { - serverName = "CockatriceSingleInstance"; - - QLocalSocket socket; - socket.connectToServer(serverName); - if (socket.waitForConnected(100)) { - // Another instance is running, send files/URLs to it - QDataStream out(&socket); - out << initialFiles; - socket.flush(); - socket.waitForBytesWritten(1000); - - return false; // Do not continue in this process - } - - // No other instance, create server - server = new QLocalServer(this); - connect(server, &QLocalServer::newConnection, this, &SingleInstanceManager::receiveFiles); - if (!server->listen(serverName)) { - QLocalServer::removeServer(serverName); - server->listen(serverName); - } - return true; - } + bool tryRun(const QStringList &initialFiles); signals: void filesReceived(const QStringList &files); private slots: - void receiveFiles() - { - QLocalSocket *clientConnection = server->nextPendingConnection(); - connect(clientConnection, &QLocalSocket::disconnected, clientConnection, &QLocalSocket::deleteLater); - clientConnection->waitForReadyRead(1000); - - QDataStream in(clientConnection); - QStringList files; - in >> files; - - emit filesReceived(files); - clientConnection->disconnectFromServer(); - } + void handleNewConnection(); private: QString serverName; QLocalServer *server = nullptr; }; -#endif // COCKATRICE_SINGLE_INSTANCE_MANAGER_H +#endif // COCKATRICE_SINGLE_INSTANCE_MANAGER_H \ No newline at end of file