mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-01-25 02:44:51 -08:00
Compare commits
6 Commits
2026-01-24
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c02cf5e89e | ||
|
|
92f02fa4ee | ||
|
|
49e6cf95c4 | ||
|
|
8a126263a9 | ||
|
|
afdb385770 | ||
|
|
5b8897231d |
2
.github/workflows/documentation-build.yml
vendored
2
.github/workflows/documentation-build.yml
vendored
@@ -22,6 +22,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Graphviz
|
||||
run: |
|
||||
|
||||
@@ -254,7 +254,7 @@ endif()
|
||||
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zach@cockatrice.us>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME}")
|
||||
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_PACKAGE_DESCRIPTION "Cockatrice is an open-source, multiplatform application for playing tabletop card games over a network. The program's server design prevents users from manipulating the game for unfair advantage. The client also provides a single-player mode, which allows users to brew while offline.")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||
|
||||
@@ -175,9 +175,11 @@ QModelIndex DeckStateManager::addCard(const ExactCard &card, const QString &zone
|
||||
|
||||
QString zone = card.getInfo().getIsToken() ? DECK_ZONE_TOKENS : zoneName;
|
||||
|
||||
QString reason = tr("Added (%1): %2 (%3) %4")
|
||||
.arg(zone, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
|
||||
card.getPrinting().getProperty("num"));
|
||||
CardSetPtr set = card.getPrinting().getSet();
|
||||
QString setName = set ? set->getCorrectedShortName() : "";
|
||||
|
||||
QString reason =
|
||||
tr("Added (%1): %2 (%3) %4").arg(zone, card.getName(), setName, card.getPrinting().getProperty("num"));
|
||||
|
||||
QModelIndex idx = modifyDeck(reason, [&card, &zone](auto model) { return model->addCard(card, zone); });
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ QString HomeStyledButton::generateButtonStylesheet(const QPair<QColor, QColor> &
|
||||
return QString(R"(
|
||||
QPushButton {
|
||||
font-size: 34px;
|
||||
font-weight: bold;
|
||||
font-family: sans-serif, "Segoe UI", "Helvetica Neue";
|
||||
padding: 30px;
|
||||
color: white;
|
||||
border: 2px solid %1;
|
||||
@@ -88,16 +90,12 @@ void HomeStyledButton::paintEvent(QPaintEvent *event)
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::TextAntialiasing);
|
||||
|
||||
QFont font = this->font();
|
||||
font.setBold(true);
|
||||
painter.setFont(font);
|
||||
|
||||
QFontMetrics fm(font);
|
||||
QSize textSize = fm.size(Qt::TextSingleLine, this->text());
|
||||
QFontMetrics fm(font());
|
||||
QSize textSize = fm.size(Qt::TextSingleLine, text());
|
||||
QPointF center((width() - textSize.width()) / 2.0, (height() + textSize.height() / 2.0) / 2.0);
|
||||
|
||||
QPainterPath path;
|
||||
path.addText(center, font, this->text());
|
||||
path.addText(center, font(), text());
|
||||
|
||||
painter.setPen(QPen(Qt::black, 2.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
painter.setBrush(Qt::white);
|
||||
|
||||
@@ -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 ®exResult = 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;
|
||||
|
||||
@@ -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 ®exResult = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ public:
|
||||
GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate |
|
||||
GameEventStorageItem::SendToOthers,
|
||||
int privatePlayerId = -1);
|
||||
void returnCardsFromPlayer(GameEventStorage &ges, Server_AbstractPlayer *player);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user