Revealing a library to a player now grants that player permission to drag cards out of that library onto his own table. This permission is revoked by shuffling the library. The zone view window tracks content changes of the zone for as long as the permission lasts so that card ID changes are kept track of. This hopefully fixes issues #5 and #12.

This commit is contained in:
Max-Wilhelm Bruker 2012-03-24 17:48:25 +01:00
parent 2ce18a82f5
commit adbb607700
30 changed files with 231 additions and 101 deletions

View file

@ -14,11 +14,12 @@ message Command_MoveCard {
extend GameCommand {
optional Command_MoveCard ext = 1027;
}
optional string start_zone = 1;
optional ListOfCardsToMove cards_to_move = 2;
optional sint32 target_player_id = 3 [default = -1];
optional string target_zone = 4;
optional sint32 x = 5 [default = -1];
optional sint32 y = 6 [default = -1];
optional sint32 start_player_id = 1 [default = -1];
optional string start_zone = 2;
optional ListOfCardsToMove cards_to_move = 3;
optional sint32 target_player_id = 4 [default = -1];
optional string target_zone = 5;
optional sint32 x = 6 [default = -1];
optional sint32 y = 7 [default = -1];
}

View file

@ -6,4 +6,5 @@ message Command_RevealCards {
optional string zone_name = 1;
optional sint32 card_id = 2 [default = -1];
optional sint32 player_id = 3 [default = -1];
optional bool grant_write_access = 4;
}

View file

@ -6,12 +6,13 @@ message Event_MoveCard {
}
optional sint32 card_id = 1 [default = -1];
optional string card_name = 2;
optional string start_zone = 3;
optional sint32 position = 4 [default = -1];
optional sint32 target_player_id = 5 [default = -1];
optional string target_zone = 6;
optional sint32 x = 7 [default = -1];
optional sint32 y = 8 [default = -1];
optional sint32 new_card_id = 9 [default = -1];
optional bool face_down = 10;
optional sint32 start_player_id = 3 [default = -1];
optional string start_zone = 4;
optional sint32 position = 5 [default = -1];
optional sint32 target_player_id = 6 [default = -1];
optional string target_zone = 7;
optional sint32 x = 8 [default = -1];
optional sint32 y = 9 [default = -1];
optional sint32 new_card_id = 10 [default = -1];
optional bool face_down = 11;
}

View file

@ -9,4 +9,5 @@ message Event_RevealCards {
optional sint32 card_id = 2 [default = -1];
optional sint32 other_player_id = 3 [default = -1];
repeated ServerInfo_Card cards = 4;
optional bool grant_write_access = 5;
}

View file

@ -43,6 +43,8 @@ void Server_CardZone::shuffle()
for (int i = cards.size(); i; i--)
temp.append(cards.takeAt(rng->getNumber(0, i - 1)));
cards = temp;
playersWithWritePermission.clear();
}
int Server_CardZone::removeCard(Server_Card *card)
@ -206,4 +208,10 @@ void Server_CardZone::clear()
for (int i = 0; i < cards.size(); i++)
delete cards.at(i);
cards.clear();
playersWithWritePermission.clear();
}
void Server_CardZone::addWritePermission(int playerId)
{
playersWithWritePermission.insert(playerId);
}

View file

@ -23,6 +23,7 @@
#include <QList>
#include <QString>
#include <QMap>
#include <QSet>
#include "pb/serverinfo_zone.pb.h"
class Server_Card;
@ -37,6 +38,7 @@ private:
bool has_coords;
ServerInfo_Zone::ZoneType type;
int cardsBeingLookedAt;
QSet<int> playersWithWritePermission;
public:
Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type);
~Server_CardZone();
@ -60,6 +62,8 @@ public:
void insertCard(Server_Card *card, int x, int y);
void shuffle();
void clear();
void addWritePermission(int playerId);
const QSet<int> &getPlayersWithWritePermission() const { return playersWithWritePermission; }
};
#endif

View file

@ -342,21 +342,6 @@ Response::ResponseCode Server_Player::undoDraw(GameEventStorage &ges)
return retVal;
}
Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, const QString &_startZone, const QList<const CardToMove *> &_cards, int targetPlayerId, const QString &_targetZone, int x, int y)
{
QMutexLocker locker(&game->gameMutex);
Server_CardZone *startzone = getZones().value(_startZone);
Server_Player *targetPlayer = game->getPlayers().value(targetPlayerId);
if (!targetPlayer)
return Response::RespNameNotFound;
Server_CardZone *targetzone = targetPlayer->getZones().value(_targetZone);
if ((!startzone) || (!targetzone))
return Response::RespNameNotFound;
return moveCard(ges, startzone, _cards, targetzone, x, y);
}
class Server_Player::MoveCardCompareFunctor {
private:
int x;
@ -510,6 +495,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, Server_Car
privatePosition = position;
Event_MoveCard eventOthers;
eventOthers.set_start_player_id(startzone->getPlayer()->getPlayerId());
eventOthers.set_start_zone(startzone->getName().toStdString());
eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId());
if (startzone != targetzone)
@ -858,11 +844,31 @@ Response::ResponseCode Server_Player::cmdMoveCard(const Command_MoveCard &cmd, R
if (conceded)
return Response::RespContextError;
Server_Player *startPlayer = game->getPlayers().value(cmd.has_start_player_id() ? cmd.start_player_id() : playerId);
if (!startPlayer)
return Response::RespNameNotFound;
Server_CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(cmd.start_zone()));
if (!startZone)
return Response::RespNameNotFound;
if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId)))
return Response::RespContextError;
Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id());
if (!targetPlayer)
return Response::RespNameNotFound;
Server_CardZone *targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone()));
if (!targetZone)
return Response::RespNameNotFound;
if ((startPlayer != this) && (targetPlayer != this))
return Response::RespContextError;
QList<const CardToMove *> cardsToMove;
for (int i = 0; i < cmd.cards_to_move().card_size(); ++i)
cardsToMove.append(&cmd.cards_to_move().card(i));
return moveCard(ges, QString::fromStdString(cmd.start_zone()), cardsToMove, cmd.target_player_id(), QString::fromStdString(cmd.target_zone()), cmd.x(), cmd.y());
return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y());
}
Response::ResponseCode Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges)
@ -1470,6 +1476,7 @@ Response::ResponseCode Server_Player::cmdRevealCards(const Command_RevealCards &
}
Event_RevealCards eventOthers;
eventOthers.set_grant_write_access(cmd.grant_write_access());
eventOthers.set_zone_name(zone->getName().toStdString());
if (cmd.has_card_id())
eventOthers.set_card_id(cmd.card_id());
@ -1511,10 +1518,20 @@ Response::ResponseCode Server_Player::cmdRevealCards(const Command_RevealCards &
}
if (cmd.has_player_id()) {
if (cmd.grant_write_access())
zone->addWritePermission(cmd.player_id());
ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id());
ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers);
} else
} else {
if (cmd.grant_write_access()) {
const QList<int> &playerIds = game->getPlayers().keys();
for (int i = 0; i < playerIds.size(); ++i)
zone->addWritePermission(playerIds[i]);
}
ges.enqueueGameEvent(eventPrivate, playerId);
}
return Response::RespOk;
}

View file

@ -117,7 +117,6 @@ public:
Response::ResponseCode drawCards(GameEventStorage &ges, int number);
Response::ResponseCode undoDraw(GameEventStorage &ges);
Response::ResponseCode moveCard(GameEventStorage &ges, const QString &_startZone, const QList<const CardToMove *> &_cards, int _targetPlayer, const QString &_targetZone, int _x, int _y);
Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList<const CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false);
void unattachCard(GameEventStorage &ges, Server_Card *card);
Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue);

View file

@ -194,8 +194,6 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
if (authState == NotLoggedIn)
return Response::RespLoginNeeded;
qDebug() << QString::fromStdString(cont.DebugString());
QMap<int, QPair<int, int> > gameMap = getGames();
if (!gameMap.contains(cont.game_id()))
return Response::RespNotInRoom;