Compare commits

..

3 Commits

Author SHA1 Message Date
ebbit1q
8a126263a9 do not ignore return value of opening log in servatrice when rotating (#6564) 2026-01-24 15:05:26 -05:00
ebbit1q
afdb385770 move returning cards to server_game (#6561)
lock the game mutex instead of player mutex when returning cards
2026-01-24 12:54:29 -05:00
tooomm
5b8897231d CI: Include submodules in repo checkout (Docs deployment) (#6557)
* Enable submodule checkout in documentation build

* Change submodule checkout to recursive
2026-01-24 13:24:19 +01:00
5 changed files with 52 additions and 45 deletions

View File

@@ -22,6 +22,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install Graphviz
run: |

View File

@@ -575,51 +575,8 @@ Server_AbstractPlayer::cmdConcede(const Command_Concede & /*cmd*/, ResponseConta
setConceded(true);
game->removeArrowsRelatedToPlayer(ges, this);
game->unattachCards(ges, this);
game->returnCardsFromPlayer(ges, this);
playerMutex.lock();
// Return cards to their rightful owners before conceding the game
static const QRegularExpression ownerRegex{"Owner: ?([^\n]+)"};
for (const auto &card : zones.value("table")->getCards()) {
if (card == nullptr) {
continue;
}
const auto &regexResult = ownerRegex.match(card->getAnnotation());
if (!regexResult.hasMatch()) {
continue;
}
CardToMove cardToMove;
cardToMove.set_card_id(card->getId());
for (const auto *player : game->getPlayers()) {
if (player == nullptr || player->getUserInfo() == nullptr) {
continue;
}
const auto &ownerToReturnTo = regexResult.captured(1);
const auto &correctOwner = QString::compare(QString::fromStdString(player->getUserInfo()->name()),
ownerToReturnTo, Qt::CaseInsensitive) == 0;
if (!correctOwner) {
continue;
}
const auto &startZone = zones.value("table");
const auto &targetZone = player->getZones().value("table");
if (startZone == nullptr || targetZone == nullptr) {
continue;
}
moveCard(ges, startZone, QList<const CardToMove *>() << &cardToMove, targetZone, 0, 0, false);
break;
}
}
playerMutex.unlock();
// All borrowed cards have been returned, can now continue cleanup process
clearZones();
Event_PlayerPropertiesChanged event;

View File

@@ -23,6 +23,7 @@
#include "../server_database_interface.h"
#include "../server_protocolhandler.h"
#include "../server_room.h"
#include "libcockatrice/protocol/pb/command_move_card.pb.h"
#include "server_abstract_player.h"
#include "server_arrow.h"
#include "server_card.h"
@@ -31,6 +32,7 @@
#include "server_spectator.h"
#include <QDebug>
#include <QRegularExpression>
#include <QTimer>
#include <google/protobuf/descriptor.h>
#include <libcockatrice/deck_list/deck_list.h>
@@ -824,3 +826,46 @@ void Server_Game::getInfo(ServerInfo_Game &result) const
result.set_start_time(startTime.toSecsSinceEpoch());
}
}
void Server_Game::returnCardsFromPlayer(GameEventStorage &ges, Server_AbstractPlayer *player)
{
QMutexLocker locker(&gameMutex);
// Return cards to their rightful owners before conceding the game
static const QRegularExpression ownerRegex{"Owner: ?([^\n]+)"};
const auto &playerTable = player->getZones().value("table");
for (const auto &card : playerTable->getCards()) {
if (card == nullptr) {
continue;
}
const auto &regexResult = ownerRegex.match(card->getAnnotation());
if (!regexResult.hasMatch()) {
continue;
}
CardToMove cardToMove;
cardToMove.set_card_id(card->getId());
for (const auto *otherPlayer : getPlayers()) {
if (otherPlayer == nullptr || otherPlayer->getUserInfo() == nullptr) {
continue;
}
const auto &ownerToReturnTo = regexResult.captured(1);
const auto &correctOwner = QString::compare(QString::fromStdString(otherPlayer->getUserInfo()->name()),
ownerToReturnTo, Qt::CaseInsensitive) == 0;
if (!correctOwner) {
continue;
}
const auto &targetZone = otherPlayer->getZones().value("table");
if (playerTable == nullptr || targetZone == nullptr) {
continue;
}
player->moveCard(ges, playerTable, QList<const CardToMove *>() << &cardToMove, targetZone, 0, 0, false);
break;
}
}
}

View File

@@ -218,6 +218,7 @@ public:
GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate |
GameEventStorageItem::SendToOthers,
int privatePlayerId = -1);
void returnCardsFromPlayer(GameEventStorage &ges, Server_AbstractPlayer *player);
};
#endif

View File

@@ -116,7 +116,9 @@ void ServerLogger::rotateLogs()
flushBuffer();
logFile->close();
logFile->open(QIODevice::Append);
if (!logFile->open(QIODevice::Append)) {
std::cerr << "ERROR: Failed to open log file for writing!" << std::endl;
}
}
QFile *ServerLogger::logFile;