diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 04599409..5902e418 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -28,6 +28,8 @@ HEADERS += src/abstractcounter.h \ src/handcounter.h \ src/carddatabase.h \ src/gameview.h \ + src/gameselector.h \ + src/gametypemap.h \ src/decklistmodel.h \ src/dlg_load_deck_from_clipboard.h \ src/dlg_load_remote_deck.h \ @@ -114,6 +116,7 @@ SOURCES += src/abstractcounter.cpp \ src/handcounter.cpp \ src/carddatabase.cpp \ src/gameview.cpp \ + src/gameselector.cpp \ src/decklistmodel.cpp \ src/dlg_load_deck_from_clipboard.cpp \ src/dlg_load_remote_deck.cpp \ @@ -136,6 +139,7 @@ SOURCES += src/abstractcounter.cpp \ src/gamescene.cpp \ src/arrowitem.cpp \ src/arrowtarget.cpp \ + src/tab.cpp \ src/tab_server.cpp \ src/tab_room.cpp \ src/tab_message.cpp \ diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc index 55356130..3a75a53d 100644 --- a/cockatrice/cockatrice.qrc +++ b/cockatrice/cockatrice.qrc @@ -55,6 +55,7 @@ translations/cockatrice_pl.qm translations/cockatrice_sk.qm + resources/countries/ar.svg resources/countries/at.svg resources/countries/au.svg resources/countries/be.svg diff --git a/cockatrice/resources/countries/ar.svg b/cockatrice/resources/countries/ar.svg new file mode 100644 index 00000000..543196fc --- /dev/null +++ b/cockatrice/resources/countries/ar.svg @@ -0,0 +1,109 @@ + + + + + \ No newline at end of file diff --git a/cockatrice/resources/phases/icon_phase_cleanup.svg b/cockatrice/resources/phases/icon_phase_cleanup.svg index a675d66f..9786daca 100644 --- a/cockatrice/resources/phases/icon_phase_cleanup.svg +++ b/cockatrice/resources/phases/icon_phase_cleanup.svg @@ -1,749 +1,186 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_combat_attackers.svg b/cockatrice/resources/phases/icon_phase_combat_attackers.svg index 540107ac..d7483253 100644 --- a/cockatrice/resources/phases/icon_phase_combat_attackers.svg +++ b/cockatrice/resources/phases/icon_phase_combat_attackers.svg @@ -1,162 +1,103 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_combat_blockers.svg b/cockatrice/resources/phases/icon_phase_combat_blockers.svg index 6344ef6b..6602eaef 100644 --- a/cockatrice/resources/phases/icon_phase_combat_blockers.svg +++ b/cockatrice/resources/phases/icon_phase_combat_blockers.svg @@ -1,181 +1,1930 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_combat_damage.svg b/cockatrice/resources/phases/icon_phase_combat_damage.svg index 8536764e..aa356e2a 100644 --- a/cockatrice/resources/phases/icon_phase_combat_damage.svg +++ b/cockatrice/resources/phases/icon_phase_combat_damage.svg @@ -1,169 +1,108 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_combat_end.svg b/cockatrice/resources/phases/icon_phase_combat_end.svg index 9e7b8950..bbbbf9bf 100644 --- a/cockatrice/resources/phases/icon_phase_combat_end.svg +++ b/cockatrice/resources/phases/icon_phase_combat_end.svg @@ -1,253 +1,319 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_combat_start.svg b/cockatrice/resources/phases/icon_phase_combat_start.svg index 996571d7..b80b571d 100644 --- a/cockatrice/resources/phases/icon_phase_combat_start.svg +++ b/cockatrice/resources/phases/icon_phase_combat_start.svg @@ -1,253 +1,348 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_draw.svg b/cockatrice/resources/phases/icon_phase_draw.svg index 51918274..4d106219 100644 --- a/cockatrice/resources/phases/icon_phase_draw.svg +++ b/cockatrice/resources/phases/icon_phase_draw.svg @@ -1,192 +1,190 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_main1.svg b/cockatrice/resources/phases/icon_phase_main1.svg index 264cef39..48fce651 100644 --- a/cockatrice/resources/phases/icon_phase_main1.svg +++ b/cockatrice/resources/phases/icon_phase_main1.svg @@ -1,135 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_main2.svg b/cockatrice/resources/phases/icon_phase_main2.svg index 50f77fa7..61be736e 100644 --- a/cockatrice/resources/phases/icon_phase_main2.svg +++ b/cockatrice/resources/phases/icon_phase_main2.svg @@ -1,135 +1,235 @@ - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_nextturn.svg b/cockatrice/resources/phases/icon_phase_nextturn.svg index 3cfd19ab..302a57d6 100644 --- a/cockatrice/resources/phases/icon_phase_nextturn.svg +++ b/cockatrice/resources/phases/icon_phase_nextturn.svg @@ -1,89 +1,102 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_untap.svg b/cockatrice/resources/phases/icon_phase_untap.svg index 2f4d8173..3d316ab0 100644 --- a/cockatrice/resources/phases/icon_phase_untap.svg +++ b/cockatrice/resources/phases/icon_phase_untap.svg @@ -1,198 +1,120 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases/icon_phase_upkeep.svg b/cockatrice/resources/phases/icon_phase_upkeep.svg index 5a06aae9..2317a937 100644 --- a/cockatrice/resources/phases/icon_phase_upkeep.svg +++ b/cockatrice/resources/phases/icon_phase_upkeep.svg @@ -1,159 +1,162 @@ - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_cleanup.svg b/cockatrice/resources/phases_old/icon_phase_cleanup.svg new file mode 100644 index 00000000..a675d66f --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_cleanup.svg @@ -0,0 +1,749 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg b/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg new file mode 100644 index 00000000..540107ac --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg b/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg new file mode 100644 index 00000000..6344ef6b --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_combat_damage.svg b/cockatrice/resources/phases_old/icon_phase_combat_damage.svg new file mode 100644 index 00000000..8536764e --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_combat_damage.svg @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_combat_end.svg b/cockatrice/resources/phases_old/icon_phase_combat_end.svg new file mode 100644 index 00000000..9e7b8950 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_combat_end.svg @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_combat_start.svg b/cockatrice/resources/phases_old/icon_phase_combat_start.svg new file mode 100644 index 00000000..996571d7 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_combat_start.svg @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_draw.svg b/cockatrice/resources/phases_old/icon_phase_draw.svg new file mode 100644 index 00000000..51918274 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_draw.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_main1.svg b/cockatrice/resources/phases_old/icon_phase_main1.svg new file mode 100644 index 00000000..264cef39 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_main1.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_main2.svg b/cockatrice/resources/phases_old/icon_phase_main2.svg new file mode 100644 index 00000000..50f77fa7 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_main2.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_nextturn.svg b/cockatrice/resources/phases_old/icon_phase_nextturn.svg new file mode 100644 index 00000000..3cfd19ab --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_nextturn.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_untap.svg b/cockatrice/resources/phases_old/icon_phase_untap.svg new file mode 100644 index 00000000..2f4d8173 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_untap.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/phases_old/icon_phase_upkeep.svg b/cockatrice/resources/phases_old/icon_phase_upkeep.svg new file mode 100644 index 00000000..5a06aae9 --- /dev/null +++ b/cockatrice/resources/phases_old/icon_phase_upkeep.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cockatrice/src/abstractcarditem.cpp b/cockatrice/src/abstractcarditem.cpp index 020b6dfc..20e7c8e9 100644 --- a/cockatrice/src/abstractcarditem.cpp +++ b/cockatrice/src/abstractcarditem.cpp @@ -26,6 +26,7 @@ AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, QGraphi AbstractCardItem::~AbstractCardItem() { qDebug() << "AbstractCardItem destructor:" << name; + emit deleteCardInfoPopup(name); } QRectF AbstractCardItem::boundingRect() const @@ -157,6 +158,10 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * void AbstractCardItem::setName(const QString &_name) { + if (name == _name) + return; + + emit deleteCardInfoPopup(name); disconnect(info, 0, this, 0); name = _name; info = db->getCard(name); @@ -213,7 +218,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event) void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::MidButton) - emit deleteCardInfoPopup(); + emit deleteCardInfoPopup(name); // This function ensures the parent function doesn't mess around with our selection. event->accept(); diff --git a/cockatrice/src/abstractcarditem.h b/cockatrice/src/abstractcarditem.h index c1345564..e11bdf85 100644 --- a/cockatrice/src/abstractcarditem.h +++ b/cockatrice/src/abstractcarditem.h @@ -30,7 +30,7 @@ private slots: signals: void hovered(AbstractCardItem *card); void showCardInfoPopup(QPoint pos, QString cardName); - void deleteCardInfoPopup(); + void deleteCardInfoPopup(QString cardName); public: enum { Type = typeCard }; int type() const { return Type; } @@ -50,6 +50,7 @@ public: bool getTapped() const { return tapped; } void setTapped(bool _tapped, bool canAnimate = false); void processHoverEvent(); + void deleteCardInfoPopup() { emit deleteCardInfoPopup(name); } protected: QSizeF getTranslatedSize(QPainter *painter) const; void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle); diff --git a/cockatrice/src/abstractclient.cpp b/cockatrice/src/abstractclient.cpp index 5fb9b433..7edb7a2e 100644 --- a/cockatrice/src/abstractclient.cpp +++ b/cockatrice/src/abstractclient.cpp @@ -32,15 +32,16 @@ void AbstractClient::processProtocolItem(ProtocolItem *item) GenericEvent *genericEvent = qobject_cast(item); if (genericEvent) { switch (genericEvent->getItemId()) { - case ItemId_Event_ConnectionClosed: emit connectionClosedEventReceived(qobject_cast(item)); break; - case ItemId_Event_AddToList: emit addToListEventReceived(qobject_cast(item)); break; - case ItemId_Event_RemoveFromList: emit removeFromListEventReceived(qobject_cast(item)); break; - case ItemId_Event_UserJoined: emit userJoinedEventReceived(qobject_cast(item)); break; - case ItemId_Event_UserLeft: emit userLeftEventReceived(qobject_cast(item)); break; - case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast(item)); break; - case ItemId_Event_ListRooms: emit listRoomsEventReceived(qobject_cast(item)); break; - case ItemId_Event_GameJoined: emit gameJoinedEventReceived(qobject_cast(item)); break; - case ItemId_Event_Message: emit messageEventReceived(qobject_cast(item)); break; + case ItemId_Event_ConnectionClosed: emit connectionClosedEventReceived(static_cast(item)); break; + case ItemId_Event_ServerShutdown: emit serverShutdownEventReceived(static_cast(item)); break; + case ItemId_Event_AddToList: emit addToListEventReceived(static_cast(item)); break; + case ItemId_Event_RemoveFromList: emit removeFromListEventReceived(static_cast(item)); break; + case ItemId_Event_UserJoined: emit userJoinedEventReceived(static_cast(item)); break; + case ItemId_Event_UserLeft: emit userLeftEventReceived(static_cast(item)); break; + case ItemId_Event_ServerMessage: emit serverMessageEventReceived(static_cast(item)); break; + case ItemId_Event_ListRooms: emit listRoomsEventReceived(static_cast(item)); break; + case ItemId_Event_GameJoined: emit gameJoinedEventReceived(static_cast(item)); break; + case ItemId_Event_Message: emit messageEventReceived(static_cast(item)); break; } if (genericEvent->getReceiverMayDelete()) delete genericEvent; diff --git a/cockatrice/src/abstractclient.h b/cockatrice/src/abstractclient.h index f43131b5..d896a89d 100644 --- a/cockatrice/src/abstractclient.h +++ b/cockatrice/src/abstractclient.h @@ -21,6 +21,7 @@ class Event_ListRooms; class Event_GameJoined; class Event_Message; class Event_ConnectionClosed; +class Event_ServerShutdown; enum ClientStatus { StatusDisconnected, @@ -43,6 +44,7 @@ signals: void gameEventContainerReceived(GameEventContainer *event); // Generic events void connectionClosedEventReceived(Event_ConnectionClosed *event); + void serverShutdownEventReceived(Event_ServerShutdown *event); void addToListEventReceived(Event_AddToList *event); void removeFromListEventReceived(Event_RemoveFromList *event); void userJoinedEventReceived(Event_UserJoined *event); diff --git a/cockatrice/src/cardinfowidget.cpp b/cockatrice/src/cardinfowidget.cpp index 37b14edf..1ce584b2 100644 --- a/cockatrice/src/cardinfowidget.cpp +++ b/cockatrice/src/cardinfowidget.cpp @@ -172,8 +172,7 @@ void CardInfoWidget::resizeEvent(QResizeEvent * /*event*/) } } -void CardInfoWidget::mouseReleaseEvent(QMouseEvent *event) +QString CardInfoWidget::getCardName() const { - if ((event->button() == Qt::MidButton) && (mode == ModePopUp)) - emit mouseReleased(); -} + return nameLabel2->text(); +} \ No newline at end of file diff --git a/cockatrice/src/cardinfowidget.h b/cockatrice/src/cardinfowidget.h index 819f514b..21ee7ccd 100644 --- a/cockatrice/src/cardinfowidget.h +++ b/cockatrice/src/cardinfowidget.h @@ -39,6 +39,7 @@ private: public: CardInfoWidget(ResizeMode _mode, QWidget *parent = 0, Qt::WindowFlags f = 0); void retranslateUi(); + QString getCardName() const; public slots: void setCard(CardInfo *card); @@ -50,12 +51,8 @@ private slots: void updatePixmap(); void minimizeClicked(int newMinimized); -signals: - void mouseReleased(); - protected: void resizeEvent(QResizeEvent *event); - void mouseReleaseEvent(QMouseEvent *event); }; #endif diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index 86194390..afc15e8c 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -34,6 +34,8 @@ CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, bool _reve connect(aAttach, SIGNAL(triggered()), this, SLOT(actAttach())); aUnattach = new QAction(this); connect(aUnattach, SIGNAL(triggered()), this, SLOT(actUnattach())); + aDrawArrow = new QAction(this); + connect(aDrawArrow, SIGNAL(triggered()), this, SLOT(actDrawArrow())); aIncP = new QAction(this); connect(aIncP, SIGNAL(triggered()), this, SLOT(actIncP())); aDecP = new QAction(this); @@ -172,6 +174,7 @@ void CardItem::updateCardMenu() cardMenu->addAction(aAttach); if (attachedTo) cardMenu->addAction(aUnattach); + cardMenu->addAction(aDrawArrow); cardMenu->addSeparator(); cardMenu->addMenu(ptMenu); cardMenu->addAction(aSetAnnotation); @@ -186,6 +189,9 @@ void CardItem::updateCardMenu() cardMenu->addAction(aSetCounter[i]); } cardMenu->addSeparator(); + } else if (zone->getName() == "stack") { + cardMenu->addAction(aDrawArrow); + cardMenu->addMenu(moveMenu); } else { cardMenu->addAction(aPlay); cardMenu->addMenu(moveMenu); @@ -209,6 +215,7 @@ void CardItem::retranslateUi() aAttach->setText(tr("&Attach to card...")); aAttach->setShortcut(tr("Ctrl+A")); aUnattach->setText(tr("Unattac&h")); + aDrawArrow->setText(tr("&Draw arrow...")); ptMenu->setTitle(tr("&Power / toughness")); aIncP->setText(tr("&Increase power")); aIncP->setShortcut(tr("Ctrl++")); @@ -399,13 +406,35 @@ void CardItem::deleteDragItem() dragItem = NULL; } +void CardItem::drawArrow(const QColor &arrowColor) +{ + if (static_cast(owner->parent())->getSpectator()) + return; + + Player *arrowOwner = static_cast(owner->parent())->getActiveLocalPlayer(); + ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor); + scene()->addItem(arrow); + arrow->grabMouse(); + + QListIterator itemIterator(scene()->selectedItems()); + while (itemIterator.hasNext()) { + CardItem *c = qgraphicsitem_cast(itemIterator.next()); + if (!c || (c == this)) + continue; + if (c->getZone() != zone) + continue; + + ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor); + scene()->addItem(childArrow); + arrow->addChildArrow(childArrow); + } +} + void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (event->buttons().testFlag(Qt::RightButton)) { if ((event->screenPos() - event->buttonDownScreenPos(Qt::RightButton)).manhattanLength() < 2 * QApplication::startDragDistance()) return; - if (static_cast(owner->parent())->getSpectator()) - return; QColor arrowColor = Qt::red; if (event->modifiers().testFlag(Qt::ControlModifier)) @@ -415,23 +444,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) else if (event->modifiers().testFlag(Qt::ShiftModifier)) arrowColor = Qt::green; - Player *arrowOwner = static_cast(owner->parent())->getActiveLocalPlayer(); - ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor); - scene()->addItem(arrow); - arrow->grabMouse(); - - QListIterator itemIterator(scene()->selectedItems()); - while (itemIterator.hasNext()) { - CardItem *c = qgraphicsitem_cast(itemIterator.next()); - if (!c || (c == this)) - continue; - if (c->getZone() != zone) - continue; - - ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor); - scene()->addItem(childArrow); - arrow->addChildArrow(childArrow); - } + drawArrow(arrowColor); } else if (event->buttons().testFlag(Qt::LeftButton)) { if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < 2 * QApplication::startDragDistance()) return; @@ -547,6 +560,11 @@ void CardItem::actUnattach() owner->actUnattach(static_cast(sender())); } +void CardItem::actDrawArrow() +{ + drawArrow(Qt::red); +} + void CardItem::actIncP() { owner->actIncPT(1, 0); diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index 88b19d6f..6c02a4bb 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -9,6 +9,7 @@ class CardZone; class ServerInfo_Card; class Player; class QAction; +class QColor; const int MAX_COUNTERS_ON_CARD = 999; @@ -33,17 +34,19 @@ private: QList aAddCounter, aSetCounter, aRemoveCounter; QAction *aPlay, *aHide, - *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aIncP, *aDecP, *aIncT, *aDecT, *aIncPT, *aDecPT, *aSetAnnotation, *aFlip, *aClone, + *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aDrawArrow, *aSetPT, *aIncP, *aDecP, *aIncT, *aDecT, *aIncPT, *aDecPT, *aSetAnnotation, *aFlip, *aClone, *aMoveToTopLibrary, *aMoveToBottomLibrary, *aMoveToGraveyard, *aMoveToExile; QMenu *cardMenu, *ptMenu, *moveMenu; void playCard(bool faceDown); + void drawArrow(const QColor &arrowColor); void prepareDelete(); private slots: void cardMenuAction(); void actCardCounterTrigger(); void actAttach(); void actUnattach(); + void actDrawArrow(); void actSetPT(); void actIncP(); void actDecP(); diff --git a/cockatrice/src/chatview.cpp b/cockatrice/src/chatview.cpp index 625301e3..9aecfd1e 100644 --- a/cockatrice/src/chatview.cpp +++ b/cockatrice/src/chatview.cpp @@ -1,35 +1,73 @@ #include #include -#include #include +#include +#include #include "chatview.h" -ChatView::ChatView(const QString &_ownName, QWidget *parent) - : QTextEdit(parent), ownName(_ownName) +ChatView::ChatView(const QString &_ownName, bool _showTimestamps, QWidget *parent) + : QTextBrowser(parent), evenNumber(true), ownName(_ownName), showTimestamps(_showTimestamps) { - setTextInteractionFlags(Qt::TextSelectableByMouse); + setReadOnly(true); + setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); + setOpenLinks(false); + connect(this, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(openLink(const QUrl &))); } -void ChatView::appendMessage(QString sender, const QString &message) +QTextCursor ChatView::prepareBlock(bool same) { + lastSender.clear(); + QTextCursor cursor(document()->lastBlock()); cursor.movePosition(QTextCursor::End); + if (!same) { + QTextBlockFormat blockFormat; + if ((evenNumber = !evenNumber)) + blockFormat.setBackground(palette().alternateBase()); + blockFormat.setBottomMargin(2); + cursor.insertBlock(blockFormat); + } else + cursor.insertHtml("
"); - QTextBlockFormat blockFormat; - blockFormat.setBottomMargin(3); - cursor.insertBlock(blockFormat); + return cursor; +} + +void ChatView::appendHtml(const QString &html) +{ + prepareBlock().insertHtml(html); + verticalScrollBar()->setValue(verticalScrollBar()->maximum()); +} + +void ChatView::appendMessage(QString sender, QString message, QColor playerColor, bool playerBold) +{ + bool sameSender = (sender == lastSender) && !lastSender.isEmpty(); + QTextCursor cursor = prepareBlock(sameSender); + lastSender = sender; - QTextCharFormat timeFormat; - timeFormat.setForeground(Qt::black); - cursor.setCharFormat(timeFormat); - cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm] ")); + if (showTimestamps) { + QTextCharFormat timeFormat; + if (sameSender) + timeFormat.setForeground(Qt::transparent); + else + timeFormat.setForeground(Qt::black); + cursor.setCharFormat(timeFormat); + cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm] ")); + } QTextCharFormat senderFormat; if (sender == ownName) { senderFormat.setFontWeight(QFont::Bold); senderFormat.setForeground(Qt::red); - } else - senderFormat.setForeground(Qt::blue); + } else { + if (playerColor == QColor()) + senderFormat.setForeground(QColor(0, 0, 254)); + else + senderFormat.setForeground(playerColor); + if (playerBold) + senderFormat.setFontWeight(QFont::Bold); + } + if (sameSender) + senderFormat.setForeground(Qt::transparent); cursor.setCharFormat(senderFormat); if (!sender.isEmpty()) sender.append(": "); @@ -39,7 +77,122 @@ void ChatView::appendMessage(QString sender, const QString &message) if (sender.isEmpty()) messageFormat.setForeground(Qt::darkGreen); cursor.setCharFormat(messageFormat); - cursor.insertText(message); + + int from = 0, index = 0; + while ((index = message.indexOf('[', from)) != -1) { + cursor.insertText(message.left(index)); + message = message.mid(index); + if (message.isEmpty()) + break; + + if (message.startsWith("[card]")) { + message = message.mid(6); + QTextCharFormat tempFormat = messageFormat; + tempFormat.setForeground(Qt::blue); + cursor.setCharFormat(tempFormat); + int closeTagIndex = message.indexOf("[/card]"); + cursor.insertText(message.left(closeTagIndex)); + cursor.setCharFormat(messageFormat); + if (closeTagIndex == -1) + message.clear(); + else + message = message.mid(closeTagIndex + 7); + } else if (message.startsWith("[url]")) { + message = message.mid(5); + int closeTagIndex = message.indexOf("[/url]"); + QString url = message.left(closeTagIndex); + if (!url.startsWith("http://")) + url.prepend("http://"); + QTextCharFormat tempFormat = messageFormat; + tempFormat.setForeground(QColor(0, 0, 254)); + tempFormat.setAnchor(true); + tempFormat.setAnchorHref(url); + cursor.setCharFormat(tempFormat); + cursor.insertText(url); + cursor.setCharFormat(messageFormat); + if (closeTagIndex == -1) + message.clear(); + else + message = message.mid(closeTagIndex + 6); + } else + from = 1; + } + if (!message.isEmpty()) + cursor.insertText(message); verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } + +void ChatView::enterEvent(QEvent * /*event*/) +{ + setMouseTracking(true); +} + +void ChatView::leaveEvent(QEvent * /*event*/) +{ + setMouseTracking(false); +} + +QTextFragment ChatView::getFragmentUnderMouse(const QPoint &pos) const +{ + QTextCursor cursor(cursorForPosition(pos)); + QTextBlock block(cursor.block()); + QTextBlock::iterator it; + for (it = block.begin(); !(it.atEnd()); ++it) { + QTextFragment frag = it.fragment(); + if (frag.contains(cursor.position())) + return frag; + } + return QTextFragment(); +} + +QString ChatView::getCardNameUnderMouse(QTextFragment frag) const +{ + if (frag.charFormat().foreground().color() == Qt::blue) + return frag.text(); + return QString(); +} + +QString ChatView::getCardNameUnderMouse(const QPoint &pos) const +{ + return getCardNameUnderMouse(getFragmentUnderMouse(pos)); +} + +void ChatView::mouseMoveEvent(QMouseEvent *event) +{ + QTextFragment frag = getFragmentUnderMouse(event->pos()); + QString cardName = getCardNameUnderMouse(frag); + if (!cardName.isEmpty()) { + viewport()->setCursor(Qt::PointingHandCursor); + emit cardNameHovered(cardName); + } else if (frag.charFormat().isAnchor()) + viewport()->setCursor(Qt::PointingHandCursor); + else + viewport()->setCursor(Qt::IBeamCursor); + + QTextBrowser::mouseMoveEvent(event); +} + +void ChatView::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::MidButton) { + QString cardName = getCardNameUnderMouse(event->pos()); + if (!cardName.isEmpty()) + emit showCardInfoPopup(event->globalPos(), cardName); + } + + QTextBrowser::mousePressEvent(event); +} + +void ChatView::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::MidButton) + emit deleteCardInfoPopup(QString("_")); + + QTextBrowser::mouseReleaseEvent(event); +} + +void ChatView::openLink(const QUrl &link) +{ + QDesktopServices::openUrl(link); +} diff --git a/cockatrice/src/chatview.h b/cockatrice/src/chatview.h index bd7e763a..33c583c6 100644 --- a/cockatrice/src/chatview.h +++ b/cockatrice/src/chatview.h @@ -1,18 +1,41 @@ #ifndef CHATVIEW_H #define CHATVIEW_H -#include +#include +#include +#include +#include class QTextTable; +class QMouseEvent; -class ChatView : public QTextEdit { +class ChatView : public QTextBrowser { Q_OBJECT; private: - QTextTable *table; + QString lastSender; + bool evenNumber; QString ownName; + bool showTimestamps; + QTextFragment getFragmentUnderMouse(const QPoint &pos) const; + QString getCardNameUnderMouse(QTextFragment frag) const; + QString getCardNameUnderMouse(const QPoint &pos) const; + QTextCursor prepareBlock(bool same = false); +private slots: + void openLink(const QUrl &link); public: - ChatView(const QString &_ownName, QWidget *parent = 0); - void appendMessage(QString sender, const QString &message); + ChatView(const QString &_ownName, bool _showTimestamps, QWidget *parent = 0); + void appendHtml(const QString &html); + void appendMessage(QString sender, QString message, QColor playerColor = QColor(), bool playerBold = false); +protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); +signals: + void cardNameHovered(QString cardName); + void showCardInfoPopup(QPoint pos, QString cardName); + void deleteCardInfoPopup(QString cardName); }; #endif \ No newline at end of file diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp index b96c93a1..0d5b69f4 100644 --- a/cockatrice/src/dlg_creategame.cpp +++ b/cockatrice/src/dlg_creategame.cpp @@ -17,6 +17,7 @@ DlgCreateGame::DlgCreateGame(AbstractClient *_client, int _roomId, const QMapsetBuddy(descriptionEdit); + descriptionEdit->setMaxLength(60); maxPlayersLabel = new QLabel(tr("P&layers:")); maxPlayersEdit = new QSpinBox(); diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index 3f1c5a3d..01d4445a 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "carddatabase.h" #include "dlg_settings.h" #include "main.h" @@ -242,8 +243,17 @@ AppearanceSettingsPage::AppearanceSettingsPage() invertVerticalCoordinateCheckBox->setChecked(settingsCache->getInvertVerticalCoordinate()); connect(invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setInvertVerticalCoordinate(int))); + minPlayersForMultiColumnLayoutLabel = new QLabel; + minPlayersForMultiColumnLayoutEdit = new QSpinBox; + minPlayersForMultiColumnLayoutEdit->setMinimum(2); + minPlayersForMultiColumnLayoutEdit->setValue(settingsCache->getMinPlayersForMultiColumnLayout()); + connect(minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), settingsCache, SLOT(setMinPlayersForMultiColumnLayout(int))); + minPlayersForMultiColumnLayoutLabel->setBuddy(minPlayersForMultiColumnLayoutEdit); + QGridLayout *tableGrid = new QGridLayout; tableGrid->addWidget(invertVerticalCoordinateCheckBox, 0, 0, 1, 2); + tableGrid->addWidget(minPlayersForMultiColumnLayoutLabel, 1, 0, 1, 1); + tableGrid->addWidget(minPlayersForMultiColumnLayoutEdit, 1, 1, 1, 1); tableGroupBox = new QGroupBox; tableGroupBox->setLayout(tableGrid); @@ -289,6 +299,7 @@ void AppearanceSettingsPage::retranslateUi() tableGroupBox->setTitle(tr("Table grid layout")); invertVerticalCoordinateCheckBox->setText(tr("Invert vertical coordinate")); + minPlayersForMultiColumnLayoutLabel->setText(tr("Minimum player count for multi-column layout:")); zoneViewGroupBox->setTitle(tr("Zone view layout")); zoneViewSortByNameCheckBox->setText(tr("Sort by name")); diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h index 859376d6..f7bd1a52 100644 --- a/cockatrice/src/dlg_settings.h +++ b/cockatrice/src/dlg_settings.h @@ -14,6 +14,7 @@ class QGroupBox; class QCheckBox; class QLabel; class QCloseEvent; +class QSpinBox; class AbstractSettingsPage : public QWidget { public: @@ -65,10 +66,11 @@ signals: void playerAreaBgChanged(const QString &path); void cardBackPicturePathChanged(const QString &path); private: - QLabel *handBgLabel, *stackBgLabel, *tableBgLabel, *playerAreaBgLabel, *cardBackPicturePathLabel; + QLabel *handBgLabel, *stackBgLabel, *tableBgLabel, *playerAreaBgLabel, *cardBackPicturePathLabel, *minPlayersForMultiColumnLayoutLabel; QLineEdit *handBgEdit, *stackBgEdit, *tableBgEdit, *playerAreaBgEdit, *cardBackPicturePathEdit; QCheckBox *displayCardNamesCheckBox, *horizontalHandCheckBox, *invertVerticalCoordinateCheckBox, *zoneViewSortByNameCheckBox, *zoneViewSortByTypeCheckBox; QGroupBox *zoneBgGroupBox, *cardsGroupBox, *handGroupBox, *tableGroupBox, *zoneViewGroupBox; + QSpinBox *minPlayersForMultiColumnLayoutEdit; public: AppearanceSettingsPage(); void retranslateUi(); diff --git a/cockatrice/src/gamescene.cpp b/cockatrice/src/gamescene.cpp index 8785adcc..8a8dd17c 100644 --- a/cockatrice/src/gamescene.cpp +++ b/cockatrice/src/gamescene.cpp @@ -3,6 +3,7 @@ #include "zoneviewwidget.h" #include "zoneviewzone.h" #include "phasestoolbar.h" +#include "settingscache.h" #include #include #include @@ -14,6 +15,7 @@ GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent) { animationTimer = new QBasicTimer; addItem(phasesToolbar); + connect(settingsCache, SIGNAL(minPlayersForMultiColumnLayoutChanged()), this, SLOT(rearrange())); } GameScene::~GameScene() @@ -59,7 +61,7 @@ void GameScene::rearrange() if (firstPlayer == -1) firstPlayer = 0; const int playersCount = playersPlaying.size(); - const int columns = playersCount < 4 ? 1 : 2; + const int columns = playersCount < settingsCache->getMinPlayersForMultiColumnLayout() ? 1 : 2; const int rows = ceil((qreal) playersCount / columns); qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing; diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp new file mode 100644 index 00000000..1feb63d0 --- /dev/null +++ b/cockatrice/src/gameselector.cpp @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "dlg_creategame.h" +#include "abstractclient.h" +#include "protocol_items.h" +#include "gameselector.h" +#include "gamesmodel.h" + +GameSelector::GameSelector(AbstractClient *_client, TabRoom *_room, const QMap &_rooms, const QMap &_gameTypes, QWidget *parent) + : QGroupBox(parent), client(_client), room(_room) +{ + gameListView = new QTreeView; + gameListModel = new GamesModel(_rooms, _gameTypes, this); + gameListProxyModel = new GamesProxyModel(this); + gameListProxyModel->setSourceModel(gameListModel); + gameListProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + gameListView->setModel(gameListProxyModel); + gameListView->setSortingEnabled(true); + gameListView->setAlternatingRowColors(true); + if (_room) + gameListView->header()->hideSection(0); + gameListView->header()->setResizeMode(1, QHeaderView::ResizeToContents); + + showFullGamesCheckBox = new QCheckBox; + showRunningGamesCheckBox = new QCheckBox; + + QVBoxLayout *filterLayout = new QVBoxLayout; + filterLayout->addWidget(showFullGamesCheckBox); + filterLayout->addWidget(showRunningGamesCheckBox); + + if (room) + createButton = new QPushButton; + else + createButton = 0; + joinButton = new QPushButton; + spectateButton = new QPushButton; + + QHBoxLayout *buttonLayout = new QHBoxLayout; + if (room) + buttonLayout->addWidget(createButton); + buttonLayout->addWidget(joinButton); + buttonLayout->addWidget(spectateButton); + buttonLayout->setAlignment(Qt::AlignTop); + + QHBoxLayout *hbox = new QHBoxLayout; + hbox->addLayout(filterLayout); + hbox->addStretch(); + hbox->addLayout(buttonLayout); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(gameListView); + mainLayout->addLayout(hbox); + + retranslateUi(); + setLayout(mainLayout); + + setMinimumWidth((qreal) (gameListView->columnWidth(0) * gameListModel->columnCount()) / 1.5); + setMinimumHeight(200); + + connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int))); + connect(showRunningGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showRunningGamesChanged(int))); + connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate())); + connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin())); + connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin())); +} + +void GameSelector::showFullGamesChanged(int state) +{ + gameListProxyModel->setFullGamesVisible(state); +} + +void GameSelector::showRunningGamesChanged(int state) +{ + gameListProxyModel->setRunningGamesVisible(state); +} + +void GameSelector::actCreate() +{ + DlgCreateGame dlg(client, room->getRoomId(), room->getGameTypes(), this); + dlg.exec(); +} + +void GameSelector::checkResponse(ResponseCode response) +{ + if (createButton) + createButton->setEnabled(true); + joinButton->setEnabled(true); + spectateButton->setEnabled(true); + + switch (response) { + case RespNotInRoom: QMessageBox::critical(this, tr("Error"), tr("Please join the appropriate room first.")); break; + case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break; + case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break; + case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break; + case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break; + case RespUserLevelTooLow: QMessageBox::critical(this, tr("Error"), tr("This game is only open to registered users.")); break; + case RespOnlyBuddies: QMessageBox::critical(this, tr("Error"), tr("This game is only open to its creator's buddies.")); break; + case RespInIgnoreList: QMessageBox::critical(this, tr("Error"), tr("You are being ignored by the creator of this game.")); break; + default: ; + } +} + +void GameSelector::actJoin() +{ + bool spectator = sender() == spectateButton; + + QModelIndex ind = gameListView->currentIndex(); + if (!ind.isValid()) + return; + ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); + QString password; + if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) { + bool ok; + password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); + if (!ok) + return; + } + + Command_JoinGame *commandJoinGame = new Command_JoinGame(game->getRoomId(), game->getGameId(), password, spectator); + connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode))); + client->sendCommand(commandJoinGame); + + if (createButton) + createButton->setEnabled(false); + joinButton->setEnabled(false); + spectateButton->setEnabled(false); +} + +void GameSelector::retranslateUi() +{ + setTitle(tr("Games")); + showFullGamesCheckBox->setText(tr("Show &full games")); + showRunningGamesCheckBox->setText(tr("Show &running games")); + if (createButton) + createButton->setText(tr("C&reate")); + joinButton->setText(tr("&Join")); + spectateButton->setText(tr("J&oin as spectator")); +} + +void GameSelector::processGameInfo(ServerInfo_Game *info) +{ + gameListModel->updateGameList(info); +} + diff --git a/cockatrice/src/gameselector.h b/cockatrice/src/gameselector.h new file mode 100644 index 00000000..cf603b33 --- /dev/null +++ b/cockatrice/src/gameselector.h @@ -0,0 +1,42 @@ +#ifndef GAMESELECTOR_H +#define GAMESELECTOR_H + +#include +#include "protocol_datastructures.h" +#include "tab_room.h" +#include "gametypemap.h" + +class QTreeView; +class GamesModel; +class GamesProxyModel; +class QPushButton; +class QCheckBox; +class AbstractClient; +class TabRoom; + +class GameSelector : public QGroupBox { + Q_OBJECT +private slots: + void showFullGamesChanged(int state); + void showRunningGamesChanged(int state); + void actCreate(); + void actJoin(); + void checkResponse(ResponseCode response); +signals: + void gameJoined(int gameId); +private: + AbstractClient *client; + TabRoom *room; + + QTreeView *gameListView; + GamesModel *gameListModel; + GamesProxyModel *gameListProxyModel; + QPushButton *createButton, *joinButton, *spectateButton; + QCheckBox *showFullGamesCheckBox, *showRunningGamesCheckBox; +public: + GameSelector(AbstractClient *_client, TabRoom *_room, const QMap &_rooms, const QMap &_gameTypes, QWidget *parent = 0); + void retranslateUi(); + void processGameInfo(ServerInfo_Game *info); +}; + +#endif \ No newline at end of file diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 700877f2..fc8e7d55 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -1,8 +1,8 @@ #include "gamesmodel.h" #include "protocol_datastructures.h" -GamesModel::GamesModel(const QMap &_gameTypes, QObject *parent) - : QAbstractTableModel(parent), gameTypes(_gameTypes) +GamesModel::GamesModel(const QMap &_rooms, const QMap &_gameTypes, QObject *parent) + : QAbstractTableModel(parent), rooms(_rooms), gameTypes(_gameTypes) { } @@ -30,17 +30,19 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const ServerInfo_Game *g = gameList[index.row()]; switch (index.column()) { - case 0: return g->getDescription(); - case 1: return g->getCreatorInfo()->getName(); - case 2: { + case 0: return rooms.value(g->getRoomId()); + case 1: return g->getDescription(); + case 2: return g->getCreatorInfo()->getName(); + case 3: { QStringList result; QList gameTypeList = g->getGameTypes(); + GameTypeMap gameTypeMap = gameTypes.value(g->getRoomId()); for (int i = 0; i < gameTypeList.size(); ++i) - result.append(gameTypes.value(gameTypeList[i]->getData())); + result.append(gameTypeMap.value(gameTypeList[i]->getData())); return result.join(", "); } - case 3: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no"); - case 4: { + case 4: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no"); + case 5: { QStringList result; if (g->getOnlyBuddies()) result.append(tr("buddies only")); @@ -48,8 +50,8 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const result.append(tr("reg. users only")); return result.join(", "); } - case 5: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers()); - case 6: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed")); + case 6: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers()); + case 7: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed")); default: return QVariant(); } } @@ -59,13 +61,14 @@ QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int ro if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal)) return QVariant(); switch (section) { - case 0: return tr("Description"); - case 1: return tr("Creator"); - case 2: return tr("Game type"); - case 3: return tr("Password"); - case 4: return tr("Restrictions"); - case 5: return tr("Players"); - case 6: return tr("Spectators"); + case 0: return tr("Room"); + case 1: return tr("Description"); + case 2: return tr("Creator"); + case 3: return tr("Game type"); + case 4: return tr("Password"); + case 5: return tr("Restrictions"); + case 6: return tr("Players"); + case 7: return tr("Spectators"); default: return QVariant(); } } @@ -82,7 +85,7 @@ void GamesModel::updateGameList(ServerInfo_Game *_game) for (int i = 0; i < oldGameTypeList.size(); ++i) gameTypeList.append(new GameTypeId(oldGameTypeList[i]->getData())); - ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), gameTypeList, new ServerInfo_User(_game->getCreatorInfo()), _game->getOnlyBuddies(), _game->getOnlyRegistered(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount()); + ServerInfo_Game *game = new ServerInfo_Game(_game->getRoomId(), _game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), _game->getStarted(), gameTypeList, new ServerInfo_User(_game->getCreatorInfo()), _game->getOnlyBuddies(), _game->getOnlyRegistered(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount()); for (int i = 0; i < gameList.size(); i++) if (gameList[i]->getGameId() == game->getGameId()) { if (game->getPlayerCount() == 0) { @@ -92,7 +95,7 @@ void GamesModel::updateGameList(ServerInfo_Game *_game) } else { delete gameList[i]; gameList[i] = game; - emit dataChanged(index(i, 0), index(i, 4)); + emit dataChanged(index(i, 0), index(i, 7)); } return; } @@ -115,17 +118,22 @@ void GamesProxyModel::setFullGamesVisible(bool _fullGamesVisible) invalidateFilter(); } +void GamesProxyModel::setRunningGamesVisible(bool _runningGamesVisible) +{ + runningGamesVisible = _runningGamesVisible; + invalidateFilter(); +} + bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourceParent*/) const { - if (fullGamesVisible) - return true; - GamesModel *model = qobject_cast(sourceModel()); if (!model) return false; ServerInfo_Game *game = model->getGame(sourceRow); - if (game->getPlayerCount() == game->getMaxPlayers()) + if ((game->getPlayerCount() == game->getMaxPlayers()) && !fullGamesVisible) + return false; + if (game->getStarted() && !runningGamesVisible) return false; return true; diff --git a/cockatrice/src/gamesmodel.h b/cockatrice/src/gamesmodel.h index a7f4fe68..8461faf6 100644 --- a/cockatrice/src/gamesmodel.h +++ b/cockatrice/src/gamesmodel.h @@ -4,6 +4,7 @@ #include #include #include +#include "gametypemap.h" class ServerInfo_Game; @@ -11,12 +12,13 @@ class GamesModel : public QAbstractTableModel { Q_OBJECT private: QList gameList; - QMap gameTypes; + QMap rooms; + QMap gameTypes; public: - GamesModel(const QMap &_gameTypes, QObject *parent = 0); + GamesModel(const QMap &_rooms, const QMap &_gameTypes, QObject *parent = 0); ~GamesModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : gameList.size(); } - int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 7; } + int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 8; } QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; @@ -28,9 +30,11 @@ class GamesProxyModel : public QSortFilterProxyModel { Q_OBJECT private: bool fullGamesVisible; + bool runningGamesVisible; public: GamesProxyModel(QObject *parent = 0); void setFullGamesVisible(bool _fullGamesVisible); + void setRunningGamesVisible(bool _runningGamesVisible); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; }; diff --git a/cockatrice/src/gametypemap.h b/cockatrice/src/gametypemap.h new file mode 100644 index 00000000..fce16175 --- /dev/null +++ b/cockatrice/src/gametypemap.h @@ -0,0 +1,8 @@ +#ifndef GAMETYPEMAP_H +#define GAMETYPEMAP_H + +#include + +typedef QMap GameTypeMap; + +#endif \ No newline at end of file diff --git a/cockatrice/src/localserver.h b/cockatrice/src/localserver.h index b68e4f25..cf24b438 100644 --- a/cockatrice/src/localserver.h +++ b/cockatrice/src/localserver.h @@ -11,11 +11,12 @@ class LocalServer : public Server public: LocalServer(QObject *parent = 0); ~LocalServer(); - AuthenticationResult checkUserPassword(const QString & /*user*/, const QString & /*password*/) { return UnknownUser; } + AuthenticationResult checkUserPassword(Server_ProtocolHandler * /*handler*/, const QString & /*user*/, const QString & /*password*/) { return UnknownUser; } QString getLoginMessage() const { return QString(); } bool getGameShouldPing() const { return false; } int getMaxGameInactivityTime() const { return 9999999; } int getMaxPlayerInactivityTime() const { return 9999999; } + bool getThreaded() const { return false; } LocalServerInterface *newConnection(); protected: diff --git a/cockatrice/src/localserverinterface.h b/cockatrice/src/localserverinterface.h index fc23b1b5..1db97412 100644 --- a/cockatrice/src/localserverinterface.h +++ b/cockatrice/src/localserverinterface.h @@ -18,14 +18,16 @@ private: ResponseCode cmdDeckDel(Command_DeckDel * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } ResponseCode cmdDeckUpload(Command_DeckUpload * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } ResponseCode cmdDeckDownload(Command_DeckDownload * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } - ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } ResponseCode cmdBanFromServer(Command_BanFromServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } + ResponseCode cmdShutdownServer(Command_ShutdownServer * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } + ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; } +protected: + bool getCompressionSupport() const { return false; } public: LocalServerInterface(LocalServer *_server); ~LocalServerInterface(); void sendProtocolItem(ProtocolItem *item, bool deleteItem = true); - signals: void itemToClient(ProtocolItem *item); public slots: diff --git a/cockatrice/src/main.h b/cockatrice/src/main.h index f8e5a147..3e7ad1ea 100644 --- a/cockatrice/src/main.h +++ b/cockatrice/src/main.h @@ -9,7 +9,7 @@ extern CardDatabase *db; extern QTranslator *translator; const QString translationPrefix = "cockatrice"; -const QString versionString = "0.20110303"; +const QString versionString = "0.20110625"; void installNewTranslator(); diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index be218d6b..98b61c90 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -1,11 +1,9 @@ #include "messagelogwidget.h" #include "player.h" #include "cardzone.h" -#include "cardinfowidget.h" #include "protocol_items.h" #include "soundengine.h" -#include -#include +#include QString MessageLogWidget::sanitizeHtml(QString dirty) const { @@ -20,123 +18,132 @@ bool MessageLogWidget::isFemale(Player *player) const return player->getUserInfo()->getGender() == ServerInfo_User::Female; } -void MessageLogWidget::logConnecting(QString hostname) -{ - append(tr("Connecting to %1...").arg(sanitizeHtml(hostname))); -} - -void MessageLogWidget::logConnected() -{ - append(tr("Connected.")); -} - -void MessageLogWidget::logDisconnected() -{ - append(tr("Disconnected from server.")); -} - -void MessageLogWidget::logSocketError(const QString &errorString) -{ - append(sanitizeHtml(errorString)); -} - -void MessageLogWidget::logServerError(ResponseCode response) -{ - switch (response) { - case RespWrongPassword: append(tr("Invalid password.")); break; - default: ; - } -} - -void MessageLogWidget::logProtocolVersionMismatch(int clientVersion, int serverVersion) -{ - append(tr("Protocol version mismatch. Client: %1, Server: %2").arg(clientVersion).arg(serverVersion)); -} - -void MessageLogWidget::logProtocolError() -{ - append(tr("Protocol error.")); -} - void MessageLogWidget::logGameJoined(int gameId) { - append(tr("You have joined game #%1.").arg(gameId)); + if (female) + appendHtml(tr("You have joined game #%1.", "female").arg(gameId)); + else + appendHtml(tr("You have joined game #%1.", "male").arg(gameId)); } void MessageLogWidget::logJoin(Player *player) { - soundEngine->notification(); - append(tr("%1 has joined the game.").arg(sanitizeHtml(player->getName()))); + soundEngine->cuckoo(); + if (isFemale(player)) + appendHtml(tr("%1 has joined the game.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 has joined the game.", "male").arg(sanitizeHtml(player->getName()))); } void MessageLogWidget::logLeave(Player *player) { - append(tr("%1 has left the game.").arg(sanitizeHtml(player->getName()))); + if (isFemale(player)) + appendHtml(tr("%1 has left the game.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 has left the game.", "male").arg(sanitizeHtml(player->getName()))); } void MessageLogWidget::logGameClosed() { - append(tr("The game has been closed.")); + appendHtml(tr("The game has been closed.")); } void MessageLogWidget::logJoinSpectator(QString name) { - append(tr("%1 is now watching the game.").arg(sanitizeHtml(name))); + appendHtml(tr("%1 is now watching the game.").arg(sanitizeHtml(name))); } void MessageLogWidget::logLeaveSpectator(QString name) { - append(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name))); + appendHtml(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name))); } void MessageLogWidget::logDeckSelect(Player *player, int deckId) { - if (deckId == -1) - append(tr("%1 has loaded a local deck.").arg(sanitizeHtml(player->getName()))); - else - append(tr("%1 has loaded deck #%2.").arg(sanitizeHtml(player->getName())).arg(deckId)); + if (deckId == -1) { + if (isFemale(player)) + appendHtml(tr("%1 has loaded a local deck.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 has loaded a local deck.", "male").arg(sanitizeHtml(player->getName()))); + } else { + if (isFemale(player)) + appendHtml(tr("%1 has loaded deck #%2.", "female").arg(sanitizeHtml(player->getName())).arg(deckId)); + else + appendHtml(tr("%1 has loaded deck #%2.", "male").arg(sanitizeHtml(player->getName())).arg(deckId)); + } } void MessageLogWidget::logReadyStart(Player *player) { - append(tr("%1 is ready to start the game.").arg(sanitizeHtml(player->getName()))); + if (isFemale(player)) + appendHtml(tr("%1 is ready to start the game.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 is ready to start the game.", "male").arg(sanitizeHtml(player->getName()))); } void MessageLogWidget::logNotReadyStart(Player *player) { - append(tr("%1 is not ready to start the game any more.").arg(sanitizeHtml(player->getName()))); + if (isFemale(player)) + appendHtml(tr("%1 is not ready to start the game any more.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 is not ready to start the game any more.", "male").arg(sanitizeHtml(player->getName()))); } void MessageLogWidget::logConcede(Player *player) { - append(tr("%1 has conceded the game.").arg(sanitizeHtml(player->getName()))); + if (isFemale(player)) + appendHtml(tr("%1 has conceded the game.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 has conceded the game.", "male").arg(sanitizeHtml(player->getName()))); } void MessageLogWidget::logGameStart() { - append(tr("The game has started.")); + appendHtml(tr("The game has started.")); +} + +void MessageLogWidget::logConnectionStateChanged(Player *player, bool connectionState) +{ + if (connectionState) { + if (isFemale(player)) + appendHtml(tr("%1 has restored connection to the game.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 has restored connection to the game.", "male").arg(sanitizeHtml(player->getName()))); + } else { + if (isFemale(player)) + appendHtml(tr("%1 has lost connection to the game.", "female").arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 has lost connection to the game.", "male").arg(sanitizeHtml(player->getName()))); + } } void MessageLogWidget::logSay(Player *player, QString message) { - append(QString("getLocal() ? "red" : "#0000fe") + QString("\">%1: %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message))); + appendMessage(player->getName(), message, QColor(), true); } void MessageLogWidget::logSpectatorSay(QString spectatorName, QString message) { - append(QString("%1: %2").arg(sanitizeHtml(spectatorName)).arg(sanitizeHtml(message))); + appendMessage(spectatorName, message, QColor(), false); } void MessageLogWidget::logShuffle(Player *player, CardZone *zone) { soundEngine->shuffle(); - if (currentContext != MessageContext_Mulligan) - append(tr("%1 shuffles %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + if (currentContext != MessageContext_Mulligan) { + if (isFemale(player)) + appendHtml(tr("%1 shuffles %2.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + else + appendHtml(tr("%1 shuffles %2.", "male").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + } } void MessageLogWidget::logRollDie(Player *player, int sides, int roll) { - append(tr("%1 rolls a %2 with a %3-sided die.").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides)); + if (isFemale(player)) + appendHtml(tr("%1 rolls a %2 with a %3-sided die.", "female").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides)); + else + appendHtml(tr("%1 rolls a %2 with a %3-sided die.", "male").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides)); } void MessageLogWidget::logDrawCards(Player *player, int number) @@ -145,16 +152,19 @@ void MessageLogWidget::logDrawCards(Player *player, int number) mulliganPlayer = player; else { soundEngine->draw(); - append(tr("%1 draws %n card(s).", "", number).arg(sanitizeHtml(player->getName()))); + if (isFemale(player)) + appendHtml(tr("%1 draws %n card(s).", "female", number).arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 draws %n card(s).", "male", number).arg(sanitizeHtml(player->getName()))); } } void MessageLogWidget::logUndoDraw(Player *player, QString cardName) { if (cardName.isEmpty()) - append((isFemale(player) ? tr("%1 undoes her last draw.") : tr("%1 undoes his last draw.")).arg(sanitizeHtml(player->getName()))); + appendHtml((isFemale(player) ? tr("%1 undoes her last draw.") : tr("%1 undoes his last draw.")).arg(sanitizeHtml(player->getName()))); else - append((isFemale(player) ? tr("%1 undoes her last draw (%2).") : tr("%1 undoes his last draw (%2).")).arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); + appendHtml((isFemale(player) ? tr("%1 undoes her last draw (%2).") : tr("%1 undoes his last draw (%2).")).arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); } QPair MessageLogWidget::getFromStr(CardZone *zone, QString cardName, int position) const @@ -219,7 +229,7 @@ void MessageLogWidget::doMoveCard(LogMoveCard &attributes) cardStr = QString("%1").arg(sanitizeHtml(cardName)); if (attributes.startZone->getPlayer() != attributes.targetZone->getPlayer()) { - append(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(attributes.player->getName())).arg(sanitizeHtml(attributes.targetZone->getPlayer()->getName())).arg(cardStr)); + appendHtml(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(attributes.player->getName())).arg(sanitizeHtml(attributes.targetZone->getPlayer()->getName())).arg(cardStr)); return; } @@ -252,7 +262,7 @@ void MessageLogWidget::doMoveCard(LogMoveCard &attributes) finalStr = tr("%1 plays %2%3."); } - append(finalStr.arg(sanitizeHtml(attributes.player->getName())).arg(cardStr).arg(fromStr).arg(attributes.newX)); + appendHtml(finalStr.arg(sanitizeHtml(attributes.player->getName())).arg(cardStr).arg(fromStr).arg(attributes.newX)); } void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *startZone, int oldX, CardZone *targetZone, int newX) @@ -271,57 +281,200 @@ void MessageLogWidget::logMulligan(Player *player, int number) if (!player) return; - if (number > -1) - append(tr("%1 takes a mulligan to %n.", "", number).arg(sanitizeHtml(player->getName()))); - else - append((isFemale(player) ? tr("%1 draws her initial hand.") : tr("%1 draws his initial hand.")).arg(sanitizeHtml(player->getName()))); + if (number > -1) { + if (isFemale(player)) + appendHtml(tr("%1 takes a mulligan to %n.", "female", number).arg(sanitizeHtml(player->getName()))); + else + appendHtml(tr("%1 takes a mulligan to %n.", "male", number).arg(sanitizeHtml(player->getName()))); + } else + appendHtml((isFemale(player) ? tr("%1 draws her initial hand.") : tr("%1 draws his initial hand.")).arg(sanitizeHtml(player->getName()))); } void MessageLogWidget::logFlipCard(Player *player, QString cardName, bool faceDown) { - if (faceDown) - append(tr("%1 flips %2 face-down.").arg(sanitizeHtml(player->getName())).arg(cardName)); - else - append(tr("%1 flips %2 face-up.").arg(sanitizeHtml(player->getName())).arg(cardName)); + if (faceDown) { + if (isFemale(player)) + appendHtml(tr("%1 flips %2 face-down.", "female").arg(sanitizeHtml(player->getName())).arg(cardName)); + else + appendHtml(tr("%1 flips %2 face-down.", "male").arg(sanitizeHtml(player->getName())).arg(cardName)); + } else { + if (isFemale(player)) + appendHtml(tr("%1 flips %2 face-up.", "female").arg(sanitizeHtml(player->getName())).arg(cardName)); + else + appendHtml(tr("%1 flips %2 face-up.", "male").arg(sanitizeHtml(player->getName())).arg(cardName)); + } } void MessageLogWidget::logDestroyCard(Player *player, QString cardName) { - append(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); + if (isFemale(player)) + appendHtml(tr("%1 destroys %2.", "female").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); + else + appendHtml(tr("%1 destroys %2.", "male").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); } void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName) { - append(tr("%1 attaches %2 to %3's %4.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("%1").arg(sanitizeHtml(targetCardName)))); + QString str; + if (isFemale(player)) { + if (isFemale(targetPlayer)) + str = tr("%1 attaches %2 to %3's %4.", "p1 female, p2 female"); + else + str = tr("%1 attaches %2 to %3's %4.", "p1 female, p2 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 attaches %2 to %3's %4.", "p1 male, p2 female"); + else + str = tr("%1 attaches %2 to %3's %4.", "p1 male, p2 male"); + } + + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("%1").arg(sanitizeHtml(targetCardName)))); } void MessageLogWidget::logUnattachCard(Player *player, QString cardName) { - append(tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); + if (isFemale(player)) + appendHtml(tr("%1 unattaches %2.", "female").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); + else + appendHtml(tr("%1 unattaches %2.", "male").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); } void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt) { - append(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt)))); + if (isFemale(player)) + appendHtml(tr("%1 creates token: %2%3.", "female").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt)))); + else + appendHtml(tr("%1 creates token: %2%3.", "male").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt)))); } void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget) { - if (playerTarget) - append(tr("%1 points from %2's %3 to %4.") - .arg(sanitizeHtml(player->getName())) - .arg(sanitizeHtml(startPlayer->getName())) - .arg(sanitizeHtml(startCard)) - .arg(sanitizeHtml(targetPlayer->getName())) - ); - else - append(tr("%1 points from %2's %3 to %4's %5.") - .arg(sanitizeHtml(player->getName())) - .arg(sanitizeHtml(startPlayer->getName())) - .arg(sanitizeHtml(startCard)) - .arg(sanitizeHtml(targetPlayer->getName())) - .arg(sanitizeHtml(targetCard)) - ); + startCard = QString("%1").arg(sanitizeHtml(startCard)); + targetCard = QString("%1").arg(sanitizeHtml(targetCard)); + QString str; + if (playerTarget) { + if ((player == startPlayer) && (player == targetPlayer)) { + if (isFemale(player)) + str = tr("%1 points from her %2 to herself.", "female"); + else + str = tr("%1 points from his %2 to himself.", "male"); + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard)); + } else if (player == startPlayer) { + if (isFemale(player)) { + if (isFemale(targetPlayer)) + str = tr("%1 points from her %2 to %3.", "p1 female, p2 female"); + else + str = tr("%1 points from her %2 to %3.", "p1 female, p2 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 points from his %2 to %3.", "p1 male, p2 female"); + else + str = tr("%1 points from his %2 to %3.", "p1 male, p2 male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName()))); + } else if (player == targetPlayer) { + if (isFemale(player)) { + if (isFemale(startPlayer)) + str = tr("%1 points from %2's %3 to herself.", "card owner female, target female"); + else + str = tr("%1 points from %2's %3 to herself.", "card owner male, target female"); + } else { + if (isFemale(startPlayer)) + str = tr("%1 points from %2's %3 to himself.", "card owner female, target male"); + else + str = tr("%1 points from %2's %3 to himself.", "card owner male, target male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard)); + } else { + if (isFemale(player)) { + if (isFemale(startPlayer)) { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 female, p3 female"); + else + str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 female, p3 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 male, p3 female"); + else + str = tr("%1 points from %2's %3 to %4.", "p1 female, p2 male, p3 male"); + } + } else { + if (isFemale(startPlayer)) { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 female, p3 female"); + else + str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 female, p3 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 male, p3 female"); + else + str = tr("%1 points from %2's %3 to %4.", "p1 male, p2 male, p3 male"); + } + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName()))); + } + } else { + if ((player == startPlayer) && (player == targetPlayer)) { + if (isFemale(player)) + str = tr("%1 points from her %2 to her %3.", "female"); + else + str = tr("%1 points from his %2 to his %3.", "male"); + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard).arg(targetCard)); + } else if (player == startPlayer) { + if (isFemale(player)) { + if (isFemale(targetPlayer)) + str = tr("%1 points from her %2 to %3's %4.", "p1 female, p2 female"); + else + str = tr("%1 points from her %2 to %3's %4.", "p1 female, p2 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 points from his %2 to %3's %4.", "p1 male, p2 female"); + else + str = tr("%1 points from his %2 to %3's %4.", "p1 male, p2 male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName())).arg(targetCard)); + } else if (player == targetPlayer) { + if (isFemale(player)) { + if (isFemale(startPlayer)) + str = tr("%1 points from %2's %3 to her own %4.", "card owner female, target female"); + else + str = tr("%1 points from %2's %3 to her own %4.", "card owner male, target female"); + } else { + if (isFemale(startPlayer)) + str = tr("%1 points from %2's %3 to his own %4.", "card owner female, target male"); + else + str = tr("%1 points from %2's %3 to his own %4.", "card owner male, target male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard).arg(targetCard)); + } else { + if (isFemale(player)) { + if (isFemale(startPlayer)) { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 female, p3 female"); + else + str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 female, p3 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 male, p3 female"); + else + str = tr("%1 points from %2's %3 to %4's %5.", "p1 female, p2 male, p3 male"); + } + } else { + if (isFemale(startPlayer)) { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 female, p3 female"); + else + str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 female, p3 male"); + } else { + if (isFemale(targetPlayer)) + str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 male, p3 female"); + else + str = tr("%1 points from %2's %3 to %4's %5.", "p1 male, p2 male, p3 male"); + } + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(startPlayer->getName())).arg(startCard).arg(sanitizeHtml(targetPlayer->getName())).arg(targetCard)); + } + } } void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue) @@ -329,10 +482,17 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c QString finalStr, colorStr; int delta = abs(oldValue - value); - if (value > oldValue) - finalStr = tr("%1 places %n %2 counter(s) on %3 (now %4).", "", delta); - else - finalStr = tr("%1 removes %n %2 counter(s) from %3 (now %4).", "", delta); + if (value > oldValue) { + if (isFemale(player)) + finalStr = tr("%1 places %n %2 counter(s) on %3 (now %4).", "female", delta); + else + finalStr = tr("%1 places %n %2 counter(s) on %3 (now %4).", "male", delta); + } else { + if (isFemale(player)) + finalStr = tr("%1 removes %n %2 counter(s) from %3 (now %4).", "female", delta); + else + finalStr = tr("%1 removes %n %2 counter(s) from %3 (now %4).", "male", delta); + } switch (counterId) { case 0: colorStr = tr("red", "", delta); break; @@ -341,7 +501,7 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c default: ; } - append(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(value)); + appendHtml(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(value)); } void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped) @@ -354,55 +514,111 @@ void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped) if (currentContext == MessageContext_MoveCard) moveCardTapped.insert(card, tapped); else { - QString cardStr; - if (!card) - cardStr = isFemale(player) ? tr("her permanents") : tr("his permanents"); - else - cardStr = QString("%1").arg(sanitizeHtml(card->getName())); - append(tr("%1 %2 %3.").arg(sanitizeHtml(player->getName())).arg(tapped ? tr("taps") : tr("untaps")).arg(cardStr)); + QString str; + if (!card) { + if (isFemale(player)) { + if (tapped) + str = tr("%1 taps her permanents.", "female"); + else + str = tr("%1 untaps her permanents.", "female"); + } else { + if (tapped) + str = tr("%1 taps his permanents.", "male"); + else + str = tr("%1 untaps his permanents.", "male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName()))); + } else { + if (isFemale(player)) { + if (tapped) + str = tr("%1 taps %2.", "female"); + else + str = tr("%1 untaps %2.", "female"); + } else { + if (tapped) + str = tr("%1 taps %2.", "male"); + else + str = tr("%1 untaps %2.", "male"); + } + QString cardStr = QString("%1").arg(sanitizeHtml(card->getName())); + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(cardStr)); + } } } void MessageLogWidget::logSetCounter(Player *player, QString counterName, int value, int oldValue) { - append(tr("%1 sets counter %2 to %3 (%4%5).").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(counterName))).arg(QString("%1").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue)); + QString str; + if (isFemale(player)) + str = tr("%1 sets counter %2 to %3 (%4%5).", "female"); + else + str = tr("%1 sets counter %2 to %3 (%4%5).", "male"); + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(counterName))).arg(QString("%1").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue)); } void MessageLogWidget::logSetDoesntUntap(Player *player, CardItem *card, bool doesntUntap) { - QString finalStr; - if (doesntUntap) - finalStr = tr("%1 sets %2 to not untap normally."); - else - finalStr = tr("%1 sets %2 to untap normally."); - append(finalStr.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName())))); + QString str; + if (doesntUntap) { + if (isFemale(player)) + str = tr("%1 sets %2 to not untap normally.", "female"); + else + str = tr("%1 sets %2 to not untap normally.", "male"); + } else { + if (isFemale(player)) + str = tr("%1 sets %2 to untap normally.", "female"); + else + str = tr("%1 sets %2 to untap normally.", "male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName())))); } void MessageLogWidget::logSetPT(Player *player, CardItem *card, QString newPT) { if (currentContext == MessageContext_MoveCard) moveCardPT.insert(card, newPT); - else - append(tr("%1 sets PT of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newPT)))); + else { + QString str; + if (isFemale(player)) + str = tr("%1 sets PT of %2 to %3.", "female"); + else + str = tr("%1 sets PT of %2 to %3.", "male"); + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newPT)))); + } } void MessageLogWidget::logSetAnnotation(Player *player, CardItem *card, QString newAnnotation) { - append(tr("%1 sets annotation of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newAnnotation)))); + QString str; + if (isFemale(player)) + str = tr("%1 sets annotation of %2 to %3.", "female"); + else + str = tr("%1 sets annotation of %2 to %3.", "male"); + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(card->getName()))).arg(QString("%1").arg(sanitizeHtml(newAnnotation)))); } void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards) { - if (numberCards != -1) - append(tr("%1 is looking at the top %2 cards %3.").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive))); - else - append(tr("%1 is looking at %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative))); + if (numberCards != -1) { + if (isFemale(player)) + appendHtml(tr("%1 is looking at the top %2 cards %3.", "female").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive))); + else + appendHtml(tr("%1 is looking at the top %2 cards %3.", "male").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive))); + } else { + if (isFemale(player)) + appendHtml(tr("%1 is looking at %2.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative))); + else + appendHtml(tr("%1 is looking at %2.", "male").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative))); + } } void MessageLogWidget::logStopDumpZone(Player *player, CardZone *zone) { QString zoneName = zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative); - append(tr("%1 stops looking at %2.").arg(sanitizeHtml(player->getName())).arg(zoneName)); + if (isFemale(player)) + appendHtml(tr("%1 stops looking at %2.", "female").arg(sanitizeHtml(player->getName())).arg(zoneName)); + else + appendHtml(tr("%1 stops looking at %2.", "male").arg(sanitizeHtml(player->getName())).arg(zoneName)); } void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId, QString cardName, Player *otherPlayer) @@ -423,30 +639,80 @@ void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId else cardStr = QString("%1").arg(sanitizeHtml(cardName)); + QString str; if (cardId == -1) { - if (otherPlayer) - append(tr("%1 reveals %2 to %3.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)).arg(sanitizeHtml(otherPlayer->getName()))); - else - append(tr("%1 reveals %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + if (otherPlayer) { + if (isFemale(player)) { + if (isFemale(otherPlayer)) + str = tr("%1 reveals %2 to %3.", "p1 female, p2 female"); + else + str = tr("%1 reveals %2 to %3.", "p1 female, p2 male"); + } else { + if (isFemale(otherPlayer)) + str = tr("%1 reveals %2 to %3.", "p1 male, p2 female"); + else + str = tr("%1 reveals %2 to %3.", "p1 male, p2 male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)).arg(sanitizeHtml(otherPlayer->getName()))); + } else { + if (isFemale(player)) + appendHtml(tr("%1 reveals %2.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + else + appendHtml(tr("%1 reveals %2.", "male").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + } } else if (cardId == -2) { - if (otherPlayer) - append(tr("%1 randomly reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName()))); - else - append(tr("%1 randomly reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr)); + if (otherPlayer) { + if (isFemale(player)) { + if (isFemale(otherPlayer)) + str = tr("%1 randomly reveals %2%3 to %4.", "p1 female, p2 female"); + else + str = tr("%1 randomly reveals %2%3 to %4.", "p1 female, p2 male"); + } else { + if (isFemale(otherPlayer)) + str = tr("%1 randomly reveals %2%3 to %4.", "p1 male, p2 female"); + else + str = tr("%1 randomly reveals %2%3 to %4.", "p1 male, p2 male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName()))); + } else { + if (isFemale(player)) + appendHtml(tr("%1 randomly reveals %2%3.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + else + appendHtml(tr("%1 randomly reveals %2%3.", "male").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr)); + } } else { - if (otherPlayer) - append(tr("%1 reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName()))); - else - append(tr("%1 reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr)); + if (otherPlayer) { + if (isFemale(player)) { + if (isFemale(otherPlayer)) + str = tr("%1 reveals %2%3 to %4.", "p1 female, p2 female"); + else + str = tr("%1 reveals %2%3 to %4.", "p1 female, p2 male"); + } else { + if (isFemale(otherPlayer)) + str = tr("%1 reveals %2%3 to %4.", "p1 male, p2 female"); + else + str = tr("%1 reveals %2%3 to %4.", "p1 male, p2 male"); + } + appendHtml(str.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName()))); + } else { + if (isFemale(player)) + appendHtml(tr("%1 reveals %2%3.", "female").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative))); + else + appendHtml(tr("%1 reveals %2%3.", "male").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr)); + } } } void MessageLogWidget::logSetActivePlayer(Player *player) { soundEngine->notification(); - append(QString()); - append("" + tr("It is now %1's turn.").arg(player->getName()) + ""); - append(QString()); + + QString str; + if (isFemale(player)) + str = tr("It is now %1's turn.", "female"); + else + str = tr("It is now %1's turn.", "male"); + appendHtml("
" + str.arg(player->getName()) + "
"); } void MessageLogWidget::logSetActivePhase(int phase) @@ -466,7 +732,7 @@ void MessageLogWidget::logSetActivePhase(int phase) case 9: phaseName = tr("second main phase"); break; case 10: phaseName = tr("ending phase"); break; } - append("" + tr("It is now the %1.").arg(phaseName) + ""); + appendHtml("" + tr("It is now the %1.").arg(phaseName) + ""); } void MessageLogWidget::containerProcessingStarted(GameEventContext *_context) @@ -499,6 +765,7 @@ void MessageLogWidget::containerProcessingDone() void MessageLogWidget::connectToPlayer(Player *player) { + connect(player, SIGNAL(logConnectionStateChanged(Player *, bool)), this, SLOT(logConnectionStateChanged(Player *, bool))); connect(player, SIGNAL(logSay(Player *, QString)), this, SLOT(logSay(Player *, QString))); connect(player, SIGNAL(logShuffle(Player *, CardZone *)), this, SLOT(logShuffle(Player *, CardZone *))); connect(player, SIGNAL(logRollDie(Player *, int, int)), this, SLOT(logRollDie(Player *, int, int))); @@ -522,67 +789,7 @@ void MessageLogWidget::connectToPlayer(Player *player) connect(player, SIGNAL(logRevealCards(Player *, CardZone *, int, QString, Player *)), this, SLOT(logRevealCards(Player *, CardZone *, int, QString, Player *))); } -MessageLogWidget::MessageLogWidget(QWidget *parent) - : QTextEdit(parent) +MessageLogWidget::MessageLogWidget(const QString &_ownName, bool _female, QWidget *parent) + : ChatView(_ownName, false, parent), female(_female) { - setReadOnly(true); -} - -void MessageLogWidget::enterEvent(QEvent * /*event*/) -{ - setMouseTracking(true); -} - -void MessageLogWidget::leaveEvent(QEvent * /*event*/) -{ - setMouseTracking(false); -} - -QString MessageLogWidget::getCardNameUnderMouse(const QPoint &pos) const -{ - QTextCursor cursor(cursorForPosition(pos)); - QTextBlock block(cursor.block()); - QTextBlock::iterator it; - for (it = block.begin(); !(it.atEnd()); ++it) { - QTextFragment frag = it.fragment(); - if (!frag.contains(cursor.position())) - continue; - - if (frag.charFormat().foreground().color() == Qt::blue) - return frag.text(); - - break; - } - return QString(); -} - -void MessageLogWidget::mouseMoveEvent(QMouseEvent *event) -{ - QString cardName = getCardNameUnderMouse(event->pos()); - if (!cardName.isEmpty()) { - viewport()->setCursor(Qt::PointingHandCursor); - emit cardNameHovered(cardName); - } else - viewport()->setCursor(Qt::IBeamCursor); - - QTextEdit::mouseMoveEvent(event); -} - -void MessageLogWidget::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::MidButton) { - QString cardName = getCardNameUnderMouse(event->pos()); - if (!cardName.isEmpty()) - emit showCardInfoPopup(event->globalPos(), cardName); - } - - QTextEdit::mousePressEvent(event); -} - -void MessageLogWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::MidButton) - emit deleteCardInfoPopup(); - - QTextEdit::mouseReleaseEvent(event); } diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index fe548547..37d4a242 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -1,15 +1,13 @@ #ifndef MESSAGELOGWIDGET_H #define MESSAGELOGWIDGET_H -#include +#include "chatview.h" #include #include "translation.h" #include "protocol_datastructures.h" class Player; class CardZone; -class QMouseEvent; -class QEvent; class CardInfoWidget; class GameEventContext; class CardItem; @@ -24,17 +22,16 @@ struct LogMoveCard { int newX; }; -class MessageLogWidget : public QTextEdit { +class MessageLogWidget : public ChatView { Q_OBJECT private: enum MessageContext { MessageContext_None, MessageContext_MoveCard, MessageContext_Mulligan }; - CardInfoWidget *infoWidget; QString sanitizeHtml(QString dirty) const; bool isFemale(Player *player) const; QPair getFromStr(CardZone *zone, QString cardName, int position) const; - QString getCardNameUnderMouse(const QPoint &pos) const; MessageContext currentContext; + bool female; QList moveCardQueue; QMap moveCardPT; @@ -42,18 +39,7 @@ private: Player *mulliganPlayer; int mulliganNumber; -signals: - void cardNameHovered(QString cardName); - void showCardInfoPopup(QPoint pos, QString cardName); - void deleteCardInfoPopup(); public slots: - void logConnecting(QString hostname); - void logConnected(); - void logDisconnected(); - void logSocketError(const QString &errorString); - void logServerError(ResponseCode response); - void logProtocolVersionMismatch(int clientVersion, int serverVersion); - void logProtocolError(); void logGameJoined(int gameId); void logJoin(Player *player); void logLeave(Player *player); @@ -65,6 +51,7 @@ public slots: void logNotReadyStart(Player *player); void logConcede(Player *player); void logGameStart(); + void logConnectionStateChanged(Player *player, bool connectionState); void logSay(Player *player, QString message); void logSpectatorSay(QString spectatorName, QString message); void logShuffle(Player *player, CardZone *zone); @@ -95,13 +82,7 @@ public slots: void containerProcessingDone(); public: void connectToPlayer(Player *player); - MessageLogWidget(QWidget *parent = 0); -protected: - void enterEvent(QEvent *event); - void leaveEvent(QEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); + MessageLogWidget(const QString &_ownName, bool _female, QWidget *parent = 0); }; #endif diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 7ebf9cdf..fc794bd3 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -706,6 +706,11 @@ void Player::setCardAttrHelper(GameEventContext *context, CardItem *card, const } } +void Player::eventConnectionStateChanged(Event_ConnectionStateChanged *event) +{ + emit logConnectionStateChanged(this, event->getConnected()); +} + void Player::eventSay(Event_Say *event) { emit logSay(this, event->getMessage()); @@ -862,6 +867,8 @@ void Player::eventMoveCard(Event_MoveCard *event, GameEventContext *context) CardItem *card = startZone->takeCard(position, event->getCardId(), startZone != targetZone); if (!card) return; + if (startZone != targetZone) + card->deleteCardInfoPopup(); card->setName(event->getCardName()); if (card->getAttachedTo() && (startZone != targetZone)) { @@ -1036,6 +1043,7 @@ void Player::processGameEvent(GameEvent *event, GameEventContext *context) { qDebug() << "player event: id=" << event->getItemId(); switch (event->getItemId()) { + case ItemId_Event_ConnectionStateChanged: eventConnectionStateChanged(static_cast(event)); break; case ItemId_Event_Say: eventSay(static_cast(event)); break; case ItemId_Event_Shuffle: eventShuffle(static_cast(event)); break; case ItemId_Event_RollDie: eventRollDie(static_cast(event)); break; diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index 8645d70f..72f19c26 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -26,6 +26,7 @@ class CommandContainer; class GameCommand; class GameEvent; class GameEventContext; +class Event_ConnectionStateChanged; class Event_Say; class Event_Shuffle; class Event_RollDie; @@ -69,6 +70,7 @@ class Player : public QObject, public QGraphicsItem { signals: void newCardAdded(AbstractCardItem *card); // Log events + void logConnectionStateChanged(Player *player, bool connectionState); void logSay(Player *player, QString message); void logShuffle(Player *player, CardZone *zone); void logRollDie(Player *player, int sides, int roll); @@ -176,6 +178,7 @@ private: void initSayMenu(); + void eventConnectionStateChanged(Event_ConnectionStateChanged *event); void eventSay(Event_Say *event); void eventShuffle(Event_Shuffle *event); void eventRollDie(Event_RollDie *event); diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp index fac63019..8f084487 100644 --- a/cockatrice/src/remoteclient.cpp +++ b/cockatrice/src/remoteclient.cpp @@ -83,6 +83,7 @@ void RemoteClient::readData() xmlWriter->writeStartDocument(); xmlWriter->writeStartElement("cockatrice_client_stream"); xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion)); + xmlWriter->writeAttribute("comp", "1"); topLevelItem = new TopLevelProtocolItem; connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *))); diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index f7494d76..8c3cee47 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -24,6 +24,7 @@ SettingsCache::SettingsCache() displayCardNames = settings->value("cards/displaycardnames", true).toBool(); horizontalHand = settings->value("hand/horizontal", true).toBool(); invertVerticalCoordinate = settings->value("table/invert_vertical", false).toBool(); + minPlayersForMultiColumnLayout = settings->value("interface/min_players_multicolumn", 5).toInt(); tapAnimation = settings->value("cards/tapanimation", true).toBool(); zoneViewSortByName = settings->value("zoneview/sortbyname", true).toBool(); @@ -143,6 +144,13 @@ void SettingsCache::setInvertVerticalCoordinate(int _invertVerticalCoordinate) emit invertVerticalCoordinateChanged(); } +void SettingsCache::setMinPlayersForMultiColumnLayout(int _minPlayersForMultiColumnLayout) +{ + minPlayersForMultiColumnLayout = _minPlayersForMultiColumnLayout; + settings->setValue("interface/min_players_multicolumn", minPlayersForMultiColumnLayout); + emit minPlayersForMultiColumnLayoutChanged(); +} + void SettingsCache::setTapAnimation(int _tapAnimation) { tapAnimation = _tapAnimation; diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index c834716a..b3f1ae6c 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -20,6 +20,7 @@ signals: void displayCardNamesChanged(); void horizontalHandChanged(); void invertVerticalCoordinateChanged(); + void minPlayersForMultiColumnLayoutChanged(); void soundPathChanged(); private: QSettings *settings; @@ -34,6 +35,7 @@ private: bool displayCardNames; bool horizontalHand; bool invertVerticalCoordinate; + int minPlayersForMultiColumnLayout; bool tapAnimation; bool zoneViewSortByName, zoneViewSortByType; bool soundEnabled; @@ -57,6 +59,7 @@ public: bool getDisplayCardNames() const { return displayCardNames; } bool getHorizontalHand() const { return horizontalHand; } bool getInvertVerticalCoordinate() const { return invertVerticalCoordinate; } + int getMinPlayersForMultiColumnLayout() const { return minPlayersForMultiColumnLayout; } bool getTapAnimation() const { return tapAnimation; } bool getZoneViewSortByName() const { return zoneViewSortByName; } bool getZoneViewSortByType() const { return zoneViewSortByType; } @@ -80,6 +83,7 @@ public slots: void setDisplayCardNames(int _displayCardNames); void setHorizontalHand(int _horizontalHand); void setInvertVerticalCoordinate(int _invertVerticalCoordinate); + void setMinPlayersForMultiColumnLayout(int _minPlayersForMultiColumnLayout); void setTapAnimation(int _tapAnimation); void setZoneViewSortByName(int _zoneViewSortByName); void setZoneViewSortByType(int _zoneViewSortByType); diff --git a/cockatrice/src/soundengine.cpp b/cockatrice/src/soundengine.cpp index 5daeae9a..247567cc 100644 --- a/cockatrice/src/soundengine.cpp +++ b/cockatrice/src/soundengine.cpp @@ -25,7 +25,7 @@ SoundEngine::SoundEngine(QObject *parent) void SoundEngine::cacheData() { static const QStringList fileNames = QStringList() - << "notification" << "draw" << "playcard" << "shuffle" << "tap" << "untap"; + << "notification" << "draw" << "playcard" << "shuffle" << "tap" << "untap" << "cuckoo"; for (int i = 0; i < fileNames.size(); ++i) { QFile file(settingsCache->getSoundPath() + "/" + fileNames[i] + ".raw"); file.open(QIODevice::ReadOnly); @@ -75,3 +75,8 @@ void SoundEngine::untap() { playSound("untap"); } + +void SoundEngine::cuckoo() +{ + playSound("cuckoo"); +} diff --git a/cockatrice/src/soundengine.h b/cockatrice/src/soundengine.h index 312a476b..d65b3f2d 100644 --- a/cockatrice/src/soundengine.h +++ b/cockatrice/src/soundengine.h @@ -25,6 +25,7 @@ public slots: void shuffle(); void tap(); void untap(); + void cuckoo(); }; extern SoundEngine *soundEngine; diff --git a/cockatrice/src/tab.cpp b/cockatrice/src/tab.cpp new file mode 100644 index 00000000..2eed9b54 --- /dev/null +++ b/cockatrice/src/tab.cpp @@ -0,0 +1,32 @@ +#include "tab.h" +#include "cardinfowidget.h" +#include +#include + +Tab::Tab(TabSupervisor *_tabSupervisor, QWidget *parent) + : QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false), infoPopup(0) +{ +} + +void Tab::showCardInfoPopup(const QPoint &pos, const QString &cardName) +{ + infoPopup = new CardInfoWidget(CardInfoWidget::ModePopUp, 0, Qt::Widget | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint); + infoPopup->setAttribute(Qt::WA_TransparentForMouseEvents); + infoPopup->setCard(cardName); + QRect screenRect = qApp->desktop()->screenGeometry(this); + infoPopup->move( + qMax(screenRect.left(), qMin(pos.x() - infoPopup->width() / 2, screenRect.left() + screenRect.width() - infoPopup->width())), + qMax(screenRect.top(), qMin(pos.y() - infoPopup->height() / 2, screenRect.top() + screenRect.height() - infoPopup->height())) + ); + infoPopup->show(); +} + +void Tab::deleteCardInfoPopup(const QString &cardName) +{ + if (infoPopup) { + if ((infoPopup->getCardName() == cardName) || (cardName == "_")) { + infoPopup->deleteLater(); + infoPopup = 0; + } + } +} diff --git a/cockatrice/src/tab.h b/cockatrice/src/tab.h index 31fdcbab..3fefde1a 100644 --- a/cockatrice/src/tab.h +++ b/cockatrice/src/tab.h @@ -5,19 +5,23 @@ class QMenu; class TabSupervisor; +class CardInfoWidget; class Tab : public QWidget { Q_OBJECT signals: - void userEvent(); + void userEvent(bool globalEvent = true); protected: QMenu *tabMenu; TabSupervisor *tabSupervisor; +protected slots: + void showCardInfoPopup(const QPoint &pos, const QString &cardName); + void deleteCardInfoPopup(const QString &cardName); private: bool contentsChanged; + CardInfoWidget *infoPopup; public: - Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0) - : QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false) { } + Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0); QMenu *getTabMenu() const { return tabMenu; } bool getContentsChanged() const { return contentsChanged; } void setContentsChanged(bool _contentsChanged) { contentsChanged = _contentsChanged; } diff --git a/cockatrice/src/tab_admin.cpp b/cockatrice/src/tab_admin.cpp index 4ea3a652..08232138 100644 --- a/cockatrice/src/tab_admin.cpp +++ b/cockatrice/src/tab_admin.cpp @@ -1,19 +1,72 @@ +#include #include +#include #include #include #include +#include +#include +#include #include "tab_admin.h" #include "abstractclient.h" #include "protocol_items.h" -TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent) - : Tab(_tabSupervisor, parent), locked(true), client(_client) +ShutdownDialog::ShutdownDialog(QWidget *parent) + : QDialog(parent) +{ + QLabel *reasonLabel = new QLabel(tr("&Reason for shutdown:")); + reasonEdit = new QLineEdit; + reasonLabel->setBuddy(reasonEdit); + QLabel *minutesLabel = new QLabel(tr("&Time until shutdown (minutes):")); + minutesEdit = new QSpinBox; + minutesLabel->setBuddy(minutesEdit); + minutesEdit->setMinimum(0); + minutesEdit->setValue(5); + + QPushButton *okButton = new QPushButton(tr("&OK")); + okButton->setAutoDefault(true); + okButton->setDefault(true); + connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); + QPushButton *cancelButton = new QPushButton(tr("&Cancel")); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(); + buttonLayout->addWidget(okButton); + buttonLayout->addWidget(cancelButton); + + QGridLayout *mainLayout = new QGridLayout; + mainLayout->addWidget(reasonLabel, 0, 0); + mainLayout->addWidget(reasonEdit, 0, 1); + mainLayout->addWidget(minutesLabel, 1, 0); + mainLayout->addWidget(minutesEdit, 1, 1); + mainLayout->addLayout(buttonLayout, 2, 0, 1, 2); + + setLayout(mainLayout); + setWindowTitle(tr("Shut down server")); +} + +QString ShutdownDialog::getReason() const +{ + return reasonEdit->text(); +} + +int ShutdownDialog::getMinutes() const +{ + return minutesEdit->value(); +} + +TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool _fullAdmin, QWidget *parent) + : Tab(_tabSupervisor, parent), locked(true), client(_client), fullAdmin(_fullAdmin) { updateServerMessageButton = new QPushButton; connect(updateServerMessageButton, SIGNAL(clicked()), this, SLOT(actUpdateServerMessage())); + shutdownServerButton = new QPushButton; + connect(shutdownServerButton, SIGNAL(clicked()), this, SLOT(actShutdownServer())); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(updateServerMessageButton); + vbox->addWidget(shutdownServerButton); vbox->addStretch(); adminGroupBox = new QGroupBox; @@ -38,6 +91,7 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidg void TabAdmin::retranslateUi() { updateServerMessageButton->setText(tr("Update server &message")); + shutdownServerButton->setText(tr("&Shut down server")); adminGroupBox->setTitle(tr("Server administration functions")); unlockButton->setText(tr("&Unlock functions")); @@ -49,10 +103,18 @@ void TabAdmin::actUpdateServerMessage() client->sendCommand(new Command_UpdateServerMessage()); } +void TabAdmin::actShutdownServer() +{ + ShutdownDialog dlg; + if (dlg.exec()) + client->sendCommand(new Command_ShutdownServer(dlg.getReason(), dlg.getMinutes())); +} + void TabAdmin::actUnlock() { if (QMessageBox::question(this, tr("Unlock administration functions"), tr("Do you really want to unlock the administration functions?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - adminGroupBox->setEnabled(true); + if (fullAdmin) + adminGroupBox->setEnabled(true); lockButton->setEnabled(true); unlockButton->setEnabled(false); locked = false; @@ -61,7 +123,8 @@ void TabAdmin::actUnlock() void TabAdmin::actLock() { - adminGroupBox->setEnabled(false); + if (fullAdmin) + adminGroupBox->setEnabled(false); lockButton->setEnabled(false); unlockButton->setEnabled(true); locked = true; diff --git a/cockatrice/src/tab_admin.h b/cockatrice/src/tab_admin.h index 8450d473..a4982bba 100644 --- a/cockatrice/src/tab_admin.h +++ b/cockatrice/src/tab_admin.h @@ -2,27 +2,43 @@ #define TAB_ADMIN_H #include "tab.h" +#include class AbstractClient; class QGroupBox; class QPushButton; +class QSpinBox; +class QLineEdit; + +class ShutdownDialog : public QDialog { + Q_OBJECT +private: + QLineEdit *reasonEdit; + QSpinBox *minutesEdit; +public: + ShutdownDialog(QWidget *parent = 0); + QString getReason() const; + int getMinutes() const; +}; class TabAdmin : public Tab { Q_OBJECT private: bool locked; AbstractClient *client; - QPushButton *updateServerMessageButton; + bool fullAdmin; + QPushButton *updateServerMessageButton, *shutdownServerButton; QGroupBox *adminGroupBox; QPushButton *unlockButton, *lockButton; private slots: void actUpdateServerMessage(); + void actShutdownServer(); void actUnlock(); void actLock(); public: - TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent = 0); + TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool _fullAdmin, QWidget *parent = 0); void retranslateUi(); QString getTabText() const { return tr("Administration"); } bool getLocked() const { return locked; } diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index e8018c98..9b15e0de 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -5,8 +5,6 @@ #include #include #include -#include -#include #include "tab_game.h" #include "cardinfowidget.h" #include "playerlistwidget.h" @@ -160,8 +158,8 @@ void DeckViewContainer::setDeck(DeckList *deck) readyStartButton->setEnabled(true); } -TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) - : Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1), infoPopup(0) +TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, ServerInfo_User *_userInfo, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) + : Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1) { phasesToolbar = new PhasesToolbar; phasesToolbar->hide(); @@ -178,10 +176,10 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_client timeElapsedLabel = new QLabel; timeElapsedLabel->setAlignment(Qt::AlignCenter); - messageLog = new MessageLogWidget; + messageLog = new MessageLogWidget(_userInfo->getName(), _userInfo->getGender() == ServerInfo_User::Female); connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString))); connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString))); - connect(messageLog, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup())); + connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); sayLabel = new QLabel; sayEdit = new QLineEdit; sayLabel->setBuddy(sayEdit); @@ -747,7 +745,7 @@ void TabGame::newCardAdded(AbstractCardItem *card) { connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfo, SLOT(setCard(AbstractCardItem *))); connect(card, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString))); - connect(card, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup())); + connect(card, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); } CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const @@ -779,24 +777,3 @@ Player *TabGame::getActiveLocalPlayer() const return 0; } - -void TabGame::showCardInfoPopup(const QPoint &pos, const QString &cardName) -{ - infoPopup = new CardInfoWidget(CardInfoWidget::ModePopUp, 0, Qt::Widget | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint); - infoPopup->setAttribute(Qt::WA_TransparentForMouseEvents); - infoPopup->setCard(cardName); - QRect screenRect = qApp->desktop()->screenGeometry(this); - infoPopup->move( - qMax(screenRect.left(), qMin(pos.x() - infoPopup->width() / 2, screenRect.left() + screenRect.width() - infoPopup->width())), - qMax(screenRect.top(), qMin(pos.y() - infoPopup->height() / 2, screenRect.top() + screenRect.height() - infoPopup->height())) - ); - infoPopup->show(); -} - -void TabGame::deleteCardInfoPopup() -{ - if (infoPopup) { - infoPopup->deleteLater(); - infoPopup = 0; - } -} diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h index 5982b42b..a5eb5db9 100644 --- a/cockatrice/src/tab_game.h +++ b/cockatrice/src/tab_game.h @@ -100,7 +100,6 @@ private: int activePlayer; QSplitter *splitter; - CardInfoWidget *infoPopup; CardInfoWidget *cardInfo; PlayerListWidget *playerListWidget; QLabel *timeElapsedLabel; @@ -147,8 +146,6 @@ signals: void openMessageDialog(const QString &userName, bool focus); private slots: void newCardAdded(AbstractCardItem *card); - void showCardInfoPopup(const QPoint &pos, const QString &cardName); - void deleteCardInfoPopup(); void actConcede(); void actLeaveGame(); @@ -158,7 +155,7 @@ private slots: void actNextPhase(); void actNextTurn(); public: - TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); + TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, ServerInfo_User *_userInfo, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); ~TabGame(); void retranslateUi(); void closeRequest(); diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index 03fb401f..f4efd7f5 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -11,7 +11,9 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName) : Tab(_tabSupervisor), client(_client), userName(_userName), userOnline(true) { - chatView = new ChatView(_ownName); + chatView = new ChatView(_ownName, true); + connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString))); + connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); sayEdit = new QLineEdit; connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage())); diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index f40458cd..7fbce5a7 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -4,127 +4,17 @@ #include #include #include -#include #include #include -#include #include #include -#include "dlg_creategame.h" #include "tab_supervisor.h" #include "tab_room.h" #include "userlist.h" #include "abstractclient.h" #include "protocol_items.h" -#include "gamesmodel.h" #include "chatview.h" - -GameSelector::GameSelector(AbstractClient *_client, TabRoom *_room, QWidget *parent) - : QGroupBox(parent), client(_client), room(_room) -{ - gameListView = new QTreeView; - gameListModel = new GamesModel(room->getGameTypes(), this); - gameListProxyModel = new GamesProxyModel(this); - gameListProxyModel->setSourceModel(gameListModel); - gameListProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); - gameListView->setModel(gameListProxyModel); - gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents); - gameListView->setSortingEnabled(true); - - showFullGamesCheckBox = new QCheckBox; - createButton = new QPushButton; - joinButton = new QPushButton; - spectateButton = new QPushButton; - QHBoxLayout *buttonLayout = new QHBoxLayout; - buttonLayout->addWidget(showFullGamesCheckBox); - buttonLayout->addStretch(); - buttonLayout->addWidget(createButton); - buttonLayout->addWidget(joinButton); - buttonLayout->addWidget(spectateButton); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(gameListView); - mainLayout->addLayout(buttonLayout); - - retranslateUi(); - setLayout(mainLayout); - - setMinimumWidth((qreal) (gameListView->columnWidth(0) * gameListModel->columnCount()) / 1.5); - setMinimumHeight(200); - - connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int))); - connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate())); - connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin())); - connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin())); -} - -void GameSelector::showFullGamesChanged(int state) -{ - gameListProxyModel->setFullGamesVisible(state); -} - -void GameSelector::actCreate() -{ - DlgCreateGame dlg(client, room->getRoomId(), room->getGameTypes(), this); - dlg.exec(); -} - -void GameSelector::checkResponse(ResponseCode response) -{ - createButton->setEnabled(true); - joinButton->setEnabled(true); - spectateButton->setEnabled(true); - - switch (response) { - case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break; - case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break; - case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break; - case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break; - case RespUserLevelTooLow: QMessageBox::critical(this, tr("Error"), tr("This game is only open to registered users.")); break; - case RespOnlyBuddies: QMessageBox::critical(this, tr("Error"), tr("This game is only open to its creator's buddies.")); break; - case RespInIgnoreList: QMessageBox::critical(this, tr("Error"), tr("You are being ignored by the creator of this game.")); break; - default: ; - } -} - -void GameSelector::actJoin() -{ - bool spectator = sender() == spectateButton; - - QModelIndex ind = gameListView->currentIndex(); - if (!ind.isValid()) - return; - ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); - QString password; - if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) { - bool ok; - password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); - if (!ok) - return; - } - - Command_JoinGame *commandJoinGame = new Command_JoinGame(room->getRoomId(), game->getGameId(), password, spectator); - connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode))); - client->sendCommand(commandJoinGame); - - createButton->setEnabled(false); - joinButton->setEnabled(false); - spectateButton->setEnabled(false); -} - -void GameSelector::retranslateUi() -{ - setTitle(tr("Games")); - showFullGamesCheckBox->setText(tr("Show &full games")); - createButton->setText(tr("C&reate")); - joinButton->setText(tr("&Join")); - spectateButton->setText(tr("J&oin as spectator")); -} - -void GameSelector::processGameInfo(ServerInfo_Game *info) -{ - gameListModel->updateGameList(info); -} +#include "gameselector.h" TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info) : Tab(_tabSupervisor), client(_client), roomId(info->getRoomId()), roomName(info->getName()), ownName(_ownName) @@ -133,11 +23,15 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const Q for (int i = 0; i < gameTypeList.size(); ++i) gameTypes.insert(gameTypeList[i]->getGameTypeId(), gameTypeList[i]->getDescription()); - gameSelector = new GameSelector(client, this); + QMap tempMap; + tempMap.insert(info->getRoomId(), gameTypes); + gameSelector = new GameSelector(client, this, QMap(), tempMap); userList = new UserList(tabSupervisor, client, UserList::RoomList); connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool))); - chatView = new ChatView(ownName); + chatView = new ChatView(ownName, true); + connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString))); + connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); sayLabel = new QLabel; sayEdit = new QLineEdit; sayLabel->setBuddy(sayEdit); @@ -262,5 +156,5 @@ void TabRoom::processLeaveRoomEvent(Event_LeaveRoom *event) void TabRoom::processSayEvent(Event_RoomSay *event) { chatView->appendMessage(event->getPlayerName(), event->getMessage()); - emit userEvent(); + emit userEvent(false); } diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h index 9c19542f..37e6a3d1 100644 --- a/cockatrice/src/tab_room.h +++ b/cockatrice/src/tab_room.h @@ -2,20 +2,16 @@ #define TAB_ROOM_H #include "tab.h" -#include "protocol_datastructures.h" #include +#include class AbstractClient; class UserList; class QLabel; class ChatView; class QLineEdit; -class QTreeView; class QPushButton; class QTextTable; -class QCheckBox; -class GamesModel; -class GamesProxyModel; class RoomEvent; class ServerInfo_Room; class ServerInfo_Game; @@ -24,31 +20,7 @@ class Event_JoinRoom; class Event_LeaveRoom; class Event_RoomSay; class ProtocolResponse; -class TabRoom; - -class GameSelector : public QGroupBox { - Q_OBJECT -private slots: - void showFullGamesChanged(int state); - void actCreate(); - void actJoin(); - void checkResponse(ResponseCode response); -signals: - void gameJoined(int gameId); -private: - AbstractClient *client; - TabRoom *room; - - QTreeView *gameListView; - GamesModel *gameListModel; - GamesProxyModel *gameListProxyModel; - QPushButton *createButton, *joinButton, *spectateButton; - QCheckBox *showFullGamesCheckBox; -public: - GameSelector(AbstractClient *_client, TabRoom *_room, QWidget *parent = 0); - void retranslateUi(); - void processGameInfo(ServerInfo_Game *info); -}; +class GameSelector; class TabRoom : public Tab { Q_OBJECT diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp index be7751a0..824d149d 100644 --- a/cockatrice/src/tab_supervisor.cpp +++ b/cockatrice/src/tab_supervisor.cpp @@ -101,15 +101,14 @@ void TabSupervisor::retranslateUi() int TabSupervisor::myAddTab(Tab *tab) { - connect(tab, SIGNAL(userEvent()), this, SLOT(tabUserEvent())); + connect(tab, SIGNAL(userEvent(bool)), this, SLOT(tabUserEvent(bool))); return addTab(tab, tab->getTabText()); } -void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo) +void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *_userInfo) { client = _client; - userName = userInfo->getName(); - userLevel = userInfo->getUserLevel(); + userInfo = new ServerInfo_User(_userInfo); connect(client, SIGNAL(roomEventReceived(RoomEvent *)), this, SLOT(processRoomEvent(RoomEvent *))); connect(client, SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *))); @@ -135,8 +134,8 @@ void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo) } else tabDeckStorage = 0; - if (userInfo->getUserLevel() & ServerInfo_User::IsAdmin) { - tabAdmin = new TabAdmin(this, client); + if (userInfo->getUserLevel() & ServerInfo_User::IsModerator) { + tabAdmin = new TabAdmin(this, client, (userInfo->getUserLevel() & ServerInfo_User::IsAdmin)); myAddTab(tabAdmin); } else tabAdmin = 0; @@ -146,6 +145,7 @@ void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo) void TabSupervisor::startLocal(const QList &_clients) { + userInfo = new ServerInfo_User; localClients = _clients; for (int i = 0; i < localClients.size(); ++i) connect(localClients[i], SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *))); @@ -192,6 +192,9 @@ void TabSupervisor::stop() while (messageIterator.hasNext()) messageIterator.next().value()->deleteLater(); messageTabs.clear(); + + delete userInfo; + userInfo = 0; } void TabSupervisor::updatePingTime(int value, int max) @@ -221,7 +224,7 @@ void TabSupervisor::addCloseButtonToTab(Tab *tab, int tabIndex) void TabSupervisor::gameJoined(Event_GameJoined *event) { - TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); + TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), userInfo, event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); int tabIndex = myAddTab(tab); @@ -232,7 +235,7 @@ void TabSupervisor::gameJoined(Event_GameJoined *event) void TabSupervisor::localGameJoined(Event_GameJoined *event) { - TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); + TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), userInfo, event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); int tabIndex = myAddTab(tab); addCloseButtonToTab(tab, tabIndex); @@ -258,7 +261,7 @@ void TabSupervisor::gameLeft(TabGame *tab) void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent) { - TabRoom *tab = new TabRoom(this, client, userName, info); + TabRoom *tab = new TabRoom(this, client, userInfo->getName(), info); connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); int tabIndex = myAddTab(tab); @@ -278,10 +281,10 @@ void TabSupervisor::roomLeft(TabRoom *tab) TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus) { - if (receiverName == userName) + if (receiverName == userInfo->getName()) return 0; - TabMessage *tab = new TabMessage(this, client, userName, receiverName); + TabMessage *tab = new TabMessage(this, client, userInfo->getName(), receiverName); connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *))); int tabIndex = myAddTab(tab); addCloseButtonToTab(tab, tabIndex); @@ -299,14 +302,15 @@ void TabSupervisor::talkLeft(TabMessage *tab) removeTab(indexOf(tab)); } -void TabSupervisor::tabUserEvent() +void TabSupervisor::tabUserEvent(bool globalEvent) { Tab *tab = static_cast(sender()); if (tab != currentWidget()) { tab->setContentsChanged(true); setTabIcon(indexOf(tab), *tabChangedIcon); } - QApplication::alert(this); + if (globalEvent) + QApplication::alert(this); } void TabSupervisor::processRoomEvent(RoomEvent *event) @@ -371,3 +375,8 @@ bool TabSupervisor::getAdminLocked() const return true; return tabAdmin->getLocked(); } + +int TabSupervisor::getUserLevel() const +{ + return userInfo->getUserLevel(); +} diff --git a/cockatrice/src/tab_supervisor.h b/cockatrice/src/tab_supervisor.h index 439ac1f8..0a38d5f8 100644 --- a/cockatrice/src/tab_supervisor.h +++ b/cockatrice/src/tab_supervisor.h @@ -37,8 +37,7 @@ protected: class TabSupervisor : public QTabWidget { Q_OBJECT private: - QString userName; - int userLevel; + ServerInfo_User *userInfo; QIcon *tabChangedIcon; AbstractClient *client; QList localClients; @@ -61,7 +60,7 @@ public: int getGameCount() const { return gameTabs.size(); } TabUserLists *getUserListsTab() const { return tabUserLists; } bool getAdminLocked() const; - int getUserLevel() const { return userLevel; } + int getUserLevel() const; signals: void setMenu(QMenu *menu); void localGameEnded(); @@ -78,7 +77,7 @@ private slots: void processUserLeft(const QString &userName); void processUserJoined(const QString &userName); void talkLeft(TabMessage *tab); - void tabUserEvent(); + void tabUserEvent(bool globalEvent); void processRoomEvent(RoomEvent *event); void processGameEventContainer(GameEventContainer *cont); void processMessageEvent(Event_Message *event); diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp index c904513c..71101f48 100644 --- a/cockatrice/src/userlist.cpp +++ b/cockatrice/src/userlist.cpp @@ -5,11 +5,59 @@ #include "pixmapgenerator.h" #include "userinfobox.h" #include "protocol_items.h" +#include "gameselector.h" #include #include #include #include #include +#include +#include +#include +#include +#include + +BanDialog::BanDialog(QWidget *parent) + : QDialog(parent) +{ + QLabel *durationLabel = new QLabel(tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban.")); + durationEdit = new QSpinBox; + durationEdit->setMinimum(0); + durationEdit->setValue(5); + QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and cannot be seen by the banned person.")); + reasonEdit = new QPlainTextEdit; + + QPushButton *okButton = new QPushButton(tr("&OK")); + okButton->setAutoDefault(true); + connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); + QPushButton *cancelButton = new QPushButton(tr("&Cancel")); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(); + buttonLayout->addWidget(okButton); + buttonLayout->addWidget(cancelButton); + + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(durationLabel); + vbox->addWidget(durationEdit); + vbox->addWidget(reasonLabel); + vbox->addWidget(reasonEdit); + vbox->addLayout(buttonLayout); + + setLayout(vbox); + setWindowTitle(tr("Ban user from server")); +} + +int BanDialog::getMinutes() const +{ + return durationEdit->value(); +} + +QString BanDialog::getReason() const +{ + return reasonEdit->toPlainText(); +} UserListItemDelegate::UserListItemDelegate(QObject *const parent) : QStyledItemDelegate(parent) @@ -59,6 +107,7 @@ UserList::UserList(TabSupervisor *_tabSupervisor, AbstractClient *_client, UserL userTree->setRootIsDecorated(false); userTree->setIconSize(QSize(20, 12)); userTree->setItemDelegate(itemDelegate); + userTree->setAlternatingRowColors(true); connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int))); QVBoxLayout *vbox = new QVBoxLayout; @@ -163,6 +212,35 @@ void UserList::userClicked(QTreeWidgetItem *item, int /*column*/) emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true); } +void UserList::gamesOfUserReceived(ProtocolResponse *resp) +{ + Command_GetGamesOfUser *command = static_cast(sender()); + Response_GetGamesOfUser *response = qobject_cast(resp); + if (!response) + return; + + QMap gameTypeMap; + QMap roomMap; + const QList roomList = response->getRoomList(); + for (int i = 0; i < roomList.size(); ++i) { + roomMap.insert(roomList[i]->getRoomId(), roomList[i]->getName()); + const QList gameTypeList = roomList[i]->getGameTypeList(); + GameTypeMap tempMap; + for (int j = 0; j < gameTypeList.size(); ++j) + tempMap.insert(gameTypeList[j]->getGameTypeId(), gameTypeList[j]->getDescription()); + gameTypeMap.insert(roomList[i]->getRoomId(), tempMap); + } + + GameSelector *selector = new GameSelector(client, 0, roomMap, gameTypeMap); + const QList gameList = response->getGameList(); + for (int i = 0; i < gameList.size(); ++i) + selector->processGameInfo(gameList[i]); + + selector->setWindowTitle(tr("%1's games").arg(command->getUserName())); + selector->setAttribute(Qt::WA_DeleteOnClose); + selector->show(); +} + void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) { const QString &userName = index.sibling(index.row(), 2).data(Qt::UserRole).toString(); @@ -172,6 +250,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) aUserName->setEnabled(false); QAction *aDetails = new QAction(tr("User &details"), this); QAction *aChat = new QAction(tr("Direct &chat"), this); + QAction *aShowGames = new QAction(tr("Show this user's &games"), this); QAction *aAddToBuddyList = new QAction(tr("Add to &buddy list"), this); QAction *aRemoveFromBuddyList = new QAction(tr("Remove from &buddy list"), this); QAction *aAddToIgnoreList = new QAction(tr("Add to &ignore list"), this); @@ -182,6 +261,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) menu->addAction(aUserName); menu->addSeparator(); menu->addAction(aDetails); + menu->addAction(aShowGames); menu->addAction(aChat); if ((userLevel & ServerInfo_User::IsRegistered) && (tabSupervisor->getUserLevel() & ServerInfo_User::IsRegistered)) { menu->addSeparator(); @@ -210,15 +290,18 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) client->sendCommand(new Command_AddToList("buddy", userName)); else if (actionClicked == aRemoveFromBuddyList) client->sendCommand(new Command_RemoveFromList("buddy", userName)); - else if (actionClicked == aAddToIgnoreList) + else if (actionClicked == aShowGames) { + Command *cmd = new Command_GetGamesOfUser(userName); + connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(gamesOfUserReceived(ProtocolResponse *))); + client->sendCommand(cmd); + } else if (actionClicked == aAddToIgnoreList) client->sendCommand(new Command_AddToList("ignore", userName)); else if (actionClicked == aRemoveFromIgnoreList) client->sendCommand(new Command_RemoveFromList("ignore", userName)); else if (actionClicked == aBan) { - bool ok; - int minutes = QInputDialog::getInt(this, tr("Duration"), tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban."), 0, 0, 2147483647, 10, &ok); - if (ok) - client->sendCommand(new Command_BanFromServer(userName, minutes)); + BanDialog dlg(this); + if (dlg.exec()) + client->sendCommand(new Command_BanFromServer(userName, dlg.getMinutes(), dlg.getReason())); } delete menu; diff --git a/cockatrice/src/userlist.h b/cockatrice/src/userlist.h index a611bf5d..c71ddc31 100644 --- a/cockatrice/src/userlist.h +++ b/cockatrice/src/userlist.h @@ -1,6 +1,7 @@ #ifndef USERLIST_H #define USERLIST_H +#include #include #include #include @@ -9,6 +10,20 @@ class QTreeWidget; class ServerInfo_User; class AbstractClient; class TabSupervisor; +class QSpinBox; +class QPlainTextEdit; +class ProtocolResponse; + +class BanDialog : public QDialog { + Q_OBJECT +private: + QSpinBox *durationEdit; + QPlainTextEdit *reasonEdit; +public: + BanDialog(QWidget *parent = 0); + int getMinutes() const; + QString getReason() const; +}; class UserListItemDelegate : public QStyledItemDelegate { public: @@ -38,6 +53,7 @@ private: void setUserOnline(QTreeWidgetItem *user, bool online); private slots: void userClicked(QTreeWidgetItem *item, int column); + void gamesOfUserReceived(ProtocolResponse *resp); signals: void openMessageDialog(const QString &userName, bool focus); void addBuddy(const QString &userName); diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 595e8b8e..7acbe551 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -56,11 +56,18 @@ void MainWindow::processConnectionClosedEvent(Event_ConnectionClosed *event) reasonStr = tr("There are too many concurrent connections from your address."); else if (reason == "banned") reasonStr = tr("Banned by moderator."); + else if (reason == "server_shutdown") + reasonStr = tr("Scheduled server shutdown."); else reasonStr = tr("Unknown reason."); QMessageBox::critical(this, tr("Connection closed"), tr("The server has terminated your connection.\nReason: %1").arg(reasonStr)); } +void MainWindow::processServerShutdownEvent(Event_ServerShutdown *event) +{ + QMessageBox::information(this, tr("Scheduled server shutdown"), tr("The server is going to be restarted in %n minute(s).\nAll running games will be lost.\nReason for shutdown: %1", "", event->getMinutes()).arg(event->getReason())); +} + void MainWindow::statusChanged(ClientStatus _status) { setClientStatusTitle(); @@ -290,6 +297,7 @@ MainWindow::MainWindow(QWidget *parent) client = new RemoteClient(this); connect(client, SIGNAL(connectionClosedEventReceived(Event_ConnectionClosed *)), this, SLOT(processConnectionClosedEvent(Event_ConnectionClosed *))); + connect(client, SIGNAL(serverShutdownEventReceived(Event_ServerShutdown *)), this, SLOT(processServerShutdownEvent(Event_ServerShutdown *))); connect(client, SIGNAL(serverError(ResponseCode)), this, SLOT(serverError(ResponseCode))); connect(client, SIGNAL(socketError(const QString &)), this, SLOT(socketError(const QString &))); connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout())); diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h index 9ca62ba8..4d8b45d6 100644 --- a/cockatrice/src/window_main.h +++ b/cockatrice/src/window_main.h @@ -36,6 +36,7 @@ private slots: void updateTabMenu(QMenu *menu); void statusChanged(ClientStatus _status); void processConnectionClosedEvent(Event_ConnectionClosed *event); + void processServerShutdownEvent(Event_ServerShutdown *event); void serverTimeout(); void serverError(ResponseCode r); void socketError(const QString &errorStr); diff --git a/cockatrice/translations/cockatrice_cs.ts b/cockatrice/translations/cockatrice_cs.ts index 1ce8de4b..fd328067 100644 --- a/cockatrice/translations/cockatrice_cs.ts +++ b/cockatrice/translations/cockatrice_cs.ts @@ -37,90 +37,125 @@ AppearanceSettingsPage - + Zone background pictures - + Path to hand background: - + Path to stack background: - + Path to table background: - + Path to player info background: - + Path to picture of card back: - + Card rendering - + Display card names on cards having a picture - + Hand layout - + Display hand horizontally (wastes space) - + Table grid layout - + Invert vertical coordinate - + + Minimum player count for multi-column layout: + + + + Zone view layout - + Sort by name - + Sort by type - - - - - + + + + + Choose path + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + + + + + &Cancel + + + + + Ban user from server + + + CardDatabaseModel @@ -195,197 +230,202 @@ CardItem - + &Play - + &Hide - + &Tap - + &Untap - + Toggle &normal untapping - + &Flip - + &Clone - + Ctrl+H - + &Attach to card... - + Ctrl+A - + Unattac&h - - - &Power / toughness - - - - - &Increase power - - - - - Ctrl++ - - - - - &Decrease power - - - - - Ctrl+- - - - - - I&ncrease toughness - - - Alt++ + &Draw arrow... - D&ecrease toughness + &Power / toughness - Alt+- + &Increase power - In&crease power and toughness + Ctrl++ - Ctrl+Alt++ + &Decrease power - Dec&rease power and toughness + Ctrl+- - Ctrl+Alt+- + I&ncrease toughness - Set &power and toughness... + Alt++ - Ctrl+P + D&ecrease toughness - &Set annotation... + Alt+- + + + + + In&crease power and toughness - red + Ctrl+Alt++ - yellow + Dec&rease power and toughness - green + Ctrl+Alt+- + + + + + Set &power and toughness... - &Add counter (%1) + Ctrl+P - - &Remove counter (%1) + + &Set annotation... + + + + + red - &Set counters (%1)... + yellow - &top of library - - - - - &bottom of library + green - &graveyard - - - - - Ctrl+Del + &Add counter (%1) - &exile + &Remove counter (%1) + &Set counters (%1)... + + + + + &top of library + + + + + &bottom of library + + + + + &graveyard + + + + + Ctrl+Del + + + + + &exile + + + + &Move to @@ -756,12 +796,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General @@ -787,22 +827,22 @@ DeckViewContainer - + Load &local deck - + Load d&eck from server - + Ready to s&tart - + Load deck @@ -891,82 +931,82 @@ - + P&layers: - + Game type - + &Password: - + Only &buddies can join - + Only &registered users can join - + Joining restrictions - + &Spectators allowed - + Spectators &need a password to join - + Spectators can &chat - + Spectators see &everything - + Spectators - + &OK - + &Cancel - + Create game - + Error - + Server error. @@ -1108,59 +1148,59 @@ DlgSettings - - - + + + Error - + Your card database is invalid. Would you like to go back and set the correct path? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + General - + Appearance - + User interface - + Deck editor - + Messages - + &Close @@ -1168,83 +1208,94 @@ GameSelector - - - - - - - + + + + + + + + Error - + + Please join the appropriate room first. + + + + Wrong password. - + Spectators are not allowed in this game. - + The game is already full. - + The game does not exist any more. - + This game is only open to registered users. - + This game is only open to its creator's buddies. - + You are being ignored by the creator of this game. - + Join game - + Password: - + Games - + Show &full games - + + Show &running games + + + + C&reate - + &Join - + J&oin as spectator @@ -1260,67 +1311,72 @@ GamesModel - + yes - + yes, free for spectators - + no - + buddies only - + reg. users only - + not allowed - - - Description - - - - - Creator - - - Game type + Room - Password + Description - Restrictions + Creator - Players + Game type + Password + + + + + Restrictions + + + + + Players + + + + Spectators @@ -1328,50 +1384,50 @@ GeneralSettingsPage - - + + English - - - + + + Choose path - + Personal settings - + Language: - + Download card pictures on the fly - + Paths - + Decks directory: - + Pictures directory: - + Path to card database: @@ -1390,216 +1446,237 @@ + Scheduled server shutdown. + + + + Unknown reason. - + Connection closed - + The server has terminated your connection. Reason: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + + Number of players - + Please enter the number of players. - - + + Player %1 - + About Cockatrice - + Version %1 - + Authors: - + Translators: - + Spanish: - + Portugese (Portugal): - + Portugese (Brazil): - + French: - + Japanese: - + Russian: - + Czech: - + Slovak: - - + - - + + + Error - + Server timeout - + Invalid login data. - + There is already an active session using this user name. Please close that session first and re-login. - + Socket error: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. - + Connecting to %1... - + Disconnected - + Logged in at %1 - + &Connect... - + &Disconnect - + Start &local game... - + &Deck editor - + &Full screen - + Ctrl+F - + &Settings... - + &Exit - + &Cockatrice - + &About Cockatrice - + &Help - + Are you sure? - + There are still open games. Are you sure you want to quit? @@ -1607,108 +1684,183 @@ Local version is %1, remote version is %2. MessageLogWidget - - Connecting to %1... - - - - - Connected. - - - - - Disconnected from server. - - - - - Invalid password. - - - - - Protocol version mismatch. Client: %1, Server: %2 - - - - - Protocol error. - - - - - You have joined game #%1. - - - - - %1 has joined the game. - - - - - %1 has left the game. - - - - + The game has been closed. - + %1 is now watching the game. - + %1 is not watching the game any more. - - - %1 has loaded a local deck. - - - - - %1 has loaded deck #%2. - - - %1 is ready to start the game. - - - - - %1 is not ready to start the game any more. - - - - - %1 has conceded the game. - - - - The game has started. - - %1 shuffles %2. + + You have joined game #%1. + female - + + You have joined game #%1. + male + + + + + %1 has joined the game. + female + + + + + %1 has joined the game. + male + + + + + %1 has left the game. + female + + + + + %1 has left the game. + male + + + + + %1 has loaded a local deck. + female + + + + + %1 has loaded a local deck. + male + + + + + %1 has loaded deck #%2. + female + + + + + %1 has loaded deck #%2. + male + + + + + %1 is ready to start the game. + female + + + + + %1 is ready to start the game. + male + + + + + %1 is not ready to start the game any more. + female + + + + + %1 is not ready to start the game any more. + male + + + + + %1 has conceded the game. + female + + + + + %1 has conceded the game. + male + + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + %1 rolls a %2 with a %3-sided die. + female + + + + + %1 rolls a %2 with a %3-sided die. + male - + %1 draws %n card(s). + female + + + + + + + + + %1 draws %n card(s). + male @@ -1716,189 +1868,200 @@ Local version is %1, remote version is %2. - + %1 undoes his last draw. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). - + %1 undoes her last draw (%2). - + from table - + from graveyard - + from exile - + from hand - + the bottom card of his library - + the bottom card of her library - + from the bottom of his library - + from the bottom of her library - + the top card of his library - + the top card of her library - + from the top of his library - + from the top of her library - + from library - + from sideboard - + from the stack - - + + a card - + %1 gives %2 control over %3. - + %1 puts %2 into play tapped%3. - + %1 puts %2 into play%3. - + %1 puts %2%3 into graveyard. - + %1 exiles %2%3. - + %1 moves %2%3 to hand. - + %1 puts %2%3 into his library. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. - + %1 plays %2%3. - + %1 takes a mulligan to %n. + female + + + + + + + + + %1 takes a mulligan to %n. + male @@ -1906,58 +2069,285 @@ Local version is %1, remote version is %2. - - %1 draws his initial hand. - - - - - %1 draws her initial hand. - - - - + %1 flips %2 face-down. + female - + + %1 flips %2 face-down. + male + + + + %1 flips %2 face-up. + female - - %1 destroys %2. - - - - - %1 attaches %2 to %3's %4. - - - - - %1 unattaches %2. - - - - - %1 creates token: %2%3. + + %1 flips %2 face-up. + male - %1 points from %2's %3 to %4. + %1 destroys %2. + female - + + %1 destroys %2. + male + + + + + %1 unattaches %2. + female + + + + + %1 unattaches %2. + male + + + + + %1 creates token: %2%3. + female + + + + + %1 creates token: %2%3. + male + + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male - + %1 places %n %2 counter(s) on %3 (now %4). + female @@ -1965,8 +2355,19 @@ Local version is %1, remote version is %2. - + + %1 places %n %2 counter(s) on %3 (now %4). + male + + + + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female @@ -1974,7 +2375,315 @@ Local version is %1, remote version is %2. - + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + + + + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + + + + + %1 sets counter %2 to %3 (%4%5). + male + + + + + %1 sets %2 to not untap normally. + female + + + + + %1 sets %2 to not untap normally. + male + + + + + %1 sets %2 to untap normally. + female + + + + + %1 sets %2 to untap normally. + male + + + + + %1 sets PT of %2 to %3. + female + + + + + %1 sets PT of %2 to %3. + male + + + + + %1 sets annotation of %2 to %3. + female + + + + + %1 sets annotation of %2 to %3. + male + + + + + %1 is looking at the top %2 cards %3. + female + + + + + %1 is looking at the top %2 cards %3. + male + + + + + %1 is looking at %2. + female + + + + + %1 is looking at %2. + male + + + + + %1 stops looking at %2. + female + + + + + %1 stops looking at %2. + male + + + + + %1 reveals %2 to %3. + p1 female, p2 female + + + + + %1 reveals %2 to %3. + p1 female, p2 male + + + + + %1 reveals %2 to %3. + p1 male, p2 female + + + + + %1 reveals %2 to %3. + p1 male, p2 male + + + + + %1 reveals %2. + female + + + + + %1 reveals %2. + male + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 randomly reveals %2%3. + female + + + + + %1 randomly reveals %2%3. + male + + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 reveals %2%3. + female + + + + + %1 reveals %2%3. + male + + + + + It is now %1's turn. + female + + + + + It is now %1's turn. + male + + + + + %1 draws his initial hand. + + + + + %1 draws her initial hand. + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + + + + red @@ -1983,7 +2692,7 @@ Local version is %1, remote version is %2. - + yellow @@ -1992,7 +2701,7 @@ Local version is %1, remote version is %2. - + green @@ -2001,162 +2710,62 @@ Local version is %1, remote version is %2. - - his permanents - - - - - her permanents - - - - - %1 %2 %3. - - - - - taps - - - - - untaps - - - - - %1 sets counter %2 to %3 (%4%5). - - - - - %1 sets %2 to not untap normally. - - - - - %1 sets %2 to untap normally. - - - - - %1 sets PT of %2 to %3. - - - - - %1 sets annotation of %2 to %3. - - - - - %1 is looking at the top %2 cards %3. - - - - - %1 is looking at %2. - - - - - %1 stops looking at %2. - - - - - %1 reveals %2 to %3. - - - - - %1 reveals %2. - - - - - %1 randomly reveals %2%3 to %4. - - - - - %1 randomly reveals %2%3. - - - - - %1 reveals %2%3 to %4. - - - - - %1 reveals %2%3. - - - - - It is now %1's turn. - - - - + untap step - + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + ending phase - + It is now the %1. @@ -2164,22 +2773,22 @@ Local version is %1, remote version is %2. MessagesSettingsPage - + Add message - + Message: - + &Add - + &Remove @@ -2515,7 +3124,7 @@ Local version is %1, remote version is %2. - + Number: @@ -2540,27 +3149,27 @@ Local version is %1, remote version is %2. - + Set power/toughness - + Please enter the new PT: - + Set annotation - + Please enter the new annotation: - + Set counters @@ -2705,40 +3314,73 @@ Local version is %1, remote version is %2. + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + + + + + &Cancel + + + + + Shut down server + + + TabAdmin - + Update server &message - + + &Shut down server + + + + Server administration functions - + &Unlock functions - + &Lock functions - + Unlock administration functions - + Do you really want to unlock the administration functions? - + Administration @@ -2813,137 +3455,137 @@ Please enter a name: TabGame - + F5 - + F6 - + F7 - + F8 - + F9 - + F10 - + &Phases - + &Game - + Next &phase - + Ctrl+Space - + Next &turn - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows - + Ctrl+R - + &Concede - + F2 - + &Leave game - + Ctrl+Q - + &Say: - + Concede - + Are you sure you want to concede this game? - + Leave game - + Are you sure you want to leave this game? - + Kicked - + You have been kicked out of the game. - + Game %1: %2 @@ -2951,27 +3593,27 @@ Please enter a name: TabMessage - + Personal &talk - + &Leave - + This user is ignoring you. - + %1 has left the server. - + %1 has joined the server. @@ -2984,27 +3626,27 @@ Please enter a name: TabRoom - + &Say: - + Chat - + &Room - + &Leave room - + You are flooding the chat. Please wait a couple of seconds. @@ -3076,37 +3718,37 @@ Please enter a name: UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + Animation settings - + &Tap/untap animation - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3114,71 +3756,70 @@ Please enter a name: UserList - + Users online: %1 - + Users in this room: %1 - + Buddies online: %1 / %2 - + Ignored users online: %1 / %2 - + + %1's games + + + + User &details - + Direct &chat - + + Show this user's &games + + + + Add to &buddy list - + Remove from &buddy list - + Add to &ignore list - + Remove from &ignore list - + Ban from &server - - - Duration - - - - - Please enter the duration of the ban (in minutes). -Enter 0 for an indefinite ban. - - WndDeckEditor diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts index 85e2d47b..cd581e18 100644 --- a/cockatrice/translations/cockatrice_de.ts +++ b/cockatrice/translations/cockatrice_de.ts @@ -60,66 +60,71 @@ AppearanceSettingsPage - + Zone background pictures Hintergrundbilder für Kartenzonen - + Path to hand background: Hintergrundbild für die Hand: - + Path to stack background: Hintergrundbild für den Stapel: - + Path to table background: Hintergrundbild für das Spielfeld: - + Path to player info background: Hintergrundbild für den Spielerbereich: - + Path to picture of card back: Pfad zum Bild der Kartenrückseite: - + Card rendering Kartendarstellung - + Display card names on cards having a picture Kartennamen darstellen auch bei Karten, die Bilder haben - + Hand layout Kartenhand - + Display hand horizontally (wastes space) Hand horizonal anzeigen (verschwendet Platz) - + Table grid layout Spielfeldraster + + + Minimum player count for multi-column layout: + Mindestspielerzahl für mehrspaltige Anordnung: + Economical layout Platzsparende Anordnung - + Invert vertical coordinate Vertikale Koordinate umkehren @@ -128,17 +133,17 @@ Platzsparende Anordnung - + Zone view layout Aussehen des Zonenbetrachters - + Sort by name nach Namen sortieren - + Sort by type nach Kartentypen sortieren @@ -147,15 +152,51 @@ standardmäßig alphabetisch sortieren - - - - - + + + + + Choose path Pfad auswählen + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + Bitte geben Sie die Dauer des Banns ein (in Minuten). +Geben Sie 0 ein für einen unbefristeten Bann. + + + Please enter the reason for the ban. This is only saved for moderators and cannot be seen by the banned person. + Bitte geben Sie den Grund für den Bann ein. Dies wird nur für Moderatoren gespeichert und kann von der gebannten Person nicht gesehen werden. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + Bitte geben Sie den Grund für den Bann ein. +Dies wird nur für Moderatoren gespeichert und kann von der gebannten Person nicht gesehen werden. + + + + &OK + &OK + + + + &Cancel + &Abbrechen + + + + Ban user from server + Benutzer vom Server bannen + + CardDatabaseModel @@ -238,57 +279,57 @@ CardItem - + &Play &Ausspielen - + &Hide &Verstecken - + &Tap &Tappen - + &Untap E&nttappen - + Toggle &normal untapping N&ormales Enttappen umschalten - + &Flip &Umdrehen - + &Clone &Kopieren - + Ctrl+H Ctrl+H - + &Attach to card... &An Karte anlegen... - + Ctrl+A Ctrl+A - + Unattac&h &Von Karte lösen @@ -297,142 +338,147 @@ &Kampfwerte setzen... - + + &Draw arrow... + &Pfeil zeichnen... + + + &Power / toughness &Kampfwerte - + &Increase power &Stärke erhöhen - + Ctrl++ Ctrl++ - + &Decrease power S&tärke senken - + Ctrl+- Ctrl+- - + I&ncrease toughness &Widerstandskraft erhöhen - + Alt++ Alt++ - + D&ecrease toughness W&iderstandskraft senken - + Alt+- Alt+- - + In&crease power and toughness Stärke und Widerstandskraft &erhöhen - + Ctrl+Alt++ Ctrl+Alt++ - + Dec&rease power and toughness Stärke und Widerstandskraft s&enken - + Ctrl+Alt+- Ctrl+Alt+- - + Set &power and toughness... &Kampfwerte setzen... - + Ctrl+P Ctrl+P - + &Set annotation... &Hinweis setzen... - + red rot - + yellow gelb - + green grün - + &Add counter (%1) Zählmarke &hinzufügen (%1) - + &Remove counter (%1) Zählmarke &entfernen (%1) - + &Set counters (%1)... Zählmarken &setzen (%1)... - + &top of library &auf die Bibliothek - + &bottom of library &unter die Bibliothek - + &graveyard in den &Friedhof - + Ctrl+Del Ctrl+Del - + &exile ins &Exil - + &Move to &Verschieben @@ -1163,12 +1209,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) Karten&preisfunktionen anschalten (benutzt Daten von blacklotusproject.com) - + General Allgemeines @@ -1209,22 +1255,22 @@ DeckViewContainer - + Load &local deck &Lokales Deck laden - + Load d&eck from server Deck vom Server l&aden - + Ready to s&tart Bereit zum S&tarten - + Load deck Deck laden @@ -1320,42 +1366,42 @@ &Beschreibung: - + &Password: &Passwort: - + P&layers: &Spieler: - + Game type Spieltyp - + Only &buddies can join Nur &Freunde können teilnehmen - + Only &registered users can join Nur &registrierte Benutzer können teilnehmen - + Joining restrictions Teilnahmebedingungen - + &Spectators allowed &Zuschauer zugelassen - + Spectators &need a password to join Zuschauer brauchen &auch ein Passwort @@ -1364,37 +1410,37 @@ Zuschauer können sp&rechen - + Spectators can &chat Zuschauer können s&chreiben - + Spectators see &everything Zuschauer sehen &alles - + Spectators Zuschauer - + &OK &OK - + &Cancel &Abbruch - + Create game Spiel erstellen - + Error Fehler @@ -1403,7 +1449,7 @@ Ungültige Anzahl an Spielern. - + Server error. Serverfehler. @@ -1576,9 +1622,9 @@ DlgSettings - - - + + + Error Fehler @@ -1595,52 +1641,52 @@ Der Pfad zum Kartenbilderverzeichnis ist ungültig. - + Your card database is invalid. Would you like to go back and set the correct path? Ihre Kartendatenbank ist ungültig. Möchten Sie zurückgehen und den korrekten Pfad einstellen? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? Der Pfad zu Ihrem Deckordner ist ungültig. Möchten Sie zurückgehen und den korrekten Pfad einstellen? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? Der Pfad zu Ihrem Kartenbilderordner ist ungültig. Möchten Sie zurückgehen und den korrekten Pfad einstellen? - + Settings Einstellungen - + General Allgemeines - + Appearance Erscheinungsbild - + User interface Bedienung - + Deck editor Deckeditor - + Messages Nachrichten - + &Close S&chließen @@ -1906,23 +1952,24 @@ GameSelector - + C&reate Spiel e&rstellen - + &Join &Teilnehmen - - - - - - - + + + + + + + + Error Fehler @@ -1931,66 +1978,76 @@ XXX - + + Please join the appropriate room first. + Bitte betreten Sie erst den entsprechenden Raum. + + + Wrong password. Falsches Passwort. - + Spectators are not allowed in this game. In diesem Spiel sind keine Zuschauer zugelassen. - + The game is already full. Das Spiel ist bereits voll. - + The game does not exist any more. Dieses Spiel gibt es nicht mehr. - + This game is only open to registered users. Dieses Spiel kann nur von registrierten Benutzern betreten werden. - + This game is only open to its creator's buddies. Dieses Spiel kann nur von Freunden des Erstellers betreten werden. - + You are being ignored by the creator of this game. Der Ersteller dieses Spiels ignoriert Sie. - + Join game Spiel beitreten - + Password: Passwort: - + Games Spiele - + Show &full games &Volle Spiele anzeigen + + + Show &running games + &Laufende Spiele anzeigen + &Show full games &Volle Spiele anzeigen - + J&oin as spectator &Zuschauen @@ -2006,12 +2063,12 @@ GamesModel - + yes ja - + no nein @@ -2020,57 +2077,62 @@ Spiel ID - + Creator Ersteller - + Description Beschreibung - + yes, free for spectators ja, außer für Zuschauer - + buddies only nur Freunde - + reg. users only nur reg. Benutzer - + not allowed nicht erlaubt + Room + Raum + + + Game type Spieltyp - + Password Passwort - + Restrictions Bedingungen - + Players Spieler - + Spectators Zuschauer @@ -2078,50 +2140,50 @@ GeneralSettingsPage - - - + + + Choose path Pfad auswählen - + Personal settings Persönliche Einstellungen - + Language: Sprache: - + Download card pictures on the fly Kartenbilder dynamisch herunterladen - + Paths Pfade - + Decks directory: Verzeichnis mit Decklisten: - + Pictures directory: Verzeichnis mit Bilddateien: - + Path to card database: Pfad zur Kartendatenbank: - - + + English Deutsch @@ -2140,138 +2202,162 @@ + Scheduled server shutdown. + Planmäßige Serverabschaltung. + + + Unknown reason. Unbekannter Grund. - + Connection closed Verbindung geschlossen - + The server has terminated your connection. Reason: %1 Der Server hat Ihre Verbindung beendet. Grund: %1 - + + Scheduled server shutdown + Planmäßige Serverabschaltung + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + Der Server wird in %n Minute neu gestartet. +Alle laufenden Spiele werden beendet. +Grund für die Abschaltung: %1 + Der Server wird in %n Minuten neu gestartet. +Alle laufenden Spiele werden beendet. +Grund für die Abschaltung: %1 + + + + Number of players Spieleranzahl - + Please enter the number of players. Bitte die Spieleranzahl eingeben: - - + + Player %1 Spieler %1 - + About Cockatrice Über Cockatrice - + Version %1 Version %1 - + Authors: Autoren: - + Translators: Übersetzer: - + Spanish: Spanisch: - + Portugese (Portugal): Portugiesisch (Portugal): - + Portugese (Brazil): Portugiesisch (Brasilien): - + French: Französisch: - + Japanese: Japanisch: - + Russian: Russisch: - + Czech: Tschechisch: - + Slovak: Slowakisch: - - + - - + + + Error Fehler - + Server timeout Server Zeitüberschreitung - + Invalid login data. Ungültige Anmeldedaten. - + There is already an active session using this user name. Please close that session first and re-login. Es gibt bereits eine aktive Verbindung mit diesem Benutzernamen. Bitte schließen Sie diese Verbindung zuerst und versuchen Sie es dann erneut. - + Socket error: %1 Netzwerkfehler: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. Sie versuchen sich an einem veralteten Server anzumelden. Bitte verwenden Sie eine ältere Cockatrice-Version oder melden Sie sich an einem aktuellen Server an. Lokale Version ist %1, Serverversion ist %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. Ihr Cockatrice-Client ist veraltet. Bitte laden Sie sich die neueste Version herunter. @@ -2282,52 +2368,52 @@ Lokale Version ist %1, Serverversion ist %2. Protokollversionen stimmen nicht überein. Lokale Version: %1, Serverversion: %2. - + Connecting to %1... Verbinde zu %1... - + Disconnected nicht verbunden - + Logged in at %1 Angemeldet bei %1 - + &Connect... &Verbinden... - + &Disconnect Verbindung &trennen - + Start &local game... &Lokales Spiel starten... - + &About Cockatrice &Über Cockatrice - + &Help &Hilfe - + Are you sure? Sind Sie sicher? - + There are still open games. Are you sure you want to quit? Es gibt noch offene Spiele. Wollen Sie das Programm wirklich beenden? @@ -2344,27 +2430,27 @@ Lokale Version ist %1, Serverversion ist %2. Spiel ver&lassen - + &Deck editor &Deck-Editor - + &Full screen &Vollbild - + Ctrl+F Ctrl+F - + &Settings... &Einstellungen... - + &Exit &Beenden @@ -2377,7 +2463,7 @@ Lokale Version ist %1, Serverversion ist %2. Esc - + &Cockatrice &Cockatrice @@ -2405,24 +2491,20 @@ Lokale Version ist %1, Serverversion ist %2. MessageLogWidget - Connecting to %1... - Verbinde zu %1... + Verbinde zu %1... - Connected. - Verbunden. + Verbunden. - Disconnected from server. - Verbindung zum Server getrennt. + Verbindung zum Server getrennt. - Invalid password. - Ungültiges Passwort. + Ungültiges Passwort. You have joined the game. Player list: @@ -2461,8 +2543,8 @@ Lokale Version ist %1, Serverversion ist %2. %1 zieht %2 Karten - - + + a card eine Karte @@ -2519,7 +2601,7 @@ Lokale Version ist %1, Serverversion ist %2. %1s Sideboard - + The game has started. Das Spiel hat begonnen. @@ -2540,79 +2622,71 @@ Lokale Version ist %1, Serverversion ist %2. Protokollversion stimmt nicht überein. - - Protocol version mismatch. Client: %1, Server: %2 - - - - Protocol error. - Protokollfehler. + Protokollfehler. - You have joined game #%1. - Sie sind dem Spiel %1 beigetreten. + Sie sind dem Spiel %1 beigetreten. - %1 has joined the game. - %1 ist dem Spiel beigetreten. + %1 ist dem Spiel beigetreten. - %1 has left the game. - %1 hat das Spiel verlassen. + %1 hat das Spiel verlassen. - + The game has been closed. Das Spiel wurde geschlossen. - + %1 is now watching the game. %1 schaut nun dem Spiel zu. - + %1 is not watching the game any more. %1 schaut dem Spiel nicht mehr zu. - %1 has loaded a local deck. - %1 hat ein lokales Deck geladen. + %1 hat ein lokales Deck geladen. - %1 has loaded deck #%2. - %1 hat das Deck Nr. %2 geladen. + %1 hat das Deck Nr. %2 geladen. - %1 is ready to start the game. - %1 ist bereit, das Spiel zu starten. + %1 ist bereit, das Spiel zu starten. - %1 is not ready to start the game any more. - %1 ist nicht mehr bereit, das Spiel zu starten. + %1 ist nicht mehr bereit, das Spiel zu starten. - %1 has conceded the game. - %1 hat das Spiel aufgegeben. + %1 hat das Spiel aufgegeben. + + + %1 has restored connection to the game. + %1 ist wieder mit dem Spiel verbunden. + + + %1 has lost connection to the game. + %1 hat die Verbindung zum Spiel verloren. - %1 shuffles %2. - %1 mischt %2. + %1 mischt %2. - %1 rolls a %2 with a %3-sided die. - %1 würfelt eine %2 mit einem %3-seitigen Würfel. + %1 würfelt eine %2 mit einem %3-seitigen Würfel. %1 draws a card. @@ -2623,290 +2697,1063 @@ Lokale Version ist %1, Serverversion ist %2. %1 zieht %2 Karten. - %1 draws %n card(s). + + %1 zieht eine Karte. + %1 zieht %n Karten. + + + + + You have joined game #%1. + female + Sie sind dem Spiel %1 beigetreten. + + + + You have joined game #%1. + male + Sie sind dem Spiel %1 beigetreten. + + + + %1 has joined the game. + female + %1 ist dem Spiel beigetreten. + + + + %1 has joined the game. + male + %1 ist dem Spiel beigetreten. + + + + %1 has left the game. + female + %1 hat das Spiel verlassen. + + + + %1 has left the game. + male + %1 hat das Spiel verlassen. + + + + %1 has loaded a local deck. + female + %1 hat ein lokales Deck geladen. + + + + %1 has loaded a local deck. + male + %1 hat ein lokales Deck geladen. + + + + %1 has loaded deck #%2. + female + %1 hat das Deck Nr. %2 geladen. + + + + %1 has loaded deck #%2. + male + %1 hat das Deck Nr. %2 geladen. + + + + %1 is ready to start the game. + female + %1 ist bereit, das Spiel zu starten. + + + + %1 is ready to start the game. + male + %1 ist bereit, das Spiel zu starten. + + + + %1 is not ready to start the game any more. + female + %1 ist nicht mehr bereit, das Spiel zu starten. + + + + %1 is not ready to start the game any more. + male + %1 ist nicht mehr bereit, das Spiel zu starten. + + + + %1 has conceded the game. + female + %1 hat das Spiel aufgegeben. + + + + %1 has conceded the game. + male + %1 hat das Spiel aufgegeben. + + + + %1 has restored connection to the game. + female + %1 ist wieder mit dem Spiel verbunden. + + + + %1 has restored connection to the game. + male + %1 ist wieder mit dem Spiel verbunden. + + + + %1 has lost connection to the game. + female + %1 hat die Verbindung zum Spiel verloren. + + + + %1 has lost connection to the game. + male + %1 hat die Verbindung zum Spiel verloren. + + + + %1 shuffles %2. + female + %1 mischt %2. + + + + %1 shuffles %2. + male + %1 mischt %2. + + + + %1 rolls a %2 with a %3-sided die. + female + %1 würfelt eine %2 mit einem %3-seitigen Würfel. + + + + %1 rolls a %2 with a %3-sided die. + male + %1 würfelt eine %2 mit einem %3-seitigen Würfel. + + + + %1 draws %n card(s). + female + + %1 zieht eine Karte. + %1 zieht %n Karten. + + + + + %1 draws %n card(s). + male %1 zieht eine Karte. %1 zieht %n Karten. - + %1 undoes his last draw. %1 legt die zuletzt gezogene Karte zurück. - + %1 undoes her last draw. %1 legt die zuletzt gezogene Karte zurück. - + %1 undoes his last draw (%2). %1 legt die zuletzt gezogene Karte zurück (%2). - + %1 undoes her last draw (%2). %1 legt die zuletzt gezogene Karte zurück (%2). - + from table vom Spielfeld - + from graveyard aus dem Friedhof - + from exile aus dem Exil - + from hand von der Hand - + the bottom card of his library die unterste Karte seiner Bibliothek - + the bottom card of her library die unterste Karte ihrer Bibliothek - + from the bottom of his library , die unterste Karte seiner Bibliothek, - + from the bottom of her library , die unterste Karte ihrer Bibliothek, - + the top card of his library die oberste Karte seiner Bibliothek - + the top card of her library die oberste Karte ihrer Bibliothek - + from the top of his library , die oberste Karte seiner Bibliothek, - + from the top of her library , die oberste Karte ihrer Bibliothek, - + from library aus der Bibliothek - + from sideboard aus dem Sideboard - + from the stack vom Stapel - + %1 gives %2 control over %3. %1 überlässt %2 die Kontrolle über %3. - + %1 puts %2 into play tapped%3. %1 bringt %2 getappt%3 ins Spiel. - + %1 puts %2 into play%3. %1 bringt %2%3 ins Spiel. - + %1 puts %2%3 into graveyard. %1 legt %2%3 auf den Friedhof. - + %1 exiles %2%3. %1 schickt %2%3 ins Exil. - + %1 moves %2%3 to hand. %1 nimmt %2%3 auf die Hand. - + %1 puts %2%3 into his library. %1 legt %2%3 in seine Bibliothek. - + %1 puts %2%3 into her library. %1 legt %2%3 in ihre Bibliothek. - + %1 puts %2%3 on bottom of his library. %1 legt %2%3 unter seine Bibliothek. - + %1 puts %2%3 on bottom of her library. %1 legt %2%3 unter ihre Bibliothek. - + %1 puts %2%3 on top of his library. %1 legt %2%3 auf die Bibliothek. - + %1 puts %2%3 on top of her library. %1 legt %2%3 auf die Bibliothek. - + %1 puts %2%3 into his library at position %4. %1 legt %2%3 in seine Bibliothek an %4. Stelle. - + %1 puts %2%3 into her library at position %4. %1 legt %2%3 in ihre Bibliothek an %4. Stelle. - + %1 moves %2%3 to sideboard. %1 legt %2%3 in sein Sideboard. - + %1 plays %2%3. %1 spielt %2%3 aus. - + %1 takes a mulligan to %n. + female + + %1 nimmt einen Mulligan auf %n. + %1 nimmt einen Mulligan auf %n. + + + + + %1 takes a mulligan to %n. + male %1 nimmt einen Mulligan auf %n. %1 nimmt einen Mulligan auf %n. - - %1 draws his initial hand. - %1 zieht seine Starthand. - - - - %1 draws her initial hand. - %1 zieht ihre Starthand. - - - + %1 flips %2 face-down. + female %1 wendet %2 auf die Rückseite. - + + %1 flips %2 face-down. + male + %1 wendet %2 auf die Rückseite. + + + %1 flips %2 face-up. + female %1 wendet %2 auf die Vorderseite. - - %1 destroys %2. - %1 zerstört %2. - - - - %1 attaches %2 to %3's %4. - %1 legt %2 an %3s %4 an. - - - - %1 unattaches %2. - %1 löst %2 ab. - - - - %1 creates token: %2%3. - %1 erstellt Token: %2%3. + + %1 flips %2 face-up. + male + %1 wendet %2 auf die Vorderseite. + %1 destroys %2. + female + %1 zerstört %2. + + + + %1 destroys %2. + male + %1 zerstört %2. + + + %1 attaches %2 to %3's %4. + female + %1 legt %2 an %3s %4 an. + + + %1 attaches %2 to %3's %4. + male + %1 legt %2 an %3s %4 an. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + %1 legt %2 an %3s %4 an. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + %1 legt %2 an %3s %4 an. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + %1 legt %2 an %3s %4 an. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + %1 legt %2 an %3s %4 an. + + + + %1 unattaches %2. + female + %1 löst %2 ab. + + + + %1 unattaches %2. + male + %1 löst %2 ab. + + + + %1 creates token: %2%3. + female + %1 erstellt Token: %2%3. + + + + %1 creates token: %2%3. + male + %1 erstellt Token: %2%3. + + + + %1 points from her %2 to herself. + female + %1 zeigt von ihrem %2 auf sich selbst. + + + + %1 points from his %2 to himself. + male + %1 zeigt von seinem %2 auf sich selbst. + + + + %1 points from her %2 to %3. + p1 female, p2 female + %1 zeigt von ihrem %2 auf %3. + + + + %1 points from her %2 to %3. + p1 female, p2 male + %1 zeigt von ihrem %2 auf %3. + + + + %1 points from his %2 to %3. + p1 male, p2 female + %1 zeigt von seinem %2 auf %3. + + + + %1 points from his %2 to %3. + p1 male, p2 male + %1 zeigt von seinem %2 auf %3. + + + + %1 points from %2's %3 to herself. + card owner female, target female + %1 zeigt von %2s %3 auf sich selbst. + + + + %1 points from %2's %3 to herself. + card owner male, target female + %1 zeigt von %2s %3 auf sich selbst. + + + + %1 points from %2's %3 to himself. + card owner female, target male + %1 zeigt von %2s %3 auf sich selbst. + + + + %1 points from %2's %3 to himself. + card owner male, target male + %1 zeigt von %2s %3 auf sich selbst. + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female %1 zeigt von %2s %3 auf %4. + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + %1 zeigt von %2s %3 auf %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + %1 zeigt von %2s %3 auf %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + %1 zeigt von %2s %3 auf %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + %1 zeigt von %2s %3 auf %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + %1 zeigt von %2s %3 auf %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + %1 zeigt von %2s %3 auf %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + %1 zeigt von %2s %3 auf %4. + + + + %1 points from her %2 to her %3. + female + %1 zeigt von ihrem %2 auf ihren %3. + + + + %1 points from his %2 to his %3. + male + %1 zeigt von seinem %2 auf seinen %3. + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + %1 zeigt von ihrem %2 auf %3s %4. + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + %1 zeigt von ihrem %2 auf %3s %4. + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + %1 zeigt von seinem %2 auf %3s %4. + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + %1 zeigt von seinem %2 auf %3s %4. + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + %1 zeigt von %2s %3 auf ihren eigenen %4. + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + %1 zeigt von %2s %3 auf ihren eigenen %4. + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + %1 zeigt von %2s %3 auf seinen eigenen %4. + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + %1 zeigt von %2s %3 auf seinen eigenen %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + %1 zeigt von %2s %3 auf %4s %5. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + %1 zeigt von %2s %3 auf %4s %5. + - + %1 places %n %2 counter(s) on %3 (now %4). + female %1 legt eine %2 Marke auf %3 (jetzt %4). %1 legt %n %2 Marken auf %3 (jetzt %4). - + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 legt eine %2 Marke auf %3 (jetzt %4). + %1 legt %n %2 Marken auf %3 (jetzt %4). + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + %1 entfernt eine %2 Marke von %3 (jetzt %4). + %1 entfernt %n %2 Marken von %3 (jetzt %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male %1 entfernt eine %2 Marke von %3 (jetzt %4). %1 entfernt %n %2 Marken von %3 (jetzt %4). - - her permanents - ihre bleibenden Karten + + %1 taps her permanents. + female + %1 tappt ihre bleibenden Karten. - + + %1 untaps her permanents. + female + %1 enttappt ihre bleibenden Karten. + + + + %1 taps his permanents. + male + %1 tappt seine bleibenden Karten. + + + + %1 untaps his permanents. + male + %1 enttappt seine bleibenden Karten. + + + + %1 taps %2. + female + %1 tappt %2. + + + + %1 untaps %2. + female + %1 enttappt %2. + + + + %1 taps %2. + male + %1 tappt %2. + + + + %1 untaps %2. + male + %1 enttappt %2. + + + + %1 sets counter %2 to %3 (%4%5). + female + %1 setzt Zähler %2 auf %3 (%4%5). + + + + %1 sets counter %2 to %3 (%4%5). + male + %1 setzt Zähler %2 auf %3 (%4%5). + + + + %1 sets %2 to not untap normally. + female + %1 setzt %2 auf explizites Enttappen. + + + + %1 sets %2 to not untap normally. + male + %1 setzt %2 auf explizites Enttappen. + + + + %1 sets %2 to untap normally. + female + %1 setzt %2 auf normales Enttappen. + + + + %1 sets %2 to untap normally. + male + %1 setzt %2 auf normales Enttappen. + + + + %1 sets PT of %2 to %3. + female + %1 setzt Kampfwerte von %2 auf %3. + + + + %1 sets PT of %2 to %3. + male + %1 setzt Kampfwerte von %2 auf %3. + + + + %1 sets annotation of %2 to %3. + female + %1 versieht %2 mit dem Hinweis %3. + + + + %1 sets annotation of %2 to %3. + male + %1 versieht %2 mit dem Hinweis %3. + + + + %1 is looking at the top %2 cards %3. + female + %1 sieht sich die obersten %2 Karten %3 an. + + + + %1 is looking at the top %2 cards %3. + male + %1 sieht sich die obersten %2 Karten %3 an. + + + + %1 is looking at %2. + female + %1 sieht sich %2 an. + + + + %1 is looking at %2. + male + %1 sieht sich %2 an. + + + + %1 stops looking at %2. + female + %1 sieht sich %2 nicht mehr an. + + + + %1 stops looking at %2. + male + %1 sieht sich %2 nicht mehr an. + + + + %1 reveals %2 to %3. + p1 female, p2 female + %1 zeigt %3 %2. + + + + %1 reveals %2 to %3. + p1 female, p2 male + %1 zeigt %3 %2. + + + + %1 reveals %2 to %3. + p1 male, p2 female + %1 zeigt %3 %2. + + + + %1 reveals %2 to %3. + p1 male, p2 male + %1 zeigt %3 %2. + + + + %1 reveals %2. + female + %1 zeigt %2 offen vor. + + + + %1 reveals %2. + male + %1 zeigt %2 offen vor. + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female %1 zeigt %4 zufällig %2%3 vor. - + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + %1 zeigt %4 zufällig %2%3 vor. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + %1 zeigt %4 zufällig %2%3 vor. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + %1 zeigt %4 zufällig %2%3 vor. + + + %1 randomly reveals %2%3. + female %1 zeigt zufällig %2%3 offen vor. - + + %1 randomly reveals %2%3. + male + %1 zeigt zufällig %2%3 offen vor. + + + %1 reveals %2%3 to %4. + p1 female, p2 female %1 zeigt %4 %2%3 vor. - + + %1 reveals %2%3 to %4. + p1 female, p2 male + %1 zeigt %4 %2%3 vor. + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + %1 zeigt %4 %2%3 vor. + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + %1 zeigt %4 %2%3 vor. + + + %1 reveals %2%3. + female %1 zeigt %2%3 offen vor. + + + %1 reveals %2%3. + male + %1 zeigt %2%3 offen vor. + + + + It is now %1's turn. + female + %1 ist am Zug. + + + + It is now %1's turn. + male + %1 ist am Zug. + + + %1 takes a mulligan to %n. + + %1 nimmt einen Mulligan auf %n. + %1 nimmt einen Mulligan auf %n. + + + + + %1 draws his initial hand. + %1 zieht seine Starthand. + + + + %1 draws her initial hand. + %1 zieht ihre Starthand. + + + %1 flips %2 face-down. + %1 wendet %2 auf die Rückseite. + + + %1 flips %2 face-up. + %1 wendet %2 auf die Vorderseite. + + + %1 destroys %2. + %1 zerstört %2. + + + %1 attaches %2 to %3's %4. + %1 legt %2 an %3s %4 an. + + + %1 unattaches %2. + %1 löst %2 ab. + + + %1 creates token: %2%3. + %1 erstellt Token: %2%3. + + + %1 points from %2's %3 to %4. + %1 zeigt von %2s %3 auf %4. + + + %1 places %n %2 counter(s) on %3 (now %4). + + %1 legt eine %2 Marke auf %3 (jetzt %4). + %1 legt %n %2 Marken auf %3 (jetzt %4). + + + + %1 removes %n %2 counter(s) from %3 (now %4). + + %1 entfernt eine %2 Marke von %3 (jetzt %4). + %1 entfernt %n %2 Marken von %3 (jetzt %4). + + + + her permanents + ihre bleibenden Karten + + + %1 randomly reveals %2%3 to %4. + %1 zeigt %4 zufällig %2%3 vor. + + + %1 randomly reveals %2%3. + %1 zeigt zufällig %2%3 offen vor. + + + %1 reveals %2%3 to %4. + %1 zeigt %4 %2%3 vor. + + + %1 reveals %2%3. + %1 zeigt %2%3 offen vor. + %1 creates token: %2 (%3). %1 erstellt einen Spielstein: %2 (%3). - %1 points from %2's %3 to %4's %5. - %1 zeigt von %2s %3 auf %4s %5. + %1 zeigt von %2s %3 auf %4s %5. %1 places %n counter(s) (%2) on %3 (now %4). @@ -2923,7 +3770,7 @@ Lokale Version ist %1, Serverversion ist %2. - + red rote @@ -2931,7 +3778,7 @@ Lokale Version ist %1, Serverversion ist %2. - + yellow gelbe @@ -2939,7 +3786,7 @@ Lokale Version ist %1, Serverversion ist %2. - + green grüne @@ -2947,24 +3794,20 @@ Lokale Version ist %1, Serverversion ist %2. - %1 sets counter %2 to %3 (%4%5). - %1 setzt Zähler %2 auf %3 (%4%5). + %1 setzt Zähler %2 auf %3 (%4%5). - %1 sets PT of %2 to %3. - %1 setzt Kampfwerte von %2 auf %3. + %1 setzt Kampfwerte von %2 auf %3. - %1 sets annotation of %2 to %3. - %1 versieht %2 mit dem Hinweis %3. + %1 versieht %2 mit dem Hinweis %3. - %1 is looking at the top %2 cards %3. - %1 sieht sich die obersten %2 Karten %3 an. + %1 sieht sich die obersten %2 Karten %3 an. from graveyard @@ -3059,9 +3902,8 @@ Lokale Version ist %1, Serverversion ist %2. %1 entfernt %2 Zählmarken von %3 (jetzt %4). - %1 %2 %3. - %1 %2 %3. + %1 %2 %3. %1 sets counter "%2" to %3 (%4%5). @@ -3072,24 +3914,20 @@ Lokale Version ist %1, Serverversion ist %2. %1 sieht sich die obersten %2 Karten %3 an. - %1 is looking at %2. - %1 sieht sich %2 an. + %1 sieht sich %2 an. - %1 stops looking at %2. - %1 sieht sich %2 nicht mehr an. + %1 sieht sich %2 nicht mehr an. - %1 reveals %2 to %3. - %1 zeigt %3 %2. + %1 zeigt %3 %2. - %1 reveals %2. - %1 zeigt %2 offen vor. + %1 zeigt %2 offen vor. %1 randomly reveals %2 from %3 to %4. @@ -3108,7 +3946,7 @@ Lokale Version ist %1, Serverversion ist %2. %1 zeigt %2 aus %3 offen vor. - + ending phase die Zugendphase @@ -3137,57 +3975,56 @@ Lokale Version ist %1, Serverversion ist %2. %1 sieht sich %2s %3 nicht mehr an - It is now %1's turn. - %1 ist am Zug. + %1 ist am Zug. - + untap step das Enttappsegment - + upkeep step das Versorgungssegment - + draw step das Ziehsegment - + first main phase die erste Hauptphase - + beginning of combat step das Anfangssegment der Kampfphase - + declare attackers step das Angreifer-Deklarieren-Segment - + declare blockers step das Blocker-Deklarieren-Segment - + combat damage step das Kampfschadenssegment - + end of combat step das Endsegment der Kampfphase - + second main phase die zweite Hauptphase @@ -3196,7 +4033,7 @@ Lokale Version ist %1, Serverversion ist %2. das Ende-des-Zuges-Segment - + It is now the %1. Es ist nun %1. @@ -3205,14 +4042,12 @@ Lokale Version ist %1, Serverversion ist %2. %1 bewegt %2 %3 nach %4 - taps - tappt + tappt - untaps - enttappt + enttappt %1 creates token: <font color="blue">%2</font> @@ -3235,9 +4070,8 @@ Lokale Version ist %1, Serverversion ist %2. %1 entfernt %2 Zählmarken von %3 (jetzt %4) - his permanents - seine bleibenden Karten + seine bleibenden Karten %1 %2 %3 @@ -3248,14 +4082,12 @@ Lokale Version ist %1, Serverversion ist %2. %1 setzt Zähler "%2" auf %3 (%4%5) - %1 sets %2 to not untap normally. - %1 setzt %2 auf explizites Enttappen. + %1 setzt %2 auf explizites Enttappen. - %1 sets %2 to untap normally. - %1 setzt %2 auf normales Enttappen. + %1 setzt %2 auf normales Enttappen. %1 is looking at the top %2 cards of %3's %4 @@ -3269,12 +4101,12 @@ Lokale Version ist %1, Serverversion ist %2. MessagesSettingsPage - + &Add &Hinzufügen - + &Remove &Entfernen @@ -3287,12 +4119,12 @@ Lokale Version ist %1, Serverversion ist %2. Entfernen - + Add message Nachricht hinzufügen - + Message: Nachricht: @@ -3768,7 +4600,7 @@ Lokale Version ist %1, Serverversion ist %2. - + Number: Anzahl: @@ -3783,27 +4615,27 @@ Lokale Version ist %1, Serverversion ist %2. Oberste Karten ins Exil schicken - + Set power/toughness Kampfwerte setzen - + Please enter the new PT: Bitte die neuen Kampfwerte eingeben: - + Set annotation Hinweis setzen - + Please enter the new annotation: Bitte den Hinweis eingeben: - + Set counters Setze Zählmarken @@ -4021,40 +4853,77 @@ Lokale Version ist %1, Serverversion ist %2. Langer Name + + ShutdownDialog + + + &Reason for shutdown: + G&rund für die Abschaltung: + + + + &Time until shutdown (minutes): + &Zeit bis zur Abschaltung (Minuten): + + + + &OK + &OK + + + + &Cancel + &Abbrechen + + + + Shut down server + Server abschalten + + TabAdmin - + Update server &message Server&nachricht aktualisieren - + Shut down server + Server abschalten + + + + &Shut down server + &Server abschalten + + + Server administration functions Funktionen zur Serverwartung - + &Unlock functions &Sperre aufheben - + &Lock functions Funktionen s&perren - + Unlock administration functions Wartungsfunktionen entsperren - + Do you really want to unlock the administration functions? Möchten Sie wirklich die Sperre der Wartungsfunktionen aufheben? - + Administration Wartung @@ -4149,107 +5018,107 @@ Bitte geben Sie einen Namen ein: TabGame - + F5 F5 - + F6 F6 - + F7 F7 - + F8 F8 - + F9 F9 - + F10 F10 - + &Phases &Phasen - + &Game Spi&el - + Next &phase Nächste &Phase - + Ctrl+Space Ctrl+Space - + Next &turn Nächster &Zug - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter - + &Remove all local arrows &Lokale Pfeile entfernen - + Ctrl+R Ctrl+R - + &Concede - + F2 F2 - + &Leave game Spiel ver&lassen - + Ctrl+Q Ctrl+Q - + Kicked Herausgeworfen - + You have been kicked out of the game. Sie wurden aus dem Spiel geworfen. @@ -4270,7 +5139,7 @@ Bitte geben Sie einen Namen ein: Spiel s&tarten - + &Say: &Sagen: @@ -4283,22 +5152,22 @@ Bitte geben Sie einen Namen ein: Esc - + Concede Aufgeben - + Are you sure you want to concede this game? Sind Sie sicher, dass Sie das Spiel aufgeben möchten? - + Leave game Spiel verlassen - + Are you sure you want to leave this game? Sind Sie sicher, dass Sie das Spiel verlassen möchten? @@ -4307,7 +5176,7 @@ Bitte geben Sie einen Namen ein: Deck laden - + Game %1: %2 Spiel %1: %2 @@ -4315,27 +5184,27 @@ Bitte geben Sie einen Namen ein: TabMessage - + Personal &talk Persönliches &Gespräch - + &Leave Ver&lassen - + This user is ignoring you. Dieser Benutzer ignoriert Sie. - + %1 has left the server. %1 hat den Server verlassen. - + %1 has joined the server. %1 hat den Server betreten. @@ -4348,27 +5217,27 @@ Bitte geben Sie einen Namen ein: TabRoom - + &Say: &Sagen: - + Chat Unterhaltung - + &Room &Raum - + &Leave room Raum ver&lassen - + You are flooding the chat. Please wait a couple of seconds. Sie überfluten den Chatraum. Bitte warten Sie ein paar Sekunden. @@ -4467,37 +5336,37 @@ Bitte geben Sie einen Namen ein: UserInterfaceSettingsPage - + General interface settings Allgemeine Bedienung - + &Double-click cards to play them (instead of single-click) Karten durch &Doppelklick ausspielen (statt Einzelklick) - + Animation settings Animationseinstellungen - + &Tap/untap animation Animiertes &Tappen/Enttappen - + Enable &sounds &Sound anschalten - + Path to sounds directory: Pfad zum Verzeichnis mit den Sounddateien: - + Choose path Pfad auswählen @@ -4505,70 +5374,78 @@ Bitte geben Sie einen Namen ein: UserList - + Users online: %1 Benutzer online: %1 - + Users in this room: %1 Benutzer in diesem Raum: %1 - + Buddies online: %1 / %2 Freunde online: %1 / %2 - + Ignored users online: %1 / %2 Ignorierte Benutzer online: %1 / %2 - + + %1's games + %1s Spiele + + + User &details Benutzer&details - + Direct &chat &Persönliches Gespräch - + + Show this user's &games + Spiele dieses &Benutzers anzeigen + + + Add to &buddy list Zur &Freundesliste hinzufügen - + Remove from &buddy list Von &Freundesliste entfernen - + Add to &ignore list &Ignorieren - + Remove from &ignore list Nicht mehr &ignorieren - + Ban from &server Vom &Server bannen - Duration - Dauer + Dauer - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Bitte geben Sie die Dauer des Banns ein (in Minuten). + Bitte geben Sie die Dauer des Banns ein (in Minuten). Geben Sie 0 ein für einen unbefristeten Bann. diff --git a/cockatrice/translations/cockatrice_en.ts b/cockatrice/translations/cockatrice_en.ts index 415aa3fd..4c6421f1 100644 --- a/cockatrice/translations/cockatrice_en.ts +++ b/cockatrice/translations/cockatrice_en.ts @@ -37,90 +37,125 @@ AppearanceSettingsPage - + Zone background pictures - + Path to hand background: - + Path to stack background: - + Path to table background: - + Path to player info background: - + Path to picture of card back: - + Card rendering - + Display card names on cards having a picture - + Hand layout - + Display hand horizontally (wastes space) - + Table grid layout - + Invert vertical coordinate - + + Minimum player count for multi-column layout: + + + + Zone view layout - + Sort by name - + Sort by type - - - - - + + + + + Choose path + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + + + + + &Cancel + + + + + Ban user from server + + + CardDatabaseModel @@ -195,197 +230,202 @@ CardItem - + &Play - + &Hide - + &Tap - + &Untap - + Toggle &normal untapping - + &Flip - + &Clone - + Ctrl+H - + &Attach to card... - + Ctrl+A - + Unattac&h - - - &Power / toughness - - - - - &Increase power - - - - - Ctrl++ - - - - - &Decrease power - - - - - Ctrl+- - - - - - I&ncrease toughness - - - Alt++ + &Draw arrow... - D&ecrease toughness + &Power / toughness - Alt+- + &Increase power - In&crease power and toughness + Ctrl++ - Ctrl+Alt++ + &Decrease power - Dec&rease power and toughness + Ctrl+- - Ctrl+Alt+- + I&ncrease toughness - Set &power and toughness... + Alt++ - Ctrl+P + D&ecrease toughness - &Set annotation... + Alt+- + + + + + In&crease power and toughness - red + Ctrl+Alt++ - yellow + Dec&rease power and toughness - green + Ctrl+Alt+- + + + + + Set &power and toughness... - &Add counter (%1) + Ctrl+P - - &Remove counter (%1) + + &Set annotation... + + + + + red - &Set counters (%1)... + yellow - &top of library - - - - - &bottom of library + green - &graveyard - - - - - Ctrl+Del + &Add counter (%1) - &exile + &Remove counter (%1) + &Set counters (%1)... + + + + + &top of library + + + + + &bottom of library + + + + + &graveyard + + + + + Ctrl+Del + + + + + &exile + + + + &Move to @@ -756,12 +796,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General @@ -787,22 +827,22 @@ DeckViewContainer - + Load &local deck - + Load d&eck from server - + Ready to s&tart - + Load deck @@ -891,82 +931,82 @@ - + &Password: - + P&layers: - + Game type - + Only &buddies can join - + Only &registered users can join - + Joining restrictions - + &Spectators allowed - + Spectators &need a password to join - + Spectators can &chat - + Spectators see &everything - + Spectators - + &OK - + &Cancel - + Create game - + Error - + Server error. @@ -1108,59 +1148,59 @@ DlgSettings - - - + + + Error - + Your card database is invalid. Would you like to go back and set the correct path? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + General - + Appearance - + User interface - + Deck editor - + Messages - + &Close @@ -1168,83 +1208,94 @@ GameSelector - + C&reate - + &Join - - - - - - - + + + + + + + + Error - + + Please join the appropriate room first. + + + + Wrong password. - + Spectators are not allowed in this game. - + The game is already full. - + The game does not exist any more. - + This game is only open to registered users. - + This game is only open to its creator's buddies. - + You are being ignored by the creator of this game. - + Join game - + Password: - + Games - + Show &full games - + + Show &running games + + + + J&oin as spectator @@ -1260,67 +1311,72 @@ GamesModel - + yes - + no - + Creator - + Description - + yes, free for spectators - + buddies only - + reg. users only - + not allowed - Game type - - - - - Password - - - - - Restrictions + Room - Players + Game type + Password + + + + + Restrictions + + + + + Players + + + + Spectators @@ -1328,50 +1384,50 @@ GeneralSettingsPage - - - + + + Choose path - + Personal settings - + Language: - + Download card pictures on the fly - + Paths - + Decks directory: - + Pictures directory: - + Path to card database: - - + + English English @@ -1390,216 +1446,236 @@ + Scheduled server shutdown. + + + + Unknown reason. - + Connection closed - + The server has terminated your connection. Reason: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + Number of players - + Please enter the number of players. - - + + Player %1 - + About Cockatrice - + Version %1 - + Authors: - + Translators: - + Spanish: - + Portugese (Portugal): - + Portugese (Brazil): - + French: - + Japanese: - + Russian: - + Czech: - + Slovak: - - + - - + + + Error - + Server timeout - + Invalid login data. - + There is already an active session using this user name. Please close that session first and re-login. - + Socket error: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. - + Connecting to %1... - + Disconnected - + Logged in at %1 - + &Connect... - + &Disconnect - + Start &local game... - + &Deck editor - + &Full screen - + Ctrl+F - + &Settings... - + &Exit - + &Cockatrice - + &About Cockatrice - + &Help - + Are you sure? - + There are still open games. Are you sure you want to quit? @@ -1607,267 +1683,962 @@ Local version is %1, remote version is %2. MessageLogWidget - - Connecting to %1... - - - - - Disconnected from server. - - - - - Invalid password. - - - - - Protocol error. - - - - + The game has been closed. - + %1 is now watching the game. - + %1 is not watching the game any more. - - - %1 is not ready to start the game any more. - - - - - %1 shuffles %2. - - - - - %1 rolls a %2 with a %3-sided die. - - - %1 draws %n card(s). - + %1 draws a card. %1 draws %n cards. - + + You have joined game #%1. + female + + + + + You have joined game #%1. + male + + + + + %1 has joined the game. + female + + + + + %1 has joined the game. + male + + + + + %1 has left the game. + female + + + + + %1 has left the game. + male + + + + + %1 has loaded a local deck. + female + + + + + %1 has loaded a local deck. + male + + + + + %1 has loaded deck #%2. + female + + + + + %1 has loaded deck #%2. + male + + + + + %1 is ready to start the game. + female + + + + + %1 is ready to start the game. + male + + + + + %1 is not ready to start the game any more. + female + + + + + %1 is not ready to start the game any more. + male + + + + + %1 has conceded the game. + female + + + + + %1 has conceded the game. + male + + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + + %1 rolls a %2 with a %3-sided die. + female + + + + + %1 rolls a %2 with a %3-sided die. + male + + + + + %1 draws %n card(s). + female + + %1 draws a card. + %1 draws %n cards. + + + + + %1 draws %n card(s). + male + + %1 draws a card. + %1 draws %n cards. + + + + %1 undoes his last draw. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). - + %1 undoes her last draw (%2). - + from table - + from graveyard - + from exile - + from hand - + the bottom card of his library - + the bottom card of her library - + from the bottom of his library - + from the bottom of her library - + the top card of his library - + the top card of her library - + from the top of his library - + from the top of her library - + from library - + from sideboard - + from the stack - + %1 gives %2 control over %3. - + %1 puts %2 into play tapped%3. - + %1 puts %2 into play%3. - + %1 puts %2%3 into graveyard. - + %1 exiles %2%3. - + %1 moves %2%3 to hand. - + %1 puts %2%3 into his library. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. - + %1 plays %2%3. - - - - a card - + + + %1 takes a mulligan to %n. + female + + + + + + + + %1 takes a mulligan to %n. + male + + + + - + %1 flips %2 face-down. + female - + + %1 flips %2 face-down. + male + + + + %1 flips %2 face-up. + female - - %1 attaches %2 to %3's %4. + + %1 flips %2 face-up. + male - + + %1 destroys %2. + female + + + + + %1 destroys %2. + male + + + + %1 unattaches %2. + female - + + %1 unattaches %2. + male + + + + + %1 creates token: %2%3. + female + + + + + %1 creates token: %2%3. + male + + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + + + + + %1 places %n %2 counter(s) on %3 (now %4). + female + + %1 places a %2 counter on %3 (now %4). + %1 places %n %2 counters on %3 (now %4). + + + + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 places a %2 counter on %3 (now %4). + %1 places %n %2 counters on %3 (now %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + %1 removes a %2 counter from %3 (now %4). + %1 removes %n %2 counters from %3 (now %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + %1 removes a %2 counter from %3 (now %4). + %1 removes %n %2 counters from %3 (now %4). + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + + + + + %1 sets counter %2 to %3 (%4%5). + male + + + + + %1 sets %2 to not untap normally. + female + + + + + %1 sets %2 to not untap normally. + male + + + + + %1 sets %2 to untap normally. + female + + + + + %1 sets %2 to untap normally. + male + + + + + %1 sets PT of %2 to %3. + female + + + + + %1 sets PT of %2 to %3. + male + + + + + %1 sets annotation of %2 to %3. + female + + + + + %1 sets annotation of %2 to %3. + male + + + + + %1 is looking at the top %2 cards %3. + female + + + + + %1 is looking at the top %2 cards %3. + male + + + + + %1 is looking at %2. + female + + + + + %1 is looking at %2. + male + + + + + %1 stops looking at %2. + female + + + + + %1 stops looking at %2. + male + + + + + %1 reveals %2 to %3. + p1 female, p2 female + + + + + %1 reveals %2 to %3. + p1 female, p2 male + + + + + %1 reveals %2 to %3. + p1 male, p2 female + + + + + %1 reveals %2 to %3. + p1 male, p2 male + + + + + %1 reveals %2. + female + + + + + %1 reveals %2. + male + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 randomly reveals %2%3. + female + + + + + %1 randomly reveals %2%3. + male + + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 reveals %2%3. + female + + + + + %1 reveals %2%3. + male + + + + + It is now %1's turn. + female + + + + + It is now %1's turn. + male + + + + + + a card @@ -1885,7 +2656,7 @@ Local version is %1, remote version is %2. - + red @@ -1893,7 +2664,7 @@ Local version is %1, remote version is %2. - + yellow @@ -1901,7 +2672,7 @@ Local version is %1, remote version is %2. - + green @@ -1909,284 +2680,138 @@ Local version is %1, remote version is %2. - - %1 sets counter %2 to %3 (%4%5). - - - - - %1 sets PT of %2 to %3. - - - - - %1 sets annotation of %2 to %3. - - - - - %1 is looking at the top %2 cards %3. - - - - + The game has started. - - Connected. - - - - - Protocol version mismatch. Client: %1, Server: %2 - - - - - You have joined game #%1. - - - - - %1 has joined the game. - - - - - %1 has left the game. - - - - - %1 has loaded a local deck. - - - - - %1 has loaded deck #%2. - - - - - %1 is ready to start the game. - - - - - %1 has conceded the game. - - - - - %1 takes a mulligan to %n. - - - - - - - + %1 draws his initial hand. - + %1 draws her initial hand. - - - %1 destroys %2. - - - - - %1 creates token: %2%3. - - - - - %1 points from %2's %3 to %4. - - - %1 places %n %2 counter(s) on %3 (now %4). - + %1 places a %2 counter on %3 (now %4). %1 places %n %2 counters on %3 (now %4). - %1 removes %n %2 counter(s) from %3 (now %4). - + %1 removes a %2 counter from %3 (now %4). %1 removes %n %2 counters from %3 (now %4). - - her permanents - - - - - %1 %2 %3. - - - - - %1 is looking at %2. - - - - - %1 stops looking at %2. - - - - - %1 reveals %2 to %3. - - - - - %1 reveals %2. - - - - + ending phase - - It is now %1's turn. - - - - - %1 randomly reveals %2%3 to %4. - - - - - %1 randomly reveals %2%3. - - - - - %1 reveals %2%3 to %4. - - - - - %1 reveals %2%3. - - - - + untap step - + + %1 attaches %2 to %3's %4. + p1 female, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + + + + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + It is now the %1. - - - taps - - - - - untaps - - - - - %1 sets %2 to not untap normally. - - - - - %1 sets %2 to untap normally. - - - - - his permanents - - MessagesSettingsPage - + &Add - + &Remove - + Add message - + Message: @@ -2522,7 +3147,7 @@ Local version is %1, remote version is %2. - + Number: @@ -2547,27 +3172,27 @@ Local version is %1, remote version is %2. - + Set power/toughness - + Please enter the new PT: - + Set annotation - + Please enter the new annotation: - + Set counters @@ -2712,40 +3337,73 @@ Local version is %1, remote version is %2. + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + + + + + &Cancel + + + + + Shut down server + + + TabAdmin - + Update server &message - + + &Shut down server + + + + Server administration functions - + &Unlock functions - + &Lock functions - + Unlock administration functions - + Do you really want to unlock the administration functions? - + Administration @@ -2820,137 +3478,137 @@ Please enter a name: TabGame - + F5 - + F6 - + F7 - + F8 - + F9 - + F10 - + &Phases - + &Game - + Next &phase - + Ctrl+Space - + Next &turn - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows - + Ctrl+R - + &Concede - + F2 - + &Leave game - + Ctrl+Q - + &Say: - + Concede - + Are you sure you want to concede this game? - + Leave game - + Are you sure you want to leave this game? - + Kicked - + You have been kicked out of the game. - + Game %1: %2 @@ -2958,27 +3616,27 @@ Please enter a name: TabMessage - + Personal &talk - + &Leave - + This user is ignoring you. - + %1 has left the server. - + %1 has joined the server. @@ -2991,27 +3649,27 @@ Please enter a name: TabRoom - + &Say: - + Chat - + &Room - + &Leave room - + You are flooding the chat. Please wait a couple of seconds. @@ -3083,37 +3741,37 @@ Please enter a name: UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + Animation settings - + &Tap/untap animation - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3121,71 +3779,70 @@ Please enter a name: UserList - + Users online: %1 - + Users in this room: %1 - + Buddies online: %1 / %2 - + Ignored users online: %1 / %2 - + + %1's games + + + + User &details - + Direct &chat - + + Show this user's &games + + + + Add to &buddy list - + Remove from &buddy list - + Add to &ignore list - + Remove from &ignore list - + Ban from &server - - - Duration - - - - - Please enter the duration of the ban (in minutes). -Enter 0 for an indefinite ban. - - WndDeckEditor diff --git a/cockatrice/translations/cockatrice_es.ts b/cockatrice/translations/cockatrice_es.ts index 116265d5..cee81068 100644 --- a/cockatrice/translations/cockatrice_es.ts +++ b/cockatrice/translations/cockatrice_es.ts @@ -37,66 +37,71 @@ AppearanceSettingsPage - + Zone background pictures Imagenes de la zona de fondo - + Path to hand background: Ruta a la imagen de fondo de la mano: - + Path to stack background: Ruta a la imagen de fondo de la pila: - + Path to table background: Ruta a la imagen de fondo de la mesa: - + Path to player info background: Ruta a la imagen de fondo de la información del jugador: - + Path to picture of card back: Ruta al reverso de las cartas: - + Card rendering Renderizado de las cartas - + Display card names on cards having a picture Mostrar nombre de las cartas en aquellas que tengan imagen - + Hand layout Disposición de la mano - + Display hand horizontally (wastes space) Mostrar la mano horizontalmente (desperdicia espacio) - + Table grid layout Disposición de la rejilla de la mesa + + + Minimum player count for multi-column layout: + + Economical layout Disposición Económica - + Invert vertical coordinate Invertir coordenada vertical @@ -105,30 +110,61 @@ Disposición económica - + Zone view layout Distribución de la zona de visionado - + Sort by name Ordenar por nombre - + Sort by type Ordenar por tipo - - - - - + + + + + Choose path Elija ruta + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + Por favor, introduce la duración del ban (en minutos) +Indica 0 para un ban indefinido. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + &Aceptar + + + + &Cancel + &Cancelar + + + + Ban user from server + + + CardDatabaseModel @@ -203,57 +239,57 @@ CardItem - + &Play &Jugar - + &Hide &Ocultar - + &Tap &Girar - + &Untap &Enderezar - + Toggle &normal untapping Alternar enderezamiento &normal - + &Flip &Voltear - + &Clone &Clonar - + Ctrl+H Ctrl+H - + &Attach to card... Ane&xar a una carta... - + Ctrl+A Ctrl+A - + Unattac&h Desane&xar @@ -262,142 +298,147 @@ Establecer &F/R... - + + &Draw arrow... + + + + &Power / toughness &Fuerza / resistencia - + &Increase power &Incrementar fuerza - + Ctrl++ Ctrl++ - + &Decrease power &Decrementar fuerza - + Ctrl+- Ctrl+- - + I&ncrease toughness I&ncrementar resistencia - + Alt++ Alt++ - + D&ecrease toughness D&ecrementar resistencia - + Alt+- Alt+- - + In&crease power and toughness In&crementar fuerza y resistencia - + Ctrl+Alt++ Ctrl+Alt++ - + Dec&rease power and toughness Dec&rementar fuerza y resistencia - + Ctrl+Alt+- Ctrl+Alt+- - + Set &power and toughness... Establecer &fuerza y resistencia... - + Ctrl+P Ctrl+P - + &Set annotation... E&scribir anotación... - + red rojo - + yellow amarillo - + green verde - + &Add counter (%1) &Añadir contador (%1) - + &Remove counter (%1) &Quitar contador (%1) - + &Set counters (%1)... E&stablecer contadores (%1)... - + &top of library &parte superior de la biblioteca - + &bottom of library &fondo de la biblioteca - + &graveyard &cementerio - + Ctrl+Del Ctrl+Del - + &exile &exilio - + &Move to &Mover a @@ -1098,12 +1139,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General General @@ -1129,22 +1170,22 @@ DeckViewContainer - + Load &local deck Cargar mazo &local - + Load d&eck from server Cargar mazo del &servidor - + Ready to s&tart Listo para &empezar - + Load deck Cargar mazo @@ -1240,82 +1281,82 @@ &Descripción: - + &Password: &Contraseña: - + P&layers: &Jugadores: - + Game type Tipo de partida - + Only &buddies can join Sólo los &amigos pueden participar - + Only &registered users can join Sólo los usuarios &registrados pueden participar - + Joining restrictions Restricciones de participación - + &Spectators allowed Permitir e&spectadores - + Spectators &need a password to join Los espectadores &necesitan contraseña para unirse - + Spectators can &chat Los espectadores pueden &chatear - + Spectators see &everything Los espectadores pueden verlo &todo - + Spectators Espectadores - + &OK &Aceptar - + &Cancel &Cancelar - + Create game Crear partida - + Error Error - + Server error. Error del servidor. @@ -1457,9 +1498,9 @@ DlgSettings - - - + + + Error Error @@ -1476,52 +1517,52 @@ La ruta a tu directorio de imagenes de las cartas es invalida. - + Your card database is invalid. Would you like to go back and set the correct path? Tu base de datos de cartas es invalida. ¿Deseas volver y seleccionar la ruta correcta? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? La ruta a tu directorio de mazos es invalida. ¿Deseas volver y seleccionar la ruta correcta? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? La ruta a tu directorio de imagenes de las cartas es invalida.¿Deseas volver y seleccionar la ruta correcta? - + Settings Preferencias - + General General - + Appearance Apariencia - + User interface Interfaz de usuario - + Deck editor - + Messages Mensajes - + &Close &Cerrar @@ -1529,87 +1570,98 @@ GameSelector - + C&reate C&rear - + &Join E&ntrar - - - - - - - + + + + + + + + Error Error - + + Please join the appropriate room first. + + + + Wrong password. Contraseña incorrecta. - + Spectators are not allowed in this game. No se permiten espectadores en esta partida. - + The game is already full. La partida no tiene plazas libres. - + The game does not exist any more. La partida ya no existe. - + This game is only open to registered users. Esta partida está abierta sólo a usuarios registrados. - + This game is only open to its creator's buddies. Esta partida está abierta sólo a los amigos del creador. - + You are being ignored by the creator of this game. Estas siendo ignorado por el creador de la partida. - + Join game Entrar en la partida - + Password: Contraseña: - + Games Partidas - + Show &full games Ver partidas &sin plazas libres + + + Show &running games + + &Show full games &Ver partidas sin plazas libres - + J&oin as spectator Entrar como e&spectador @@ -1625,67 +1677,72 @@ GamesModel - + yes - + no no - + Creator Creador - + Description Descripción - + yes, free for spectators sí, libre para espectadores - + buddies only solo amigos - + reg. users only solo usuarios registrados - + not allowed no permitido + Room + Sala + + + Game type Tipo de partida - + Password Contraseña - + Restrictions Restricciones - + Players Jugadores - + Spectators Espectadores @@ -1693,50 +1750,50 @@ GeneralSettingsPage - - - + + + Choose path Elija ruta - + Personal settings Preferencias personales - + Language: Idioma: - + Download card pictures on the fly Descargar imagenes de las cartas al vuelo - + Paths Rutas - + Decks directory: Directorio de mazos: - + Pictures directory: Directorio de imagenes: - + Path to card database: Ruta a la base de datos de las cartas: - - + + English Español @@ -1755,138 +1812,158 @@ + Scheduled server shutdown. + + + + Unknown reason. Motivo desconocido. - + Connection closed Conexión cerrada - + The server has terminated your connection. Reason: %1 El servidor ha finalizado tu conexión. Motivo: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + Number of players Número de jugadores - + Please enter the number of players. Por favor, introduzca el número de jugadores. - - + + Player %1 Jugador %1 - + About Cockatrice Acerca de Cockatrice - + Version %1 Versión %1 - + Authors: Autores: - + Translators: Traductores: - + Spanish: Español: - + Portugese (Portugal): Portugués (Portugal): - + Portugese (Brazil): Portugués (Brasil): - + French: Francés: - + Japanese: Japonés: - + Russian: Ruso: - + Czech: - + Slovak: - - + - - + + + Error Error - + Server timeout Tiempo de espera del servidor agotado - + Invalid login data. Datos de conexión invalidos. - + There is already an active session using this user name. Please close that session first and re-login. Ya existe una sesión activa usando ese nombre de usuario. Por favor, cierra esa sesión primero y reintentalo. - + Socket error: %1 Error del Socket: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. Estás intentando conectar a un servidor obsoleto. Por favor, usa una versión anterior de Cockatrice o conecta a un servidor apropiado. La versión local es %1, la versión remota es %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. Tu cliente de Cockatrice esta obsoleto. Por favor, actualiza tu versión de Cockatrice. @@ -1897,82 +1974,82 @@ La versión local es %1, la versión remota es %2. La versión del protocolo es diferente. Version local: %1, version remota: %2. - + Connecting to %1... Conectando a %1... - + Disconnected Desconectado - + Logged in at %1 Conectado en %1 - + &Connect... &Conectar... - + &Disconnect &Desconectar - + Start &local game... Empezar partida &local... - + &Deck editor Editor de &mazos - + &Full screen &Pantalla completa - + Ctrl+F CTRL+F - + &Settings... &Preferencias... - + &Exit &Salir - + &Cockatrice &Cockatrice - + &About Cockatrice &Acerca de Cockatrice - + &Help A&yuda - + Are you sure? ¿Estás seguro? - + There are still open games. Are you sure you want to quit? Todavía hay partidas abiertas. ¿Estás seguro que quieres salir? @@ -1980,268 +2057,1041 @@ La versión local es %1, la versión remota es %2. MessageLogWidget - Connecting to %1... - Conectando a %1... + Conectando a %1... - Disconnected from server. - Desconectado del servidor. + Desconectado del servidor. - Invalid password. - Contraseña incorrecta. + Contraseña incorrecta. - Protocol error. - Error del protocolo. + Error del protocolo. - + The game has been closed. La partida ha sido cerrada. - + %1 is now watching the game. %1 está ahora observando la partida. - + %1 is not watching the game any more. %1 ya no está observado más la partida. - %1 is not ready to start the game any more. - %1 ya no está listo para empezar el juego. + %1 ya no está listo para empezar el juego. - - %1 shuffles %2. - - - - %1 rolls a %2 with a %3-sided die. - %1 sacó un %2 con un dado de %3 caras. + %1 sacó un %2 con un dado de %3 caras. - %1 draws %n card(s). - + %1 roba %n carta. %1 roba %n cartas. - + + You have joined game #%1. + female + Te has unido a la partida #%1. + + + + You have joined game #%1. + male + Te has unido a la partida #%1. + + + + %1 has joined the game. + female + %1 se ha unido a la partida. + + + + %1 has joined the game. + male + %1 se ha unido a la partida. + + + + %1 has left the game. + female + %1 ha dejado la partida. + + + + %1 has left the game. + male + %1 ha dejado la partida. + + + + %1 has loaded a local deck. + female + %1 ha cargado un mazo local. + + + + %1 has loaded a local deck. + male + %1 ha cargado un mazo local. + + + + %1 has loaded deck #%2. + female + %1 ha cargado el mazo #%2. + + + + %1 has loaded deck #%2. + male + %1 ha cargado el mazo #%2. + + + + %1 is ready to start the game. + female + %1 está preparado para empezar la partida. + + + + %1 is ready to start the game. + male + %1 está preparado para empezar la partida. + + + + %1 is not ready to start the game any more. + female + %1 ya no está listo para empezar el juego. + + + + %1 is not ready to start the game any more. + male + %1 ya no está listo para empezar el juego. + + + + %1 has conceded the game. + female + %1 ha concedido la partida. + + + + %1 has conceded the game. + male + %1 ha concedido la partida. + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + + %1 rolls a %2 with a %3-sided die. + female + %1 sacó un %2 con un dado de %3 caras. + + + + %1 rolls a %2 with a %3-sided die. + male + %1 sacó un %2 con un dado de %3 caras. + + + + %1 draws %n card(s). + female + + %1 roba %n carta. + %1 roba %n cartas. + + + + + %1 draws %n card(s). + male + + %1 roba %n carta. + %1 roba %n cartas. + + + + %1 undoes his last draw. %1 deshace su último robo. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). %1 deshace su último robo (%2). - + %1 undoes her last draw (%2). - + from table de la mesa - + from graveyard del cementerio - + from exile del exilio - + from hand de la mano - + the bottom card of his library el fondo de la biblioteca - + the bottom card of her library - + from the bottom of his library del fondo de la biblioteca - + from the bottom of her library - + the top card of his library la parte superior de la biblioteca - + the top card of her library - + from the top of his library de la parte superior de la biblioteca - + from the top of her library - + from library de la biblioteca - + from sideboard de la reserva - + from the stack de la pila - + %1 gives %2 control over %3. %1 entrega a %2 el control sobre %3. - + %1 puts %2 into play tapped%3. %1 pone %2 en juego%3 girado. - + %1 puts %2 into play%3. %1 pone %2 en juego%3. - + %1 puts %2%3 into graveyard. %1 pone %2%3 en el cementerio. - + %1 exiles %2%3. %1 exilia %2%3. - + %1 moves %2%3 to hand. %1 mueve %2%3 a la mano. - + %1 puts %2%3 into his library. %1 pone %2%3 en la biblioteca. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. %1 pone %2%3 en la parte inferior de su biblioteca. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. %1 pone %2%3 en la parte superior de su biblioteca. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. %1 pone %2%3 en su biblioteca en la posición %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. %1 mueve %2%3 a la reserva. - + %1 plays %2%3. %1 juega %2%3. + + + %1 takes a mulligan to %n. + female + + + + + + + + %1 takes a mulligan to %n. + male + + + + + - - + + %1 flips %2 face-down. + female + %1 voltea %2 boca abajo. + + + + %1 flips %2 face-down. + male + %1 voltea %2 boca abajo. + + + + %1 flips %2 face-up. + female + %1 voltea %2 boca arriba. + + + + %1 flips %2 face-up. + male + %1 voltea %2 boca arriba. + + + + %1 destroys %2. + female + %1 destruye %2. + + + + %1 destroys %2. + male + %1 destruye %2. + + + %1 attaches %2 to %3's %4. + female + %1 anexa %2 a el %4 de %3. + + + %1 attaches %2 to %3's %4. + male + %1 anexa %2 a el %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + %1 anexa %2 a el %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + %1 anexa %2 a el %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + %1 anexa %2 a el %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + %1 anexa %2 a el %4 de %3. + + + + %1 unattaches %2. + female + %1 desanexa %2. + + + + %1 unattaches %2. + male + %1 desanexa %2. + + + + %1 creates token: %2%3. + female + %1 crea una ficha: %2%3. + + + + %1 creates token: %2%3. + male + %1 crea una ficha: %2%3. + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + %1 apunta desde el %3 de %2 a %4. + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + %1 apunta desde el %3 de %2 al %5 de %4. + + + + %1 places %n %2 counter(s) on %3 (now %4). + female + + %1 pone %n %2 contador en %3 (ahora %4). + %1 pone %n %2 contadores en %3 (ahora %4). + + + + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 pone %n %2 contador en %3 (ahora %4). + %1 pone %n %2 contadores en %3 (ahora %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + %1 remueve %n %2 contador en %3 (ahora %4). + %1 remueve %n %2 contadores en %3 (ahora %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + %1 remueve %n %2 contador en %3 (ahora %4). + %1 remueve %n %2 contadores en %3 (ahora %4). + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + %1 establece los contadores de %2 a %3 (%4%5). + + + + %1 sets counter %2 to %3 (%4%5). + male + %1 establece los contadores de %2 a %3 (%4%5). + + + + %1 sets %2 to not untap normally. + female + %1 establece que %2 no se endereze normalmente. + + + + %1 sets %2 to not untap normally. + male + %1 establece que %2 no se endereze normalmente. + + + + %1 sets %2 to untap normally. + female + %1 establece que %2 se endereze normalmente. + + + + %1 sets %2 to untap normally. + male + %1 establece que %2 se endereze normalmente. + + + + %1 sets PT of %2 to %3. + female + %1 establece F/R de %2 a %3. + + + + %1 sets PT of %2 to %3. + male + %1 establece F/R de %2 a %3. + + + + %1 sets annotation of %2 to %3. + female + %1 establece la anotación de %2 a %3. + + + + %1 sets annotation of %2 to %3. + male + %1 establece la anotación de %2 a %3. + + + + %1 is looking at the top %2 cards %3. + female + %1 esta mirando las primeras %2 cartas de %3. + + + + %1 is looking at the top %2 cards %3. + male + %1 esta mirando las primeras %2 cartas de %3. + + + + %1 is looking at %2. + female + %1 está mirando: %2. + + + + %1 is looking at %2. + male + %1 está mirando: %2. + + + + %1 stops looking at %2. + female + %1 termina de mirar: %2. + + + + %1 stops looking at %2. + male + %1 termina de mirar: %2. + + + + %1 reveals %2 to %3. + p1 female, p2 female + %1 revela %2 a %3. + + + + %1 reveals %2 to %3. + p1 female, p2 male + %1 revela %2 a %3. + + + + %1 reveals %2 to %3. + p1 male, p2 female + %1 revela %2 a %3. + + + + %1 reveals %2 to %3. + p1 male, p2 male + %1 revela %2 a %3. + + + + %1 reveals %2. + female + %1 revela %2. + + + + %1 reveals %2. + male + %1 revela %2. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + %1 revela aleatoriamente %2%3 a %4. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + %1 revela aleatoriamente %2%3 a %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + %1 revela aleatoriamente %2%3 a %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + %1 revela aleatoriamente %2%3 a %4. + + + + %1 randomly reveals %2%3. + female + %1 revela aleatoriamente %2%3. + + + + %1 randomly reveals %2%3. + male + %1 revela aleatoriamente %2%3. + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + %1 revela %2%3 a %4. + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + %1 revela %2%3 a %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + %1 revela %2%3 a %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + %1 revela %2%3 a %4. + + + + %1 reveals %2%3. + female + %1 revela %2%3. + + + + %1 reveals %2%3. + male + %1 revela %2%3. + + + + It is now %1's turn. + female + Es el turno de %1. + + + + It is now %1's turn. + male + Es el turno de %1. + + + + a card una carta - %1 flips %2 face-down. - %1 voltea %2 boca abajo. + %1 voltea %2 boca abajo. - %1 flips %2 face-up. - %1 voltea %2 boca arriba. + %1 voltea %2 boca arriba. - %1 attaches %2 to %3's %4. - %1 anexa %2 a el %4 de %3. + %1 anexa %2 a el %4 de %3. - %1 unattaches %2. - %1 desanexa %2. + %1 desanexa %2. - %1 points from %2's %3 to %4's %5. - %1 apunta desde el %3 de %2 al %5 de %4. + %1 apunta desde el %3 de %2 al %5 de %4. %1 places %n counter(s) (%2) on %3 (now %4). @@ -2258,7 +3108,7 @@ La versión local es %1, la versión remota es %2. - + red rojo @@ -2266,7 +3116,7 @@ La versión local es %1, la versión remota es %2. - + yellow amarillo @@ -2274,7 +3124,7 @@ La versión local es %1, la versión remota es %2. - + green verde @@ -2282,74 +3132,61 @@ La versión local es %1, la versión remota es %2. - %1 sets counter %2 to %3 (%4%5). - %1 establece los contadores de %2 a %3 (%4%5). + %1 establece los contadores de %2 a %3 (%4%5). - %1 sets PT of %2 to %3. - %1 establece F/R de %2 a %3. + %1 establece F/R de %2 a %3. - %1 sets annotation of %2 to %3. - %1 establece la anotación de %2 a %3. + %1 establece la anotación de %2 a %3. - %1 is looking at the top %2 cards %3. - %1 esta mirando las primeras %2 cartas de %3. + %1 esta mirando las primeras %2 cartas de %3. - + The game has started. La partida ha comenzado. - Connected. - Conectado. + Conectado. - Protocol version mismatch. Client: %1, Server: %2 - La versión del protocolo es diferente. Cliente: %1, Servidor: %2 + La versión del protocolo es diferente. Cliente: %1, Servidor: %2 - You have joined game #%1. - Te has unido a la partida #%1. + Te has unido a la partida #%1. - %1 has joined the game. - %1 se ha unido a la partida. + %1 se ha unido a la partida. - %1 has left the game. - %1 ha dejado la partida. + %1 ha dejado la partida. - %1 has loaded a local deck. - %1 ha cargado un mazo local. + %1 ha cargado un mazo local. - %1 has loaded deck #%2. - %1 ha cargado el mazo #%2. + %1 ha cargado el mazo #%2. - %1 is ready to start the game. - %1 está preparado para empezar la partida. + %1 está preparado para empezar la partida. - %1 has conceded the game. - %1 ha concedido la partida. + %1 ha concedido la partida. %1 draws a card. @@ -2360,218 +3197,185 @@ La versión local es %1, la versión remota es %2. %1 roba %2 cartas. - %1 destroys %2. - %1 destruye %2. + %1 destruye %2. - %1 creates token: %2%3. - %1 crea una ficha: %2%3. + %1 crea una ficha: %2%3. - %1 points from %2's %3 to %4. - %1 apunta desde el %3 de %2 a %4. + %1 apunta desde el %3 de %2 a %4. - %1 places %n %2 counter(s) on %3 (now %4). - + %1 pone %n %2 contador en %3 (ahora %4). %1 pone %n %2 contadores en %3 (ahora %4). - %1 removes %n %2 counter(s) from %3 (now %4). - + %1 remueve %n %2 contador en %3 (ahora %4). %1 remueve %n %2 contadores en %3 (ahora %4). - %1 %2 %3. - %1 %2 %3. + %1 %2 %3. - %1 is looking at %2. - %1 está mirando: %2. + %1 está mirando: %2. - %1 stops looking at %2. - %1 termina de mirar: %2. + %1 termina de mirar: %2. - %1 reveals %2 to %3. - %1 revela %2 a %3. + %1 revela %2 a %3. - %1 reveals %2. - %1 revela %2. + %1 revela %2. - + ending phase fase de fin de turno - It is now %1's turn. - Es el turno de %1. + Es el turno de %1. %1 shuffles his library. %1 baraja su biblioteca. - - - %1 takes a mulligan to %n. - - - - - - + %1 draws his initial hand. - + %1 draws her initial hand. - - her permanents - - - - %1 randomly reveals %2%3 to %4. - %1 revela aleatoriamente %2%3 a %4. + %1 revela aleatoriamente %2%3 a %4. - %1 randomly reveals %2%3. - %1 revela aleatoriamente %2%3. + %1 revela aleatoriamente %2%3. - %1 reveals %2%3 to %4. - %1 revela %2%3 a %4. + %1 revela %2%3 a %4. - %1 reveals %2%3. - %1 revela %2%3. + %1 revela %2%3. - + untap step paso de enderezar - + upkeep step paso de mantenimiento - + draw step paso de robar - + first main phase primera fase principal - + beginning of combat step paso de inicio de combate - + declare attackers step paso de declarar atacantes - + declare blockers step paso de declarar bloqueadores - + combat damage step paso de daño de combate - + end of combat step paso de fin de combate - + second main phase segunda fase principal - + It is now the %1. Ahora es el %1. - taps - gira + gira - untaps - endereza + endereza - %1 sets %2 to not untap normally. - %1 establece que %2 no se endereze normalmente. + %1 establece que %2 no se endereze normalmente. - %1 sets %2 to untap normally. - %1 establece que %2 se endereze normalmente. + %1 establece que %2 se endereze normalmente. - his permanents - sus permanentes + sus permanentes MessagesSettingsPage - + &Add &Añadir - + &Remove &Quitar - + Add message Añadir mensaje - + Message: Mensaje: @@ -2915,7 +3719,7 @@ La versión local es %1, la versión remota es %2. - + Number: Número: @@ -2940,27 +3744,27 @@ La versión local es %1, la versión remota es %2. Número de caras: - + Set power/toughness Establecer fuerza/resistencia - + Please enter the new PT: Por favor, introduzca la nueva F/R: - + Set annotation Escribir anotación - + Please enter the new annotation: Por favor, introduza la nueva anotación: - + Set counters Establecer contadores @@ -3140,40 +3944,73 @@ La versión local es %1, la versión remota es %2. Nombre largo + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + &Aceptar + + + + &Cancel + &Cancelar + + + + Shut down server + + + TabAdmin - + Update server &message Actualizar &mensaje del servidor - + + &Shut down server + + + + Server administration functions Funciones de administración del servidor - + &Unlock functions &Desbloquear funciones - + &Lock functions &Bloquear funciones - + Unlock administration functions Desbloquear funciones de administración - + Do you really want to unlock the administration functions? ¿Realmente quieres desbloquear las funciones de administración? - + Administration Administración @@ -3268,137 +4105,137 @@ Por favor, introduzca un nombre: TabGame - + F5 F5 - + F6 F6 - + F7 F7 - + F8 F8 - + F9 F9 - + F10 F10 - + &Phases &Fases - + &Game &Partida - + Next &phase Próxima &fase - + Ctrl+Space Ctrl+Space - + Next &turn Próximo &turno - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter - + &Remove all local arrows &Retirar todas las flechas locales - + Ctrl+R Ctrl+R - + &Concede &Conceder - + F2 F2 - + &Leave game &Abandonar la partida - + Ctrl+Q Ctrl+Q - + &Say: &Decir: - + Concede Conceder - + Are you sure you want to concede this game? ¿Estás seguro de que quieres conceder esta partida? - + Leave game Abandonar la partida - + Are you sure you want to leave this game? ¿Estás seguro de que quieres abandonar la partida? - + Kicked Expulsado - + You have been kicked out of the game. Has sido expulsado de la partida. - + Game %1: %2 Partida %1: %2 @@ -3406,27 +4243,27 @@ Por favor, introduzca un nombre: TabMessage - + Personal &talk &Conversación personal - + &Leave &Cerrar - + This user is ignoring you. Este usuario está ignorandote. - + %1 has left the server. %1 ha abandonado el servidor. - + %1 has joined the server. %1 se ha unido al servidor. @@ -3439,27 +4276,27 @@ Por favor, introduzca un nombre: TabRoom - + &Say: &Decir: - + Chat Chat - + &Room &Sala - + &Leave room &Dejar sala - + You are flooding the chat. Please wait a couple of seconds. Estás floodeando el chat. Por favor, espera unos segundos. @@ -3543,37 +4380,37 @@ Por favor, introduzca un nombre: UserInterfaceSettingsPage - + General interface settings Preferencias generales de la interfaz - + &Double-click cards to play them (instead of single-click) &Doble click en las cartas para jugarlas (en lugar de un solo click) - + Animation settings Opciones de animación - + &Tap/untap animation Animación de &girar/enderezar - + Enable &sounds - + Path to sounds directory: - + Choose path Elija ruta @@ -3581,70 +4418,78 @@ Por favor, introduzca un nombre: UserList - + Users online: %1 Usuarios online: %1 - + Users in this room: %1 Usuarios en esta sala: %1 - + Buddies online: %1 / %2 Amigos online: %1 / %2 - + Ignored users online: %1 / %2 Usuarios ignorados online: %1 / %2 - + + %1's games + + + + User &details &Detalles del usuario - + Direct &chat &Chat privado - + + Show this user's &games + + + + Add to &buddy list Añadir a la lista de &amigos - + Remove from &buddy list Quitar de la lista de &amigos - + Add to &ignore list Añadir a la lista de &ignorados - + Remove from &ignore list Quitar de la lista de &ignorados - + Ban from &server Banear del &servidor - Duration - Duración + Duración - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Por favor, introduce la duración del ban (en minutos) + Por favor, introduce la duración del ban (en minutos) Indica 0 para un ban indefinido. diff --git a/cockatrice/translations/cockatrice_fr.ts b/cockatrice/translations/cockatrice_fr.ts index de17833e..301f3217 100644 --- a/cockatrice/translations/cockatrice_fr.ts +++ b/cockatrice/translations/cockatrice_fr.ts @@ -37,90 +37,126 @@ AppearanceSettingsPage - + Zone background pictures Zone images de fond - + Path to hand background: Chemin pour les images de fond de main: - + Path to stack background: Chemin pour les images de fond de pile: - + Path to table background: Chemin pour les images d'arrière-plan: - + Path to player info background: Chemin pour les images de fond d'affichage d'informations: - + Path to picture of card back: Chemin pour les images de dos des cartes: - + Card rendering Rendu des cartes - + Display card names on cards having a picture Afficher le nom des cartes ayant une image - + Hand layout Disposition de la main - + Display hand horizontally (wastes space) Montrer la main horizontalement - + Table grid layout Disposition en forme de grille - + Invert vertical coordinate Inverser la disposition du champ de bataille - + + Minimum player count for multi-column layout: + + + + Zone view layout Voir disposition de la zone - + Sort by name Tri par nom - + Sort by type Tri par type - - - - - + + + + + Choose path Choisir le chemin + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + Entrez la durée de temps du ban (en minutes). +Entrez 0 pour une durée illimitée du ban. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + &OK + + + + &Cancel + &Annuler + + + + Ban user from server + + + CardDatabaseModel @@ -195,57 +231,57 @@ CardItem - + &Play &Jouer - + &Hide &Cacher - + &Tap &Engager - + &Untap &Dégager - + Toggle &normal untapping Activer/ Désactiver le dégagement &normal - + &Flip &Retourner la carte - + &Clone &Copier une carte - + Ctrl+H - + &Attach to card... &Attacher à la carte... - + Ctrl+A Ctrl+A - + Unattac&h Détac&her @@ -254,142 +290,147 @@ Fixer &F/E... - + + &Draw arrow... + + + + &Power / toughness F&orce / Endurance - + &Increase power &Augmenter force - + Ctrl++ Ctrl++ - + &Decrease power &Diminuer force - + Ctrl+- Ctrl+- - + I&ncrease toughness A&ugmenter endurance - + Alt++ Alt++ - + D&ecrease toughness D&iminuer endurance - + Alt+- Alt+- - + In&crease power and toughness Au&gmenter la force et l'endurance - + Ctrl+Alt++ Ctrl+Alt++ - + Dec&rease power and toughness Di&minuer la force et l'endurance - + Ctrl+Alt+- Ctrl+Alt+- - + Set &power and toughness... Fi&xer la force et l'endurance... - + Ctrl+P Ctrl+P - + &Set annotation... A&jouter note... - + red rouge - + yellow jaune - + green vert - + &Add counter (%1) &Ajouter compteur (%1) - + &Remove counter (%1) &Retirer compteur (%1) - + &Set counters (%1)... &Fixer marqueurs (%1)... - + &top of library dessus de la &Bibliothèque - + &bottom of library &dessous de la bibliothèque - + &graveyard &cimetière - + Ctrl+Del Ctrl+Del - + &exile &exiler - + &Move to &Aller @@ -960,12 +1001,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General Géneral @@ -991,22 +1032,22 @@ DeckViewContainer - + Load &local deck Charger un deck &local - + Load d&eck from server Charger un d&eck depuis le serveur - + Ready to s&tart P&rêt à démarrer - + Load deck Charger deck @@ -1102,82 +1143,82 @@ &Description: - + &Password: Mot de &Passe: - + P&layers: &Joueurs: - + Game type Type de partie - + Only &buddies can join Seuls les &amis peuvent rejoindre - + Only &registered users can join Seules les personnes en&registrées peuvent rejoindre - + Joining restrictions Conditions pour rejoindre - + &Spectators allowed &Spectateurs autorisés - + Spectators &need a password to join Les spectateurs ont besoin d'un &mot de passe pour rejoindre - + Spectators can &chat Les spectateurs peuvent dis&cuter - + Spectators see &everything Les spectateurs p&euvent tout voir - + Spectators Spectateurs - + &OK &OK - + &Cancel &Annuler - + Create game Créer partie - + Error Erreur - + Server error. Erreur serveur. @@ -1319,59 +1360,59 @@ DlgSettings - - - + + + Error Erreur - + Your card database is invalid. Would you like to go back and set the correct path? Votre base de carte est invalide. Souhaitez-vous redéfinir le chemin d'accès? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? Le chemin d'accès pour le répertoire de votre deck est invalide. Souhaitez-vous redéfinir le chemin d'accès? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? Le chemin d'accès pour le répertoire de vos images est invalide. Souhaitez-vous redéfinir le chemin d'accès? - + Settings Paramètres - + General Géneral - + Appearance Apparence - + User interface Interface utilisateur - + Deck editor - + Messages Messages - + &Close &Fermer @@ -1379,88 +1420,99 @@ GameSelector - - - - - - - + + + + + + + + Error Erreur - + + Please join the appropriate room first. + + + + Wrong password. Mot de passe erroné. - + Spectators are not allowed in this game. Les spectateurs ne sont pas autorisés dans cette partie. - + The game is already full. Cette partie est déjà pleine. - + The game does not exist any more. La partie n'existe plus. - + This game is only open to registered users. Cette partie n'est accessible qu'aux joueurs enregistrés. - + This game is only open to its creator's buddies. Cette partie n'est accessible qu'aux amis. - + You are being ignored by the creator of this game. Vous avez été ignoré par le créateur de la partie. - + Join game Rejoindre partie - + Password: Mot de passe: - + Games Parties - + Show &full games Montrer &toutes les parties + + + Show &running games + + &Show full games toutes ou complèetes? &Montrer toutes les parties - + C&reate C&réer - + &Join Re&joindre - + J&oin as spectator Rej&oindre en tant que spectateur @@ -1476,67 +1528,72 @@ GamesModel - + yes oui - + yes, free for spectators oui, libre pour les spectateurs - + no non - + buddies only invités uniquement - + reg. users only joueurs enregistrés uniquement - + not allowed non autorisé - + + Room + Salon + + + Description Description - + Creator Créateur - + Game type Type de jeu - + Password Mot de passe - + Restrictions Restrictions - + Players Joueurs - + Spectators Spectateurs @@ -1544,50 +1601,50 @@ GeneralSettingsPage - - + + English Français - - - + + + Choose path Choisir chemin d'accès - + Personal settings Paramètres personnels - + Language: Langue: - + Download card pictures on the fly Charger les images de cartes à la volée - + Paths Chemins - + Decks directory: Répertoire des decks: - + Pictures directory: Répertoire des images: - + Path to card database: Chemin vers la base de cartes: @@ -1595,23 +1652,23 @@ MainWindow - + Number of players Nombre de joueurs - + Please enter the number of players. Entrez s'il vous plait le nombre de joueurs. - - + + Player %1 Joueur %1 - + About Cockatrice à propos de Cockatrice @@ -1620,67 +1677,67 @@ <font size="8"><b>Cockatrice</b></font><br>Version %1<br><br><br><b>Auteurs:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Tranducteurs:</b><br>Espagnol: Gocho<br>Portugais: Milton Gonçalves<br>Portugais: Milton Gonçalves<br>Français: Yannick HAMMER<br> - + Version %1 Version %1 - + Authors: Auteurs: - + Translators: Traducteurs: - + Spanish: Espagnol: - + Portugese (Portugal): Portugais (Portugal): - + Portugese (Brazil): Portugais (Brésil): - + French: Français: - + Japanese: Japonais: - - + - - + + + Error Erreur - + Server timeout Délai de la demande dépassé - + Invalid login data. Information de connexion érronée. - + Socket error: %1 Erreur de socket: %1 @@ -1700,136 +1757,156 @@ + Scheduled server shutdown. + + + + Unknown reason. Raison inconnue. - + Connection closed Connection fermée - + The server has terminated your connection. Reason: %1 Le serveur a coupé votre connexion. Raison: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + Russian: putted "France" instead of "Russe" -> meant that I must put the translation laguage country, isn't it? France: - + Czech: - + Slovak: - + There is already an active session using this user name. Please close that session first and re-login. Il y a déjà une session ouvert avec le même pseudo. Fermez cette session puis re-connectez-vous. - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. Vous tentez de vous connecter à un serveur obsolète. Chargez la nouvelle version de Cockatrice ou connectez-vous à un serveur approprié. La version la plus récente est %1, l'ancienne version est %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. Votre client Cockatrice est obsolète. Veuillez charger la nouvelle version. La version la plus récente est %1, l'ancienne version est %2. - + Connecting to %1... Connexion à %1... - + Disconnected Déconnecté - + Logged in at %1 Connecté à %1 - + &Connect... à verifier &Connecter... - + &Disconnect &Déconnecter - + Start &local game... Démarrer une partie &locale... - + &Deck editor Éditeur de &deck - + &Full screen &Plein écran - + Ctrl+F Ctrl+F - + &Settings... &Paramètres... - + &Exit &Quitter - + &Cockatrice &Cockatrice - + &About Cockatrice À propos de Cock&atrice - + &Help A&ide - + Are you sure? Êtes-vous sûr? - + There are still open games. Are you sure you want to quit? Il y a encore des parties en cours. Êtes-vous sûr de vouloir quitter? @@ -1837,93 +1914,79 @@ La version la plus récente est %1, l'ancienne version est %2. MessageLogWidget - Connecting to %1... - Connexion à %1... + Connexion à %1... - Connected. - Connecté. + Connecté. - Disconnected from server. - Déconnecté du serveur. + Déconnecté du serveur. - Invalid password. - Mot de passe invalide. + Mot de passe invalide. - Protocol version mismatch. Client: %1, Server: %2 - Version de protocole différente. Version locale: %1 ,version distante: %2 + Version de protocole différente. Version locale: %1 ,version distante: %2 - Protocol error. - Erreur de protocole. + Erreur de protocole. - You have joined game #%1. - Vous avez rejoint la partie #%1. + Vous avez rejoint la partie #%1. - %1 has joined the game. - %1 a rejoint la partie. + %1 a rejoint la partie. - %1 has left the game. - %1 a quitté la partie. + %1 a quitté la partie. - + The game has been closed. La partie a été fermée. - + %1 is now watching the game. %1 est maintenant spectateur. - + %1 is not watching the game any more. %1 n'est plus spectateur. - %1 has loaded a local deck. - %1 a chargé un deck local. + %1 a chargé un deck local. - %1 has loaded deck #%2. - %1 a chargé le deck #%2. + %1 a chargé le deck #%2. + + + %1 is ready to start the game. + %1 est prêt à démarrer la partie. + + + %1 is not ready to start the game any more. + %1 n'est plus prêt à démarrer la partie. + + + %1 has conceded the game. + partie ou jeu + %1 a concédé la partie. - %1 is ready to start the game. - %1 est prêt à démarrer la partie. - - - - %1 is not ready to start the game any more. - %1 n'est plus prêt à démarrer la partie. - - - - %1 has conceded the game. - partie ou jeu - %1 a concédé la partie. - - - The game has started. La partie commence. @@ -1932,10 +1995,9 @@ La version la plus récente est %1, l'ancienne version est %2.%1 mélange sa bibliothèque. - %1 rolls a %2 with a %3-sided die. is it always a dice? - %1 lance un %2 à %3 faces. + %1 lance un %2 à %3 faces. %1 draws a card. @@ -1946,260 +2008,1028 @@ La version la plus récente est %1, l'ancienne version est %2.%1 pioche %2 cartes. - - from table - depuis le champ de bataille + + You have joined game #%1. + female + Vous avez rejoint la partie #%1. - - from graveyard - depuis son cimetière + + You have joined game #%1. + male + Vous avez rejoint la partie #%1. - - from exile - depuis la zone exil + + %1 has joined the game. + female + %1 a rejoint la partie. - - from hand - depuis sa main + + %1 has joined the game. + male + %1 a rejoint la partie. - - the bottom card of his library - la carte du dessous de sa bibliothèque + + %1 has left the game. + female + %1 a quitté la partie. - - the bottom card of her library + + %1 has left the game. + male + %1 a quitté la partie. + + + + %1 has loaded a local deck. + female + %1 a chargé un deck local. + + + + %1 has loaded a local deck. + male + %1 a chargé un deck local. + + + + %1 has loaded deck #%2. + female + %1 a chargé le deck #%2. + + + + %1 has loaded deck #%2. + male + %1 a chargé le deck #%2. + + + + %1 is ready to start the game. + female + %1 est prêt à démarrer la partie. + + + + %1 is ready to start the game. + male + %1 est prêt à démarrer la partie. + + + + %1 is not ready to start the game any more. + female + %1 n'est plus prêt à démarrer la partie. + + + + %1 is not ready to start the game any more. + male + %1 n'est plus prêt à démarrer la partie. + + + + %1 has conceded the game. + female + %1 a concédé la partie. + + + + %1 has conceded the game. + male + %1 a concédé la partie. + + + + %1 has restored connection to the game. + female - - from the bottom of his library - du dessous de sa bibliothèque - - - - from the bottom of her library + + %1 has restored connection to the game. + male - - the top card of his library - le carte du dessus de sa bibliothèque - - - - the top card of her library + + %1 has lost connection to the game. + female - - from the top of his library - du dessus de sa bibliothèque - - - - from the top of her library + + %1 has lost connection to the game. + male - - from library - depuis sa bibliothèque - - - - from sideboard - depuis sa réserve - - - - from the stack - depuis la pile - - - - %1 puts %2 into play tapped%3. - %1 met %2 en jeu engagé%3. - - - - %1 puts %2 into play%3. - what is %3? plz exemple (resp. by Ranma : XX met island en jeu -depuis sa main-.) - %1 met %2 en jeu %3. - - - - %1 puts %2%3 into graveyard. - %1 met %2%3 dans son cimetière. - - - - %1 exiles %2%3. - %1 exile %2%3. - - - - %1 moves %2%3 to hand. - %1 met %2%3 dans sa main. - - - - %1 puts %2%3 into his library. - %1 met %2%3 dans sa bibliothèque. - - - - %1 puts %2%3 into her library. - - - - - %1 puts %2%3 on bottom of his library. - %1 met %2%3 en-dessous de sa bibliothèque. - - - - %1 puts %2%3 on bottom of her library. - - - - - %1 puts %2%3 on top of his library. - %1 met %2%3 au-dessus de sa bibliothèque. - - - - %1 puts %2%3 on top of her library. - - - - - %1 puts %2%3 into his library at position %4. - %1 met %2%3 dans sa bibliothèque à la position n°%4. - - - - %1 puts %2%3 into her library at position %4. - - - - - %1 moves %2%3 to sideboard. - %1 met %2%3 à sa réserve. - - - - %1 plays %2%3. - %1 joue %2%3. - - - - - a card - une carte - - - + %1 shuffles %2. + female + + + %1 shuffles %2. + male + + + + + %1 rolls a %2 with a %3-sided die. + female + %1 lance un %2 à %3 faces. + + + + %1 rolls a %2 with a %3-sided die. + male + %1 lance un %2 à %3 faces. + - + %1 draws %n card(s). - + female + + %1 pioche %n carte. + %1 pioche %n cartes. + + + + + %1 draws %n card(s). + male + %1 pioche %n carte. %1 pioche %n cartes. - - %1 undoes his last draw. - %1 annule sa dernière pioche. + + from table + depuis le champ de bataille - - %1 undoes her last draw. + + from graveyard + depuis son cimetière + + + + from exile + depuis la zone exil + + + + from hand + depuis sa main + + + + the bottom card of his library + la carte du dessous de sa bibliothèque + + + + the bottom card of her library - - %1 undoes his last draw (%2). - %1 annule sa dernière pioche (%2). + + from the bottom of his library + du dessous de sa bibliothèque - - %1 undoes her last draw (%2). + + from the bottom of her library - - %1 gives %2 control over %3. - %1 donne le contrôle de %2 à %3. + + the top card of his library + le carte du dessus de sa bibliothèque + + + + the top card of her library + + + + + from the top of his library + du dessus de sa bibliothèque + + + + from the top of her library + + + + + from library + depuis sa bibliothèque + + + + from sideboard + depuis sa réserve + + + + from the stack + depuis la pile + + + + %1 puts %2 into play tapped%3. + %1 met %2 en jeu engagé%3. + + + + %1 puts %2 into play%3. + what is %3? plz exemple (resp. by Ranma : XX met island en jeu -depuis sa main-.) + %1 met %2 en jeu %3. + + + + %1 puts %2%3 into graveyard. + %1 met %2%3 dans son cimetière. + + + + %1 exiles %2%3. + %1 exile %2%3. + + + + %1 moves %2%3 to hand. + %1 met %2%3 dans sa main. + + + + %1 puts %2%3 into his library. + %1 met %2%3 dans sa bibliothèque. + + + + %1 puts %2%3 into her library. + + + + + %1 puts %2%3 on bottom of his library. + %1 met %2%3 en-dessous de sa bibliothèque. + + + + %1 puts %2%3 on bottom of her library. + + + + + %1 puts %2%3 on top of his library. + %1 met %2%3 au-dessus de sa bibliothèque. + + + + %1 puts %2%3 on top of her library. + + + + + %1 puts %2%3 into his library at position %4. + %1 met %2%3 dans sa bibliothèque à la position n°%4. + + + + %1 puts %2%3 into her library at position %4. + + + + + %1 moves %2%3 to sideboard. + %1 met %2%3 à sa réserve. + + + + %1 plays %2%3. + %1 joue %2%3. - + %1 takes a mulligan to %n. + female + + + + + + + + %1 takes a mulligan to %n. + male - + + %1 flips %2 face-down. + female + %1 retourne %2 face cachée. + + + + %1 flips %2 face-down. + male + %1 retourne %2 face cachée. + + + + %1 flips %2 face-up. + female + %1 retourne %2 face visible. + + + + %1 flips %2 face-up. + male + %1 retourne %2 face visible. + + + + %1 destroys %2. + female + %1 détruit %2. + + + + %1 destroys %2. + male + %1 détruit %2. + + + %1 attaches %2 to %3's %4. + female + %1 attache %2 sur %4 de %3. + + + %1 attaches %2 to %3's %4. + male + %1 attache %2 sur %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + %1 attache %2 sur %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + %1 attache %2 sur %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + %1 attache %2 sur %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + %1 attache %2 sur %4 de %3. + + + + %1 unattaches %2. + female + %1 détache %2. + + + + %1 unattaches %2. + male + %1 détache %2. + + + + %1 creates token: %2%3. + female + %1 crée un jeton %2%3. + + + + %1 creates token: %2%3. + male + %1 crée un jeton %2%3. + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + %1 désigne le %3 de %2 à %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + %1 désigne le %3 de %2 à %4. + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + %1 désigne le %3 de %2 à %5 de %4. + + + + %1 places %n %2 counter(s) on %3 (now %4). + female + + %1 met %n %2 marqueur sur %3 (maintenant %4). + %1 met %n %2 marqueurs sur %3 (maintenant %4). + + + + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 met %n %2 marqueur sur %3 (maintenant %4). + %1 met %n %2 marqueurs sur %3 (maintenant %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + %1 retire %n %2 marqueur de %3 (maintenant %4). + %1 retire %n %2 marqueurs de %3 (maintenant %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + %1 retire %n %2 marqueur de %3 (maintenant %4). + %1 retire %n %2 marqueurs de %3 (maintenant %4). + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + %1 met les marqueurs %2 à %3 (%4%5). + + + + %1 sets counter %2 to %3 (%4%5). + male + %1 met les marqueurs %2 à %3 (%4%5). + + + + %1 sets %2 to not untap normally. + female + %2 de %1 ne se dégagera pas lors de l'étape de dégagement. + + + + %1 sets %2 to not untap normally. + male + %2 de %1 ne se dégagera pas lors de l'étape de dégagement. + + + + %1 sets %2 to untap normally. + female + %2 de %1 se dégagera lors de l'étape de dégagement. + + + + %1 sets %2 to untap normally. + male + %2 de %1 se dégagera lors de l'étape de dégagement. + + + + %1 sets PT of %2 to %3. + female + %1 change la F/E de %2 à %3. + + + + %1 sets PT of %2 to %3. + male + %1 change la F/E de %2 à %3. + + + + %1 sets annotation of %2 to %3. + female + %1 met l'annotation %3 à %2. + + + + %1 sets annotation of %2 to %3. + male + %1 met l'annotation %3 à %2. + + + + %1 is looking at the top %2 cards %3. + female + %1 regarde les %2 cartes du dessus %3. + + + + %1 is looking at the top %2 cards %3. + male + %1 regarde les %2 cartes du dessus %3. + + + + %1 is looking at %2. + female + %1 regarde %2. + + + + %1 is looking at %2. + male + %1 regarde %2. + + + + %1 stops looking at %2. + female + %1 arrête de regarder %2. + + + + %1 stops looking at %2. + male + %1 arrête de regarder %2. + + + + %1 reveals %2 to %3. + p1 female, p2 female + %1 révèle %2 à %3. + + + + %1 reveals %2 to %3. + p1 female, p2 male + %1 révèle %2 à %3. + + + + %1 reveals %2 to %3. + p1 male, p2 female + %1 révèle %2 à %3. + + + + %1 reveals %2 to %3. + p1 male, p2 male + %1 révèle %2 à %3. + + + + %1 reveals %2. + female + %1 révèle %2. + + + + %1 reveals %2. + male + %1 révèle %2. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + %1 révèle au hasard %2%3 à %4. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + %1 révèle au hasard %2%3 à %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + %1 révèle au hasard %2%3 à %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + %1 révèle au hasard %2%3 à %4. + + + + %1 randomly reveals %2%3. + female + %1 révèle au hasard %2%3. + + + + %1 randomly reveals %2%3. + male + %1 révèle au hasard %2%3. + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + %1 révèle %2%3 à %4. + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + %1 révèle %2%3 à %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + %1 révèle %2%3 à %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + %1 révèle %2%3 à %4. + + + + %1 reveals %2%3. + female + %1 révèle %2%3. + + + + %1 reveals %2%3. + male + %1 révèle %2%3. + + + + It is now %1's turn. + female + C'est maintenant le tour de %1. + + + + It is now %1's turn. + male + C'est maintenant le tour de %1. + + + + + a card + une carte + + + %1 draws %n card(s). + + %1 pioche %n carte. + %1 pioche %n cartes. + + + + + %1 undoes his last draw. + %1 annule sa dernière pioche. + + + + %1 undoes her last draw. + + + + + %1 undoes his last draw (%2). + %1 annule sa dernière pioche (%2). + + + + %1 undoes her last draw (%2). + + + + + %1 gives %2 control over %3. + %1 donne le contrôle de %2 à %3. + + + %1 draws his initial hand. - + %1 draws her initial hand. - %1 flips %2 face-down. - %1 retourne %2 face cachée. + %1 retourne %2 face cachée. - %1 flips %2 face-up. - %1 retourne %2 face visible. + %1 retourne %2 face visible. - %1 destroys %2. - %1 détruit %2. + %1 détruit %2. - %1 attaches %2 to %3's %4. need exemple (Resp'.by Ranma: JoueurA attache Adventuring Gear sur -Plated Geopede- de -JoueurB-.) - %1 attache %2 sur %4 de %3. + %1 attache %2 sur %4 de %3. - %1 unattaches %2. - %1 détache %2. + %1 détache %2. - %1 creates token: %2%3. - %1 crée un jeton %2%3. + %1 crée un jeton %2%3. - %1 points from %2's %3 to %4. need exemple - %1 désigne le %3 de %2 à %4. + %1 désigne le %3 de %2 à %4. - %1 points from %2's %3 to %4's %5. need exemple - %1 désigne le %3 de %2 à %5 de %4. + %1 désigne le %3 de %2 à %5 de %4. %1 places %n counter(s) (%2) on %3 (now %4). @@ -2218,23 +3048,21 @@ La version la plus récente est %1, l'ancienne version est %2. - %1 places %n %2 counter(s) on %3 (now %4). - + %1 met %n %2 marqueur sur %3 (maintenant %4). %1 met %n %2 marqueurs sur %3 (maintenant %4). - %1 removes %n %2 counter(s) from %3 (now %4). - + %1 retire %n %2 marqueur de %3 (maintenant %4). %1 retire %n %2 marqueurs de %3 (maintenant %4). - + red rouge @@ -2242,7 +3070,7 @@ La version la plus récente est %1, l'ancienne version est %2. - + yellow jaune @@ -2250,7 +3078,7 @@ La version la plus récente est %1, l'ancienne version est %2. - + green vert @@ -2258,169 +3086,145 @@ La version la plus récente est %1, l'ancienne version est %2. - his permanents - ses permanents + ses permanents - - her permanents - - - - %1 %2 %3. wtf ? - %1 %2 %3. + %1 %2 %3. - taps - engage + engage - untaps - dégage + dégage - %1 sets counter %2 to %3 (%4%5). need exemple - %1 met les marqueurs %2 à %3 (%4%5). + %1 met les marqueurs %2 à %3 (%4%5). - %1 sets %2 to not untap normally. need exemple - %2 de %1 ne se dégagera pas lors de l'étape de dégagement. + %2 de %1 ne se dégagera pas lors de l'étape de dégagement. - %1 sets %2 to untap normally. - %2 de %1 se dégagera lors de l'étape de dégagement. + %2 de %1 se dégagera lors de l'étape de dégagement. - %1 sets PT of %2 to %3. exemple plz - %1 change la F/E de %2 à %3. + %1 change la F/E de %2 à %3. - %1 sets annotation of %2 to %3. - %1 met l'annotation %3 à %2. + %1 met l'annotation %3 à %2. - %1 is looking at the top %2 cards %3. exemple plz - %1 regarde les %2 cartes du dessus %3. + %1 regarde les %2 cartes du dessus %3. - %1 is looking at %2. exemple plz - %1 regarde %2. + %1 regarde %2. - %1 stops looking at %2. need exemple to be sure - %1 arrête de regarder %2. + %1 arrête de regarder %2. - %1 reveals %2 to %3. - %1 révèle %2 à %3. + %1 révèle %2 à %3. - %1 reveals %2. - %1 révèle %2. + %1 révèle %2. - %1 randomly reveals %2%3 to %4. - %1 révèle au hasard %2%3 à %4. + %1 révèle au hasard %2%3 à %4. - %1 randomly reveals %2%3. - %1 révèle au hasard %2%3. + %1 révèle au hasard %2%3. - %1 reveals %2%3 to %4. - %1 révèle %2%3 à %4. + %1 révèle %2%3 à %4. - %1 reveals %2%3. - %1 révèle %2%3. + %1 révèle %2%3. - It is now %1's turn. - C'est maintenant le tour de %1. + C'est maintenant le tour de %1. - + untap step étape de dégagement - + upkeep step étape d'entretien - + draw step étape de pioche - + first main phase première phase principale - + beginning of combat step étape de début du combat - + declare attackers step étape de déclaration des attaquants - + declare blockers step étape de déclaration des bloqueurs - + combat damage step étape de répartition et de résolution des blessures - + end of combat step étape de fin de combat - + second main phase seconde phase principale - + ending phase phase de fin de tour - + It is now the %1. need exemple C'est maintenant %1. @@ -2429,22 +3233,22 @@ La version la plus récente est %1, l'ancienne version est %2. MessagesSettingsPage - + Add message Ajouter message - + Message: Message: - + &Add &Ajouter - + &Remove &Enlever @@ -2780,7 +3584,7 @@ La version la plus récente est %1, l'ancienne version est %2. - + Number: Nombre: @@ -2805,28 +3609,28 @@ La version la plus récente est %1, l'ancienne version est %2.Nombre de faces: - + Set power/toughness Fixer force/endurance - + Please enter the new PT: maybe better with / Entrer la nouvelle F/E: - + Set annotation Mettre une note - + Please enter the new annotation: Entrez la nouvelle note: - + Set counters Mettre des marqueurs @@ -2999,40 +3803,73 @@ La version la plus récente est %1, l'ancienne version est %2.Nom complet + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + &OK + + + + &Cancel + &Annuler + + + + Shut down server + + + TabAdmin - + Update server &message Mettre à jour le &message du serveur - + + &Shut down server + + + + Server administration functions Fonctions d'administration du serveur - + &Unlock functions &Débloquer fonctions - + &Lock functions &Bloquer fonctions - + Unlock administration functions Débloquer fonctions d'administration - + Do you really want to unlock the administration functions? Êtes-vous sûr de vouloir débloquer les fonctions d'administration? - + Administration Administration @@ -3127,137 +3964,137 @@ Entrez un nom s'il vous plaît: TabGame - + F5 F5 - + F6 F6 - + F7 F7 - + F8 F8 - + F9 F9 - + F10 F10 - + &Phases - + &Game &Partie - + Next &phase &Prochaine phase - + Ctrl+Space Ctrl+Space - + Next &turn Prochain &Tour - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter - + &Remove all local arrows &Retirer toutes les flèches locales - + Ctrl+R Ctrl+R - + &Concede &Concéder - + F2 F2 - + &Leave game &Quitter la partie - + Ctrl+Q Ctrl+Q - + &Say: &Dire: - + Concede Concéder - + Are you sure you want to concede this game? Êtes-vous sûr de vouloir concéder la partie? - + Leave game Quitter la partie - + Are you sure you want to leave this game? Êtes-vous sûr de vouloir quitter la partie? - + Kicked Exclu - + You have been kicked out of the game. Vous avez été exclu de la partie. - + Game %1: %2 Partie %1:%2 @@ -3265,28 +4102,28 @@ Entrez un nom s'il vous plaît: TabMessage - + Personal &talk need exemple &Discussion privée - + &Leave &Quitter - + This user is ignoring you. Cet utilisateur vous a ignoré. - + %1 has left the server. %1 a quitté le serveur. - + %1 has joined the server. %1 a rejoint le serveur. @@ -3299,27 +4136,27 @@ Entrez un nom s'il vous plaît: TabRoom - + &Say: &Dire: - + Chat Chat - + &Room &Salon - + &Leave room &Quitter le salon - + You are flooding the chat. Please wait a couple of seconds. Vous floodez le chat. Veuillez patienter quelques secondes. @@ -3404,37 +4241,37 @@ Entrez un nom s'il vous plaît: UserInterfaceSettingsPage - + General interface settings Réglages généraux de l'interface - + &Double-click cards to play them (instead of single-click) &Double cliquer sur la carte pour la jouer (au lieu d'un simple clic) - + Animation settings Réglage des animations - + &Tap/untap animation &Animation d'engagement et de dégagement - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3442,70 +4279,78 @@ Entrez un nom s'il vous plaît: UserList - + Users online: %1 Utilisateurs en ligne:%1 - + Users in this room: %1 Utilisateurs dans ce salon: %1 - + Buddies online: %1 / %2 Amis connectés; %1 / %2 - + Ignored users online: %1 / %2 Personnes sur liste noire connectés: %1 / %2 - + + %1's games + + + + User &details &Détails utilisateur - + Direct &chat &Chat direct - + + Show this user's &games + + + + Add to &buddy list Ajouter à la liste d'&amis - + Remove from &buddy list Retirer de la liste d'&amis - + Add to &ignore list Ajouter à la liste &noire - + Remove from &ignore list Retirer de la liste &noire - + Ban from &server Bannir du &serveur - Duration - Durée + Durée - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Entrez la durée de temps du ban (en minutes). + Entrez la durée de temps du ban (en minutes). Entrez 0 pour une durée illimitée du ban. diff --git a/cockatrice/translations/cockatrice_ja.ts b/cockatrice/translations/cockatrice_ja.ts index 4ae3575c..5470b772 100644 --- a/cockatrice/translations/cockatrice_ja.ts +++ b/cockatrice/translations/cockatrice_ja.ts @@ -37,58 +37,58 @@ AppearanceSettingsPage - + Zone background pictures 背景画像の設定 - + Path to hand background: 手札の背景画像へのパス: - + Path to stack background: スタックゾーンの背景画像へのパス: - + Path to table background: テーブルの背景画像へのパス: - + Path to player info background: プレイヤー画像へのパス: - + Path to picture of card back: カード背面画像へのパス: - + Card rendering カードレンダリング - + Display card names on cards having a picture やや不明 画像持ちカードのカードネームを表示する - + Hand layout 手札のレイアウト - + Display hand horizontally (wastes space) 手札を横に並べる(スペースを消費します) - + Table grid layout テーブルグリッドのレイアウト @@ -97,35 +97,70 @@ 省スペースレイアウト(カード間間隔を細かくできます) - + Invert vertical coordinate 垂直反転調整 - + + Minimum player count for multi-column layout: + + + + Zone view layout ゾーンビューレイアウト - + Sort by name 名前で整列 - + Sort by type タイプで整列 - - - - - + + + + + Choose path 画像の指定 + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + バンする期間を入力してください(分単位).0でバンを解除します. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + + + + + &Cancel + + + + + Ban user from server + + + CardDatabaseModel @@ -200,58 +235,58 @@ CardItem - + &Play プレイ - + &Hide テスト版のため確認取れず再度チェック 裏にしてプレイ - + &Tap タップ - + &Untap アンタップ - + Toggle &normal untapping 通常のアンタップをしない - + &Flip 裏にする - + &Clone 複製する - + Ctrl+H - + &Attach to card... カードに付ける... - + Ctrl+A - + Unattac&h 取り外す @@ -260,142 +295,147 @@ P/Tを決める... - + + &Draw arrow... + + + + &Power / toughness パワー / タフネス - + &Increase power パワーを上げる - + Ctrl++ - + &Decrease power パワーを下げる - + Ctrl+- - + I&ncrease toughness タフネスを上げる - + Alt++ - + D&ecrease toughness タフネスを下げる - + Alt+- - + In&crease power and toughness パワーとタフネスを上げる - + Ctrl+Alt++ - + Dec&rease power and toughness パワーとタフネスを下げる - + Ctrl+Alt+- - + Set &power and toughness... パワーとタフネスを設定する... - + Ctrl+P - + &Set annotation... 注釈を付ける... - + red - + yellow - + green - + &Add counter (%1) カウンターを乗せる (%1) - + &Remove counter (%1) カウンターを取り除く (%1) - + &Set counters (%1)... カウンターの数を決める (%1)... - + &top of library ライブラリーの一番上へ - + &bottom of library ライブラリーの一番下へ - + &graveyard 墓地へ - + Ctrl+Del - + &exile 追放領域へ - + &Move to 移動させる @@ -804,12 +844,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General 全般 @@ -835,22 +875,22 @@ DeckViewContainer - + Load &local deck ローカルからデッキをロード - + Load d&eck from server サーバーからデッキをロード - + Ready to s&tart 開始準備完了 - + Load deck デッキをロード @@ -939,82 +979,82 @@ 説明: - + &Password: パスワード: - + P&layers: プレイヤー人数: - + Game type ゲームタイプ - + Only &buddies can join フレンドのみ参加可能 - + Only &registered users can join 登録済みプレイヤーのみ参加可能 - + Joining restrictions 参加制限 - + &Spectators allowed 観戦者を許可する - + Spectators &need a password to join 観戦者は参加にパスワードが必要 - + Spectators can &chat 観戦者はチャットに参加できる - + Spectators see &everything 観戦者は全て見れる - + Spectators 観戦者 - + &OK - + &Cancel - + Create game 部屋を作る - + Error エラー - + Server error. サーバーエラー. @@ -1156,59 +1196,59 @@ DlgSettings - - - + + + Error エラー - + Your card database is invalid. Would you like to go back and set the correct path? あなたのカードデータベースは無効です.前に戻って正しいパスを設定してください. - + The path to your deck directory is invalid. Would you like to go back and set the correct path? あなたのデッキディレクトリへのパスは無効です.前に戻って正しいパスを設定してください. - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? あなたのカード画像ディレクトリへのパスは無効です.前に戻って正しいパスを設定してください. - + Settings 設定 - + General 全般 - + Appearance 外観 - + User interface ユーザーインターフェース - + Deck editor - + Messages メッセージ - + &Close @@ -1216,87 +1256,98 @@ GameSelector - + C&reate 部屋を作る - + &Join 参加する - - - - - - - + + + + + + + + Error エラー - + + Please join the appropriate room first. + + + + Wrong password. パスワードが間違っています. - + Spectators are not allowed in this game. この試合は観戦者は許可されていません. - + The game is already full. このゲームはすでに満員です. - + The game does not exist any more. このゲームはもう存在しません. - + This game is only open to registered users. このゲームは登録済みプレイヤーにのみ公開されています. - + This game is only open to its creator's buddies. このゲームは作成者のフレンドのみに公開されています. - + You are being ignored by the creator of this game. あなたはこのゲームの作成者によって拒否されています. - + Join game 参加 - + Password: パスワード: - + Games ゲーム - + Show &full games 全てのゲームを見る + + + Show &running games + + &Show full games 全てのゲームを見る - + J&oin as spectator 観戦者として参加 @@ -1312,67 +1363,72 @@ GamesModel - + yes あり - + no なし - + Creator 作成者 - + Description 説明 - + yes, free for spectators あり,観戦は自由 - + buddies only フレンドのみ - + reg. users only 登録済みユーザーのみ - + not allowed 不許可 + Room + 部屋 + + + Game type ゲームタイプ - + Password パスワード - + Restrictions 制限 - + Players プレイヤー - + Spectators 観戦者 @@ -1380,50 +1436,50 @@ GeneralSettingsPage - - - + + + Choose path パスを選択 - + Personal settings 個人設定 - + Language: 言語: - + Download card pictures on the fly - + Paths パス - + Decks directory: デッキディレクトリ: - + Pictures directory: カード画像のディレクトリ: - + Path to card database: カードデータベースのパス: - - + + English Japanese @@ -1443,220 +1499,239 @@ + Scheduled server shutdown. + + + + Unknown reason. 不明な理由. - + Connection closed 通信切断 - + The server has terminated your connection. Reason: %1 サーバーはあなたの接続を切断しました. 理由: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + Number of players プレイヤー人数 - + Please enter the number of players. プレイヤーの人数を入れてください. - - + + Player %1 プレイヤー %1 - + About Cockatrice Cockatriceについて - + Version %1 - + Authors: 著者: - + Translators: 翻訳者: - + Spanish: スペイン語: - + Portugese (Portugal): ポルトガル語(ポルトガル): - + Portugese (Brazil): ポルトガル語(ブラジル): - + French: フランス語: - + Japanese: 日本語: - + Russian: ロシア語: - + Czech: - + Slovak: - - + - - + + + Error エラー - + Server timeout サーバータイムアウト - + Invalid login data. 無効なログインデータです. - + There is already an active session using this user name. Please close that session first and re-login. これはすでにこのユーザー名で使われているアクティブなセッションです. まずこのセッションを閉じてログインしなおしてください. - + Socket error: %1 ソケットエラー: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. あなたは古いVerのサーバーに接続しようとしています.CockatriceのVerをダウングレードするか適正なサーバーに接続してください. ローカルVer %1,リモートVer %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. あなたのCockatriceのVerが古いです.Cockatriceをアップデートしてください. ローカルVer %1,リモートVer %2. - + Connecting to %1... %1へ接続しています... - + Disconnected 切断されました - + Logged in at %1 %1にログイン中 - + &Connect... 接続... - + &Disconnect 切断 - + Start &local game... ローカルゲームを開始... - + &Deck editor デッキエディター - + &Full screen フルスクリーン - + Ctrl+F - + &Settings... 設定... - + &Exit 終了 - + &Cockatrice - + &About Cockatrice - + &Help ヘルプ - + Are you sure? よろしいですか? - + There are still open games. Are you sure you want to quit? ゲームがまだ開いています.本当に退出しますか? @@ -1664,266 +1739,947 @@ Local version is %1, remote version is %2. MessageLogWidget - - Connecting to %1... - - - - - Disconnected from server. - - - - - Invalid password. - - - - - Protocol error. - - - - + The game has been closed. - + %1 is now watching the game. - + %1 is not watching the game any more. - - %1 is not ready to start the game any more. - - - - - %1 shuffles %2. + + You have joined game #%1. + female - + + You have joined game #%1. + male + + + + + %1 has joined the game. + female + + + + + %1 has joined the game. + male + + + + + %1 has left the game. + female + + + + + %1 has left the game. + male + + + + + %1 has loaded a local deck. + female + + + + + %1 has loaded a local deck. + male + + + + + %1 has loaded deck #%2. + female + + + + + %1 has loaded deck #%2. + male + + + + + %1 is ready to start the game. + female + + + + + %1 is ready to start the game. + male + + + + + %1 is not ready to start the game any more. + female + + + + + %1 is not ready to start the game any more. + male + + + + + %1 has conceded the game. + female + + + + + %1 has conceded the game. + male + + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + %1 rolls a %2 with a %3-sided die. - + female + + + + + %1 rolls a %2 with a %3-sided die. + male + - + %1 draws %n card(s). - + female + + + + + + + %1 draws %n card(s). + male + - + %1 undoes his last draw. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). - + %1 undoes her last draw (%2). - + from table - + from graveyard - + from exile - + from hand - + the bottom card of his library - + the bottom card of her library - + from the bottom of his library - + from the bottom of her library - + the top card of his library - + the top card of her library - + from the top of his library - + from the top of her library - + from library - + from sideboard - + from the stack - + %1 gives %2 control over %3. - + %1 puts %2 into play tapped%3. - + %1 puts %2 into play%3. - + %1 puts %2%3 into graveyard. - + %1 exiles %2%3. - + %1 moves %2%3 to hand. - + %1 puts %2%3 into his library. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. - + %1 plays %2%3. - - - - a card - + + + %1 takes a mulligan to %n. + female + + + + + + + %1 takes a mulligan to %n. + male + + + - + %1 flips %2 face-down. - + female + - + + %1 flips %2 face-down. + male + + + + %1 flips %2 face-up. - + female + - - %1 attaches %2 to %3's %4. - + + %1 flips %2 face-up. + male + - + + %1 destroys %2. + female + + + + + %1 destroys %2. + male + + + + %1 unattaches %2. - + female + - + + %1 unattaches %2. + male + + + + + %1 creates token: %2%3. + female + + + + + %1 creates token: %2%3. + male + + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + + + + + %1 places %n %2 counter(s) on %3 (now %4). + female + + + + + + + %1 places %n %2 counter(s) on %3 (now %4). + male + + + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + + + + + %1 sets counter %2 to %3 (%4%5). + male + + + + + %1 sets %2 to not untap normally. + female + + + + + %1 sets %2 to not untap normally. + male + + + + + %1 sets %2 to untap normally. + female + + + + + %1 sets %2 to untap normally. + male + + + + + %1 sets PT of %2 to %3. + female + + + + + %1 sets PT of %2 to %3. + male + + + + + %1 sets annotation of %2 to %3. + female + + + + + %1 sets annotation of %2 to %3. + male + + + + + %1 is looking at the top %2 cards %3. + female + + + + + %1 is looking at the top %2 cards %3. + male + + + + + %1 is looking at %2. + female + + + + + %1 is looking at %2. + male + + + + + %1 stops looking at %2. + female + + + + + %1 stops looking at %2. + male + + + + + %1 reveals %2 to %3. + p1 female, p2 female + + + + + %1 reveals %2 to %3. + p1 female, p2 male + + + + + %1 reveals %2 to %3. + p1 male, p2 female + + + + + %1 reveals %2 to %3. + p1 male, p2 male + + + + + %1 reveals %2. + female + + + + + %1 reveals %2. + male + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 randomly reveals %2%3. + female + + + + + %1 randomly reveals %2%3. + male + + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 reveals %2%3. + female + + + + + %1 reveals %2%3. + male + + + + + It is now %1's turn. + female + + + + + It is now %1's turn. + male + + + + + + a card @@ -1939,302 +2695,145 @@ Local version is %1, remote version is %2. - + red - + yellow - + green - - %1 sets counter %2 to %3 (%4%5). - - - - - %1 sets PT of %2 to %3. - - - - - %1 sets annotation of %2 to %3. - - - - - %1 is looking at the top %2 cards %3. - - - - + The game has started. - - Connected. - - - - - Protocol version mismatch. Client: %1, Server: %2 - - - - - You have joined game #%1. - - - - - %1 has joined the game. - - - - - %1 has left the game. - - - - - %1 has loaded a local deck. - - - - - %1 has loaded deck #%2. - - - - - %1 is ready to start the game. - - - - - %1 has conceded the game. - - - - - %1 takes a mulligan to %n. - - - - - - + %1 draws his initial hand. - + %1 draws her initial hand. - - %1 destroys %2. - - - - - %1 creates token: %2%3. - - - - - %1 points from %2's %3 to %4. - - - - - %1 places %n %2 counter(s) on %3 (now %4). - - - - - - - %1 removes %n %2 counter(s) from %3 (now %4). - - - - - - - her permanents - - - - - %1 %2 %3. - - - - - %1 is looking at %2. - - - - - %1 stops looking at %2. - - - - - %1 reveals %2 to %3. - - - - - %1 reveals %2. - - - - + ending phase - - It is now %1's turn. - - - - - %1 randomly reveals %2%3 to %4. - - - - - %1 randomly reveals %2%3. - - - - - %1 reveals %2%3 to %4. - - - - - %1 reveals %2%3. - - - - + untap step - + + %1 attaches %2 to %3's %4. + p1 female, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + + + + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + It is now the %1. - - - taps - - - - - untaps - - - - - %1 sets %2 to not untap normally. - - - - - %1 sets %2 to untap normally. - - - - - his permanents - - MessagesSettingsPage - + &Add 追加 - + &Remove 削除 - + Add message メッセージを追加する - + Message: メッセージ: @@ -2570,7 +3169,7 @@ Local version is %1, remote version is %2. - + Number: 枚数 @@ -2595,27 +3194,27 @@ Local version is %1, remote version is %2. 面の数: - + Set power/toughness パワーとタフネスを設定する - + Please enter the new PT: 新しいP/Tを入力してください - + Set annotation 補足を付ける - + Please enter the new annotation: 新しい補足を付けてください - + Set counters カウンターを設定する @@ -2779,40 +3378,73 @@ Local version is %1, remote version is %2. 正式名称 + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + + + + + &Cancel + + + + + Shut down server + + + TabAdmin - + Update server &message サーバー更新&メッセージ - + + &Shut down server + + + + Server administration functions サーバー管理機能 - + &Unlock functions 機能をアンロックする - + &Lock functions 機能をロックする - + Unlock administration functions 管理機能をアンロックする - + Do you really want to unlock the administration functions? 本当に管理機能をアンロックしますか? - + Administration 管理者 @@ -2906,137 +3538,137 @@ Please enter a name: TabGame - + F5 - + F6 - + F7 - + F8 - + F9 - + F10 - + &Phases フェイズ - + &Game ゲーム - + Next &phase 次のフェイズ - + Ctrl+Space - + Next &turn 次のターン - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows 全ての矢印を消す - + Ctrl+R - + &Concede 投了する - + F2 - + &Leave game ゲームを退出する - + Ctrl+Q - + &Say: 発言する - + Concede 投了する - + Are you sure you want to concede this game? 本当にこのゲームに投了しますか? - + Leave game ゲームから退出する - + Are you sure you want to leave this game? 本当にこのゲームから退出しますか? - + Kicked キック - + You have been kicked out of the game. あなたはこのゲームからキックされました. - + Game %1: %2 ゲーム %1: %2 @@ -3044,27 +3676,27 @@ Please enter a name: TabMessage - + Personal &talk 個人会話 - + &Leave 退出する - + This user is ignoring you. このユーザーはあなたを無視しています. - + %1 has left the server. %1はサーバーから退出しました. - + %1 has joined the server. %1がサーバーに参加しました. @@ -3077,27 +3709,27 @@ Please enter a name: TabRoom - + &Say: 発言する - + Chat チャット - + &Room 部屋 - + &Leave room 部屋から出る - + You are flooding the chat. Please wait a couple of seconds. あなたはチャットルームから弾かれました.少々お待ちください. @@ -3181,37 +3813,37 @@ Please enter a name: UserInterfaceSettingsPage - + General interface settings インターフェース総合設定 - + &Double-click cards to play them (instead of single-click) ダブルクリックでカードをプレイする(シングルクリックの代わり) - + Animation settings アニメーション設定 - + &Tap/untap animation タップ/アンタップアニメーション - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3219,70 +3851,78 @@ Please enter a name: UserList - + Users online: %1 ユーザー オンライン: %1 - + Users in this room: %1 部屋のユーザー数: %1 - + Buddies online: %1 / %2 フレンドオンライン: %1 / %2 - + Ignored users online: %1 / %2 無視ユーザーオンライン: %1 / %2 - + + %1's games + + + + User &details ユーザー補足 - + Direct &chat 個人チャット - + + Show this user's &games + + + + Add to &buddy list フレンドリストに追加 - + Remove from &buddy list フレンドリストから削除 - + Add to &ignore list 無視リストに追加 - + Remove from &ignore list 無視リストから削除 - + Ban from &server サーバーからバンする - Duration - 期間 + 期間 - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - バンする期間を入力してください(分単位).0でバンを解除します. + バンする期間を入力してください(分単位).0でバンを解除します. diff --git a/cockatrice/translations/cockatrice_pl.ts b/cockatrice/translations/cockatrice_pl.ts index bdaa8263..f13d9e82 100644 --- a/cockatrice/translations/cockatrice_pl.ts +++ b/cockatrice/translations/cockatrice_pl.ts @@ -37,90 +37,125 @@ AppearanceSettingsPage - + Zone background pictures - + Path to hand background: - + Path to stack background: - + Path to table background: - + Path to player info background: - + Path to picture of card back: - + Card rendering - + Display card names on cards having a picture - + Hand layout - + Display hand horizontally (wastes space) - + Table grid layout - + Invert vertical coordinate - + + Minimum player count for multi-column layout: + + + + Zone view layout - + Sort by name - + Sort by type - - - - - + + + + + Choose path + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + + + + + &Cancel + + + + + Ban user from server + + + CardDatabaseModel @@ -195,197 +230,202 @@ CardItem - + &Play - + &Hide - + &Tap - + &Untap - + Toggle &normal untapping - + &Flip - + &Clone - + Ctrl+H - + &Attach to card... - + Ctrl+A - + Unattac&h - - - &Power / toughness - - - - - &Increase power - - - - - Ctrl++ - - - - - &Decrease power - - - - - Ctrl+- - - - - - I&ncrease toughness - - - Alt++ + &Draw arrow... - D&ecrease toughness + &Power / toughness - Alt+- + &Increase power - In&crease power and toughness + Ctrl++ - Ctrl+Alt++ + &Decrease power - Dec&rease power and toughness + Ctrl+- - Ctrl+Alt+- + I&ncrease toughness - Set &power and toughness... + Alt++ - Ctrl+P + D&ecrease toughness - &Set annotation... + Alt+- + + + + + In&crease power and toughness - red + Ctrl+Alt++ - yellow + Dec&rease power and toughness - green + Ctrl+Alt+- + + + + + Set &power and toughness... - &Add counter (%1) + Ctrl+P - - &Remove counter (%1) + + &Set annotation... + + + + + red - &Set counters (%1)... + yellow - &top of library - - - - - &bottom of library + green - &graveyard - - - - - Ctrl+Del + &Add counter (%1) - &exile + &Remove counter (%1) + &Set counters (%1)... + + + + + &top of library + + + + + &bottom of library + + + + + &graveyard + + + + + Ctrl+Del + + + + + &exile + + + + &Move to @@ -756,12 +796,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General @@ -787,22 +827,22 @@ DeckViewContainer - + Load &local deck - + Load d&eck from server - + Ready to s&tart - + Load deck @@ -891,82 +931,82 @@ - + P&layers: - + Game type - + &Password: - + Only &buddies can join - + Only &registered users can join - + Joining restrictions - + &Spectators allowed - + Spectators &need a password to join - + Spectators can &chat - + Spectators see &everything - + Spectators - + &OK - + &Cancel - + Create game - + Error - + Server error. @@ -1108,59 +1148,59 @@ DlgSettings - - - + + + Error - + Your card database is invalid. Would you like to go back and set the correct path? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + General - + Appearance - + User interface - + Deck editor - + Messages - + &Close @@ -1168,83 +1208,94 @@ GameSelector - - - - - - - + + + + + + + + Error - + + Please join the appropriate room first. + + + + Wrong password. - + Spectators are not allowed in this game. - + The game is already full. - + The game does not exist any more. - + This game is only open to registered users. - + This game is only open to its creator's buddies. - + You are being ignored by the creator of this game. - + Join game - + Password: - + Games - + Show &full games - + + Show &running games + + + + C&reate - + &Join - + J&oin as spectator @@ -1260,67 +1311,72 @@ GamesModel - + yes - + yes, free for spectators - + no - + buddies only - + reg. users only - + not allowed - - - Description - - - - - Creator - - - Game type + Room - Password + Description - Restrictions + Creator - Players + Game type + Password + + + + + Restrictions + + + + + Players + + + + Spectators @@ -1328,50 +1384,50 @@ GeneralSettingsPage - - + + English - - - + + + Choose path - + Personal settings - + Language: - + Download card pictures on the fly - + Paths - + Decks directory: - + Pictures directory: - + Path to card database: @@ -1390,216 +1446,237 @@ + Scheduled server shutdown. + + + + Unknown reason. - + Connection closed - + The server has terminated your connection. Reason: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + + Number of players - + Please enter the number of players. - - + + Player %1 - + About Cockatrice - + Version %1 - + Authors: - + Translators: - + Spanish: - + Portugese (Portugal): - + Portugese (Brazil): - + French: - + Japanese: - + Russian: - + Czech: - + Slovak: - - + - - + + + Error - + Server timeout - + Invalid login data. - + There is already an active session using this user name. Please close that session first and re-login. - + Socket error: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. - + Connecting to %1... - + Disconnected - + Logged in at %1 - + &Connect... - + &Disconnect - + Start &local game... - + &Deck editor - + &Full screen - + Ctrl+F - + &Settings... - + &Exit - + &Cockatrice - + &About Cockatrice - + &Help - + Are you sure? - + There are still open games. Are you sure you want to quit? @@ -1607,108 +1684,183 @@ Local version is %1, remote version is %2. MessageLogWidget - - Connecting to %1... - - - - - Connected. - - - - - Disconnected from server. - - - - - Invalid password. - - - - - Protocol version mismatch. Client: %1, Server: %2 - - - - - Protocol error. - - - - - You have joined game #%1. - - - - - %1 has joined the game. - - - - - %1 has left the game. - - - - + The game has been closed. - + %1 is now watching the game. - + %1 is not watching the game any more. - - - %1 has loaded a local deck. - - - - - %1 has loaded deck #%2. - - - %1 is ready to start the game. - - - - - %1 is not ready to start the game any more. - - - - - %1 has conceded the game. - - - - The game has started. - - %1 shuffles %2. + + You have joined game #%1. + female - + + You have joined game #%1. + male + + + + + %1 has joined the game. + female + + + + + %1 has joined the game. + male + + + + + %1 has left the game. + female + + + + + %1 has left the game. + male + + + + + %1 has loaded a local deck. + female + + + + + %1 has loaded a local deck. + male + + + + + %1 has loaded deck #%2. + female + + + + + %1 has loaded deck #%2. + male + + + + + %1 is ready to start the game. + female + + + + + %1 is ready to start the game. + male + + + + + %1 is not ready to start the game any more. + female + + + + + %1 is not ready to start the game any more. + male + + + + + %1 has conceded the game. + female + + + + + %1 has conceded the game. + male + + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + %1 rolls a %2 with a %3-sided die. + female + + + + + %1 rolls a %2 with a %3-sided die. + male - + %1 draws %n card(s). + female + + + + + + + + + %1 draws %n card(s). + male @@ -1716,189 +1868,200 @@ Local version is %1, remote version is %2. - + %1 undoes his last draw. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). - + %1 undoes her last draw (%2). - + from table - + from graveyard - + from exile - + from hand - + the bottom card of his library - + the bottom card of her library - + from the bottom of his library - + from the bottom of her library - + the top card of his library - + the top card of her library - + from the top of his library - + from the top of her library - + from library - + from sideboard - + from the stack - - + + a card - + %1 gives %2 control over %3. - + %1 puts %2 into play tapped%3. - + %1 puts %2 into play%3. - + %1 puts %2%3 into graveyard. - + %1 exiles %2%3. - + %1 moves %2%3 to hand. - + %1 puts %2%3 into his library. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. - + %1 plays %2%3. - + %1 takes a mulligan to %n. + female + + + + + + + + + %1 takes a mulligan to %n. + male @@ -1906,58 +2069,285 @@ Local version is %1, remote version is %2. - - %1 draws his initial hand. - - - - - %1 draws her initial hand. - - - - + %1 flips %2 face-down. + female - + + %1 flips %2 face-down. + male + + + + %1 flips %2 face-up. + female - - %1 destroys %2. - - - - - %1 attaches %2 to %3's %4. - - - - - %1 unattaches %2. - - - - - %1 creates token: %2%3. + + %1 flips %2 face-up. + male - %1 points from %2's %3 to %4. + %1 destroys %2. + female - + + %1 destroys %2. + male + + + + + %1 unattaches %2. + female + + + + + %1 unattaches %2. + male + + + + + %1 creates token: %2%3. + female + + + + + %1 creates token: %2%3. + male + + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male - + %1 places %n %2 counter(s) on %3 (now %4). + female @@ -1965,8 +2355,19 @@ Local version is %1, remote version is %2. - + + %1 places %n %2 counter(s) on %3 (now %4). + male + + + + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female @@ -1974,7 +2375,315 @@ Local version is %1, remote version is %2. - + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + + + + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + + + + + %1 sets counter %2 to %3 (%4%5). + male + + + + + %1 sets %2 to not untap normally. + female + + + + + %1 sets %2 to not untap normally. + male + + + + + %1 sets %2 to untap normally. + female + + + + + %1 sets %2 to untap normally. + male + + + + + %1 sets PT of %2 to %3. + female + + + + + %1 sets PT of %2 to %3. + male + + + + + %1 sets annotation of %2 to %3. + female + + + + + %1 sets annotation of %2 to %3. + male + + + + + %1 is looking at the top %2 cards %3. + female + + + + + %1 is looking at the top %2 cards %3. + male + + + + + %1 is looking at %2. + female + + + + + %1 is looking at %2. + male + + + + + %1 stops looking at %2. + female + + + + + %1 stops looking at %2. + male + + + + + %1 reveals %2 to %3. + p1 female, p2 female + + + + + %1 reveals %2 to %3. + p1 female, p2 male + + + + + %1 reveals %2 to %3. + p1 male, p2 female + + + + + %1 reveals %2 to %3. + p1 male, p2 male + + + + + %1 reveals %2. + female + + + + + %1 reveals %2. + male + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 randomly reveals %2%3. + female + + + + + %1 randomly reveals %2%3. + male + + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 reveals %2%3. + female + + + + + %1 reveals %2%3. + male + + + + + It is now %1's turn. + female + + + + + It is now %1's turn. + male + + + + + %1 draws his initial hand. + + + + + %1 draws her initial hand. + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + + + + red @@ -1983,7 +2692,7 @@ Local version is %1, remote version is %2. - + yellow @@ -1992,7 +2701,7 @@ Local version is %1, remote version is %2. - + green @@ -2001,162 +2710,62 @@ Local version is %1, remote version is %2. - - his permanents - - - - - her permanents - - - - - %1 %2 %3. - - - - - taps - - - - - untaps - - - - - %1 sets counter %2 to %3 (%4%5). - - - - - %1 sets %2 to not untap normally. - - - - - %1 sets %2 to untap normally. - - - - - %1 sets PT of %2 to %3. - - - - - %1 sets annotation of %2 to %3. - - - - - %1 is looking at the top %2 cards %3. - - - - - %1 is looking at %2. - - - - - %1 stops looking at %2. - - - - - %1 reveals %2 to %3. - - - - - %1 reveals %2. - - - - - %1 randomly reveals %2%3 to %4. - - - - - %1 randomly reveals %2%3. - - - - - %1 reveals %2%3 to %4. - - - - - %1 reveals %2%3. - - - - - It is now %1's turn. - - - - + untap step - + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + ending phase - + It is now the %1. @@ -2164,22 +2773,22 @@ Local version is %1, remote version is %2. MessagesSettingsPage - + Add message - + Message: - + &Add - + &Remove @@ -2515,7 +3124,7 @@ Local version is %1, remote version is %2. - + Number: @@ -2540,27 +3149,27 @@ Local version is %1, remote version is %2. - + Set power/toughness - + Please enter the new PT: - + Set annotation - + Please enter the new annotation: - + Set counters @@ -2705,40 +3314,73 @@ Local version is %1, remote version is %2. + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + + + + + &Cancel + + + + + Shut down server + + + TabAdmin - + Update server &message - + + &Shut down server + + + + Server administration functions - + &Unlock functions - + &Lock functions - + Unlock administration functions - + Do you really want to unlock the administration functions? - + Administration @@ -2813,137 +3455,137 @@ Please enter a name: TabGame - + F5 - + F6 - + F7 - + F8 - + F9 - + F10 - + &Phases - + &Game - + Next &phase - + Ctrl+Space - + Next &turn - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows - + Ctrl+R - + &Concede - + F2 - + &Leave game - + Ctrl+Q - + &Say: - + Concede - + Are you sure you want to concede this game? - + Leave game - + Are you sure you want to leave this game? - + Kicked - + You have been kicked out of the game. - + Game %1: %2 @@ -2951,27 +3593,27 @@ Please enter a name: TabMessage - + Personal &talk - + &Leave - + This user is ignoring you. - + %1 has left the server. - + %1 has joined the server. @@ -2984,27 +3626,27 @@ Please enter a name: TabRoom - + &Say: - + Chat - + &Room - + &Leave room - + You are flooding the chat. Please wait a couple of seconds. @@ -3076,37 +3718,37 @@ Please enter a name: UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + Animation settings - + &Tap/untap animation - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3114,71 +3756,70 @@ Please enter a name: UserList - + Users online: %1 - + Users in this room: %1 - + Buddies online: %1 / %2 - + Ignored users online: %1 / %2 - + + %1's games + + + + User &details - + Direct &chat - + + Show this user's &games + + + + Add to &buddy list - + Remove from &buddy list - + Add to &ignore list - + Remove from &ignore list - + Ban from &server - - - Duration - - - - - Please enter the duration of the ban (in minutes). -Enter 0 for an indefinite ban. - - WndDeckEditor diff --git a/cockatrice/translations/cockatrice_pt-br.ts b/cockatrice/translations/cockatrice_pt-br.ts index c0549f8d..9c018f04 100644 --- a/cockatrice/translations/cockatrice_pt-br.ts +++ b/cockatrice/translations/cockatrice_pt-br.ts @@ -37,57 +37,57 @@ AppearanceSettingsPage - + Zone background pictures Imagens de fundo das zonas - + Path to hand background: Caminho para o fundo da mão: - + Path to stack background: Caminho para o fundo da pilha: - + Path to table background: Caminho para o fundo da mesa: - + Path to player info background: Caminho para o fundo das informações do jogador: - + Path to picture of card back: Caminho para a imagem do verso dos cards: - + Card rendering Renderização do card - + Display card names on cards having a picture Mostrar o nome dos cards nos cards que tem imagem - + Hand layout Layout da mão - + Display hand horizontally (wastes space) Mostrar a mão na horizontal (desperdiça espaço) - + Table grid layout Layout do campo de batalha @@ -96,35 +96,71 @@ Layout econômico - + Invert vertical coordinate Inverter a coordenada vertical - + + Minimum player count for multi-column layout: + + + + Zone view layout Layout de vista da zona - + Sort by name Ordenar por nome - + Sort by type Ordenar por tipo - - - - - + + + + + Choose path Escolher caminho + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + Por favor, digite a duração do banimento (em minutos). +Digite 0 para banir indefinidamente. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + &OK + + + + &Cancel + &Cancelar + + + + Ban user from server + + + CardDatabaseModel @@ -199,57 +235,57 @@ CardItem - + &Play &Jogar - + &Hide &Ocultar - + &Tap &Virar - + &Untap &Desvirar - + Toggle &normal untapping &Trocar o modo de desvirar - + &Flip Virar a &face - + &Clone Clo&nar - + Ctrl+H Ctrl+H - + &Attach to card... Ane&xar ao card... - + Ctrl+A Ctrl+A - + Unattac&h De&sanexar @@ -258,142 +294,147 @@ Alterar &P/R... - + + &Draw arrow... + + + + &Power / toughness Po&der / resistência - + &Increase power Au&mentar poder - + Ctrl++ Ctrl++ - + &Decrease power Dimi&nuir poder - + Ctrl+- Ctrl+- - + I&ncrease toughness A&umentar resistência - + Alt++ Alt++ - + D&ecrease toughness D&iminuir resistência - + Alt+- Alt+- - + In&crease power and toughness Aumen&tar poder e resistência - + Ctrl+Alt++ Ctrl+Alt++ - + Dec&rease power and toughness Diminuir p&oder e resistência - + Ctrl+Alt+- Ctrl+Alt+- - + Set &power and toughness... Alterar poder e resis&tência... - + Ctrl+P Ctrl+P - + &Set annotation... Alterar &nota... - + red vermelho - + yellow amarelo - + green verde - + &Add counter (%1) Adicionar &marcador (%1) - + &Remove counter (%1) &Remover marcador (%1) - + &Set counters (%1)... &Alterar marcadores (%1)... - + &top of library topo do &grimório - + &bottom of library &fundo do grimório - + &graveyard &cemitério - + Ctrl+Del Ctrl+Del - + &exile &exílio - + &Move to Mo&ver para @@ -964,12 +1005,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General Geral @@ -995,22 +1036,22 @@ DeckViewContainer - + Load &local deck Carregar dec&k local - + Load d&eck from server Carregar deck do &servidor - + Ready to s&tart &Pronto para começar - + Load deck Carregar deck @@ -1106,82 +1147,82 @@ &Descrição: - + &Password: S&enha: - + P&layers: &Jogadores: - + Game type Tipo de jogo - + Only &buddies can join Apenas ami&gos podem entrar - + Only &registered users can join Apenas usuários re&gistrados podem entrar - + Joining restrictions Restrições para entrar - + &Spectators allowed &Permitir visitantes - + Spectators &need a password to join Visitantes &precisam de senha para entrar - + Spectators can &chat Visitantes podem c&onversar - + Spectators see &everything Visitantes podem ver &tudo - + Spectators Visitantes - + &OK &OK - + &Cancel &Cancelar - + Create game Criar jogo - + Error Erro - + Server error. Erro do servidor. @@ -1323,59 +1364,59 @@ DlgSettings - - - + + + Error Erro - + Your card database is invalid. Would you like to go back and set the correct path? O seu banco de dados de cards é inválido. Você gostaria de voltar e corrigir o caminho? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? O caminho para a sua pasta de decks é inválido. Você gostaria de voltar e corrigir o caminho? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? O caminho para a sua pasta de imagens de cards é inválido. Você gostaria de voltar e corrigir o caminho? - + Settings Configurações - + General Geral - + Appearance Aparência - + User interface Interface do usuário - + Deck editor - + Messages Mensagens - + &Close &Fechar @@ -1383,87 +1424,98 @@ GameSelector - + C&reate &Criar - + &Join &Entrar - - - - - - - + + + + + + + + Error Erro - + + Please join the appropriate room first. + + + + Wrong password. Senha incorreta. - + Spectators are not allowed in this game. Não são permitidos visitantes neste jogo. - + The game is already full. O jogo está cheio. - + The game does not exist any more. O jogo não existe mais. - + This game is only open to registered users. Este jogo é aberto apenas para usuários registrados. - + This game is only open to its creator's buddies. Este jogo é aberto apenas para os amigos de quem criou o jogo. - + You are being ignored by the creator of this game. Você está sendo ignorado pelo criador deste jogo. - + Join game Entrar no jogo - + Password: Senha: - + Games Jogos - + Show &full games &Mostrar os jogos cheios + + + Show &running games + + &Show full games &Mostrar os jogos cheios - + J&oin as spectator E&ntrar como visitante @@ -1479,67 +1531,72 @@ GamesModel - + yes sim - + no não - + Creator Criador - + Description Descrição - + yes, free for spectators sim, livre para visitantes - + buddies only apenas amigos - + reg. users only usuários reg. apenas - + not allowed não permitidos + Room + Sala + + + Game type Tipo de jogo - + Password Senha - + Restrictions Restrições - + Players Jogadores - + Spectators Visitantes @@ -1547,50 +1604,50 @@ GeneralSettingsPage - - - + + + Choose path Escolher caminho - + Personal settings Configurações pessoais - + Language: Língua: - + Download card pictures on the fly Baixar a imagem dos cards em tempo real - + Paths Caminhos - + Decks directory: Pasta de decks: - + Pictures directory: Pasta de imagens: - + Path to card database: Caminho para o banco de dados dos cards: - - + + English Português do Brasil @@ -1598,23 +1655,23 @@ MainWindow - + Number of players Número de jogadores - + Please enter the number of players. Por favor, entre o número de jogadores. - - + + Player %1 Jogador %1 - + About Cockatrice Sobre o Cockatrice @@ -1623,72 +1680,72 @@ <font size="8"><b>Cockatrice</b></font><br>Version %1<br><br><br><b>Authors:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Translators:</b><br>Spanish: Gocho<br>Portugese: Milton Gonçalves<br>Brazilian Portuguese: Thiago Queiroz<br> - + Version %1 Versão %1 - + Authors: Autores: - + Translators: Tradutores: - + Spanish: Espanhol: - + Portugese (Portugal): Português (Portugal): - + Portugese (Brazil): Português (Brasil): - + French: Francês: - + Japanese: Japonês: - + Russian: Russo: - - + - - + + + Error Erro - + Server timeout Tempo esgotado do servidor - + Invalid login data. Informações de login inválidas. - + Socket error: %1 Erro de ligação:%1 @@ -1708,129 +1765,149 @@ + Scheduled server shutdown. + + + + Unknown reason. Razão desconhecida. - + Connection closed Conexão fechada - + The server has terminated your connection. Reason: %1 O servidor terminou sua conexão. Razão: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + Czech: - + Slovak: - + There is already an active session using this user name. Please close that session first and re-login. Já existe uma sessão ativa usando este nome de usuário. Por favor, feche a sessão primeiro e logue novamente. - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. Você está tentando conectar a um servidor obsoleto. Por favor, faça um downgrade na versão do seu Cockatrice ou conecte-se ao servidor correto. A versão local é %1 e a versão remota é %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. A versão do seu Cockatrice é obsoleta. Por favor, atualize a sua versão. A versão local é %1 e a versão remota é %2. - + Connecting to %1... Conectando a %1... - + Disconnected Desconectado - + Logged in at %1 Logado em %1 - + &Connect... &Conectar... - + &Disconnect &Desconectar - + Start &local game... Iniciar jogo &local... - + &Deck editor Editor de &decks - + &Full screen Tela &cheia - + Ctrl+F Ctrl+F - + &Settings... &Configurações... - + &Exit &Sair - + &Cockatrice &Cockatrice - + &About Cockatrice So&bre o Cockatrice - + &Help &Ajuda - + Are you sure? Você tem certeza? - + There are still open games. Are you sure you want to quit? Ainda existem jogos abertos. Você tem certeza que deseja sair? @@ -1838,268 +1915,1041 @@ A versão local é %1 e a versão remota é %2. MessageLogWidget - Connecting to %1... - Conectando a %1... + Conectando a %1... - Disconnected from server. - Desconectado do servidor. + Desconectado do servidor. - Invalid password. - Senha incorreta. + Senha incorreta. - Protocol error. - Erro de protocolo. + Erro de protocolo. - + The game has been closed. O jogo foi fechado. - + %1 is now watching the game. %1 está assistindo o jogo agora. - + %1 is not watching the game any more. %1 não está mais assistindo o jogo. - %1 is not ready to start the game any more. - %1 não está mais pronto para começar o jogo. + %1 não está mais pronto para começar o jogo. - - %1 shuffles %2. - - - - %1 rolls a %2 with a %3-sided die. - %1 tirou um %2 com um dado de %3 lados. + %1 tirou um %2 com um dado de %3 lados. - %1 draws %n card(s). - + %1 compra %n card. %1 compra %n cards. - + + You have joined game #%1. + female + Você entrou no jogo nº %1. + + + + You have joined game #%1. + male + Você entrou no jogo nº %1. + + + + %1 has joined the game. + female + %1 entrou no jogo. + + + + %1 has joined the game. + male + %1 entrou no jogo. + + + + %1 has left the game. + female + %1 saiu do jogo. + + + + %1 has left the game. + male + %1 saiu do jogo. + + + + %1 has loaded a local deck. + female + %1 carregou um deck local. + + + + %1 has loaded a local deck. + male + %1 carregou um deck local. + + + + %1 has loaded deck #%2. + female + %1 carregou o deck nº %2. + + + + %1 has loaded deck #%2. + male + %1 carregou o deck nº %2. + + + + %1 is ready to start the game. + female + %1 está pronto para começar o jogo. + + + + %1 is ready to start the game. + male + %1 está pronto para começar o jogo. + + + + %1 is not ready to start the game any more. + female + %1 não está mais pronto para começar o jogo. + + + + %1 is not ready to start the game any more. + male + %1 não está mais pronto para começar o jogo. + + + + %1 has conceded the game. + female + %1 concedeu o jogo. + + + + %1 has conceded the game. + male + %1 concedeu o jogo. + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + + %1 rolls a %2 with a %3-sided die. + female + %1 tirou um %2 com um dado de %3 lados. + + + + %1 rolls a %2 with a %3-sided die. + male + %1 tirou um %2 com um dado de %3 lados. + + + + %1 draws %n card(s). + female + + %1 compra %n card. + %1 compra %n cards. + + + + + %1 draws %n card(s). + male + + %1 compra %n card. + %1 compra %n cards. + + + + %1 undoes his last draw. %1 desfaz sua última compra. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). %1 desfaz sua última compra (%2). - + %1 undoes her last draw (%2). - + from table vindo do campo de batalha - + from graveyard vindo do cemitério - + from exile vindo do exílio - + from hand vindo da mão - + the bottom card of his library o card do fundo do seu grimório - + the bottom card of her library - + from the bottom of his library vindo do fundo do seu grimório - + from the bottom of her library - + the top card of his library o card do topo do seu grimório - + the top card of her library - + from the top of his library vindo do topo do seu grimório - + from the top of her library - + from library vindo do grimório - + from sideboard vindo do sideboard - + from the stack vindo da pilha - + %1 gives %2 control over %3. %1 dá controle para %2 sobre %3. - + %1 puts %2 into play tapped%3. %1 põe %2 em jogo virado%3. - + %1 puts %2 into play%3. %1 põe %2 no campo de batalha %3. - + %1 puts %2%3 into graveyard. %1 põe %2 no cemitério%3. - + %1 exiles %2%3. %1 exila %2%3. - + %1 moves %2%3 to hand. %1 move %2 para a mão%3. - + %1 puts %2%3 into his library. %1 põe %2 no seu grimório%3. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. %1 põe %2 no fundo do seu grimório%3. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. %1 põe %2 no topo do seu grimório%3. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. %1 põe %2 no seu grimório na posição %4%3. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. %1 move %2 para o sideboard%3. - + %1 plays %2%3. %1 põe %2 na pilha%3. + + + %1 takes a mulligan to %n. + female + + + + + + + + %1 takes a mulligan to %n. + male + + + + + - - + + %1 flips %2 face-down. + female + %1 vira %2 para baixo. + + + + %1 flips %2 face-down. + male + %1 vira %2 para baixo. + + + + %1 flips %2 face-up. + female + %1 vira %2 para cima. + + + + %1 flips %2 face-up. + male + %1 vira %2 para cima. + + + + %1 destroys %2. + female + %1 destrói %2. + + + + %1 destroys %2. + male + %1 destrói %2. + + + %1 attaches %2 to %3's %4. + female + %1 anexa %2 a %4 de %3. + + + %1 attaches %2 to %3's %4. + male + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + %1 anexa %2 a %4 de %3. + + + + %1 unattaches %2. + female + %1 desanexa %2. + + + + %1 unattaches %2. + male + %1 desanexa %2. + + + + %1 creates token: %2%3. + female + %1 cria a ficha: %2%3. + + + + %1 creates token: %2%3. + male + %1 cria a ficha: %2%3. + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + %1 aponta para %4 com %3 de %2 . + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + %1 aponta para %4 com %3 de %2 . + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + %1 aponta para %5 de %4 com %3 de %2. + + + + %1 places %n %2 counter(s) on %3 (now %4). + female + + %1 põe %n marcador %2 em %3 (agora %4). + %1 põe %n marcadores %2 em %3 (agora %4). + + + + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 põe %n marcador %2 em %3 (agora %4). + %1 põe %n marcadores %2 em %3 (agora %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + %1 tira %n marcador %2 em %3 (agora %4). + %1 tira %n marcadores %2 em %3 (agora %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + %1 tira %n marcador %2 em %3 (agora %4). + %1 tira %n marcadores %2 em %3 (agora %4). + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + %1 altera o marcador %2 para %3 (%4%5). + + + + %1 sets counter %2 to %3 (%4%5). + male + %1 altera o marcador %2 para %3 (%4%5). + + + + %1 sets %2 to not untap normally. + female + %1 define que %2 não desvira normalmente. + + + + %1 sets %2 to not untap normally. + male + %1 define que %2 não desvira normalmente. + + + + %1 sets %2 to untap normally. + female + %1 define que %2 desvira normalmente. + + + + %1 sets %2 to untap normally. + male + %1 define que %2 desvira normalmente. + + + + %1 sets PT of %2 to %3. + female + %1 altera o P/R de %2 para %3. + + + + %1 sets PT of %2 to %3. + male + %1 altera o P/R de %2 para %3. + + + + %1 sets annotation of %2 to %3. + female + %1 altera a nota de %2 para%3. + + + + %1 sets annotation of %2 to %3. + male + %1 altera a nota de %2 para%3. + + + + %1 is looking at the top %2 cards %3. + female + %1 está olhando para os %2 cards do topo %3. + + + + %1 is looking at the top %2 cards %3. + male + %1 está olhando para os %2 cards do topo %3. + + + + %1 is looking at %2. + female + %1 está olhando para %2. + + + + %1 is looking at %2. + male + %1 está olhando para %2. + + + + %1 stops looking at %2. + female + %1 para de olhar para %2. + + + + %1 stops looking at %2. + male + %1 para de olhar para %2. + + + + %1 reveals %2 to %3. + p1 female, p2 female + %1 revela %2 para %3. + + + + %1 reveals %2 to %3. + p1 female, p2 male + %1 revela %2 para %3. + + + + %1 reveals %2 to %3. + p1 male, p2 female + %1 revela %2 para %3. + + + + %1 reveals %2 to %3. + p1 male, p2 male + %1 revela %2 para %3. + + + + %1 reveals %2. + female + %1 revela %2. + + + + %1 reveals %2. + male + %1 revela %2. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + %1 revela aleatoriamente %2%3. para %4. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + %1 revela aleatoriamente %2%3. para %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + %1 revela aleatoriamente %2%3. para %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + %1 revela aleatoriamente %2%3. para %4. + + + + %1 randomly reveals %2%3. + female + %1 revela aleatoriamente %2%3. + + + + %1 randomly reveals %2%3. + male + %1 revela aleatoriamente %2%3. + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + %1 revela %2%3 para %4. + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + %1 revela %2%3 para %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + %1 revela %2%3 para %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + %1 revela %2%3 para %4. + + + + %1 reveals %2%3. + female + %1 revela %2%3. + + + + %1 reveals %2%3. + male + %1 revela %2%3. + + + + It is now %1's turn. + female + Agora é o turno de %1. + + + + It is now %1's turn. + male + Agora é o turno de %1. + + + + a card um card - %1 flips %2 face-down. - %1 vira %2 para baixo. + %1 vira %2 para baixo. - %1 flips %2 face-up. - %1 vira %2 para cima. + %1 vira %2 para cima. - %1 attaches %2 to %3's %4. - %1 anexa %2 a %4 de %3. + %1 anexa %2 a %4 de %3. - %1 unattaches %2. - %1 desanexa %2. + %1 desanexa %2. - %1 points from %2's %3 to %4's %5. - %1 aponta para %5 de %4 com %3 de %2. + %1 aponta para %5 de %4 com %3 de %2. %1 places %n counter(s) (%2) on %3 (now %4). @@ -2116,7 +2966,7 @@ A versão local é %1 e a versão remota é %2. - + red vermelho @@ -2124,7 +2974,7 @@ A versão local é %1 e a versão remota é %2. - + yellow amarelo @@ -2132,7 +2982,7 @@ A versão local é %1 e a versão remota é %2. - + green verde @@ -2140,74 +2990,61 @@ A versão local é %1 e a versão remota é %2. - %1 sets counter %2 to %3 (%4%5). - %1 altera o marcador %2 para %3 (%4%5). + %1 altera o marcador %2 para %3 (%4%5). - %1 sets PT of %2 to %3. - %1 altera o P/R de %2 para %3. + %1 altera o P/R de %2 para %3. - %1 sets annotation of %2 to %3. - %1 altera a nota de %2 para%3. + %1 altera a nota de %2 para%3. - %1 is looking at the top %2 cards %3. - %1 está olhando para os %2 cards do topo %3. + %1 está olhando para os %2 cards do topo %3. - + The game has started. O jogo começou. - Connected. - Conectado. + Conectado. - Protocol version mismatch. Client: %1, Server: %2 - Versão dos protocolos incompatível. Versão do utilizador:%1, versão do servidor:%2 + Versão dos protocolos incompatível. Versão do utilizador:%1, versão do servidor:%2 - You have joined game #%1. - Você entrou no jogo nº %1. + Você entrou no jogo nº %1. - %1 has joined the game. - %1 entrou no jogo. + %1 entrou no jogo. - %1 has left the game. - %1 saiu do jogo. + %1 saiu do jogo. - %1 has loaded a local deck. - %1 carregou um deck local. + %1 carregou um deck local. - %1 has loaded deck #%2. - %1 carregou o deck nº %2. + %1 carregou o deck nº %2. - %1 is ready to start the game. - %1 está pronto para começar o jogo. + %1 está pronto para começar o jogo. - %1 has conceded the game. - %1 concedeu o jogo. + %1 concedeu o jogo. %1 draws a card. @@ -2218,218 +3055,185 @@ A versão local é %1 e a versão remota é %2. %1 compra %2 cards. - %1 destroys %2. - %1 destrói %2. + %1 destrói %2. - %1 creates token: %2%3. - %1 cria a ficha: %2%3. + %1 cria a ficha: %2%3. - %1 points from %2's %3 to %4. - %1 aponta para %4 com %3 de %2 . + %1 aponta para %4 com %3 de %2 . - %1 places %n %2 counter(s) on %3 (now %4). - + %1 põe %n marcador %2 em %3 (agora %4). %1 põe %n marcadores %2 em %3 (agora %4). - %1 removes %n %2 counter(s) from %3 (now %4). - + %1 tira %n marcador %2 em %3 (agora %4). %1 tira %n marcadores %2 em %3 (agora %4). - %1 %2 %3. - %1 %2 %3. + %1 %2 %3. - %1 is looking at %2. - %1 está olhando para %2. + %1 está olhando para %2. - %1 stops looking at %2. - %1 para de olhar para %2. + %1 para de olhar para %2. - %1 reveals %2 to %3. - %1 revela %2 para %3. + %1 revela %2 para %3. - %1 reveals %2. - %1 revela %2. + %1 revela %2. - + ending phase fase final - It is now %1's turn. - Agora é o turno de %1. + Agora é o turno de %1. %1 shuffles his library. %1 embaralha o seu grimório. - - - %1 takes a mulligan to %n. - - - - - - + %1 draws his initial hand. - + %1 draws her initial hand. - - her permanents - - - - %1 randomly reveals %2%3 to %4. - %1 revela aleatoriamente %2%3. para %4. + %1 revela aleatoriamente %2%3. para %4. - %1 randomly reveals %2%3. - %1 revela aleatoriamente %2%3. + %1 revela aleatoriamente %2%3. - %1 reveals %2%3 to %4. - %1 revela %2%3 para %4. + %1 revela %2%3 para %4. - %1 reveals %2%3. - %1 revela %2%3. + %1 revela %2%3. - + untap step etapa de desvirar - + upkeep step etapa de manutenção - + draw step etapa de compra - + first main phase primeira fase principal - + beginning of combat step etapa de início de combate - + declare attackers step etapa de declaracão de atacantes - + declare blockers step etapa de declaração de bloqueadores - + combat damage step etapa de dano de combate - + end of combat step etapa de fim de combate - + second main phase segunda fase principal - + It is now the %1. Agora é a %1. - taps - vira + vira - untaps - desvira + desvira - %1 sets %2 to not untap normally. - %1 define que %2 não desvira normalmente. + %1 define que %2 não desvira normalmente. - %1 sets %2 to untap normally. - %1 define que %2 desvira normalmente. + %1 define que %2 desvira normalmente. - his permanents - as suas permanentes + as suas permanentes MessagesSettingsPage - + &Add &Adicionar - + &Remove &Remover - + Add message Adicionar mensagem - + Message: Mensagem: @@ -2765,7 +3569,7 @@ A versão local é %1 e a versão remota é %2. - + Number: Número: @@ -2790,27 +3594,27 @@ A versão local é %1 e a versão remota é %2. Número de lados: - + Set power/toughness Alterar poder/resistência - + Please enter the new PT: Por favor, entre com o novo P/R: - + Set annotation Alterar nota - + Please enter the new annotation: Por favor, entre com a nova nota: - + Set counters Alterar marcadores @@ -2982,40 +3786,73 @@ A versão local é %1 e a versão remota é %2. Nome longo + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + &OK + + + + &Cancel + &Cancelar + + + + Shut down server + + + TabAdmin - + Update server &message &Atualizar mensagem do servidor - + + &Shut down server + + + + Server administration functions Funções do administrador do servidor - + &Unlock functions &Desbloquear funções - + &Lock functions &Bloquear funções - + Unlock administration functions Desbloquear funções do administrador - + Do you really want to unlock the administration functions? Você quer mesmo desbloquear as funções do administrador? - + Administration Administração @@ -3110,137 +3947,137 @@ Por favor, entre um nome: TabGame - + F5 F5 - + F6 F6 - + F7 F7 - + F8 F8 - + F9 F9 - + F10 F10 - + &Phases &Etapas - + &Game &Jogo - + Next &phase Próxima &etapa - + Ctrl+Space Ctrl+Espaço - + Next &turn Próximo &turno - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter - + &Remove all local arrows &Apagar todas as setas locais - + Ctrl+R Ctrl+R - + &Concede &Conceder - + F2 F2 - + &Leave game &Sair do jogo - + Ctrl+Q Ctrl+Q - + &Say: &Falar: - + Concede Conceder - + Are you sure you want to concede this game? Você tem certeza que deseja conceder este jogo? - + Leave game Sair do jogo - + Are you sure you want to leave this game? Você tem certeza que deseja sair deste jogo? - + Kicked Chutado - + You have been kicked out of the game. Você foi chutado do jogo. - + Game %1: %2 Jogo %1: %2 @@ -3248,27 +4085,27 @@ Por favor, entre um nome: TabMessage - + Personal &talk Chat &privado - + &Leave &Sair - + This user is ignoring you. Este usuário está ignorando você. - + %1 has left the server. %1 saiu do servidor. - + %1 has joined the server. %1 entrou no servidor. @@ -3281,27 +4118,27 @@ Por favor, entre um nome: TabRoom - + &Say: &Falar: - + Chat Chat - + &Room &Sala - + &Leave room S&air da sala - + You are flooding the chat. Please wait a couple of seconds. Você está flodando o chat. Por favor, espere alguns segundos. @@ -3385,37 +4222,37 @@ Por favor, entre um nome: UserInterfaceSettingsPage - + General interface settings Configurações gerais de interface - + &Double-click cards to play them (instead of single-click) &Duplo clique nos cards para jogá-los (ao invés de clique simples) - + Animation settings Configurações de animação - + &Tap/untap animation Animação de &virar/desvirar - + Enable &sounds - + Path to sounds directory: - + Choose path Escolher caminho @@ -3423,70 +4260,78 @@ Por favor, entre um nome: UserList - + Users online: %1 Usuários online: %1 - + Users in this room: %1 Usuários nesta sala: %1 - + Buddies online: %1 / %2 Amigos online: %1 / %2 - + Ignored users online: %1 / %2 Usuários ignorados online: %1 / %2 - + + %1's games + + + + User &details &Detalhes do usuário - + Direct &chat &Chat direto - + + Show this user's &games + + + + Add to &buddy list Adicionar à &lista de amigos - + Remove from &buddy list Remover da li&sta de amigos - + Add to &ignore list Adicionar à li&sta dos ignorados - + Remove from &ignore list Remover da lista dos i&gnorados - + Ban from &server Ban&ir do servidor - Duration - Duração + Duração - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Por favor, digite a duração do banimento (em minutos). + Por favor, digite a duração do banimento (em minutos). Digite 0 para banir indefinidamente. diff --git a/cockatrice/translations/cockatrice_pt.ts b/cockatrice/translations/cockatrice_pt.ts index 9b7dac82..db115aa2 100644 --- a/cockatrice/translations/cockatrice_pt.ts +++ b/cockatrice/translations/cockatrice_pt.ts @@ -37,57 +37,57 @@ AppearanceSettingsPage - + Zone background pictures Zona das imagens de fundo - + Path to hand background: Directório da imagem de fundo da mão: - + Path to stack background: Directório da imagem de fundo da pilha: - + Path to table background: Directório da imagem de fundo do campo de batalha: - + Path to player info background: Directório da imagem de fundo da informação de jogador: - + Path to picture of card back: Directório da imagem do verso da carta: - + Card rendering Rendering da carta - + Display card names on cards having a picture Mostrar o nome em cartas com imagem - + Hand layout Disposição da Mão - + Display hand horizontally (wastes space) Mostrar mão horizontalmente (desperdiça espaço) - + Table grid layout Esquema da mesa @@ -96,35 +96,71 @@ Esquema económico - + Invert vertical coordinate Inverter coordenada vertical - + + Minimum player count for multi-column layout: + + + + Zone view layout Distribuição da zona de vizualização - + Sort by name Ordenar por nome - + Sort by type Ordenar por tipo - - - - - + + + + + Choose path Escolher directório + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + Por favor introduza a duração do banimento (em minutos). +Introduza 0 para um banimento indefinido. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + + + + + &Cancel + &Cancelar + + + + Ban user from server + + + CardDatabaseModel @@ -199,57 +235,57 @@ CardItem - + &Play &Jogar - + &Hide Esco&nder - + &Tap &Virar - + &Untap Desv&irar - + Toggle &normal untapping A&lterar desvirar normalmente - + &Flip Vol&tar - + &Clone Copi&ar - + Ctrl+H Ctrl+H - + &Attach to card... Ane&xar a carta... - + Ctrl+A Ctrl+A - + Unattac&h De&sanexar @@ -258,142 +294,147 @@ Definir &P/R... - + + &Draw arrow... + + + + &Power / toughness &Poder / resistência - + &Increase power &Aumentar poder - + Ctrl++ Ctrl++ - + &Decrease power &Diminuir poder - + Ctrl+- Ctrl+- - + I&ncrease toughness A&umentar resistência - + Alt++ Alt++ - + D&ecrease toughness Di&minuir resistência - + Alt+- Alt+- - + In&crease power and toughness Aumen&tar poder e resistência - + Ctrl+Alt++ Ctrl+Alt++ - + Dec&rease power and toughness Dimin&uir poder e resistência - + Ctrl+Alt+- Ctrl+Alt+- - + Set &power and toughness... Definir &poder e resistência... - + Ctrl+P Ctrl+P - + &Set annotation... Colocar &nota... - + red vermelho - + yellow amarelo - + green verde - + &Add counter (%1) Adicionar &marcador (%1) - + &Remove counter (%1) &Remover marcador (%1) - + &Set counters (%1)... &Denifir marcadores (%1)... - + &top of library Topo do &grimório - + &bottom of library &Fundo do grimório - + &graveyard &Cemitério - + Ctrl+Del Ctrl+Del - + &exile &Exílio - + &Move to M&over para @@ -964,12 +1005,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General Geral @@ -995,22 +1036,22 @@ DeckViewContainer - + Load &local deck Carregar deck l&ocal - + Load d&eck from server Carregar deck do &servidor - + Ready to s&tart &Pronto para começar - + Load deck Carregar deck @@ -1106,82 +1147,82 @@ &Descrição: - + &Password: &Password: - + P&layers: &Jogadores: - + Game type Tipo de jogo - + Only &buddies can join Apenas &amigos podem entrar - + Only &registered users can join Apenas utilizadores &registados podem entrar - + Joining restrictions Restrições para ligar - + &Spectators allowed &Espectadores permitidos - + Spectators &need a password to join Espectadores &necessitam de password para aceder - + Spectators can &chat Espectadores podem c&onversar - + Spectators see &everything Espectadores podem ver &tudo - + Spectators Espectadores - + &OK O&K - + &Cancel &Cancelar - + Create game Criar jogo - + Error Erro - + Server error. Erro do servidor. @@ -1323,59 +1364,59 @@ DlgSettings - - - + + + Error Erro - + Your card database is invalid. Would you like to go back and set the correct path? A sua base de dados é inválida. Gostaria de voltar atrás e corrigir o directório? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? O directório do seu deck é inválido. Gostaria de voltar atrás e corrigir o directório? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? O directório das imagens das cartas é inválido. Gostaria de voltar atrás e corrigir o directório? - + Settings Definições - + General Geral - + Appearance Aparência - + User interface Interface do utilizador - + Deck editor - + Messages Mensagens - + &Close &Fechar @@ -1383,87 +1424,98 @@ GameSelector - - - - - - - + + + + + + + + Error Erro - + + Please join the appropriate room first. + + + + Wrong password. Password incorrecta. - + Spectators are not allowed in this game. Não são permitidos espectadores neste jogo. - + The game is already full. O jogo já se encontra cheio. - + The game does not exist any more. O jogo já não existe. - + This game is only open to registered users. Este jogo só está aberto a utilizadores registados. - + This game is only open to its creator's buddies. Este jogo só está aberto aos amigos do seu criador. - + You are being ignored by the creator of this game. Você está a ser ignorado pelo criador deste jogo. - + Join game Entrar no jogo - + Password: Password: - + Games Jogos - + Show &full games &Mostrar jogos cheios + + + Show &running games + + &Show full games &Mostrar jogos cheios - + C&reate &Criar - + &Join &Entrar - + J&oin as spectator Entrar como &espectador @@ -1479,67 +1531,72 @@ GamesModel - + yes sim - + yes, free for spectators sim, livre para espectadores - + no não - + buddies only amigos apenas - + reg. users only utilizadores registados apenas - + not allowed não permitidos - + + Room + Sala + + + Description Descrição - + Creator Criador - + Game type Tipo de jogo - + Password Password - + Restrictions Restrições - + Players Jogadores - + Spectators Espectadores @@ -1547,50 +1604,50 @@ GeneralSettingsPage - - + + English Português - - - + + + Choose path Escolher directório - + Personal settings Defenições pessoais - + Language: Língua: - + Download card pictures on the fly Baixar a imagem das cartas ao passar - + Paths Directórios - + Decks directory: Directório dos decks: - + Pictures directory: Directório das imagens: - + Path to card database: Directório da base de dados de cartas: @@ -1598,23 +1655,23 @@ MainWindow - + Number of players Número de jogadores - + Please enter the number of players. Por favor introduza o número de jogadores. - - + + Player %1 Jogador %1 - + About Cockatrice Sobre o Cockatrice @@ -1623,22 +1680,22 @@ <font size="8"><b>Cockatrice</b></font><br>Versão %1<br><br><br><b>Autores:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Tradutores:</b><br>Espanhol: Gocho<br>Português: Milton Gonçalves<br> - + Version %1 Versão %1 - + Authors: Autores: - + Translators: Tradutores: - + Spanish: Espanhol: @@ -1647,52 +1704,52 @@ Português: - + Portugese (Portugal): Português (Portugal): - + Portugese (Brazil): Português (Brasil): - + French: Francês: - + Japanese: Japonês: - + Russian: Russo: - - + - - + + + Error Erro - + Server timeout Tempo do servidor esgotado - + Invalid login data. Informação de login incorrecta. - + Socket error: %1 Erro de ligação:%1 @@ -1712,129 +1769,149 @@ + Scheduled server shutdown. + + + + Unknown reason. Razão desconhecida. - + Connection closed Ligação terminada - + The server has terminated your connection. Reason: %1 O servidor terminou a sua ligação. Motivo: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + Czech: - + Slovak: - + There is already an active session using this user name. Please close that session first and re-login. Já existe uma sessão activa com este nome de utilizador. Por favor termine essa sessão e volte a ligar-se. - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. Está a tentar ligar-se a um servidor obsoleto. Por favor faça downgrade à sua versão do Cockatrice ou ligue-se a servidor adequado. Versão local é %1, versão remota é %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. A sua versão do Cockatrice é obsoleta. Por favor actualize-a. Versão local é %1, versão remota é %2. - + Connecting to %1... Ligando a %1... - + Disconnected Desligado - + Logged in at %1 Logado em %1 - + &Connect... &Ligar... - + &Disconnect &Desligar - + Start &local game... Começar &jogo local... - + &Deck editor &Editor de decks - + &Full screen Ecrã &inteiro - + Ctrl+F Ctrl+F - + &Settings... &Configurações... - + &Exit &Sair - + &Cockatrice &Cockatrice - + &About Cockatrice S&obre o Cockatrice - + &Help &Ajuda - + Are you sure? Tens a certeza? - + There are still open games. Are you sure you want to quit? Ainda há jogos abertos. Tem a certeza que deseja sair? @@ -1842,92 +1919,78 @@ Versão local é %1, versão remota é %2. MessageLogWidget - Connecting to %1... - Ligando a %1... + Ligando a %1... - Connected. - Ligado. + Ligado. - Disconnected from server. - Desligado do servidor. + Desligado do servidor. - Invalid password. - Password incorrecto. + Password incorrecto. - Protocol version mismatch. Client: %1, Server: %2 - Versão dos protocolos incompatível. Versão do utilizador:%1, versão do servidor:%2 + Versão dos protocolos incompatível. Versão do utilizador:%1, versão do servidor:%2 - Protocol error. - Erro de protocolo. + Erro de protocolo. - You have joined game #%1. - Você entrou no jogo #%1. + Você entrou no jogo #%1. - %1 has joined the game. - %1 entrou no jogo. + %1 entrou no jogo. - %1 has left the game. - %1 abandonou o jogo. + %1 abandonou o jogo. - + The game has been closed. Este jogo foi encerrado. - + %1 is now watching the game. %1 está agora a ver o jogo. - + %1 is not watching the game any more. %1 já não está a ver o jogo. - %1 has loaded a local deck. - %1 carregou um deck local. + %1 carregou um deck local. - %1 has loaded deck #%2. - %1 carregou o deck #%2. + %1 carregou o deck #%2. + + + %1 is ready to start the game. + %1 está pronto a começar o jogo. + + + %1 is not ready to start the game any more. + %1 já não está pronto a começar o jogo. + + + %1 has conceded the game. + %1 concedeu o jogo. - %1 is ready to start the game. - %1 está pronto a começar o jogo. - - - - %1 is not ready to start the game any more. - %1 já não está pronto a começar o jogo. - - - - %1 has conceded the game. - %1 concedeu o jogo. - - - The game has started. O jogo começou. @@ -1936,9 +1999,8 @@ Versão local é %1, versão remota é %2. %1 baralha o grimório. - %1 rolls a %2 with a %3-sided die. - %1 obteve %2 com um dado de %3 faces. + %1 obteve %2 com um dado de %3 faces. %1 draws a card. @@ -1949,272 +2011,1038 @@ Versão local é %1, versão remota é %2. %1 compra %2 cartas. - + + You have joined game #%1. + female + Você entrou no jogo #%1. + + + + You have joined game #%1. + male + Você entrou no jogo #%1. + + + + %1 has joined the game. + female + %1 entrou no jogo. + + + + %1 has joined the game. + male + %1 entrou no jogo. + + + + %1 has left the game. + female + %1 abandonou o jogo. + + + + %1 has left the game. + male + %1 abandonou o jogo. + + + + %1 has loaded a local deck. + female + %1 carregou um deck local. + + + + %1 has loaded a local deck. + male + %1 carregou um deck local. + + + + %1 has loaded deck #%2. + female + %1 carregou o deck #%2. + + + + %1 has loaded deck #%2. + male + %1 carregou o deck #%2. + + + + %1 is ready to start the game. + female + %1 está pronto a começar o jogo. + + + + %1 is ready to start the game. + male + %1 está pronto a começar o jogo. + + + + %1 is not ready to start the game any more. + female + %1 já não está pronto a começar o jogo. + + + + %1 is not ready to start the game any more. + male + %1 já não está pronto a começar o jogo. + + + + %1 has conceded the game. + female + %1 concedeu o jogo. + + + + %1 has conceded the game. + male + %1 concedeu o jogo. + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + + %1 rolls a %2 with a %3-sided die. + female + %1 obteve %2 com um dado de %3 faces. + + + + %1 rolls a %2 with a %3-sided die. + male + %1 obteve %2 com um dado de %3 faces. + + + + %1 draws %n card(s). + female + + %1 compra %n carta. + %1 compra %n cartas. + + + + + %1 draws %n card(s). + male + + %1 compra %n carta. + %1 compra %n cartas. + + + + from table vindo da mesa - + from graveyard vindo do cemitério - + from exile vindo do exílio - + from hand vindo da mão - + the bottom card of his library a carta do fundo do seu grimório - + the bottom card of her library - + from the bottom of his library do fundo do seu grimório - + from the bottom of her library - + the top card of his library a carta do topo do seu grimório - + the top card of her library - + from the top of his library do topo do seu grimório - + from the top of her library - + from library do grimório - + from sideboard do sideboard - + from the stack da pilha - + %1 puts %2 into play tapped%3. %1 coloca %2 em jogo virado(a)%3. - + %1 puts %2 into play%3. %1 coloca %2 em jogo %3. - + %1 puts %2%3 into graveyard. %1 coloca %2%3 no cemitério. - + %1 exiles %2%3. %1 exila %2%3. - + %1 moves %2%3 to hand. %1 move %2%3 para a mão. - + %1 puts %2%3 into his library. %1 coloca %2%3 no seu grimório. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. %1 coloca %2%3 no fundo do seu grimório. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. %1 coloca %2%3 no topo do seu grimório. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. %1 coloca %2%3 no seu grimório na posição %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. %1 move %2%3 para o sideboard. - + %1 plays %2%3. %1 joga %2%3. - + %1 takes a mulligan to %n. + female + + + + + + + + %1 takes a mulligan to %n. + male - - %1 draws his initial hand. + + %1 flips %2 face-down. + female + %1 volta a face de %2 para baixo. + + + + %1 flips %2 face-down. + male + %1 volta a face de %2 para baixo. + + + + %1 flips %2 face-up. + female + %1 volta a face de %2 para cima. + + + + %1 flips %2 face-up. + male + %1 volta a face de %2 para cima. + + + + %1 destroys %2. + female + %1 destrói %2. + + + + %1 destroys %2. + male + %1 destrói %2. + + + %1 attaches %2 to %3's %4. + female + %1 anexa %2 a %4 de %3. + + + %1 attaches %2 to %3's %4. + male + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + %1 anexa %2 a %4 de %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + %1 anexa %2 a %4 de %3. + + + + %1 unattaches %2. + female + %1 desanexa %2. + + + + %1 unattaches %2. + male + %1 desanexa %2. + + + + %1 creates token: %2%3. + female + %1 cria ficha: %2%3. + + + + %1 creates token: %2%3. + male + %1 cria ficha: %2%3. + + + + %1 points from her %2 to herself. + female - - %1 draws her initial hand. + + %1 points from his %2 to himself. + male + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + %1 aponta de %3 de %2 para %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + %1 aponta de %3 de %2 para %4. + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + %1 aponta de %3 de %2 para %5 de %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + %1 aponta de %3 de %2 para %5 de %4. + - + %1 places %n %2 counter(s) on %3 (now %4). - + female + %1 coloca %n %2 marcador em %3 (agora com %4). %1 coloca %n %2 marcadores em %3 (agora com %4). - + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 coloca %n %2 marcador em %3 (agora com %4). + %1 coloca %n %2 marcadores em %3 (agora com %4). + + + + %1 removes %n %2 counter(s) from %3 (now %4). - + female + + %1 remove %n %2 marcador de %3 (agora com %4). + %1 remove %n %2 marcadores de %3 (agora com %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + %1 remove %n %2 marcador de %3 (agora com %4). %1 remove %n %2 marcadores de %3 (agora com %4). - - - a card - uma carta + + %1 taps her permanents. + female + - - %1 shuffles %2. + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + %1 altera o número de marcadores %2 para %3(%4%5). + + + + %1 sets counter %2 to %3 (%4%5). + male + %1 altera o número de marcadores %2 para %3(%4%5). + + + + %1 sets %2 to not untap normally. + female + %1 define %2 para não desvirar normalmente. + + + + %1 sets %2 to not untap normally. + male + %1 define %2 para não desvirar normalmente. + + + + %1 sets %2 to untap normally. + female + %1 define %2 para desvirar normalmente. + + + + %1 sets %2 to untap normally. + male + %1 define %2 para desvirar normalmente. + + + + %1 sets PT of %2 to %3. + female + %1 define o P/R de %2 como %3. + + + + %1 sets PT of %2 to %3. + male + %1 define o P/R de %2 como %3. + + + + %1 sets annotation of %2 to %3. + female + %1 coloca uma nota de %2 em%3. + + + + %1 sets annotation of %2 to %3. + male + %1 coloca uma nota de %2 em%3. + + + + %1 is looking at the top %2 cards %3. + female + %1 está a olhar para as %2 cartas do topo %3. + + + + %1 is looking at the top %2 cards %3. + male + %1 está a olhar para as %2 cartas do topo %3. + + + + %1 is looking at %2. + female + %1 está a olhar para %2. + + + + %1 is looking at %2. + male + %1 está a olhar para %2. + + + + %1 stops looking at %2. + female + %1 para de olhar para %2. + + + + %1 stops looking at %2. + male + %1 para de olhar para %2. + + + + %1 reveals %2 to %3. + p1 female, p2 female + %1 revela %2 a %3. + + + + %1 reveals %2 to %3. + p1 female, p2 male + %1 revela %2 a %3. + + + + %1 reveals %2 to %3. + p1 male, p2 female + %1 revela %2 a %3. + + + + %1 reveals %2 to %3. + p1 male, p2 male + %1 revela %2 a %3. + + + + %1 reveals %2. + female + %1 revela %2. + + + + %1 reveals %2. + male + %1 revela %2. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + %1 revela aleatoreamente %2%3. a %4. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + %1 revela aleatoreamente %2%3. a %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + %1 revela aleatoreamente %2%3. a %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + %1 revela aleatoreamente %2%3. a %4. + + + + %1 randomly reveals %2%3. + female + %1 revela aleatoreamente %2%3. + + + + %1 randomly reveals %2%3. + male + %1 revela aleatoreamente %2%3. + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + %1 revela %2%3 a %4. + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + %1 revela %2%3 a %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + %1 revela %2%3 a %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + %1 revela %2%3 a %4. + + + + %1 reveals %2%3. + female + %1 revela %2%3. + + + + %1 reveals %2%3. + male + %1 revela %2%3. + + + + It is now %1's turn. + female + É agora o turno de %1. + + + + It is now %1's turn. + male + É agora o turno de %1. + + + + %1 draws his initial hand. + + + + + %1 draws her initial hand. - + %1 places %n %2 counter(s) on %3 (now %4). + + %1 coloca %n %2 marcador em %3 (agora com %4). + %1 coloca %n %2 marcadores em %3 (agora com %4). + + + + %1 removes %n %2 counter(s) from %3 (now %4). + + %1 remove %n %2 marcador de %3 (agora com %4). + %1 remove %n %2 marcadores de %3 (agora com %4). + + + + + + a card + uma carta + + %1 draws %n card(s). - + %1 compra %n carta. %1 compra %n cartas. - + %1 undoes his last draw. %1 desfaz a sua última compra. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). %1 desfaz a sua última compra (%2). - + %1 undoes her last draw (%2). - + %1 gives %2 control over %3. %1 dá controlo sobre %3 a %2. - %1 flips %2 face-down. - %1 volta a face de %2 para baixo. + %1 volta a face de %2 para baixo. - %1 flips %2 face-up. - %1 volta a face de %2 para cima. + %1 volta a face de %2 para cima. - %1 destroys %2. - %1 destrói %2. + %1 destrói %2. - %1 attaches %2 to %3's %4. - %1 anexa %2 a %4 de %3. + %1 anexa %2 a %4 de %3. - %1 unattaches %2. - %1 desanexa %2. + %1 desanexa %2. - %1 creates token: %2%3. - %1 cria ficha: %2%3. + %1 cria ficha: %2%3. - %1 points from %2's %3 to %4. - %1 aponta de %3 de %2 para %4. + %1 aponta de %3 de %2 para %4. - %1 points from %2's %3 to %4's %5. - %1 aponta de %3 de %2 para %5 de %4. + %1 aponta de %3 de %2 para %5 de %4. %1 places %n counter(s) (%2) on %3 (now %4). @@ -2231,7 +3059,7 @@ Versão local é %1, versão remota é %2. - + red vermelho @@ -2239,7 +3067,7 @@ Versão local é %1, versão remota é %2. - + yellow amarelo @@ -2247,7 +3075,7 @@ Versão local é %1, versão remota é %2. - + green verde @@ -2255,162 +3083,138 @@ Versão local é %1, versão remota é %2. - his permanents - as suas permanentes + as suas permanentes - - her permanents - - - - %1 %2 %3. - %1 %2 %3. + %1 %2 %3. - taps - vira + vira - untaps - desvira + desvira - %1 sets counter %2 to %3 (%4%5). - %1 altera o número de marcadores %2 para %3(%4%5). + %1 altera o número de marcadores %2 para %3(%4%5). - %1 sets %2 to not untap normally. - %1 define %2 para não desvirar normalmente. + %1 define %2 para não desvirar normalmente. - %1 sets %2 to untap normally. - %1 define %2 para desvirar normalmente. + %1 define %2 para desvirar normalmente. - %1 sets PT of %2 to %3. - %1 define o P/R de %2 como %3. + %1 define o P/R de %2 como %3. - %1 sets annotation of %2 to %3. - %1 coloca uma nota de %2 em%3. + %1 coloca uma nota de %2 em%3. - %1 is looking at the top %2 cards %3. - %1 está a olhar para as %2 cartas do topo %3. + %1 está a olhar para as %2 cartas do topo %3. - %1 is looking at %2. - %1 está a olhar para %2. + %1 está a olhar para %2. - %1 stops looking at %2. - %1 para de olhar para %2. + %1 para de olhar para %2. - %1 reveals %2 to %3. - %1 revela %2 a %3. + %1 revela %2 a %3. - %1 reveals %2. - %1 revela %2. + %1 revela %2. - %1 randomly reveals %2%3 to %4. - %1 revela aleatoreamente %2%3. a %4. + %1 revela aleatoreamente %2%3. a %4. - %1 randomly reveals %2%3. - %1 revela aleatoreamente %2%3. + %1 revela aleatoreamente %2%3. - %1 reveals %2%3 to %4. - %1 revela %2%3 a %4. + %1 revela %2%3 a %4. - %1 reveals %2%3. - %1 revela %2%3. + %1 revela %2%3. - It is now %1's turn. - É agora o turno de %1. + É agora o turno de %1. - + untap step Etapa de Desvirar - + upkeep step Etapa de Manutenção - + draw step Etapa de Compra - + first main phase 1ª Fase Principal (pré-combate) - + beginning of combat step Etapa de Início de Combate - + declare attackers step Etapa de Declaração de Atacantes - + declare blockers step Etapa de Declaração de Bloqueadores - + combat damage step Etapa de Dano de Combate - + end of combat step Etapa de Fim de Combate - + second main phase 2ª Fase Principal (pós-combate) - + ending phase Fase Final - + It is now the %1. É agora a %1. @@ -2418,22 +3222,22 @@ Versão local é %1, versão remota é %2. MessagesSettingsPage - + Add message Adicionar mensagem - + Message: Mensagem: - + &Add &Adicionar - + &Remove &Remover @@ -2769,7 +3573,7 @@ Versão local é %1, versão remota é %2. - + Number: Número: @@ -2794,27 +3598,27 @@ Versão local é %1, versão remota é %2. Número de faces: - + Set power/toughness Definir poder/resistência - + Please enter the new PT: Por favor introduza o novo P/R: - + Set annotation Colocar nota - + Please enter the new annotation: Por favor introduza a nova nota: - + Set counters Definir marcadores @@ -2986,40 +3790,73 @@ Versão local é %1, versão remota é %2. Nome longo + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + + + + + &Cancel + &Cancelar + + + + Shut down server + + + TabAdmin - + Update server &message &Actualizar mensagem do servidor - + + &Shut down server + + + + Server administration functions Funções do administrador do servidor - + &Unlock functions &Desbloquear funções - + &Lock functions &Bloquear funções - + Unlock administration functions Desbloquear funções de administração - + Do you really want to unlock the administration functions? Quer mesmo desbloquear as funçõesde administração? - + Administration Administração @@ -3114,137 +3951,137 @@ Por favor introduza um nome: TabGame - + F5 F5 - + F6 F6 - + F7 F7 - + F8 F8 - + F9 F9 - + F10 F10 - + &Phases Fa&ses - + &Game &Jogo - + Next &phase Próxima &fase - + Ctrl+Space Ctrl+Space - + Next &turn Próximo &turno - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter - + &Remove all local arrows &Remover todas as setas locais - + Ctrl+R Ctrl+R - + &Concede &Conceder - + F2 F2 - + &Leave game Sair do &jogo - + Ctrl+Q Ctrl+Q - + &Say: &Dizer: - + Concede Conceder - + Are you sure you want to concede this game? Tem a certeza que deseja conceder este jogo? - + Leave game Sair do jogo - + Are you sure you want to leave this game? Tem a certeza que deseja sair deste jogo? - + Kicked Expulso - + You have been kicked out of the game. Você foi expulso do jogo. - + Game %1: %2 Jogo %1: %2 @@ -3252,27 +4089,27 @@ Por favor introduza um nome: TabMessage - + Personal &talk Conversação &privada - + &Leave &Abandonar - + This user is ignoring you. Este utilizador esta a ignorar-te. - + %1 has left the server. %1 abandonou o servidor. - + %1 has joined the server. %1 entrou no servidor. @@ -3285,27 +4122,27 @@ Por favor introduza um nome: TabRoom - + &Say: &Dizer: - + Chat - + &Room &Sala - + &Leave room &Abandonar a sala - + You are flooding the chat. Please wait a couple of seconds. Estás a inundar o chat .Por favor aguarde alguns segundos. @@ -3389,37 +4226,37 @@ Por favor introduza um nome: UserInterfaceSettingsPage - + General interface settings Configurações gerais da interface - + &Double-click cards to play them (instead of single-click) Clicar &duas vezes nas cartas para as jogar (ao invés de clicar apenas uma vez) - + Animation settings Configurações de Animações - + &Tap/untap animation Animação de &virar/desvirar - + Enable &sounds - + Path to sounds directory: - + Choose path Escolher directório @@ -3427,70 +4264,78 @@ Por favor introduza um nome: UserList - + Users online: %1 Utilizadores online: %1 - + Users in this room: %1 Utilizadores nesta sala:%1 - + Buddies online: %1 / %2 Amigos online: %1 / %2 - + Ignored users online: %1 / %2 Utilizadores ignorados online %1 / %2 - + + %1's games + + + + User &details Detalhes do &utilizador - + Direct &chat Conversação &directa - + + Show this user's &games + + + + Add to &buddy list Adicionar a lista de &amigos - + Remove from &buddy list Remover da lista de &amigos - + Add to &ignore list Adicionar a lista a &ignorar - + Remove from &ignore list Remover da lista a &ignorar - + Ban from &server Banir do &servidor - Duration - Duração + Duração - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Por favor introduza a duração do banimento (em minutos). + Por favor introduza a duração do banimento (em minutos). Introduza 0 para um banimento indefinido. diff --git a/cockatrice/translations/cockatrice_ru.ts b/cockatrice/translations/cockatrice_ru.ts index 1f5e95e5..a32a425d 100644 --- a/cockatrice/translations/cockatrice_ru.ts +++ b/cockatrice/translations/cockatrice_ru.ts @@ -37,90 +37,126 @@ AppearanceSettingsPage - + Zone background pictures Фоновые изображения - + Path to hand background: Рука: - + Path to stack background: Стек: - + Path to table background: Поле битвы: - + Path to player info background: Панель игрока: - + Path to picture of card back: Рубашки карт: - + Card rendering Отрисовка карт - + Display card names on cards having a picture Отображать название карты поверх изображения - + Hand layout Расположение руки - + Display hand horizontally (wastes space) Отбражать руку горизонтально - + Table grid layout Сетка - + Invert vertical coordinate Инвертировать вертикальные координату - + + Minimum player count for multi-column layout: + + + + Zone view layout Сортировка карт - + Sort by name Сортировать по имени - + Sort by type Сортировать по типу - - - - - + + + + + Choose path Выберите путь + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + Введите продолжительность бана (в минутах). +Введите 0 чтобы забанить пожизненно. + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + &Ок + + + + &Cancel + &Отмена + + + + Ban user from server + + + CardDatabaseModel @@ -195,57 +231,57 @@ CardItem - + &Play &Разыграть - + &Hide &Cкрыть - + &Tap &Повернуть - + &Untap &Развернуть - + Toggle &normal untapping (Не) &Разворачивать как обычно - + &Flip &Рубашкой вверх (вниз) - + &Clone &Клонировать - + Ctrl+H Ctrl+H - + &Attach to card... &Прикрепить к... - + Ctrl+A - + Unattac&h &Открепить @@ -254,142 +290,147 @@ Установить &Силу/Защиту... - + + &Draw arrow... + + + + &Power / toughness &Сила / защита - + &Increase power &Увеличить силу - + Ctrl++ - + &Decrease power У&меньшить силу - + Ctrl+- - + I&ncrease toughness У&величить защиту - + Alt++ - + D&ecrease toughness Уменьшить &защиту - + Alt+- - + In&crease power and toughness Увеличить силу &и защиту - + Ctrl+Alt++ - + Dec&rease power and toughness Уменьшить силу и за&щиту - + Ctrl+Alt+- - + Set &power and toughness... Уст&ановить силу / защиту... - + Ctrl+P - + &Set annotation... &Пометить... - + red Красный - + yellow Желтый - + green Зеленый - + &Add counter (%1) &Добавить жетон (%1) - + &Remove counter (%1) &Убрать жетон (%1) - + &Set counters (%1)... &Установить жетоны (%1)... - + &top of library &Наверх библиотеки - + &bottom of library &Вниз библиотеки - + &graveyard &На кладбище - + Ctrl+Del - + &exile &Изгнать - + &Move to &Переместить... @@ -910,12 +951,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General Основные @@ -941,22 +982,22 @@ DeckViewContainer - + Load &local deck Загрузить &колоду с диска - + Load d&eck from server Загрузить к&олоду с сервера - + Ready to s&tart &Готов - + Load deck Загрузить колоду @@ -1045,82 +1086,82 @@ &Подпись: - + &Password: &Пароль: - + P&layers: &Количество игроков: - + Game type Формат игры - + Only &buddies can join Только для &своих - + Only &registered users can join Только для &зарег. пользователей - + Joining restrictions Ограничения - + &Spectators allowed &Разрешить зрителей - + Spectators &need a password to join Требовать &пароль у зрителей - + Spectators can &chat Позволить зрителям &комментировать - + Spectators see &everything Показывать зрителям &все - + Spectators Зрители - + &OK &Ок - + &Cancel &Отмена - + Create game Создать игру - + Error Ошибка - + Server error. Ошибка сервера. @@ -1262,59 +1303,59 @@ DlgSettings - - - + + + Error Ошибка - + Your card database is invalid. Would you like to go back and set the correct path? База карт не найдена. Вернуться и задать правильный путь? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? Ваши колоды отсутствуют в указанной папке. Вернуться и задать правильный путь? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? Изображения карт не найдены. Вернуться и задать правильный путь? - + Settings Настройки - + General Основные - + Appearance Внешний вид - + User interface Интерфейс - + Deck editor - + Messages Сообщения - + &Close &Закрыть @@ -1322,83 +1363,94 @@ GameSelector - - - - - - - + + + + + + + + Error Ошибка - + + Please join the appropriate room first. + + + + Wrong password. Неверный пароль. - + Spectators are not allowed in this game. В эту игру не пускают зрителей. - + The game is already full. Все места заняты! =Ь - + The game does not exist any more. Эта игра была удалена. - + This game is only open to registered users. Доступно только для зарегистрированных. - + This game is only open to its creator's buddies. Доступно только для друзей. - + You are being ignored by the creator of this game. Вы добавлены в игнор-лист данного игрока. - + Join game Присоединиться - + Password: Пароль: - + Games Игры - + Show &full games Показывать &текущие - + + Show &running games + + + + C&reate С&оздать - + &Join &Присоединиться - + J&oin as spectator П&рисоединиться как зритель @@ -1414,67 +1466,72 @@ GamesModel - + yes да - + yes, free for spectators да, свободно для зрителей - + no нет - + buddies only только свои - + reg. users only только зарег. - + not allowed Не допускаются - + + Room + Комната + + + Description Подпись - + Creator Создал - + Game type Формат игры - + Password Пароль - + Restrictions Ограничения - + Players Количество игроков - + Spectators Зрители @@ -1482,50 +1539,50 @@ GeneralSettingsPage - - + + English Русский - - - + + + Choose path Путь - + Personal settings Личные настройки - + Language: Язык: - + Download card pictures on the fly Загружать изображения карт на лету - + Paths Расположение - + Decks directory: Колоды: - + Pictures directory: Изображения карт: - + Path to card database: Путь к базе карт: @@ -1544,220 +1601,241 @@ + Scheduled server shutdown. + + + + Unknown reason. Неизвестная причина. - + Connection closed Соединение прервано - + The server has terminated your connection. Reason: %1 Ваше подключение было прервано сервером. Причина: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + + Number of players Количество игроков - + Please enter the number of players. Введите количество игроков. - - + + Player %1 Игрок %1 - + About Cockatrice О программе - + Version %1 Версия %1 - + Authors: Разработчики: - + Translators: Переводчики: - + Spanish: Испанский: - + Portugese (Portugal): Португальский: - + Portugese (Brazil): Португальский (Brazil): - + French: Французский: - + Japanese: Японский: - + Russian: Русский: - + Czech: - + Slovak: - - + - - + + + Error Ошибка - + Server timeout Временная ошибка - + Invalid login data. Неверный логин/пароль. - + There is already an active session using this user name. Please close that session first and re-login. Пользователь с таким именем уже подключен. Пожалуйста, закройте это подключение и войдите заново. - + Socket error: %1 Ошибка сокета: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. Вы пытаетесь подключиться к несуществующему серверу. Пожалуйста, обновите Cockatrice или выберите другой сервер. Локальная версия %1, удаленная версия %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. Ваш клиент Cockatrice устарел. Пожалуйста, обновите Cockatrice. Локальная версия %1, удаленная версия %2. - + Connecting to %1... Подключение к %1... - + Disconnected Подключение прервано - + Logged in at %1 Подключено к %1 - + &Connect... &Подключение... - + &Disconnect П&рервать подключение - + Start &local game... &Начать локальную игру... - + &Deck editor Редактор &колод - + &Full screen П&олный экран - + Ctrl+F - + &Settings... Н&астройки - + &Exit &Выход - + &Cockatrice - + &About Cockatrice О про&грамме - + &Help &Справка - + Are you sure? Вы уверены? - + There are still open games. Are you sure you want to quit? Вы подключены к игре. Выйти? @@ -1765,92 +1843,78 @@ Local version is %1, remote version is %2. MessageLogWidget - Connecting to %1... - Подключение к %1... + Подключение к %1... - Connected. - Подключено. + Подключено. - Disconnected from server. - Нет соединения с сервером. + Нет соединения с сервером. - Invalid password. - Неверный пароль. + Неверный пароль. - Protocol version mismatch. Client: %1, Server: %2 - Несовпадение версий. Клиент: %1, Сервер: %2 + Несовпадение версий. Клиент: %1, Сервер: %2 - Protocol error. - Ошибка протокола. + Ошибка протокола. - You have joined game #%1. - Вы присоединились к игре #%1. + Вы присоединились к игре #%1. - %1 has joined the game. - %1 присоединился к игре. + %1 присоединился к игре. - %1 has left the game. - %1 покиул игру. + %1 покиул игру. - + The game has been closed. Игра закрыта. - + %1 is now watching the game. %1 вошел как зритель. - + %1 is not watching the game any more. %1 покинул зрительскую ложу. - %1 has loaded a local deck. - %1 загрузил колоду с диска. + %1 загрузил колоду с диска. - %1 has loaded deck #%2. - %1 загрузил колоду #%2. + %1 загрузил колоду #%2. + + + %1 is ready to start the game. + %1 готов начать игру. + + + %1 is not ready to start the game any more. + %1 все еще не готов. + + + %1 has conceded the game. + %1 решил сдаться. - %1 is ready to start the game. - %1 готов начать игру. - - - - %1 is not ready to start the game any more. - %1 все еще не готов. - - - - %1 has conceded the game. - %1 решил сдаться. - - - The game has started. Игра началась. @@ -1859,9 +1923,8 @@ Local version is %1, remote version is %2. %1 размешивает библиотеку. - %1 rolls a %2 with a %3-sided die. - %1 выкинул %2 / %3. + %1 выкинул %2 / %3. %1 draws a card. @@ -1872,170 +1935,960 @@ Local version is %1, remote version is %2. %1 взял %2 карт. - + + You have joined game #%1. + female + Вы присоединились к игре #%1. + + + + You have joined game #%1. + male + Вы присоединились к игре #%1. + + + + %1 has joined the game. + female + %1 присоединился к игре. + + + + %1 has joined the game. + male + %1 присоединился к игре. + + + + %1 has left the game. + female + %1 покиул игру. + + + + %1 has left the game. + male + %1 покиул игру. + + + + %1 has loaded a local deck. + female + %1 загрузил колоду с диска. + + + + %1 has loaded a local deck. + male + %1 загрузил колоду с диска. + + + + %1 has loaded deck #%2. + female + %1 загрузил колоду #%2. + + + + %1 has loaded deck #%2. + male + %1 загрузил колоду #%2. + + + + %1 is ready to start the game. + female + %1 готов начать игру. + + + + %1 is ready to start the game. + male + %1 готов начать игру. + + + + %1 is not ready to start the game any more. + female + %1 все еще не готов. + + + + %1 is not ready to start the game any more. + male + %1 все еще не готов. + + + + %1 has conceded the game. + female + %1 решил сдаться. + + + + %1 has conceded the game. + male + %1 решил сдаться. + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + + %1 rolls a %2 with a %3-sided die. + female + %1 выкинул %2 / %3. + + + + %1 rolls a %2 with a %3-sided die. + male + %1 выкинул %2 / %3. + + + + %1 draws %n card(s). + female + + %1 взял %n карту. + %1 взял %n карты. + %1 взял %n карт(ы). + + + + + %1 draws %n card(s). + male + + %1 взял %n карту. + %1 взял %n карты. + %1 взял %n карт(ы). + + + + %1 undoes his last draw. %1 отменил последнее взятие. - + %1 undoes his last draw (%2). %1 отменил %2 последних взятий. - + from table с поля битвы - + from graveyard из кладбища - + from exile из изгнания - + from hand из руки - + the bottom card of his library нижнюю карту своей библиотеки - + from the bottom of his library со дна своей библиотеки - + the top card of his library верхнюю карту своей библиотеки - + from the top of his library с верха своей библиотеки - + from library из библиотеки - + from sideboard из сайда - + from the stack из стека - - + + a card карту - + %1 gives %2 control over %3. %1 передает %2 контроль над %3. - + %1 puts %2 into play%3. %1 поместил %2 на поле битвы %3. - + %1 puts %2%3 into graveyard. %1 поместил %2%3 на кладбище. - + %1 exiles %2%3. %1 изгоняет %2%3. - + %1 moves %2%3 to hand. %1 поместил %2%3 в руку. - + %1 puts %2%3 into his library. %1 поместил %2%3 в свою библиотеку. - + %1 puts %2%3 on bottom of his library. %1 поместил %2%3 на дно своей библиотеки. - + %1 puts %2%3 on top of his library. %1 поместил %2%3 на верх своей библиотеки. - + %1 puts %2%3 into his library at position %4. %1 поместил %2%3 в свою библиотеку %4 сверху. - + %1 moves %2%3 to sideboard. %1 поместил %2%3 в сайд. - + %1 plays %2%3. %1 разыгрывает %2%3. + + + %1 takes a mulligan to %n. + female + + + + + + + + + %1 takes a mulligan to %n. + male + + + + + + - + %1 flips %2 face-down. - %1 перевернул %2 лицом вниз. + female + %1 перевернул %2 лицом вниз. - + + %1 flips %2 face-down. + male + %1 перевернул %2 лицом вниз. + + + %1 flips %2 face-up. - %1 перевернул %2 лицом вверх. + female + %1 перевернул %2 лицом вверх. - - %1 destroys %2. - %1 уничтожил %2. - - - - %1 attaches %2 to %3's %4. - %1 присоединил %2 к %4 игрока %3. - - - - %1 unattaches %2. - %1 отсоединил %2. - - - - %1 creates token: %2%3. - %1 создал фишку: %2%3. + + %1 flips %2 face-up. + male + %1 перевернул %2 лицом вверх. - %1 points from %2's %3 to %4. - %1 указывает с %3 контролируемого %2 на %4. + %1 destroys %2. + female + %1 уничтожил %2. - + + %1 destroys %2. + male + %1 уничтожил %2. + + + %1 attaches %2 to %3's %4. + female + %1 присоединил %2 к %4 игрока %3. + + + %1 attaches %2 to %3's %4. + male + %1 присоединил %2 к %4 игрока %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + %1 присоединил %2 к %4 игрока %3. + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + %1 присоединил %2 к %4 игрока %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + %1 присоединил %2 к %4 игрока %3. + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + %1 присоединил %2 к %4 игрока %3. + + + + %1 unattaches %2. + female + %1 отсоединил %2. + + + + %1 unattaches %2. + male + %1 отсоединил %2. + + + + %1 creates token: %2%3. + female + %1 создал фишку: %2%3. + + + + %1 creates token: %2%3. + male + %1 создал фишку: %2%3. + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + %1 указывает с %3 контролируемого %2 на %4. + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + %1 points from %2's %3 to %4's %5. - %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + p1 female, p2 female, p3 female + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. + + + + %1 places %n %2 counter(s) on %3 (now %4). + female + + %1 поместил %n %2 жетон на %3 (теперь %4). + %1 поместил %n %2 жетона на %3 (теперь %4). + %1 поместил %n %2 жетонов на %3 (теперь %4). + + + + + %1 places %n %2 counter(s) on %3 (now %4). + male + + %1 поместил %n %2 жетон на %3 (теперь %4). + %1 поместил %n %2 жетона на %3 (теперь %4). + %1 поместил %n %2 жетонов на %3 (теперь %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female + + %1 снял %n %2 жетон с %3 (теперь %4). + %1 снял %n %2 жетона с %3 (теперь %4). + %1 снял %n %2 жетонов с %3 (теперь %4). + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + %1 снял %n %2 жетон с %3 (теперь %4). + %1 снял %n %2 жетона с %3 (теперь %4). + %1 снял %n %2 жетонов с %3 (теперь %4). + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + %1 установил жетон %2 на %3 (%4%5). + + + + %1 sets counter %2 to %3 (%4%5). + male + %1 установил жетон %2 на %3 (%4%5). + + + + %1 sets %2 to not untap normally. + female + %2 теперь не разворачивается как обычно (%1). + + + + %1 sets %2 to not untap normally. + male + %2 теперь не разворачивается как обычно (%1). + + + + %1 sets %2 to untap normally. + female + %2 теперь разворачивается как обычно (%1). + + + + %1 sets %2 to untap normally. + male + %2 теперь разворачивается как обычно (%1). + + + + %1 sets PT of %2 to %3. + female + %1 установил Силу/Защиту %2 %3. + + + + %1 sets PT of %2 to %3. + male + %1 установил Силу/Защиту %2 %3. + + + + %1 sets annotation of %2 to %3. + female + %1 сделал пометку на %2 "%3". + + + + %1 sets annotation of %2 to %3. + male + %1 сделал пометку на %2 "%3". + + + + %1 is looking at the top %2 cards %3. + female + %1 смотрит верхние %2 карт библиотеки %3. + + + + %1 is looking at the top %2 cards %3. + male + %1 смотрит верхние %2 карт библиотеки %3. + + + + %1 is looking at %2. + female + %1 просматривает %2. + + + + %1 is looking at %2. + male + %1 просматривает %2. + + + + %1 stops looking at %2. + female + %1 закончил просматривать %2. + + + + %1 stops looking at %2. + male + %1 закончил просматривать %2. + + + + %1 reveals %2 to %3. + p1 female, p2 female + %1 показывает его %2 %3. + + + + %1 reveals %2 to %3. + p1 female, p2 male + %1 показывает его %2 %3. + + + + %1 reveals %2 to %3. + p1 male, p2 female + %1 показывает его %2 %3. + + + + %1 reveals %2 to %3. + p1 male, p2 male + %1 показывает его %2 %3. + + + + %1 reveals %2. + female + %1 открыл его %2. + + + + %1 reveals %2. + male + %1 открыл его %2. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + %1 показывает случайно выбранную%3 карту (%2) %4. + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + %1 показывает случайно выбранную%3 карту (%2) %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + %1 показывает случайно выбранную%3 карту (%2) %4. + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + %1 показывает случайно выбранную%3 карту (%2) %4. + + + + %1 randomly reveals %2%3. + female + %1 открывает случайно выбранную%3 карту (%2). + + + + %1 randomly reveals %2%3. + male + %1 открывает случайно выбранную%3 карту (%2). + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + %1 показывает%2%3 %4. + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + %1 показывает%2%3 %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + %1 показывает%2%3 %4. + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + %1 показывает%2%3 %4. + + + + %1 reveals %2%3. + female + %1 открывает%2%3. + + + + %1 reveals %2%3. + male + %1 открывает%2%3. + + + + It is now %1's turn. + female + Ход игрока %1. + + + + It is now %1's turn. + male + Ход игрока %1. + + + %1 flips %2 face-down. + %1 перевернул %2 лицом вниз. + + + %1 flips %2 face-up. + %1 перевернул %2 лицом вверх. + + + %1 destroys %2. + %1 уничтожил %2. + + + %1 attaches %2 to %3's %4. + %1 присоединил %2 к %4 игрока %3. + + + %1 unattaches %2. + %1 отсоединил %2. + + + %1 creates token: %2%3. + %1 создал фишку: %2%3. + + + %1 points from %2's %3 to %4. + %1 указывает с %3 контролируемого %2 на %4. + + + %1 points from %2's %3 to %4's %5. + %1 указывает с %3 контролируемого %2 на %5 контролируемого %4. %1 places %n counter(s) (%2) on %3 (now %4). @@ -2053,114 +2906,97 @@ Local version is %1, remote version is %2. %1 удалил %n жетоны (%2) с %3 (теперь %4). - - - %1 shuffles %2. - - - %1 draws %n card(s). - + %1 взял %n карту. %1 взял %n карты. %1 взял %n карт(ы). - + %1 undoes her last draw. - + %1 undoes her last draw (%2). - + the bottom card of her library - + from the bottom of her library - + the top card of her library - + from the top of her library - + %1 puts %2 into play tapped%3. %1 положил %2 повернутым на поле битвы%3. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into her library at position %4. - - - %1 takes a mulligan to %n. - - - - - - - + %1 draws his initial hand. - + %1 draws her initial hand. - %1 places %n %2 counter(s) on %3 (now %4). - + %1 поместил %n %2 жетон на %3 (теперь %4). %1 поместил %n %2 жетона на %3 (теперь %4). %1 поместил %n %2 жетонов на %3 (теперь %4). - %1 removes %n %2 counter(s) from %3 (now %4). - + %1 снял %n %2 жетон с %3 (теперь %4). %1 снял %n %2 жетона с %3 (теперь %4). %1 снял %n %2 жетонов с %3 (теперь %4). - + red красный @@ -2169,7 +3005,7 @@ Local version is %1, remote version is %2. - + yellow желтый @@ -2178,7 +3014,7 @@ Local version is %1, remote version is %2. - + green зеленый @@ -2187,162 +3023,138 @@ Local version is %1, remote version is %2. - his permanents - свои перманенты + свои перманенты - - her permanents - - - - %1 %2 %3. - %1 %2 %3. + %1 %2 %3. - taps - повернул + повернул - untaps - развернул + развернул - %1 sets counter %2 to %3 (%4%5). - %1 установил жетон %2 на %3 (%4%5). + %1 установил жетон %2 на %3 (%4%5). - %1 sets %2 to not untap normally. - %2 теперь не разворачивается как обычно (%1). + %2 теперь не разворачивается как обычно (%1). - %1 sets %2 to untap normally. - %2 теперь разворачивается как обычно (%1). + %2 теперь разворачивается как обычно (%1). - %1 sets PT of %2 to %3. - %1 установил Силу/Защиту %2 %3. + %1 установил Силу/Защиту %2 %3. - %1 sets annotation of %2 to %3. - %1 сделал пометку на %2 "%3". + %1 сделал пометку на %2 "%3". - %1 is looking at the top %2 cards %3. - %1 смотрит верхние %2 карт библиотеки %3. + %1 смотрит верхние %2 карт библиотеки %3. - %1 is looking at %2. - %1 просматривает %2. + %1 просматривает %2. - %1 stops looking at %2. - %1 закончил просматривать %2. + %1 закончил просматривать %2. - %1 reveals %2 to %3. - %1 показывает его %2 %3. + %1 показывает его %2 %3. - %1 reveals %2. - %1 открыл его %2. + %1 открыл его %2. - %1 randomly reveals %2%3 to %4. - %1 показывает случайно выбранную%3 карту (%2) %4. + %1 показывает случайно выбранную%3 карту (%2) %4. - %1 randomly reveals %2%3. - %1 открывает случайно выбранную%3 карту (%2). + %1 открывает случайно выбранную%3 карту (%2). - %1 reveals %2%3 to %4. - %1 показывает%2%3 %4. + %1 показывает%2%3 %4. - %1 reveals %2%3. - %1 открывает%2%3. + %1 открывает%2%3. - It is now %1's turn. - Ход игрока %1. + Ход игрока %1. - + untap step шаг разворота - + upkeep step шаг поддержки - + draw step шаг взятия карты - + first main phase первая главная фаза - + beginning of combat step шаг начала битвы - + declare attackers step шаг назначения атакующих - + declare blockers step шаг назначения блокирующих - + combat damage step шаг нанесения повреждений - + end of combat step шаг завершения битвы - + second main phase вторая главная фаза - + ending phase заключительный шаг - + It is now the %1. Сейчас %1. @@ -2350,22 +3162,22 @@ Local version is %1, remote version is %2. MessagesSettingsPage - + Add message Добавить сообщение - + Message: Сообщение: - + &Add &Добавить - + &Remove &Удалить @@ -2701,7 +3513,7 @@ Local version is %1, remote version is %2. - + Number: Количество: @@ -2726,27 +3538,27 @@ Local version is %1, remote version is %2. Количество граней: - + Set power/toughness Установить Силу/Защиту - + Please enter the new PT: Введите новые Силу/Защиту: - + Set annotation Пометка - + Please enter the new annotation: Введите текст: - + Set counters Установить жетоны @@ -2903,40 +3715,73 @@ Local version is %1, remote version is %2. Полное название + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + &Ок + + + + &Cancel + &Отмена + + + + Shut down server + + + TabAdmin - + Update server &message Обновить сооб&щения сервера - + + &Shut down server + + + + Server administration functions Функции администрирования сервера - + &Unlock functions &Разблокировать функции - + &Lock functions &Заблокировать функции - + Unlock administration functions Разблокировать административные права - + Do you really want to unlock the administration functions? Вы действительно хотите разблокировать административные права? - + Administration Администрирование @@ -3012,137 +3857,137 @@ Please enter a name: TabGame - + F5 - + F6 - + F7 - + F8 - + F9 - + F10 - + &Phases &Фазы - + &Game &Игра - + Next &phase Следующая &фаза - + Ctrl+Space - + Next &turn Следующий &ход - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows &Удалить все указатели - + Ctrl+R - + &Concede Сда&юсь! - + F2 - + &Leave game Покинуть и&гру - + Ctrl+Q - + &Say: Ска&зать: - + Concede Сдаться - + Are you sure you want to concede this game? Испугался? - + Leave game Покинуть игру - + Are you sure you want to leave this game? Вы уверены, что хотите уйти? - + Kicked Выкинут - + You have been kicked out of the game. Вас выкинули из игры. - + Game %1: %2 Игра %1: %2 @@ -3150,27 +3995,27 @@ Please enter a name: TabMessage - + Personal &talk Личная &беседа - + &Leave &Покинуть - + This user is ignoring you. Этот пользователь добавил вас в игнор-лист. - + %1 has left the server. %1 отключился. - + %1 has joined the server. %1 зашел на сервер. @@ -3183,27 +4028,27 @@ Please enter a name: TabRoom - + &Say: &Сказать: - + Chat Чат - + &Room &Комната - + &Leave room &Покинуть комнату - + You are flooding the chat. Please wait a couple of seconds. Кажется, Вы нафлудили. Пожалуйста, подождите пару секунд. @@ -3279,37 +4124,37 @@ Please enter a name: UserInterfaceSettingsPage - + General interface settings Основные настройки интерфейса - + &Double-click cards to play them (instead of single-click) &Двойной клик чтобы разыграть карту (вместо одинарного) - + Animation settings Настройки анимации - + &Tap/untap animation &Анимировать поворот/разворот карты - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3317,70 +4162,78 @@ Please enter a name: UserList - + Users online: %1 Пользователей онлайн: %1 - + Users in this room: %1 Пользователей в этой комнате: %1 - + Buddies online: %1 / %2 Друзей онлайн: %1 / %2 - + Ignored users online: %1 / %2 Игнорируемых пользователей онлайн: %1 / %2 - + + %1's games + + + + User &details Данные о &пользователе - + Direct &chat Обратиться &лично - + + Show this user's &games + + + + Add to &buddy list Добавить в список &друзей - + Remove from &buddy list &Удалить из друзей - + Add to &ignore list Добавить в &игнор-лист - + Remove from &ignore list Удалить и&з игнор-листа - + Ban from &server За&банить на сервере - Duration - Продолжительность + Продолжительность - Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Введите продолжительность бана (в минутах). + Введите продолжительность бана (в минутах). Введите 0 чтобы забанить пожизненно. diff --git a/cockatrice/translations/cockatrice_sk.ts b/cockatrice/translations/cockatrice_sk.ts index 30324e93..a5155a2f 100644 --- a/cockatrice/translations/cockatrice_sk.ts +++ b/cockatrice/translations/cockatrice_sk.ts @@ -37,90 +37,125 @@ AppearanceSettingsPage - + Zone background pictures - + Path to hand background: - + Path to stack background: - + Path to table background: - + Path to player info background: - + Path to picture of card back: - + Card rendering - + Display card names on cards having a picture - + Hand layout - + Display hand horizontally (wastes space) - + Table grid layout - + Invert vertical coordinate - + + Minimum player count for multi-column layout: + + + + Zone view layout - + Sort by name - + Sort by type - - - - - + + + + + Choose path + + BanDialog + + + Please enter the duration of the ban (in minutes). +Enter 0 for an indefinite ban. + + + + + Please enter the reason for the ban. +This is only saved for moderators and cannot be seen by the banned person. + + + + + &OK + + + + + &Cancel + + + + + Ban user from server + + + CardDatabaseModel @@ -195,197 +230,202 @@ CardItem - + &Play - + &Hide - + &Tap - + &Untap - + Toggle &normal untapping - + &Flip - + &Clone - + Ctrl+H - + &Attach to card... - + Ctrl+A - + Unattac&h - - - &Power / toughness - - - - - &Increase power - - - - - Ctrl++ - - - - - &Decrease power - - - - - Ctrl+- - - - - - I&ncrease toughness - - - Alt++ + &Draw arrow... - D&ecrease toughness + &Power / toughness - Alt+- + &Increase power - In&crease power and toughness + Ctrl++ - Ctrl+Alt++ + &Decrease power - Dec&rease power and toughness + Ctrl+- - Ctrl+Alt+- + I&ncrease toughness - Set &power and toughness... + Alt++ - Ctrl+P + D&ecrease toughness - &Set annotation... + Alt+- + + + + + In&crease power and toughness - red + Ctrl+Alt++ - yellow + Dec&rease power and toughness - green + Ctrl+Alt+- + + + + + Set &power and toughness... - &Add counter (%1) + Ctrl+P - - &Remove counter (%1) + + &Set annotation... + + + + + red - &Set counters (%1)... + yellow - &top of library - - - - - &bottom of library + green - &graveyard - - - - - Ctrl+Del + &Add counter (%1) - &exile + &Remove counter (%1) + &Set counters (%1)... + + + + + &top of library + + + + + &bottom of library + + + + + &graveyard + + + + + Ctrl+Del + + + + + &exile + + + + &Move to @@ -756,12 +796,12 @@ DeckEditorSettingsPage - + Enable &price tag feature (using data from blacklotusproject.com) - + General @@ -787,22 +827,22 @@ DeckViewContainer - + Load &local deck - + Load d&eck from server - + Ready to s&tart - + Load deck @@ -891,82 +931,82 @@ - + P&layers: - + Game type - + &Password: - + Only &buddies can join - + Only &registered users can join - + Joining restrictions - + &Spectators allowed - + Spectators &need a password to join - + Spectators can &chat - + Spectators see &everything - + Spectators - + &OK - + &Cancel - + Create game - + Error - + Server error. @@ -1108,59 +1148,59 @@ DlgSettings - - - + + + Error - + Your card database is invalid. Would you like to go back and set the correct path? - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + General - + Appearance - + User interface - + Deck editor - + Messages - + &Close @@ -1168,83 +1208,94 @@ GameSelector - - - - - - - + + + + + + + + Error - + + Please join the appropriate room first. + + + + Wrong password. - + Spectators are not allowed in this game. - + The game is already full. - + The game does not exist any more. - + This game is only open to registered users. - + This game is only open to its creator's buddies. - + You are being ignored by the creator of this game. - + Join game - + Password: - + Games - + Show &full games - + + Show &running games + + + + C&reate - + &Join - + J&oin as spectator @@ -1260,67 +1311,72 @@ GamesModel - + yes - + yes, free for spectators - + no - + buddies only - + reg. users only - + not allowed - - - Description - - - - - Creator - - - Game type + Room - Password + Description - Restrictions + Creator - Players + Game type + Password + + + + + Restrictions + + + + + Players + + + + Spectators @@ -1328,50 +1384,50 @@ GeneralSettingsPage - - + + English - - - + + + Choose path - + Personal settings - + Language: - + Download card pictures on the fly - + Paths - + Decks directory: - + Pictures directory: - + Path to card database: @@ -1390,216 +1446,237 @@ + Scheduled server shutdown. + + + + Unknown reason. - + Connection closed - + The server has terminated your connection. Reason: %1 - + + Scheduled server shutdown + + + + + The server is going to be restarted in %n minute(s). +All running games will be lost. +Reason for shutdown: %1 + + + + + + + + Number of players - + Please enter the number of players. - - + + Player %1 - + About Cockatrice - + Version %1 - + Authors: - + Translators: - + Spanish: - + Portugese (Portugal): - + Portugese (Brazil): - + French: - + Japanese: - + Russian: - + Czech: - + Slovak: - - + - - + + + Error - + Server timeout - + Invalid login data. - + There is already an active session using this user name. Please close that session first and re-login. - + Socket error: %1 - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. - + Connecting to %1... - + Disconnected - + Logged in at %1 - + &Connect... - + &Disconnect - + Start &local game... - + &Deck editor - + &Full screen - + Ctrl+F - + &Settings... - + &Exit - + &Cockatrice - + &About Cockatrice - + &Help - + Are you sure? - + There are still open games. Are you sure you want to quit? @@ -1607,108 +1684,183 @@ Local version is %1, remote version is %2. MessageLogWidget - - Connecting to %1... - - - - - Connected. - - - - - Disconnected from server. - - - - - Invalid password. - - - - - Protocol version mismatch. Client: %1, Server: %2 - - - - - Protocol error. - - - - - You have joined game #%1. - - - - - %1 has joined the game. - - - - - %1 has left the game. - - - - + The game has been closed. - + %1 is now watching the game. - + %1 is not watching the game any more. - - - %1 has loaded a local deck. - - - - - %1 has loaded deck #%2. - - - %1 is ready to start the game. - - - - - %1 is not ready to start the game any more. - - - - - %1 has conceded the game. - - - - The game has started. - - %1 shuffles %2. + + You have joined game #%1. + female - + + You have joined game #%1. + male + + + + + %1 has joined the game. + female + + + + + %1 has joined the game. + male + + + + + %1 has left the game. + female + + + + + %1 has left the game. + male + + + + + %1 has loaded a local deck. + female + + + + + %1 has loaded a local deck. + male + + + + + %1 has loaded deck #%2. + female + + + + + %1 has loaded deck #%2. + male + + + + + %1 is ready to start the game. + female + + + + + %1 is ready to start the game. + male + + + + + %1 is not ready to start the game any more. + female + + + + + %1 is not ready to start the game any more. + male + + + + + %1 has conceded the game. + female + + + + + %1 has conceded the game. + male + + + + + %1 has restored connection to the game. + female + + + + + %1 has restored connection to the game. + male + + + + + %1 has lost connection to the game. + female + + + + + %1 has lost connection to the game. + male + + + + + %1 shuffles %2. + female + + + + + %1 shuffles %2. + male + + + + %1 rolls a %2 with a %3-sided die. + female + + + + + %1 rolls a %2 with a %3-sided die. + male - + %1 draws %n card(s). + female + + + + + + + + + %1 draws %n card(s). + male @@ -1716,189 +1868,200 @@ Local version is %1, remote version is %2. - + %1 undoes his last draw. - + %1 undoes her last draw. - + %1 undoes his last draw (%2). - + %1 undoes her last draw (%2). - + from table - + from graveyard - + from exile - + from hand - + the bottom card of his library - + the bottom card of her library - + from the bottom of his library - + from the bottom of her library - + the top card of his library - + the top card of her library - + from the top of his library - + from the top of her library - + from library - + from sideboard - + from the stack - - + + a card - + %1 gives %2 control over %3. - + %1 puts %2 into play tapped%3. - + %1 puts %2 into play%3. - + %1 puts %2%3 into graveyard. - + %1 exiles %2%3. - + %1 moves %2%3 to hand. - + %1 puts %2%3 into his library. - + %1 puts %2%3 into her library. - + %1 puts %2%3 on bottom of his library. - + %1 puts %2%3 on bottom of her library. - + %1 puts %2%3 on top of his library. - + %1 puts %2%3 on top of her library. - + %1 puts %2%3 into his library at position %4. - + %1 puts %2%3 into her library at position %4. - + %1 moves %2%3 to sideboard. - + %1 plays %2%3. - + %1 takes a mulligan to %n. + female + + + + + + + + + %1 takes a mulligan to %n. + male @@ -1906,58 +2069,285 @@ Local version is %1, remote version is %2. - - %1 draws his initial hand. - - - - - %1 draws her initial hand. - - - - + %1 flips %2 face-down. + female - + + %1 flips %2 face-down. + male + + + + %1 flips %2 face-up. + female - - %1 destroys %2. - - - - - %1 attaches %2 to %3's %4. - - - - - %1 unattaches %2. - - - - - %1 creates token: %2%3. + + %1 flips %2 face-up. + male - %1 points from %2's %3 to %4. + %1 destroys %2. + female - + + %1 destroys %2. + male + + + + + %1 unattaches %2. + female + + + + + %1 unattaches %2. + male + + + + + %1 creates token: %2%3. + female + + + + + %1 creates token: %2%3. + male + + + + + %1 points from her %2 to herself. + female + + + + + %1 points from his %2 to himself. + male + + + + + %1 points from her %2 to %3. + p1 female, p2 female + + + + + %1 points from her %2 to %3. + p1 female, p2 male + + + + + %1 points from his %2 to %3. + p1 male, p2 female + + + + + %1 points from his %2 to %3. + p1 male, p2 male + + + + + %1 points from %2's %3 to herself. + card owner female, target female + + + + + %1 points from %2's %3 to herself. + card owner male, target female + + + + + %1 points from %2's %3 to himself. + card owner female, target male + + + + + %1 points from %2's %3 to himself. + card owner male, target male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4. + p1 male, p2 male, p3 male + + + + + %1 points from her %2 to her %3. + female + + + + + %1 points from his %2 to his %3. + male + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 female + + + + + %1 points from her %2 to %3's %4. + p1 female, p2 male + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 female + + + + + %1 points from his %2 to %3's %4. + p1 male, p2 male + + + + + %1 points from %2's %3 to her own %4. + card owner female, target female + + + + + %1 points from %2's %3 to her own %4. + card owner male, target female + + + + + %1 points from %2's %3 to his own %4. + card owner female, target male + + + + + %1 points from %2's %3 to his own %4. + card owner male, target male + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 female, p2 male, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 female, p3 male + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 female + + + + + %1 points from %2's %3 to %4's %5. + p1 male, p2 male, p3 male - + %1 places %n %2 counter(s) on %3 (now %4). + female @@ -1965,8 +2355,19 @@ Local version is %1, remote version is %2. - + + %1 places %n %2 counter(s) on %3 (now %4). + male + + + + + + + + %1 removes %n %2 counter(s) from %3 (now %4). + female @@ -1974,7 +2375,315 @@ Local version is %1, remote version is %2. - + + %1 removes %n %2 counter(s) from %3 (now %4). + male + + + + + + + + + %1 taps her permanents. + female + + + + + %1 untaps her permanents. + female + + + + + %1 taps his permanents. + male + + + + + %1 untaps his permanents. + male + + + + + %1 taps %2. + female + + + + + %1 untaps %2. + female + + + + + %1 taps %2. + male + + + + + %1 untaps %2. + male + + + + + %1 sets counter %2 to %3 (%4%5). + female + + + + + %1 sets counter %2 to %3 (%4%5). + male + + + + + %1 sets %2 to not untap normally. + female + + + + + %1 sets %2 to not untap normally. + male + + + + + %1 sets %2 to untap normally. + female + + + + + %1 sets %2 to untap normally. + male + + + + + %1 sets PT of %2 to %3. + female + + + + + %1 sets PT of %2 to %3. + male + + + + + %1 sets annotation of %2 to %3. + female + + + + + %1 sets annotation of %2 to %3. + male + + + + + %1 is looking at the top %2 cards %3. + female + + + + + %1 is looking at the top %2 cards %3. + male + + + + + %1 is looking at %2. + female + + + + + %1 is looking at %2. + male + + + + + %1 stops looking at %2. + female + + + + + %1 stops looking at %2. + male + + + + + %1 reveals %2 to %3. + p1 female, p2 female + + + + + %1 reveals %2 to %3. + p1 female, p2 male + + + + + %1 reveals %2 to %3. + p1 male, p2 female + + + + + %1 reveals %2 to %3. + p1 male, p2 male + + + + + %1 reveals %2. + female + + + + + %1 reveals %2. + male + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 randomly reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 randomly reveals %2%3. + female + + + + + %1 randomly reveals %2%3. + male + + + + + %1 reveals %2%3 to %4. + p1 female, p2 female + + + + + %1 reveals %2%3 to %4. + p1 female, p2 male + + + + + %1 reveals %2%3 to %4. + p1 male, p2 female + + + + + %1 reveals %2%3 to %4. + p1 male, p2 male + + + + + %1 reveals %2%3. + female + + + + + %1 reveals %2%3. + male + + + + + It is now %1's turn. + female + + + + + It is now %1's turn. + male + + + + + %1 draws his initial hand. + + + + + %1 draws her initial hand. + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 female, p2 male + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 female + + + + + %1 attaches %2 to %3's %4. + p1 male, p2 male + + + + red @@ -1983,7 +2692,7 @@ Local version is %1, remote version is %2. - + yellow @@ -1992,7 +2701,7 @@ Local version is %1, remote version is %2. - + green @@ -2001,162 +2710,62 @@ Local version is %1, remote version is %2. - - his permanents - - - - - her permanents - - - - - %1 %2 %3. - - - - - taps - - - - - untaps - - - - - %1 sets counter %2 to %3 (%4%5). - - - - - %1 sets %2 to not untap normally. - - - - - %1 sets %2 to untap normally. - - - - - %1 sets PT of %2 to %3. - - - - - %1 sets annotation of %2 to %3. - - - - - %1 is looking at the top %2 cards %3. - - - - - %1 is looking at %2. - - - - - %1 stops looking at %2. - - - - - %1 reveals %2 to %3. - - - - - %1 reveals %2. - - - - - %1 randomly reveals %2%3 to %4. - - - - - %1 randomly reveals %2%3. - - - - - %1 reveals %2%3 to %4. - - - - - %1 reveals %2%3. - - - - - It is now %1's turn. - - - - + untap step - + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + ending phase - + It is now the %1. @@ -2164,22 +2773,22 @@ Local version is %1, remote version is %2. MessagesSettingsPage - + Add message - + Message: - + &Add - + &Remove @@ -2515,7 +3124,7 @@ Local version is %1, remote version is %2. - + Number: @@ -2540,27 +3149,27 @@ Local version is %1, remote version is %2. - + Set power/toughness - + Please enter the new PT: - + Set annotation - + Please enter the new annotation: - + Set counters @@ -2705,40 +3314,73 @@ Local version is %1, remote version is %2. + + ShutdownDialog + + + &Reason for shutdown: + + + + + &Time until shutdown (minutes): + + + + + &OK + + + + + &Cancel + + + + + Shut down server + + + TabAdmin - + Update server &message - + + &Shut down server + + + + Server administration functions - + &Unlock functions - + &Lock functions - + Unlock administration functions - + Do you really want to unlock the administration functions? - + Administration @@ -2813,137 +3455,137 @@ Please enter a name: TabGame - + F5 - + F6 - + F7 - + F8 - + F9 - + F10 - + &Phases - + &Game - + Next &phase - + Ctrl+Space - + Next &turn - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows - + Ctrl+R - + &Concede - + F2 - + &Leave game - + Ctrl+Q - + &Say: - + Concede - + Are you sure you want to concede this game? - + Leave game - + Are you sure you want to leave this game? - + Kicked - + You have been kicked out of the game. - + Game %1: %2 @@ -2951,27 +3593,27 @@ Please enter a name: TabMessage - + Personal &talk - + &Leave - + This user is ignoring you. - + %1 has left the server. - + %1 has joined the server. @@ -2984,27 +3626,27 @@ Please enter a name: TabRoom - + &Say: - + Chat - + &Room - + &Leave room - + You are flooding the chat. Please wait a couple of seconds. @@ -3076,37 +3718,37 @@ Please enter a name: UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + Animation settings - + &Tap/untap animation - + Enable &sounds - + Path to sounds directory: - + Choose path @@ -3114,71 +3756,70 @@ Please enter a name: UserList - + Users online: %1 - + Users in this room: %1 - + Buddies online: %1 / %2 - + Ignored users online: %1 / %2 - + + %1's games + + + + User &details - + Direct &chat - + + Show this user's &games + + + + Add to &buddy list - + Remove from &buddy list - + Add to &ignore list - + Remove from &ignore list - + Ban from &server - - - Duration - - - - - Please enter the duration of the ban (in minutes). -Enter 0 for an indefinite ban. - - WndDeckEditor diff --git a/common/protocol.cpp b/common/protocol.cpp index fe3997ad..85c581d0 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -44,6 +44,7 @@ void ProtocolItem::initializeHash() ProtocolResponse::initializeHash(); registerSerializableItem("respjoin_room", Response_JoinRoom::newItem); registerSerializableItem("resplist_users", Response_ListUsers::newItem); + registerSerializableItem("respget_games_of_user", Response_GetGamesOfUser::newItem); registerSerializableItem("respget_user_info", Response_GetUserInfo::newItem); registerSerializableItem("respdeck_list", Response_DeckList::newItem); registerSerializableItem("respdeck_download", Response_DeckDownload::newItem); @@ -74,7 +75,7 @@ TopLevelProtocolItem::TopLevelProtocolItem() bool TopLevelProtocolItem::readCurrentItem(QXmlStreamReader *xml) { if (currentItem) { - if (currentItem->readElement(xml)) { + if (currentItem->read(xml)) { emit protocolItemReceived(currentItem); currentItem = 0; } @@ -92,6 +93,8 @@ bool TopLevelProtocolItem::readElement(QXmlStreamReader *xml) currentItem = dynamic_cast(getNewItem(childName + childSubType)); if (!currentItem) currentItem = new ProtocolItem_Invalid; + if (xml->attributes().value("comp").toString().toInt() == 1) + currentItem->setCompressed(true); readCurrentItem(xml); } @@ -254,6 +257,7 @@ void ProtocolResponse::initializeHash() { responseHash.insert(QString(), RespNothing); responseHash.insert("ok", RespOk); + responseHash.insert("not_in_room", RespNotInRoom); responseHash.insert("internal_error", RespInternalError); responseHash.insert("invalid_command", RespInvalidCommand); responseHash.insert("name_not_found", RespNameNotFound); @@ -294,6 +298,34 @@ Response_DeckList::Response_DeckList(int _cmdId, ResponseCode _responseCode, Dec insertItem(_root); } +Response_GetGamesOfUser::Response_GetGamesOfUser(int _cmdId, ResponseCode _responseCode, const QList &_roomList, const QList &_gameList) + : ProtocolResponse(_cmdId, _responseCode, "get_games_of_user") +{ + roomList = _roomList; + for (int i = 0; i < _roomList.size(); ++i) + itemList.append(_roomList[i]); + + gameList = _gameList; + for (int i = 0; i < _gameList.size(); ++i) + itemList.append(_gameList[i]); +} + +void Response_GetGamesOfUser::extractData() +{ + for (int i = 0; i < itemList.size(); ++i) { + ServerInfo_Room *room = dynamic_cast(itemList[i]); + if (room) { + roomList.append(room); + continue; + } + ServerInfo_Game *game = dynamic_cast(itemList[i]); + if (game) { + gameList.append(game); + continue; + } + } +} + Response_GetUserInfo::Response_GetUserInfo(int _cmdId, ResponseCode _responseCode, ServerInfo_User *_user) : ProtocolResponse(_cmdId, _responseCode, "get_user_info") { diff --git a/common/protocol.h b/common/protocol.h index b72deb10..beb09d49 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -42,13 +42,14 @@ enum ItemId { ItemId_Event_Ping = ItemId_Other + 212, ItemId_Event_AddToList = ItemId_Other + 213, ItemId_Response_ListUsers = ItemId_Other + 300, - ItemId_Response_GetUserInfo = ItemId_Other + 301, - ItemId_Response_DeckList = ItemId_Other + 302, - ItemId_Response_DeckDownload = ItemId_Other + 303, - ItemId_Response_DeckUpload = ItemId_Other + 304, - ItemId_Response_DumpZone = ItemId_Other + 305, - ItemId_Response_JoinRoom = ItemId_Other + 306, - ItemId_Response_Login = ItemId_Other + 307, + ItemId_Response_GetGamesOfUser = ItemId_Other + 301, + ItemId_Response_GetUserInfo = ItemId_Other + 302, + ItemId_Response_DeckList = ItemId_Other + 303, + ItemId_Response_DeckDownload = ItemId_Other + 304, + ItemId_Response_DeckUpload = ItemId_Other + 305, + ItemId_Response_DumpZone = ItemId_Other + 306, + ItemId_Response_JoinRoom = ItemId_Other + 307, + ItemId_Response_Login = ItemId_Other + 308, ItemId_Invalid = ItemId_Other + 1000 }; @@ -167,6 +168,15 @@ public: void setGameId(int _gameId) { static_cast(itemMap.value("game_id"))->setData(_gameId); } }; +class ModeratorCommand : public Command { + Q_OBJECT +public: + ModeratorCommand(const QString &_cmdName) + : Command(_cmdName) + { + } +}; + class AdminCommand : public Command { Q_OBJECT public: @@ -273,6 +283,21 @@ public: QList getUserList() const { return typecastItemList(); } }; +class Response_GetGamesOfUser : public ProtocolResponse { + Q_OBJECT +private: + QList gameList; + QList roomList; +protected: + void extractData(); +public: + Response_GetGamesOfUser(int _cmdId = -1, ResponseCode _responseCode = RespOk, const QList &_roomList = QList(), const QList &_gameList = QList()); + int getItemId() const { return ItemId_Response_GetGamesOfUser; } + static SerializableItem *newItem() { return new Response_GetGamesOfUser; } + QList getRoomList() const { return roomList; } + QList getGameList() const { return gameList; } +}; + class Response_GetUserInfo : public ProtocolResponse { Q_OBJECT public: diff --git a/common/protocol_datastructures.cpp b/common/protocol_datastructures.cpp index aaf16467..7d68434a 100644 --- a/common/protocol_datastructures.cpp +++ b/common/protocol_datastructures.cpp @@ -40,14 +40,16 @@ ServerInfo_UserList::ServerInfo_UserList(const QString &_itemType, const QList &_gameTypes, ServerInfo_User *_creatorInfo, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount) +ServerInfo_Game::ServerInfo_Game(int _roomId, int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, bool _started, const QList &_gameTypes, ServerInfo_User *_creatorInfo, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount) : SerializableItem_Map("game") { + insertItem(new SerializableItem_Int("room_id", _roomId)); insertItem(new SerializableItem_Int("game_id", _gameId)); insertItem(new SerializableItem_String("description", _description)); insertItem(new SerializableItem_Bool("has_password", _hasPassword)); insertItem(new SerializableItem_Int("player_count", _playerCount)); insertItem(new SerializableItem_Int("max_players", _maxPlayers)); + insertItem(new SerializableItem_Bool("started", _started)); if (!_creatorInfo) _creatorInfo = new ServerInfo_User; insertItem(_creatorInfo); diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index 02f5336c..a3843a3d 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -8,7 +8,7 @@ class DeckList; -enum ResponseCode { RespNothing, RespOk, RespInternalError, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespFunctionNotAllowed, RespGameNotStarted, RespGameFull, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed, RespOnlyBuddies, RespUserLevelTooLow, RespInIgnoreList, RespWouldOverwriteOldSession, RespChatFlood }; +enum ResponseCode { RespNothing, RespOk, RespNotInRoom, RespInternalError, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespFunctionNotAllowed, RespGameNotStarted, RespGameFull, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed, RespOnlyBuddies, RespUserLevelTooLow, RespInIgnoreList, RespWouldOverwriteOldSession, RespChatFlood }; // PrivateZone: Contents of the zone are always visible to the owner, // but not to anyone else. @@ -69,13 +69,15 @@ public: class ServerInfo_Game : public SerializableItem_Map { public: - ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, const QList &_gameTypes = QList(), ServerInfo_User *creatorInfo = 0, bool _onlyBuddies = false, bool _onlyRegistered = false, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1); + ServerInfo_Game(int _roomId = -1, int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, bool _started = false, const QList &_gameTypes = QList(), ServerInfo_User *creatorInfo = 0, bool _onlyBuddies = false, bool _onlyRegistered = false, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1); static SerializableItem *newItem() { return new ServerInfo_Game; } + int getRoomId() const { return static_cast(itemMap.value("room_id"))->getData(); } int getGameId() const { return static_cast(itemMap.value("game_id"))->getData(); } QString getDescription() const { return static_cast(itemMap.value("description"))->getData(); } bool getHasPassword() const { return static_cast(itemMap.value("has_password"))->getData(); } int getPlayerCount() const { return static_cast(itemMap.value("player_count"))->getData(); } int getMaxPlayers() const { return static_cast(itemMap.value("max_players"))->getData(); } + bool getStarted() const { return static_cast(itemMap.value("started"))->getData(); } QList getGameTypes() const { return typecastItemList(); } ServerInfo_User *getCreatorInfo() const { return static_cast(itemMap.value("user")); } bool getOnlyBuddies() const { return static_cast(itemMap.value("only_buddies"))->getData(); } diff --git a/common/protocol_item_ids.h b/common/protocol_item_ids.h index 2d89e883..6d6cb37b 100644 --- a/common/protocol_item_ids.h +++ b/common/protocol_item_ids.h @@ -3,81 +3,85 @@ ItemId_Command_Ping = 1001, ItemId_Command_Login = 1002, ItemId_Command_Message = 1003, ItemId_Command_ListUsers = 1004, -ItemId_Command_GetUserInfo = 1005, -ItemId_Command_AddToList = 1006, -ItemId_Command_RemoveFromList = 1007, -ItemId_Command_DeckList = 1008, -ItemId_Command_DeckNewDir = 1009, -ItemId_Command_DeckDelDir = 1010, -ItemId_Command_DeckDel = 1011, -ItemId_Command_DeckDownload = 1012, -ItemId_Command_ListRooms = 1013, -ItemId_Command_JoinRoom = 1014, -ItemId_Command_LeaveRoom = 1015, -ItemId_Command_RoomSay = 1016, -ItemId_Command_JoinGame = 1017, -ItemId_Command_KickFromGame = 1018, -ItemId_Command_LeaveGame = 1019, -ItemId_Command_Say = 1020, -ItemId_Command_Shuffle = 1021, -ItemId_Command_Mulligan = 1022, -ItemId_Command_RollDie = 1023, -ItemId_Command_DrawCards = 1024, -ItemId_Command_UndoDraw = 1025, -ItemId_Command_FlipCard = 1026, -ItemId_Command_AttachCard = 1027, -ItemId_Command_CreateToken = 1028, -ItemId_Command_CreateArrow = 1029, -ItemId_Command_DeleteArrow = 1030, -ItemId_Command_SetCardAttr = 1031, -ItemId_Command_SetCardCounter = 1032, -ItemId_Command_IncCardCounter = 1033, -ItemId_Command_ReadyStart = 1034, -ItemId_Command_Concede = 1035, -ItemId_Command_IncCounter = 1036, -ItemId_Command_CreateCounter = 1037, -ItemId_Command_SetCounter = 1038, -ItemId_Command_DelCounter = 1039, -ItemId_Command_NextTurn = 1040, -ItemId_Command_SetActivePhase = 1041, -ItemId_Command_DumpZone = 1042, -ItemId_Command_StopDumpZone = 1043, -ItemId_Command_RevealCards = 1044, -ItemId_Event_Say = 1045, -ItemId_Event_Leave = 1046, -ItemId_Event_GameClosed = 1047, -ItemId_Event_Kicked = 1048, -ItemId_Event_Shuffle = 1049, -ItemId_Event_RollDie = 1050, -ItemId_Event_MoveCard = 1051, -ItemId_Event_FlipCard = 1052, -ItemId_Event_DestroyCard = 1053, -ItemId_Event_AttachCard = 1054, -ItemId_Event_CreateToken = 1055, -ItemId_Event_DeleteArrow = 1056, -ItemId_Event_SetCardAttr = 1057, -ItemId_Event_SetCardCounter = 1058, -ItemId_Event_SetCounter = 1059, -ItemId_Event_DelCounter = 1060, -ItemId_Event_SetActivePlayer = 1061, -ItemId_Event_SetActivePhase = 1062, -ItemId_Event_DumpZone = 1063, -ItemId_Event_StopDumpZone = 1064, -ItemId_Event_RemoveFromList = 1065, -ItemId_Event_ServerMessage = 1066, -ItemId_Event_ConnectionClosed = 1067, -ItemId_Event_Message = 1068, -ItemId_Event_GameJoined = 1069, -ItemId_Event_UserLeft = 1070, -ItemId_Event_LeaveRoom = 1071, -ItemId_Event_RoomSay = 1072, -ItemId_Context_ReadyStart = 1073, -ItemId_Context_Concede = 1074, -ItemId_Context_DeckSelect = 1075, -ItemId_Context_UndoDraw = 1076, -ItemId_Context_MoveCard = 1077, -ItemId_Context_Mulligan = 1078, -ItemId_Command_UpdateServerMessage = 1079, -ItemId_Command_BanFromServer = 1080, -ItemId_Other = 1081 +ItemId_Command_GetGamesOfUser = 1005, +ItemId_Command_GetUserInfo = 1006, +ItemId_Command_AddToList = 1007, +ItemId_Command_RemoveFromList = 1008, +ItemId_Command_DeckList = 1009, +ItemId_Command_DeckNewDir = 1010, +ItemId_Command_DeckDelDir = 1011, +ItemId_Command_DeckDel = 1012, +ItemId_Command_DeckDownload = 1013, +ItemId_Command_ListRooms = 1014, +ItemId_Command_JoinRoom = 1015, +ItemId_Command_LeaveRoom = 1016, +ItemId_Command_RoomSay = 1017, +ItemId_Command_JoinGame = 1018, +ItemId_Command_KickFromGame = 1019, +ItemId_Command_LeaveGame = 1020, +ItemId_Command_Say = 1021, +ItemId_Command_Shuffle = 1022, +ItemId_Command_Mulligan = 1023, +ItemId_Command_RollDie = 1024, +ItemId_Command_DrawCards = 1025, +ItemId_Command_UndoDraw = 1026, +ItemId_Command_FlipCard = 1027, +ItemId_Command_AttachCard = 1028, +ItemId_Command_CreateToken = 1029, +ItemId_Command_CreateArrow = 1030, +ItemId_Command_DeleteArrow = 1031, +ItemId_Command_SetCardAttr = 1032, +ItemId_Command_SetCardCounter = 1033, +ItemId_Command_IncCardCounter = 1034, +ItemId_Command_ReadyStart = 1035, +ItemId_Command_Concede = 1036, +ItemId_Command_IncCounter = 1037, +ItemId_Command_CreateCounter = 1038, +ItemId_Command_SetCounter = 1039, +ItemId_Command_DelCounter = 1040, +ItemId_Command_NextTurn = 1041, +ItemId_Command_SetActivePhase = 1042, +ItemId_Command_DumpZone = 1043, +ItemId_Command_StopDumpZone = 1044, +ItemId_Command_RevealCards = 1045, +ItemId_Event_ConnectionStateChanged = 1046, +ItemId_Event_Say = 1047, +ItemId_Event_Leave = 1048, +ItemId_Event_GameClosed = 1049, +ItemId_Event_Kicked = 1050, +ItemId_Event_Shuffle = 1051, +ItemId_Event_RollDie = 1052, +ItemId_Event_MoveCard = 1053, +ItemId_Event_FlipCard = 1054, +ItemId_Event_DestroyCard = 1055, +ItemId_Event_AttachCard = 1056, +ItemId_Event_CreateToken = 1057, +ItemId_Event_DeleteArrow = 1058, +ItemId_Event_SetCardAttr = 1059, +ItemId_Event_SetCardCounter = 1060, +ItemId_Event_SetCounter = 1061, +ItemId_Event_DelCounter = 1062, +ItemId_Event_SetActivePlayer = 1063, +ItemId_Event_SetActivePhase = 1064, +ItemId_Event_DumpZone = 1065, +ItemId_Event_StopDumpZone = 1066, +ItemId_Event_RemoveFromList = 1067, +ItemId_Event_ServerMessage = 1068, +ItemId_Event_ServerShutdown = 1069, +ItemId_Event_ConnectionClosed = 1070, +ItemId_Event_Message = 1071, +ItemId_Event_GameJoined = 1072, +ItemId_Event_UserLeft = 1073, +ItemId_Event_LeaveRoom = 1074, +ItemId_Event_RoomSay = 1075, +ItemId_Context_ReadyStart = 1076, +ItemId_Context_Concede = 1077, +ItemId_Context_DeckSelect = 1078, +ItemId_Context_UndoDraw = 1079, +ItemId_Context_MoveCard = 1080, +ItemId_Context_Mulligan = 1081, +ItemId_Command_UpdateServerMessage = 1082, +ItemId_Command_ShutdownServer = 1083, +ItemId_Command_BanFromServer = 1084, +ItemId_Other = 1085 }; diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 17aea383..db7ffc1a 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -21,6 +21,11 @@ Command_ListUsers::Command_ListUsers() : Command("list_users") { } +Command_GetGamesOfUser::Command_GetGamesOfUser(const QString &_userName) + : Command("get_games_of_user") +{ + insertItem(new SerializableItem_String("user_name", _userName)); +} Command_GetUserInfo::Command_GetUserInfo(const QString &_userName) : Command("get_user_info") { @@ -255,6 +260,11 @@ Command_RevealCards::Command_RevealCards(int _gameId, const QString &_zoneName, insertItem(new SerializableItem_Int("card_id", _cardId)); insertItem(new SerializableItem_Int("player_id", _playerId)); } +Event_ConnectionStateChanged::Event_ConnectionStateChanged(int _playerId, bool _connected) + : GameEvent("connection_state_changed", _playerId) +{ + insertItem(new SerializableItem_Bool("connected", _connected)); +} Event_Say::Event_Say(int _playerId, const QString &_message) : GameEvent("say", _playerId) { @@ -398,6 +408,12 @@ Event_ServerMessage::Event_ServerMessage(const QString &_message) { insertItem(new SerializableItem_String("message", _message)); } +Event_ServerShutdown::Event_ServerShutdown(const QString &_reason, int _minutes) + : GenericEvent("server_shutdown") +{ + insertItem(new SerializableItem_String("reason", _reason)); + insertItem(new SerializableItem_Int("minutes", _minutes)); +} Event_ConnectionClosed::Event_ConnectionClosed(const QString &_reason) : GenericEvent("connection_closed") { @@ -467,11 +483,18 @@ Command_UpdateServerMessage::Command_UpdateServerMessage() : AdminCommand("update_server_message") { } -Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes) - : AdminCommand("ban_from_server") +Command_ShutdownServer::Command_ShutdownServer(const QString &_reason, int _minutes) + : AdminCommand("shutdown_server") +{ + insertItem(new SerializableItem_String("reason", _reason)); + insertItem(new SerializableItem_Int("minutes", _minutes)); +} +Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes, const QString &_reason) + : ModeratorCommand("ban_from_server") { insertItem(new SerializableItem_String("user_name", _userName)); insertItem(new SerializableItem_Int("minutes", _minutes)); + insertItem(new SerializableItem_String("reason", _reason)); } void ProtocolItem::initializeHashAuto() { @@ -479,6 +502,7 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("cmdlogin", Command_Login::newItem); itemNameHash.insert("cmdmessage", Command_Message::newItem); itemNameHash.insert("cmdlist_users", Command_ListUsers::newItem); + itemNameHash.insert("cmdget_games_of_user", Command_GetGamesOfUser::newItem); itemNameHash.insert("cmdget_user_info", Command_GetUserInfo::newItem); itemNameHash.insert("cmdadd_to_list", Command_AddToList::newItem); itemNameHash.insert("cmdremove_from_list", Command_RemoveFromList::newItem); @@ -519,6 +543,7 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("cmddump_zone", Command_DumpZone::newItem); itemNameHash.insert("cmdstop_dump_zone", Command_StopDumpZone::newItem); itemNameHash.insert("cmdreveal_cards", Command_RevealCards::newItem); + itemNameHash.insert("game_eventconnection_state_changed", Event_ConnectionStateChanged::newItem); itemNameHash.insert("game_eventsay", Event_Say::newItem); itemNameHash.insert("game_eventleave", Event_Leave::newItem); itemNameHash.insert("game_eventgame_closed", Event_GameClosed::newItem); @@ -541,6 +566,7 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("game_eventstop_dump_zone", Event_StopDumpZone::newItem); itemNameHash.insert("generic_eventremove_from_list", Event_RemoveFromList::newItem); itemNameHash.insert("generic_eventserver_message", Event_ServerMessage::newItem); + itemNameHash.insert("generic_eventserver_shutdown", Event_ServerShutdown::newItem); itemNameHash.insert("generic_eventconnection_closed", Event_ConnectionClosed::newItem); itemNameHash.insert("generic_eventmessage", Event_Message::newItem); itemNameHash.insert("generic_eventgame_joined", Event_GameJoined::newItem); @@ -554,5 +580,6 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("game_event_contextmove_card", Context_MoveCard::newItem); itemNameHash.insert("game_event_contextmulligan", Context_Mulligan::newItem); itemNameHash.insert("cmdupdate_server_message", Command_UpdateServerMessage::newItem); + itemNameHash.insert("cmdshutdown_server", Command_ShutdownServer::newItem); itemNameHash.insert("cmdban_from_server", Command_BanFromServer::newItem); } diff --git a/common/protocol_items.dat b/common/protocol_items.dat index 73369c6b..71695932 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -2,6 +2,7 @@ 0:login:s,username:s,password 0:message:s,user_name:s,text 0:list_users +0:get_games_of_user:s,user_name 0:get_user_info:s,user_name 0:add_to_list:s,list:s,user_name 0:remove_from_list:s,list:s,user_name @@ -42,6 +43,7 @@ 2:dump_zone:i,player_id:s,zone_name:i,number_cards 2:stop_dump_zone:i,player_id:s,zone_name 2:reveal_cards:s,zone_name:i,card_id:i,player_id +3:connection_state_changed:b,connected 3:say:s,message 3:leave 3:game_closed @@ -64,6 +66,7 @@ 3:stop_dump_zone:i,zone_owner_id:s,zone 4:remove_from_list:s,list:s,user_name 4:server_message:s,message +4:server_shutdown:s,reason:i,minutes 4:connection_closed:s,reason 4:message:s,sender_name:s,receiver_name:s,text 4:game_joined:i,game_id:s,game_description:i,player_id:b,spectator:b,spectators_can_talk:b,spectators_see_everything:b,resuming @@ -77,4 +80,5 @@ 6:move_card 6:mulligan:i,number 7:update_server_message -7:ban_from_server:s,user_name:i,minutes \ No newline at end of file +7:shutdown_server:s,reason:i,minutes +8:ban_from_server:s,user_name:i,minutes:s,reason \ No newline at end of file diff --git a/common/protocol_items.h b/common/protocol_items.h index d58d3dec..48401ee3 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -35,6 +35,14 @@ public: static SerializableItem *newItem() { return new Command_ListUsers; } int getItemId() const { return ItemId_Command_ListUsers; } }; +class Command_GetGamesOfUser : public Command { + Q_OBJECT +public: + Command_GetGamesOfUser(const QString &_userName = QString()); + QString getUserName() const { return static_cast(itemMap.value("user_name"))->getData(); }; + static SerializableItem *newItem() { return new Command_GetGamesOfUser; } + int getItemId() const { return ItemId_Command_GetGamesOfUser; } +}; class Command_GetUserInfo : public Command { Q_OBJECT public: @@ -389,6 +397,14 @@ public: static SerializableItem *newItem() { return new Command_RevealCards; } int getItemId() const { return ItemId_Command_RevealCards; } }; +class Event_ConnectionStateChanged : public GameEvent { + Q_OBJECT +public: + Event_ConnectionStateChanged(int _playerId = -1, bool _connected = false); + bool getConnected() const { return static_cast(itemMap.value("connected"))->getData(); }; + static SerializableItem *newItem() { return new Event_ConnectionStateChanged; } + int getItemId() const { return ItemId_Event_ConnectionStateChanged; } +}; class Event_Say : public GameEvent { Q_OBJECT public: @@ -598,6 +614,15 @@ public: static SerializableItem *newItem() { return new Event_ServerMessage; } int getItemId() const { return ItemId_Event_ServerMessage; } }; +class Event_ServerShutdown : public GenericEvent { + Q_OBJECT +public: + Event_ServerShutdown(const QString &_reason = QString(), int _minutes = -1); + QString getReason() const { return static_cast(itemMap.value("reason"))->getData(); }; + int getMinutes() const { return static_cast(itemMap.value("minutes"))->getData(); }; + static SerializableItem *newItem() { return new Event_ServerShutdown; } + int getItemId() const { return ItemId_Event_ServerShutdown; } +}; class Event_ConnectionClosed : public GenericEvent { Q_OBJECT public: @@ -706,12 +731,22 @@ public: static SerializableItem *newItem() { return new Command_UpdateServerMessage; } int getItemId() const { return ItemId_Command_UpdateServerMessage; } }; -class Command_BanFromServer : public AdminCommand { +class Command_ShutdownServer : public AdminCommand { Q_OBJECT public: - Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1); + Command_ShutdownServer(const QString &_reason = QString(), int _minutes = -1); + QString getReason() const { return static_cast(itemMap.value("reason"))->getData(); }; + int getMinutes() const { return static_cast(itemMap.value("minutes"))->getData(); }; + static SerializableItem *newItem() { return new Command_ShutdownServer; } + int getItemId() const { return ItemId_Command_ShutdownServer; } +}; +class Command_BanFromServer : public ModeratorCommand { + Q_OBJECT +public: + Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1, const QString &_reason = QString()); QString getUserName() const { return static_cast(itemMap.value("user_name"))->getData(); }; int getMinutes() const { return static_cast(itemMap.value("minutes"))->getData(); }; + QString getReason() const { return static_cast(itemMap.value("reason"))->getData(); }; static SerializableItem *newItem() { return new Command_BanFromServer; } int getItemId() const { return ItemId_Command_BanFromServer; } }; diff --git a/common/protocol_mc.pl b/common/protocol_mc.pl index 31e85b1f..2b1c96b7 100755 --- a/common/protocol_mc.pl +++ b/common/protocol_mc.pl @@ -80,6 +80,13 @@ while () { $parentConstructorCall = "$baseClass(\"$name1\")"; $constructorParamsH = ""; $constructorParamsCpp = ""; + } elsif ($type == 8) { + $type = 'cmd'; + $namePrefix = 'Command'; + $baseClass = 'ModeratorCommand'; + $parentConstructorCall = "$baseClass(\"$name1\")"; + $constructorParamsH = ""; + $constructorParamsCpp = ""; } $className = $namePrefix . '_' . $name2; $itemEnum .= "ItemId_$className = " . ++$itemId . ",\n"; diff --git a/common/serializable_item.cpp b/common/serializable_item.cpp index 9c1a7c81..42c14251 100644 --- a/common/serializable_item.cpp +++ b/common/serializable_item.cpp @@ -1,7 +1,8 @@ #include "serializable_item.h" #include #include -#include +#include + QHash SerializableItem::itemNameHash; SerializableItem *SerializableItem::getNewItem(const QString &name) @@ -16,6 +17,32 @@ void SerializableItem::registerSerializableItem(const QString &name, NewItemFunc itemNameHash.insert(name, func); } +bool SerializableItem::read(QXmlStreamReader *xml) +{ + if (!compressed) + return readElement(xml); + if (xml->isEndElement() && (xml->name() == itemType)) { + QByteArray uncompressedData = "" + qUncompress(QByteArray::fromBase64(compressedData)) + ""; + compressedData.clear(); + QBuffer compressedBuffer(&uncompressedData); + compressedBuffer.open(QIODevice::ReadOnly); + QXmlStreamReader *xml2 = new QXmlStreamReader(&compressedBuffer); + while (!xml2->atEnd()) { + xml2->readNext(); + if (xml2->name() == "d") + continue; + readElement(xml2); + } + delete xml2; + compressedBuffer.close(); + + return readElement(xml); + } else { + compressedData.append(xml->text().toString()); + return false; + } +} + bool SerializableItem::readElement(QXmlStreamReader *xml) { if (xml->isEndElement() && (xml->name() == itemType)) @@ -31,7 +58,19 @@ void SerializableItem::write(QXmlStreamWriter *xml) xml->writeStartElement(itemType); if (!itemSubType.isEmpty()) xml->writeAttribute("type", itemSubType); - writeElement(xml); + if (compressed) { + xml->writeAttribute("comp", "1"); + + QBuffer compressBuffer; + compressBuffer.open(QIODevice::WriteOnly); + QXmlStreamWriter *xml2 = new QXmlStreamWriter(&compressBuffer); + writeElement(xml2); + delete xml2; + compressBuffer.close(); + + xml->writeCharacters(qCompress(compressBuffer.data()).toBase64()); + } else + writeElement(xml); xml->writeEndElement(); } @@ -47,7 +86,7 @@ SerializableItem_Map::~SerializableItem_Map() bool SerializableItem_Map::readElement(QXmlStreamReader *xml) { if (currentItem) { - if (currentItem->readElement(xml)) + if (currentItem->read(xml)) currentItem = 0; return false; } else if (firstItem) @@ -57,6 +96,7 @@ bool SerializableItem_Map::readElement(QXmlStreamReader *xml) else if (xml->isStartElement()) { QString childName = xml->name().toString(); QString childSubType = xml->attributes().value("type").toString(); + bool childCompressed = xml->attributes().value("comp").toString().toInt() == 1; currentItem = itemMap.value(childName); if (!currentItem) { currentItem = getNewItem(childName + childSubType); @@ -64,7 +104,8 @@ bool SerializableItem_Map::readElement(QXmlStreamReader *xml) if (!currentItem) currentItem = new SerializableItem_Invalid(childName); } - if (currentItem->readElement(xml)) + currentItem->setCompressed(childCompressed); + if (currentItem->read(xml)) currentItem = 0; } return SerializableItem::readElement(xml); diff --git a/common/serializable_item.h b/common/serializable_item.h index 979ebb98..50da5e36 100644 --- a/common/serializable_item.h +++ b/common/serializable_item.h @@ -15,6 +15,10 @@ class QXmlStreamWriter; class SerializableItem : public QObject { Q_OBJECT +private: + bool compressed; + QByteArray compressedData; + QXmlStreamReader *compressedReader; protected: typedef SerializableItem *(*NewItemFunction)(); static QHash itemNameHash; @@ -23,7 +27,7 @@ protected: bool firstItem; public: SerializableItem(const QString &_itemType, const QString &_itemSubType = QString()) - : QObject(), itemType(_itemType), itemSubType(_itemSubType), firstItem(true) { } + : QObject(), compressed(false), itemType(_itemType), itemSubType(_itemSubType), firstItem(true) { } static void registerSerializableItem(const QString &name, NewItemFunction func); static SerializableItem *getNewItem(const QString &name); const QString &getItemType() const { return itemType; } @@ -31,6 +35,8 @@ public: virtual bool readElement(QXmlStreamReader *xml); virtual void writeElement(QXmlStreamWriter *xml) = 0; virtual bool isEmpty() const = 0; + void setCompressed(bool _compressed) { compressed = _compressed; } + bool read(QXmlStreamReader *xml); void write(QXmlStreamWriter *xml); }; diff --git a/common/server.cpp b/common/server.cpp index a7e4c683..70451018 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -23,6 +23,7 @@ #include "server_room.h" #include "server_protocolhandler.h" #include "protocol_datastructures.h" +#include #include Server::Server(QObject *parent) @@ -51,7 +52,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString QMutexLocker locker(&serverMutex); if (name.size() > 35) name = name.left(35); - AuthenticationResult authState = checkUserPassword(name, password); + AuthenticationResult authState = checkUserPassword(session, name, password); if (authState == PasswordWrong) return authState; @@ -73,6 +74,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString session->setUserInfo(data); users.insert(name, session); + qDebug() << "Server::loginUser: name=" << name; Event_UserJoined *event = new Event_UserJoined(new ServerInfo_User(data, false)); for (int i = 0; i < clients.size(); ++i) @@ -102,8 +104,9 @@ void Server::removeClient(Server_ProtocolHandler *client) delete event; users.remove(data->getName()); + qDebug() << "Server::removeClient: name=" << data->getName(); } - qDebug() << "Server::removeClient: " << clients.size() << "clients; " << users.size() << "users left"; + qDebug() << "Server::removeClient:" << clients.size() << "clients; " << users.size() << "users left"; } void Server::broadcastRoomUpdate() diff --git a/common/server.h b/common/server.h index 1c35f5a1..de8dd2a5 100644 --- a/common/server.h +++ b/common/server.h @@ -40,10 +40,10 @@ public: virtual int getMaxMessageCountPerInterval() const { return 0; } virtual int getMaxMessageSizePerInterval() const { return 0; } virtual int getMaxGamesPerUser() const { return 0; } + virtual bool getThreaded() const = 0; virtual QMap getBuddyList(const QString &name) = 0; virtual QMap getIgnoreList(const QString &name) = 0; - virtual bool getUserBanned(Server_ProtocolHandler * /*client*/, const QString & /*userName*/) const { return false; } protected: void prepareDestroy(); QList clients; @@ -51,7 +51,7 @@ protected: QMap rooms; virtual bool userExists(const QString &user) = 0; - virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0; + virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) = 0; virtual ServerInfo_User *getUserData(const QString &name) = 0; int getUsersCount() const; int getGamesCount() const; diff --git a/common/server_card.cpp b/common/server_card.cpp index 4c47f20d..6cafdd90 100644 --- a/common/server_card.cpp +++ b/common/server_card.cpp @@ -19,8 +19,8 @@ ***************************************************************************/ #include "server_card.h" -Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y) - : id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), power(-1), toughness(-1), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) +Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone) + : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), power(-1), toughness(-1), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) { } @@ -39,8 +39,8 @@ void Server_Card::resetState() counters.clear(); setTapped(false); setAttacking(false); - power = 0; - toughness = 0; + power = -1; + toughness = -1; setAnnotation(QString()); setDoesntUntap(false); } diff --git a/common/server_card.h b/common/server_card.h index de84d21c..a908befa 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -46,7 +46,7 @@ private: Server_Card *parentCard; QList attachedCards; public: - Server_Card(QString _name, int _id, int _coord_x, int _coord_y); + Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0); ~Server_Card(); Server_CardZone *getZone() const { return zone; } diff --git a/common/server_cardzone.cpp b/common/server_cardzone.cpp index 8738afab..dd1db3ee 100644 --- a/common/server_cardzone.cpp +++ b/common/server_cardzone.cpp @@ -52,10 +52,12 @@ int Server_CardZone::removeCard(Server_Card *card) int index = cards.indexOf(card); cards.removeAt(index); + card->setZone(0); + return index; } -Server_Card *Server_CardZone::getCard(int id, bool remove, int *position) +Server_Card *Server_CardZone::getCard(int id, int *position) { QMutexLocker locker(&player->getGame()->gameMutex); @@ -65,10 +67,6 @@ Server_Card *Server_CardZone::getCard(int id, bool remove, int *position) while (CardIterator.hasNext()) { Server_Card *tmp = CardIterator.next(); if (tmp->getId() == id) { - if (remove) { - cards.removeAt(i); - tmp->setZone(0); - } if (position) *position = i; return tmp; @@ -80,10 +78,6 @@ Server_Card *Server_CardZone::getCard(int id, bool remove, int *position) if ((id >= cards.size()) || (id < 0)) return NULL; Server_Card *tmp = cards[id]; - if (remove) { - cards.removeAt(id); - tmp->setZone(0); - } if (position) *position = id; return tmp; diff --git a/common/server_cardzone.h b/common/server_cardzone.h index 62a129a1..898e89c7 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -41,7 +41,7 @@ public: ~Server_CardZone(); int removeCard(Server_Card *card); - Server_Card *getCard(int id, bool remove, int *position = NULL); + Server_Card *getCard(int id, int *position = NULL); int getCardsBeingLookedAt() const { return cardsBeingLookedAt; } void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; } diff --git a/common/server_game.cpp b/common/server_game.cpp index 74e65ed9..5838e3f9 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -160,6 +160,8 @@ void Server_Game::doStartGameIfReady() */ activePlayer = -1; nextTurn(); + + room->broadcastGameListUpdate(this); } void Server_Game::startGameIfReady() @@ -214,6 +216,17 @@ ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_passw return RespOk; } +bool Server_Game::containsUser(const QString &userName) const +{ + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getUserInfo()->getName() == userName) + return true; + return false; +} + Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate) { QMutexLocker locker(&gameMutex); @@ -341,6 +354,13 @@ void Server_Game::nextTurn() setActivePlayer(keys[listPos]); } +void Server_Game::postConnectionStatusUpdate(Server_Player *player, bool connectionStatus) +{ + QMutexLocker locker(&gameMutex); + + sendGameEvent(new Event_ConnectionStateChanged(player->getPlayerId(), connectionStatus)); +} + QList Server_Game::getGameState(Server_Player *playerWhosAsking) const { QMutexLocker locker(&gameMutex); @@ -472,7 +492,7 @@ ServerInfo_Game *Server_Game::getInfo() const if (players.isEmpty()) // Game is closing - return new ServerInfo_Game(getGameId(), QString(), false, 0, getMaxPlayers(), QList(), 0, false, 0); + return new ServerInfo_Game(room->getId(), getGameId(), QString(), false, 0, getMaxPlayers(), false, QList(), 0, false, 0); else { // Game is open @@ -481,11 +501,13 @@ ServerInfo_Game *Server_Game::getInfo() const gameTypeList.append(new GameTypeId(gameTypes[i])); return new ServerInfo_Game( + room->getId(), getGameId(), getDescription(), !getPassword().isEmpty(), getPlayerCount(), getMaxPlayers(), + gameStarted, gameTypeList, new ServerInfo_User(getCreatorInfo(), false), onlyBuddies, diff --git a/common/server_game.h b/common/server_game.h index 2042a444..f3d761f3 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -77,6 +77,7 @@ public: bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator); + bool containsUser(const QString &userName) const; Server_Player *addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate = true); void removePlayer(Server_Player *player); void removeArrowsToPlayer(Server_Player *player); @@ -88,6 +89,7 @@ public: void setActivePlayer(int _activePlayer); void setActivePhase(int _activePhase); void nextTurn(); + void postConnectionStatusUpdate(Server_Player *player, bool connectionStatus); QList getGameState(Server_Player *playerWhosAsking) const; void sendGameEvent(GameEvent *event, GameEventContext *context = 0, Server_Player *exclude = 0); diff --git a/common/server_player.cpp b/common/server_player.cpp index e5695380..3a9899a9 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -127,7 +127,7 @@ void Server_Player::setupZones() if (!currentCard) continue; for (int k = 0; k < currentCard->getNumber(); ++k) - z->cards.append(new Server_Card(currentCard->getName(), nextCardId++, 0, 0)); + z->cards.append(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z)); } } @@ -334,7 +334,7 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st QMap cardProperties; for (int i = 0; i < _cards.size(); ++i) { int position; - Server_Card *card = startzone->getCard(_cards[i]->getCardId(), false, &position); + Server_Card *card = startzone->getCard(_cards[i]->getCardId(), &position); if (!card) return RespNameNotFound; if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) @@ -510,7 +510,7 @@ ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QStr return RespInvalidCommand; } } else { - Server_Card *card = zone->getCard(cardId, false); + Server_Card *card = zone->getCard(cardId); if (!card) return RespNameNotFound; result = card->setAttribute(attrName, attrValue, false); diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index a3ced63a..a4167009 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -46,8 +46,10 @@ void Server_ProtocolHandler::prepareDestroy() if ((authState == UnknownUser) || p->getSpectator()) g->removePlayer(p); - else + else { p->setProtocolHandler(0); + g->postConnectionStatusUpdate(p, false); + } } gameListMutex.unlock(); @@ -78,7 +80,7 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm Server_Room *room = rooms.value(roomCommand->getRoomId(), 0); if (!room) - return RespNameNotFound; + return RespNotInRoom; QMutexLocker locker(&room->roomMutex); @@ -99,7 +101,7 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm gameListMutex.lock(); if (!games.contains(gameCommand->getGameId())) { qDebug() << "invalid game"; - return RespNameNotFound; + return RespNotInRoom; } QPair gamePair = games.value(gameCommand->getGameId()); Server_Game *game = gamePair.first; @@ -142,6 +144,17 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm default: return RespInvalidCommand; } } + ModeratorCommand *moderatorCommand = qobject_cast(command); + if (moderatorCommand) { + qDebug() << "received ModeratorCommand"; + if (!(userInfo->getUserLevel() & ServerInfo_User::IsModerator)) + return RespLoginNeeded; + + switch (command->getItemId()) { + case ItemId_Command_BanFromServer: return cmdBanFromServer(static_cast(command), cont); + default: return RespInvalidCommand; + } + } AdminCommand *adminCommand = qobject_cast(command); if (adminCommand) { qDebug() << "received AdminCommand"; @@ -149,8 +162,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm return RespLoginNeeded; switch (command->getItemId()) { + case ItemId_Command_ShutdownServer: return cmdShutdownServer(static_cast(command), cont); case ItemId_Command_UpdateServerMessage: return cmdUpdateServerMessage(static_cast(command), cont); - case ItemId_Command_BanFromServer: return cmdBanFromServer(static_cast(command), cont); default: return RespInvalidCommand; } } @@ -166,6 +179,7 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm case ItemId_Command_DeckDel: return cmdDeckDel(static_cast(command), cont); case ItemId_Command_DeckUpload: return cmdDeckUpload(static_cast(command), cont); case ItemId_Command_DeckDownload: return cmdDeckDownload(static_cast(command), cont); + case ItemId_Command_GetGamesOfUser: return cmdGetGamesOfUser(static_cast(command), cont); case ItemId_Command_GetUserInfo: return cmdGetUserInfo(static_cast(command), cont); case ItemId_Command_ListRooms: return cmdListRooms(static_cast(command), cont); case ItemId_Command_JoinRoom: return cmdJoinRoom(static_cast(command), cont); @@ -267,15 +281,16 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain QString userName = cmd->getUsername().simplified(); if (userName.isEmpty() || (userInfo != 0)) return RespContextError; - if (server->getUserBanned(this, userName)) - return RespWrongPassword; authState = server->loginUser(this, userName, cmd->getPassword()); if (authState == PasswordWrong) return RespWrongPassword; if (authState == WouldOverwriteOldSession) return RespWouldOverwriteOldSession; - enqueueProtocolItem(new Event_ServerMessage(server->getLoginMessage())); + ProtocolItem *serverMessage = new Event_ServerMessage(server->getLoginMessage()); + if (getCompressionSupport()) + serverMessage->setCompressed(true); + enqueueProtocolItem(serverMessage); QList _buddyList, _ignoreList; if (authState == PasswordRight) { @@ -292,7 +307,10 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain _ignoreList.append(new ServerInfo_User(ignoreIterator.next().value())); } - cont->setResponse(new Response_Login(cont->getCmdId(), RespOk, new ServerInfo_User(userInfo, true), _buddyList, _ignoreList)); + ProtocolResponse *resp = new Response_Login(cont->getCmdId(), RespOk, new ServerInfo_User(userInfo, true), _buddyList, _ignoreList); + if (getCompressionSupport()) + resp->setCompressed(true); + cont->setResponse(resp); return RespNothing; } @@ -303,6 +321,7 @@ ResponseCode Server_ProtocolHandler::cmdMessage(Command_Message *cmd, CommandCon QString receiver = cmd->getUserName(); Server_ProtocolHandler *userHandler = server->getUsers().value(receiver); + qDebug() << "cmdMessage: recv=" << receiver << (userHandler == 0 ? "not found" : "found"); if (!userHandler) return RespNameNotFound; if (userHandler->getIgnoreList().contains(userInfo->getName())) @@ -313,6 +332,34 @@ ResponseCode Server_ProtocolHandler::cmdMessage(Command_Message *cmd, CommandCon return RespOk; } +ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(Command_GetGamesOfUser *cmd, CommandContainer *cont) +{ + if (authState == PasswordWrong) + return RespLoginNeeded; + + server->serverMutex.lock(); + if (!server->getUsers().contains(cmd->getUserName())) + return RespNameNotFound; + + QList roomList; + QList gameList; + QMapIterator roomIterator(server->getRooms()); + while (roomIterator.hasNext()) { + Server_Room *room = roomIterator.next().value(); + room->roomMutex.lock(); + roomList.append(room->getInfo(false, true)); + gameList << room->getGamesOfUser(cmd->getUserName()); + room->roomMutex.unlock(); + } + server->serverMutex.unlock(); + + ProtocolResponse *resp = new Response_GetGamesOfUser(cont->getCmdId(), RespOk, roomList, gameList); + if (getCompressionSupport()) + resp->setCompressed(true); + cont->setResponse(resp); + return RespNothing; +} + ResponseCode Server_ProtocolHandler::cmdGetUserInfo(Command_GetUserInfo *cmd, CommandContainer *cont) { if (authState == PasswordWrong) @@ -359,6 +406,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandC if (!r) return RespNameNotFound; + QMutexLocker serverLocker(&server->serverMutex); QMutexLocker roomLocker(&r->roomMutex); r->addClient(this); rooms.insert(r->getId(), r); @@ -375,6 +423,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandC for (int j = 0; j < gamePlayers.size(); ++j) if (gamePlayers[j]->getUserInfo()->getName() == userInfo->getName()) { gamePlayers[j]->setProtocolHandler(this); + game->postConnectionStatusUpdate(gamePlayers[j], true); games.insert(game->getGameId(), QPair(game, gamePlayers[j])); enqueueProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), gamePlayers[j]->getPlayerId(), gamePlayers[j]->getSpectator(), game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), true)); @@ -384,7 +433,10 @@ ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandC } } - cont->setResponse(new Response_JoinRoom(cont->getCmdId(), RespOk, r->getInfo(true))); + ServerInfo_Room *info = r->getInfo(true); + if (getCompressionSupport()) + info->setCompressed(true); + cont->setResponse(new Response_JoinRoom(cont->getCmdId(), RespOk, info)); return RespNothing; } @@ -416,8 +468,9 @@ ResponseCode Server_ProtocolHandler::cmdRoomSay(Command_RoomSay *cmd, CommandCon if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval())) return RespChatFlood; } + msg.replace(QChar('\n'), QChar(' ')); - room->say(this, cmd->getMessage()); + room->say(this, msg); return RespOk; } @@ -433,7 +486,10 @@ ResponseCode Server_ProtocolHandler::cmdListUsers(Command_ListUsers * /*cmd*/, C acceptsUserListChanges = true; - cont->setResponse(new Response_ListUsers(cont->getCmdId(), RespOk, resultList)); + ProtocolResponse *resp = new Response_ListUsers(cont->getCmdId(), RespOk, resultList); + if (getCompressionSupport()) + resp->setCompressed(true); + cont->setResponse(resp); return RespNothing; } @@ -451,7 +507,10 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm for (int i = 0; i < gameTypeList.size(); ++i) gameTypes.append(gameTypeList[i]->getData()); - Server_Game *game = room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); + QString description = cmd->getDescription(); + if (description.size() > 60) + description = description.left(60); + Server_Game *game = room->createGame(description, cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); Server_Player *creator = game->getPlayers().values().first(); @@ -712,7 +771,7 @@ ResponseCode Server_ProtocolHandler::cmdFlipCard(Command_FlipCard *cmd, CommandC if (!zone->hasCoords()) return RespContextError; - Server_Card *card = zone->getCard(cmd->getCardId(), false); + Server_Card *card = zone->getCard(cmd->getCardId()); if (!card) return RespNameNotFound; @@ -741,7 +800,7 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm if (!startzone) return RespNameNotFound; - Server_Card *card = startzone->getCard(cmd->getCardId(), false); + Server_Card *card = startzone->getCard(cmd->getCardId()); if (!card) return RespNameNotFound; @@ -763,7 +822,7 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm // Possibly a flag will have to be introduced for this sometime. if (!targetzone->hasCoords()) return RespContextError; - targetCard = targetzone->getCard(cmd->getTargetCardId(), false); + targetCard = targetzone->getCard(cmd->getTargetCardId()); if (targetCard) if (targetCard->getParentCard()) return RespContextError; @@ -873,14 +932,14 @@ ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, Co return RespNameNotFound; if (startZone->getType() != PublicZone) return RespContextError; - Server_Card *startCard = startZone->getCard(cmd->getStartCardId(), false); + Server_Card *startCard = startZone->getCard(cmd->getStartCardId()); if (!startCard) return RespNameNotFound; Server_Card *targetCard = 0; if (!playerTarget) { if (targetZone->getType() != PublicZone) return RespContextError; - targetCard = targetZone->getCard(cmd->getTargetCardId(), false); + targetCard = targetZone->getCard(cmd->getTargetCardId()); } Server_ArrowTarget *targetItem; @@ -959,7 +1018,7 @@ ResponseCode Server_ProtocolHandler::cmdSetCardCounter(Command_SetCardCounter *c if (!zone->hasCoords()) return RespContextError; - Server_Card *card = zone->getCard(cmd->getCardId(), false); + Server_Card *card = zone->getCard(cmd->getCardId()); if (!card) return RespNameNotFound; @@ -986,7 +1045,7 @@ ResponseCode Server_ProtocolHandler::cmdIncCardCounter(Command_IncCardCounter *c if (!zone->hasCoords()) return RespContextError; - Server_Card *card = zone->getCard(cmd->getCardId(), false); + Server_Card *card = zone->getCard(cmd->getCardId()); if (!card) return RespNameNotFound; @@ -1199,7 +1258,7 @@ ResponseCode Server_ProtocolHandler::cmdRevealCards(Command_RevealCards *cmd, Co return RespContextError; cardsToReveal.append(zone->cards.at(rng->getNumber(0, zone->cards.size() - 1))); } else { - Server_Card *card = zone->getCard(cmd->getCardId(), false); + Server_Card *card = zone->getCard(cmd->getCardId()); if (!card) return RespNameNotFound; cardsToReveal.append(card); diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index c65d8d02..1902f1d8 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -30,6 +30,7 @@ protected: QMap buddyList, ignoreList; void prepareDestroy(); + virtual bool getCompressionSupport() const = 0; private: QList itemQueue; QList messageSizeOverTime, messageCountOverTime; @@ -49,6 +50,7 @@ private: virtual ResponseCode cmdDeckDel(Command_DeckDel *cmd, CommandContainer *cont) = 0; virtual ResponseCode cmdDeckUpload(Command_DeckUpload *cmd, CommandContainer *cont) = 0; virtual ResponseCode cmdDeckDownload(Command_DeckDownload *cmd, CommandContainer *cont) = 0; + ResponseCode cmdGetGamesOfUser(Command_GetGamesOfUser *cmd, CommandContainer *cont); ResponseCode cmdGetUserInfo(Command_GetUserInfo *cmd, CommandContainer *cont); ResponseCode cmdListRooms(Command_ListRooms *cmd, CommandContainer *cont); ResponseCode cmdJoinRoom(Command_JoinRoom *cmd, CommandContainer *cont); @@ -87,8 +89,9 @@ private: ResponseCode cmdDumpZone(Command_DumpZone *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdStopDumpZone(Command_StopDumpZone *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdRevealCards(Command_RevealCards *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); - virtual ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont) = 0; virtual ResponseCode cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer *cont) = 0; + virtual ResponseCode cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer *cont) = 0; + virtual ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont) = 0; ResponseCode processCommandHelper(Command *command, CommandContainer *cont); private slots: diff --git a/common/server_room.cpp b/common/server_room.cpp index b954fa81..9e9aa571 100644 --- a/common/server_room.cpp +++ b/common/server_room.cpp @@ -26,7 +26,7 @@ Server *Server_Room::getServer() const return static_cast(parent()); } -ServerInfo_Room *Server_Room::getInfo(bool complete) const +ServerInfo_Room *Server_Room::getInfo(bool complete, bool showGameTypes) const { QMutexLocker locker(&roomMutex); @@ -40,10 +40,10 @@ ServerInfo_Room *Server_Room::getInfo(bool complete) const for (int i = 0; i < size(); ++i) userList.append(new ServerInfo_User(at(i)->getUserInfo(), false)); - + } + if (complete || showGameTypes) for (int i = 0; i < gameTypes.size(); ++i) gameTypeList.append(new ServerInfo_GameType(i, gameTypes[i])); - } return new ServerInfo_Room(id, name, description, games.size(), size(), autoJoin, gameList, userList, gameTypeList); } @@ -130,3 +130,15 @@ int Server_Room::getGamesCreatedByUser(const QString &userName) const ++result; return result; } + +QList Server_Room::getGamesOfUser(const QString &userName) const +{ + QList result; + QMapIterator gamesIterator(games); + while (gamesIterator.hasNext()) { + Server_Game *game = gamesIterator.next().value(); + if (game->containsUser(userName)) + result.append(game->getInfo()); + } + return result; +} diff --git a/common/server_room.h b/common/server_room.h index b99b626f..663c9cee 100644 --- a/common/server_room.h +++ b/common/server_room.h @@ -11,6 +11,7 @@ class Server_ProtocolHandler; class RoomEvent; class ServerInfo_User; class ServerInfo_Room; +class ServerInfo_Game; class Server_Game; class Server; @@ -37,8 +38,9 @@ public: QString getJoinMessage() const { return joinMessage; } const QMap &getGames() const { return games; } Server *getServer() const; - ServerInfo_Room *getInfo(bool complete) const; + ServerInfo_Room *getInfo(bool complete, bool showGameTypes = false) const; int getGamesCreatedByUser(const QString &name) const; + QList getGamesOfUser(const QString &name) const; void addClient(Server_ProtocolHandler *client); void removeClient(Server_ProtocolHandler *client); diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 06effa01..7bd64c58 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -111,7 +111,6 @@ CREATE TABLE IF NOT EXISTS `cockatrice_users` ( `avatar_bmp` blob NOT NULL, `registrationDate` datetime NOT NULL, `active` tinyint(1) NOT NULL, - `banned` tinyint(1) NOT NULL, `token` char(32) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) @@ -149,3 +148,12 @@ CREATE TABLE `cockatrice_buddylist` ( KEY `id_user2` (`id_user2`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE `cockatrice_bans` ( + `id_user` int(7) unsigned zerofill NOT NULL, + `id_admin` int(7) unsigned zerofill NOT NULL, + `time_from` datetime NOT NULL, + `minutes` int(6) NOT NULL, + `reason` text NOT NULL, + KEY `id_user` (`id_user`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index a36e3332..247111be 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -129,15 +129,20 @@ int main(int argc, char *argv[]) if (testRandom) testRNG(); - Servatrice server(settings); + Servatrice *server = new Servatrice(settings); + QObject::connect(server, SIGNAL(destroyed()), &app, SLOT(quit()), Qt::QueuedConnection); std::cerr << "-------------------------" << std::endl; std::cerr << "Server initialized." << std::endl; int retval = app.exec(); + std::cerr << "Server quit." << std::endl; + std::cerr << "-------------------------" << std::endl; + delete rng; delete settings; + delete loggerThread; return retval; } diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index eaca1de6..51ad91cb 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -44,7 +44,7 @@ void Servatrice_TcpServer::incomingConnection(int socketDescriptor) } Servatrice::Servatrice(QSettings *_settings, QObject *parent) - : Server(parent), dbMutex(QMutex::Recursive), settings(_settings), uptime(0) + : Server(parent), dbMutex(QMutex::Recursive), settings(_settings), uptime(0), shutdownTimer(0) { pingClock = new QTimer(this); connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout())); @@ -65,8 +65,8 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent) statusUpdateClock->start(statusUpdateTime); } - bool threaded = settings->value("server/threaded", false).toInt(); - tcpServer = new Servatrice_TcpServer(this, threaded); + threaded = settings->value("server/threaded", false).toInt(); + tcpServer = new Servatrice_TcpServer(this, threaded, this); int port = settings->value("server/port", 4747).toInt(); qDebug() << "Starting server on port" << port; if (tcpServer->listen(QHostAddress::Any, port)) @@ -119,6 +119,7 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent) Servatrice::~Servatrice() { prepareDestroy(); + QSqlDatabase::database().close(); } bool Servatrice::openDatabase() @@ -168,25 +169,32 @@ bool Servatrice::execSqlQuery(QSqlQuery &query) return false; } -AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QString &password) +AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) { + serverMutex.lock(); + QHostAddress address = static_cast(handler)->getPeerAddress(); + for (int i = 0; i < addressBanList.size(); ++i) + if (address == addressBanList[i].first) + return PasswordWrong; + serverMutex.unlock(); + QMutexLocker locker(&dbMutex); const QString method = settings->value("authentication/method").toString(); if (method == "none") return UnknownUser; else if (method == "sql") { checkSql(); - + QSqlQuery query; - query.prepare("select banned, password from " + dbPrefix + "_users where name = :name and active = 1"); + query.prepare("select a.password, time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.id_user = a.id and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.id_user = a.id) where a.name = :name and a.active = 1"); query.bindValue(":name", user); if (!execSqlQuery(query)) return PasswordWrong; if (query.next()) { - if (query.value(0).toInt()) + if (query.value(1).toInt() || query.value(2).toInt()) return PasswordWrong; - if (query.value(1).toString() == password) + if (query.value(0).toString() == password) return PasswordRight; else return PasswordWrong; @@ -233,7 +241,7 @@ ServerInfo_User *Servatrice::evalUserQueryResult(const QSqlQuery &query, bool co int userLevel = ServerInfo_User::IsUser | ServerInfo_User::IsRegistered; if (is_admin == 1) - userLevel |= ServerInfo_User::IsAdmin; + userLevel |= ServerInfo_User::IsAdmin | ServerInfo_User::IsModerator; else if (is_admin == 2) userLevel |= ServerInfo_User::IsModerator; @@ -324,19 +332,6 @@ QMap Servatrice::getIgnoreList(const QString &name) return result; } -bool Servatrice::getUserBanned(Server_ProtocolHandler *client, const QString &userName) const -{ - QMutexLocker locker(&serverMutex); - QHostAddress address = static_cast(client)->getPeerAddress(); - for (int i = 0; i < addressBanList.size(); ++i) - if (address == addressBanList[i].first) - return true; - for (int i = 0; i < nameBanList.size(); ++i) - if (userName == nameBanList[i].first) - return true; - return false; -} - void Servatrice::updateBanTimer() { QMutexLocker locker(&serverMutex); @@ -345,11 +340,6 @@ void Servatrice::updateBanTimer() addressBanList.removeAt(i); else ++i; - for (int i = 0; i < nameBanList.size(); ) - if (--(nameBanList[i].second) <= 0) - nameBanList.removeAt(i); - else - ++i; } void Servatrice::updateLoginMessage() @@ -374,18 +364,55 @@ void Servatrice::updateLoginMessage() void Servatrice::statusUpdate() { - QMutexLocker locker(&dbMutex); + const int uc = getUsersCount(); // for correct mutex locking order + const int gc = getGamesCount(); + uptime += statusUpdateClock->interval() / 1000; + QMutexLocker locker(&dbMutex); checkSql(); QSqlQuery query; query.prepare("insert into " + dbPrefix + "_uptime (id_server, timest, uptime, users_count, games_count) values(:id, NOW(), :uptime, :users_count, :games_count)"); query.bindValue(":id", serverId); query.bindValue(":uptime", uptime); - query.bindValue(":users_count", getUsersCount()); - query.bindValue(":games_count", getGamesCount()); + query.bindValue(":users_count", uc); + query.bindValue(":games_count", gc); execSqlQuery(query); } -const QString Servatrice::versionString = "Servatrice 0.20110527"; +void Servatrice::scheduleShutdown(const QString &reason, int minutes) +{ + QMutexLocker locker(&serverMutex); + + shutdownReason = reason; + shutdownMinutes = minutes + 1; + if (minutes > 0) { + shutdownTimer = new QTimer; + connect(shutdownTimer, SIGNAL(timeout()), this, SLOT(shutdownTimeout())); + shutdownTimer->start(60000); + } + shutdownTimeout(); +} + +void Servatrice::shutdownTimeout() +{ + QMutexLocker locker(&serverMutex); + + --shutdownMinutes; + + GenericEvent *event; + if (shutdownMinutes) + event = new Event_ServerShutdown(shutdownReason, shutdownMinutes); + else + event = new Event_ConnectionClosed("server_shutdown"); + + for (int i = 0; i < clients.size(); ++i) + clients[i]->sendProtocolItem(event, false); + delete event; + + if (!shutdownMinutes) + deleteLater(); +} + +const QString Servatrice::versionString = "Servatrice 0.20110625"; diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index f1174c91..8dae2c91 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -50,6 +50,7 @@ class Servatrice : public Server private slots: void statusUpdate(); void updateBanTimer(); + void shutdownTimeout(); public: QMutex dbMutex; static const QString versionString; @@ -67,18 +68,18 @@ public: int getMaxMessageCountPerInterval() const { return maxMessageCountPerInterval; } int getMaxMessageSizePerInterval() const { return maxMessageSizePerInterval; } int getMaxGamesPerUser() const { return maxGamesPerUser; } + bool getThreaded() const { return threaded; } QString getDbPrefix() const { return dbPrefix; } void updateLoginMessage(); ServerInfo_User *getUserData(const QString &name); int getUsersWithAddress(const QHostAddress &address) const; QMap getBuddyList(const QString &name); QMap getIgnoreList(const QString &name); - bool getUserBanned(Server_ProtocolHandler *client, const QString &userName) const; void addAddressBan(const QHostAddress &address, int minutes) { addressBanList.append(QPair(address, minutes)); } - void addNameBan(const QString &name, int minutes) { nameBanList.append(QPair(name, minutes)); } + void scheduleShutdown(const QString &reason, int minutes); protected: bool userExists(const QString &user); - AuthenticationResult checkUserPassword(const QString &user, const QString &password); + AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password); private: QTimer *pingClock, *statusUpdateClock, *banTimeoutClock; QTcpServer *tcpServer; @@ -86,12 +87,16 @@ private: QString dbPrefix; QSettings *settings; int serverId; + bool threaded; int uptime; QList > addressBanList; - QList > nameBanList; int maxGameInactivityTime, maxPlayerInactivityTime; int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser; ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete); + + QString shutdownReason; + int shutdownMinutes; + QTimer *shutdownTimer; }; #endif diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index f8e01ab4..91c7a6b9 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -33,7 +33,7 @@ #include "server_logger.h" ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent) - : Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), topLevelItem(0) + : Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), topLevelItem(0), compressionSupport(false) { xmlWriter = new QXmlStreamWriter(&xmlBuffer); xmlReader = new QXmlStreamReader; @@ -69,6 +69,7 @@ ServerSocketInterface::~ServerSocketInterface() delete xmlReader; delete socket; socket = 0; + delete topLevelItem; } void ServerSocketInterface::processProtocolItem(ProtocolItem *item) @@ -102,6 +103,8 @@ void ServerSocketInterface::readClient() if (topLevelItem) topLevelItem->readElement(xmlReader); else if (xmlReader->isStartElement() && (xmlReader->name().toString() == "cockatrice_client_stream")) { + if (xmlReader->attributes().value("comp").toString().toInt() == 1) + compressionSupport = true; topLevelItem = new TopLevelProtocolItem; connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *))); } @@ -296,7 +299,10 @@ ResponseCode ServerSocketInterface::cmdDeckList(Command_DeckList * /*cmd*/, Comm if (!deckListHelper(root)) return RespContextError; - cont->setResponse(new Response_DeckList(cont->getCmdId(), RespOk, root)); + ProtocolResponse *resp = new Response_DeckList(cont->getCmdId(), RespOk, root); + if (getCompressionSupport()) + resp->setCompressed(true); + cont->setResponse(resp); return RespNothing; } @@ -455,8 +461,8 @@ ResponseCode ServerSocketInterface::cmdDeckDownload(Command_DeckDownload *cmd, C return RespNothing; } -// ADMIN FUNCTIONS. -// Permission is checked by the calling function. +// MODERATOR FUNCTIONS. +// May be called by admins and moderators. Permission is checked by the calling function. ResponseCode ServerSocketInterface::cmdUpdateServerMessage(Command_UpdateServerMessage * /*cmd*/, CommandContainer * /*cont*/) { @@ -464,6 +470,15 @@ ResponseCode ServerSocketInterface::cmdUpdateServerMessage(Command_UpdateServerM return RespOk; } +// ADMIN FUNCTIONS. +// Permission is checked by the calling function. + +ResponseCode ServerSocketInterface::cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer * /*cont*/) +{ + servatrice->scheduleShutdown(cmd->getReason(), cmd->getMinutes()); + return RespOk; +} + ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer * /*cont*/) { QString userName = cmd->getUserName(); @@ -475,14 +490,14 @@ ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd, ServerSocketInterface *user = static_cast(server->getUsers().value(userName)); if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) { // Registered users can be banned by name. - if (minutes == 0) { - QMutexLocker locker(&servatrice->dbMutex); - QSqlQuery query; - query.prepare("update " + servatrice->getDbPrefix() + "_users set banned=1 where name = :name"); - query.bindValue(":name", userName); - servatrice->execSqlQuery(query); - } else - servatrice->addNameBan(userName, minutes); + QMutexLocker locker(&servatrice->dbMutex); + QSqlQuery query; + query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (id_user, id_admin, time_from, minutes, reason) values(:id_user, :id_admin, NOW(), :minutes, :reason)"); + query.bindValue(":id_user", getUserIdInDB(userName)); + query.bindValue(":id_admin", getUserIdInDB(userInfo->getName())); + query.bindValue(":minutes", minutes); + query.bindValue(":reason", cmd->getReason() + "\n"); + servatrice->execSqlQuery(query); } else { // Unregistered users must be banned by IP address. // Indefinite address bans are not reasonable -> default to 30 minutes. diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 8f7b937e..14cf7030 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -51,6 +51,7 @@ private: QXmlStreamReader *xmlReader; QString xmlBuffer; TopLevelProtocolItem *topLevelItem; + bool compressionSupport; int getUserIdInDB(const QString &name) const; ResponseCode cmdAddToList(Command_AddToList *cmd, CommandContainer *cont); @@ -66,8 +67,11 @@ private: ResponseCode cmdDeckUpload(Command_DeckUpload *cmd, CommandContainer *cont); DeckList *getDeckFromDatabase(int deckId); ResponseCode cmdDeckDownload(Command_DeckDownload *cmd, CommandContainer *cont); - ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont); ResponseCode cmdBanFromServer(Command_BanFromServer *cmd, CommandContainer *cont); + ResponseCode cmdShutdownServer(Command_ShutdownServer *cmd, CommandContainer *cont); + ResponseCode cmdUpdateServerMessage(Command_UpdateServerMessage *cmd, CommandContainer *cont); +protected: + bool getCompressionSupport() const { return compressionSupport; } public: ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0); ~ServerSocketInterface(); diff --git a/sounds/cuckoo.raw b/sounds/cuckoo.raw new file mode 100644 index 00000000..52f0cbb6 Binary files /dev/null and b/sounds/cuckoo.raw differ diff --git a/sounds/cuckoo.wav b/sounds/cuckoo.wav new file mode 100644 index 00000000..5eba46f9 Binary files /dev/null and b/sounds/cuckoo.wav differ