PB: server compiles again, standalone RemoteClient is able to log in

This commit is contained in:
Max-Wilhelm Bruker 2011-12-30 21:50:25 +01:00
parent 10018280e5
commit d3b96b1a88
39 changed files with 988 additions and 807 deletions

View file

@ -24,6 +24,7 @@ public:
{
return QColor(value / 65536, (value % 65536) / 256, value % 256);
}
#endif
color get_color() const // HACK
{
color c;
@ -32,7 +33,6 @@ public:
c.set_b(value % 256);
return c;
}
#endif
};
#endif

View file

@ -0,0 +1,10 @@
import "session_event.proto";
message Event_ServerIdentification {
extend SessionEvent {
optional Event_ServerIdentification ext = 500;
}
optional string server_name = 1;
optional string server_version = 2;
optional uint32 protocol_version = 3;
}

View file

@ -1,5 +1,6 @@
message SessionEvent {
enum SessionEventType {
SERVER_IDENTIFICATION = 500;
SERVER_MESSAGE = 1000;
SERVER_SHUTDOWN = 1001;
CONNECTION_CLOSED = 1002;

View file

@ -1,55 +1,3 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "protocol.h"
ProtocolItem::ProtocolItem(const QString &_itemType, const QString &_itemSubType)
: SerializableItem_Map(_itemType, _itemSubType), receiverMayDelete(true)
{
}
void ProtocolItem::initializeHash()
{
}
BlaContainer::BlaContainer()
: ProtocolItem("container", "cmd"), resp(0), gameEventQueuePublic(0), gameEventQueueOmniscient(0), gameEventQueuePrivate(0), privatePlayerId(-1)
{
}
void BlaContainer::setResponse(ProtocolResponse *_resp)
{
delete resp;
resp = _resp;
}
void BlaContainer::enqueueGameEventPublic(GameEvent *event, int gameId, GameEventContext *context)
{
if (!gameEventQueuePublic)
gameEventQueuePublic = new GameEventContainer(QList<GameEvent *>(), gameId);
gameEventQueuePublic->addGameEvent(event);
if (context)
gameEventQueuePublic->setContext(context);
}
void BlaContainer::enqueueGameEventOmniscient(GameEvent *event, int gameId, GameEventContext *context)
{
if (!gameEventQueueOmniscient)
gameEventQueueOmniscient = new GameEventContainer(QList<GameEvent *>(), gameId);
gameEventQueueOmniscient->addGameEvent(event);
if (context)
gameEventQueueOmniscient->setContext(context);
}
void BlaContainer::enqueueGameEventPrivate(GameEvent *event, int gameId, int playerId, GameEventContext *context)
{
if (!gameEventQueuePrivate)
gameEventQueuePrivate = new GameEventContainer(QList<GameEvent *>(), gameId);
gameEventQueuePrivate->addGameEvent(event);
privatePlayerId = playerId;
if (context)
gameEventQueuePrivate->setContext(context);
}
/*
Response_DeckDownload::Response_DeckDownload(int _cmdId, ResponseCode _responseCode, DeckList *_deck)
: ProtocolResponse(_cmdId, _responseCode, "deck_download")

View file

@ -6,66 +6,70 @@
#include <QHash>
#include <QObject>
#include <QVariant>
#include "serializable_item.h"
#include <QPair>
#include <google/protobuf/message.h>
#include "pb/server_message.pb.h"
class QXmlStreamReader;
class QXmlStreamWriter;
class QXmlStreamAttributes;
class ProtocolResponse;
class DeckList;
class GameEvent;
class GameEventContainer;
class GameEventContext;
class MoveCardToZone;
class ProtocolItem : public SerializableItem_Map {
Q_OBJECT
private:
bool receiverMayDelete;
static const int protocolVersion = 13;
class GameEventStorageItem {
public:
static const int protocolVersion = 13;
virtual int getItemId() const = 0;
bool getReceiverMayDelete() const { return receiverMayDelete; }
void setReceiverMayDelete(bool _receiverMayDelete) { receiverMayDelete = _receiverMayDelete; }
ProtocolItem(const QString &_itemType, const QString &_itemSubType);
bool isEmpty() const { return false; }
enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02};
Q_DECLARE_FLAGS(EventRecipients, EventRecipient)
private:
::google::protobuf::Message *event;
int playerId;
EventRecipients recipients;
public:
GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients)
: event(_event.New()), playerId(_playerId), recipients(_recipients)
{
event->CopyFrom(_event);
}
~GameEventStorageItem()
{
delete event;
}
const ::google::protobuf::Message &getEvent() const { return *event; }
int getPlayerId() const { return playerId; }
EventRecipients getRecipients() const { return recipients; }
};
// ----------------
// --- COMMANDS ---
// ----------------
Q_DECLARE_OPERATORS_FOR_FLAGS(GameEventStorageItem::EventRecipients)
class GameEventStorage {
private:
::google::protobuf::Message *gameEventContext;
GameEventContainer *gameEventQueuePublic;
GameEventContainer *gameEventQueueOmniscient;
GameEventContainer *gameEventQueuePrivate;
QList<GameEventStorageItem *> gameEventList;
int privatePlayerId;
public:
GameEventStorage();
~GameEventStorage();
GameEventStorage()
: gameEventContext(0)
{
}
~GameEventStorage()
{
delete gameEventContext;
for (int i = 0; i < gameEventList.size(); ++i)
delete gameEventList[i];
}
void setGameEventContext(::google::protobuf::Message *_gameEventContext) { gameEventContext = _gameEventContext; }
::google::protobuf::Message *getGameEventContext() const { return gameEventContext; }
GameEventContainer *getGameEventQueuePublic() const { return gameEventQueuePublic; }
void enqueueGameEventPublic(const ::google::protobuf::Message &event, int playerId);
GameEventContainer *getGameEventQueueOmniscient() const { return gameEventQueueOmniscient; }
void enqueueGameEventOmniscient(const ::google::protobuf::Message &event, int playerId);
GameEventContainer *getGameEventQueuePrivate() const { return gameEventQueuePrivate; }
void enqueueGameEventPrivate(const ::google::protobuf::Message &event, int playerId);
// XXX - DRAN DENKEN, dass privatePlayerId gesetzt wird
int getPrivatePlayerId() const { return privatePlayerId; }
void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId);
void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int _privatePlayerId = -1)
{
gameEventList.append(new GameEventStorageItem(event, playerId, recipients));
if (_privatePlayerId != -1)
privatePlayerId = _privatePlayerId;
}
};
class ResponseContainer {
@ -74,7 +78,14 @@ private:
QList<QPair<ServerMessage::MessageType, ::google::protobuf::Message *> > preResponseQueue, postResponseQueue;
public:
ResponseContainer() : responseExtension(0) { }
~ResponseContainer() { /* XXX responseExtension und Inhalt beider Listen löschen */ }
~ResponseContainer()
{
delete responseExtension;
for (int i = 0; i < preResponseQueue.size(); ++i)
delete preResponseQueue[i].second;
for (int i = 0; i < postResponseQueue.size(); ++i)
delete postResponseQueue[i].second;
}
void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; }
::google::protobuf::Message *getResponseExtension() const { return responseExtension; }
void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { preResponseQueue.append(qMakePair(type, item)); }

View file

@ -22,7 +22,9 @@
#include "server_counter.h"
#include "server_room.h"
#include "server_protocolhandler.h"
#include "protocol_datastructures.h"
#include "pb/event_user_joined.pb.h"
#include "pb/event_user_left.pb.h"
#include "pb/event_list_rooms.pb.h"
#include <QCoreApplication>
#include <QDebug>
@ -56,14 +58,13 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
if (authState == PasswordWrong)
return authState;
ServerInfo_User *data = getUserData(name);
data->setAddress(session->getAddress());
name = data->getName(); // Compensate for case indifference
ServerInfo_User data = getUserData(name);
data.set_address(session->getAddress().toStdString());
name = QString::fromStdString(data.name()); // Compensate for case indifference
if (authState == PasswordRight) {
if (users.contains(name)) {
qDebug("Login denied: would overwrite old session");
delete data;
return WouldOverwriteOldSession;
}
} else if (authState == UnknownUser) {
@ -74,7 +75,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
while (users.contains(tempName) || userExists(tempName))
tempName = name + "_" + QString::number(++i);
name = tempName;
data->setName(name);
data.set_name(name.toStdString());
}
session->setUserInfo(data);
@ -85,11 +86,13 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
session->setSessionId(startSession(name, session->getAddress()));
qDebug() << "session id:" << session->getSessionId();
Event_UserJoined *event = new Event_UserJoined(new ServerInfo_User(data, false));
Event_UserJoined event;
event.mutable_user_info()->CopyFrom(session->copyUserInfo(false));
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
for (int i = 0; i < clients.size(); ++i)
if (clients[i]->getAcceptsUserListChanges())
clients[i]->sendProtocolItem(event, false);
delete event;
clients[i]->sendProtocolItem(*se);
delete se;
return authState;
}
@ -106,14 +109,16 @@ void Server::removeClient(Server_ProtocolHandler *client)
clients.removeAt(clients.indexOf(client));
ServerInfo_User *data = client->getUserInfo();
if (data) {
Event_UserLeft *event = new Event_UserLeft(data->getName());
Event_UserLeft event;
event.set_name(data->name());
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
for (int i = 0; i < clients.size(); ++i)
if (clients[i]->getAcceptsUserListChanges())
clients[i]->sendProtocolItem(event, false);
delete event;
clients[i]->sendProtocolItem(*se);
delete se;
users.remove(data->getName());
qDebug() << "Server::removeClient: name=" << data->getName();
users.remove(QString::fromStdString(data->name()));
qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name());
if (client->getSessionId() != -1)
endSession(client->getSessionId());
@ -126,16 +131,19 @@ void Server::broadcastRoomUpdate()
{
QMutexLocker locker(&serverMutex);
Server_Room *room = static_cast<Server_Room *>(sender());
QList<ServerInfo_Room *> eventRoomList;
Event_ListRooms event;
ServerInfo_Room *roomInfo = event.add_room_list();
room->roomMutex.lock();
eventRoomList.append(new ServerInfo_Room(room->getId(), room->getName(), room->getDescription(), room->getGames().size(), room->size(), room->getAutoJoin()));
roomInfo->CopyFrom(room->getInfo(false));
room->roomMutex.unlock();
Event_ListRooms *event = new Event_ListRooms(eventRoomList);
SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
for (int i = 0; i < clients.size(); ++i)
if (clients[i]->getAcceptsRoomListChanges())
clients[i]->sendProtocolItem(event, false);
delete event;
clients[i]->sendProtocolItem(*se);
delete se;
}
void Server::addRoom(Server_Room *newRoom)

View file

@ -42,8 +42,10 @@ public:
virtual int getMaxGamesPerUser() const { return 0; }
virtual bool getThreaded() const = 0;
virtual QMap<QString, ServerInfo_User *> getBuddyList(const QString &name) = 0;
virtual QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name) = 0;
virtual QMap<QString, ServerInfo_User> getBuddyList(const QString &name) = 0;
virtual QMap<QString, ServerInfo_User> getIgnoreList(const QString &name) = 0;
virtual bool isInBuddyList(const QString &whoseList, const QString &who) = 0;
virtual bool isInIgnoreList(const QString &whoseList, const QString &who) = 0;
protected:
void prepareDestroy();
QList<Server_ProtocolHandler *> clients;
@ -54,7 +56,7 @@ protected:
virtual void endSession(int sessionId) = 0;
virtual bool userExists(const QString &user) = 0;
virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) = 0;
virtual ServerInfo_User *getUserData(const QString &name) = 0;
virtual ServerInfo_User getUserData(const QString &name) = 0;
int getUsersCount() const;
int getGamesCount() const;
int nextGameId;

View file

@ -26,7 +26,7 @@
#include "server_game.h"
#include "pb/command_move_card.pb.h"
Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type)
Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type)
: player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0)
{
}
@ -62,7 +62,7 @@ Server_Card *Server_CardZone::getCard(int id, int *position)
{
QMutexLocker locker(&player->getGame()->gameMutex);
if (type != HiddenZone) {
if (type != ServerInfo_Zone::HiddenZone) {
QListIterator<Server_Card *> CardIterator(cards);
int i = 0;
while (CardIterator.hasNext()) {
@ -160,7 +160,7 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const
return !coordMap.contains((x / 3) * 3);
}
void Server_CardZone::moveCard(BlaContainer *bla, QMap<int, Server_Card *> &coordMap, Server_Card *card, int x, int y)
void Server_CardZone::moveCard(GameEventStorage &ges, QMap<int, Server_Card *> &coordMap, Server_Card *card, int x, int y)
{
QMutexLocker locker(&player->getGame()->gameMutex);
@ -168,13 +168,13 @@ void Server_CardZone::moveCard(BlaContainer *bla, QMap<int, Server_Card *> &coor
CardToMove *cardToMove = new CardToMove;
cardToMove->set_card_id(card->getId());
player->moveCard(bla, this, QList<const CardToMove *>() << cardToMove, this, x, y, card->getFaceDown(), false);
player->moveCard(ges, this, QList<const CardToMove *>() << cardToMove, this, x, y, card->getFaceDown(), false);
delete cardToMove;
coordMap.insert(y * 10000 + x, card);
}
void Server_CardZone::fixFreeSpaces(BlaContainer *bla)
void Server_CardZone::fixFreeSpaces(GameEventStorage &ges)
{
QMutexLocker locker(&player->getGame()->gameMutex);
@ -193,15 +193,15 @@ void Server_CardZone::fixFreeSpaces(BlaContainer *bla)
if (!coordMap.contains(y * 10000 + baseX)) {
if (coordMap.contains(y * 10000 + baseX + 1))
moveCard(bla, coordMap, coordMap.value(y * 10000 + baseX + 1), baseX, y);
moveCard(ges, coordMap, coordMap.value(y * 10000 + baseX + 1), baseX, y);
else if (coordMap.contains(y * 10000 + baseX + 2)) {
moveCard(bla, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX, y);
moveCard(ges, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX, y);
continue;
} else
continue;
}
if (!coordMap.contains(y * 10000 + baseX + 1) && coordMap.contains(y * 10000 + baseX + 2))
moveCard(bla, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX + 1, y);
moveCard(ges, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX + 1, y);
}
}

View file

@ -22,6 +22,7 @@
#include <QList>
#include <QString>
#include <QMap>
#include "pb/serverinfo_zone.pb.h"
class Server_Card;

View file

@ -25,11 +25,26 @@
#include "server_card.h"
#include "server_cardzone.h"
#include "server_counter.h"
#include "decklist.h"
#include "pb/event_game_closed.pb.h"
#include "pb/event_game_host_changed.pb.h"
#include "pb/event_game_state_changed.pb.h"
#include "pb/event_connection_state_changed.pb.h"
#include "pb/event_kicked.pb.h"
#include "pb/event_ping.pb.h"
#include "pb/event_join.pb.h"
#include "pb/event_leave.pb.h"
#include "pb/event_delete_arrow.pb.h"
#include "pb/event_set_active_player.pb.h"
#include "pb/event_set_active_phase.pb.h"
#include "pb/serverinfo_playerping.pb.h"
#include <google/protobuf/descriptor.h>
#include "protocol.h"
#include <QTimer>
#include <QDebug>
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *_room)
: QObject(), room(_room), hostId(0), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0), gameMutex(QMutex::Recursive)
: QObject(), room(_room), hostId(0), creatorInfo(new ServerInfo_User(_creator->copyUserInfo(false))), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0), gameMutex(QMutex::Recursive)
{
connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection);
@ -47,7 +62,7 @@ Server_Game::~Server_Game()
QMutexLocker roomLocker(&room->roomMutex);
QMutexLocker locker(&gameMutex);
sendGameEvent(new Event_GameClosed);
sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1));
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext())
@ -56,13 +71,16 @@ Server_Game::~Server_Game()
room->removeGame(this);
delete creatorInfo;
creatorInfo = 0;
qDebug() << "Server_Game destructor: gameId=" << gameId;
}
void Server_Game::pingClockTimeout()
{
QMutexLocker locker(&gameMutex);
++secondsElapsed;
Event_Ping event;
event.set_seconds_elapsed(++secondsElapsed);
QList<ServerInfo_PlayerPing *> pingList;
QMapIterator<int, Server_Player *> playerIterator(players);
@ -79,9 +97,12 @@ void Server_Game::pingClockTimeout()
allPlayersInactive = false;
} else
pingTime = -1;
pingList.append(new ServerInfo_PlayerPing(player->getPlayerId(), pingTime));
ServerInfo_PlayerPing *pingInfo = event.add_ping_list();
pingInfo->set_player_id(player->getPlayerId());
pingInfo->set_ping_time(pingTime);
}
sendGameEvent(new Event_Ping(secondsElapsed, pingList));
sendGameEventContainer(prepareGameEvent(event, -1));
const int maxTime = room->getServer()->getMaxGameInactivityTime();
if (allPlayersInactive) {
@ -144,7 +165,15 @@ void Server_Game::doStartGameIfReady()
playerIterator.toFront();
while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value();
sendGameEventToPlayer(player, new Event_GameStateChanged(gameStarted, 0, 0, getGameState(player)));
Event_GameStateChanged event;
event.set_game_started(true);
event.set_active_player_id(0);
event.set_active_phase(0);
QListIterator<ServerInfo_Player> gameStateIterator(getGameState(player));
while (gameStateIterator.hasNext())
event.add_player_list()->CopyFrom(gameStateIterator.next());
player->sendGameEvent(prepareGameEvent(event, -1));
}
/* QSqlQuery query;
@ -200,31 +229,37 @@ void Server_Game::stopGameIfFinished()
playerIterator.toFront();
while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value();
sendGameEventToPlayer(player, new Event_GameStateChanged(gameStarted, -1, -1, getGameState(player)));
Event_GameStateChanged event;
event.set_game_started(false);
QListIterator<ServerInfo_Player> gameStateIterator(getGameState(player));
while (gameStateIterator.hasNext())
event.add_player_list()->CopyFrom(gameStateIterator.next());
player->sendGameEvent(prepareGameEvent(event, -1));
}
}
ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions)
Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions)
{
if (!(overrideRestrictions && (user->getUserLevel() & ServerInfo_User::IsModerator))) {
if (!(overrideRestrictions && (user->user_level() & ServerInfo_User::IsModerator))) {
if ((_password != password) && !(spectator && !spectatorsNeedPassword))
return RespWrongPassword;
if (!(user->getUserLevel() & ServerInfo_User::IsRegistered) && onlyRegistered)
return RespUserLevelTooLow;
return Response::RespWrongPassword;
if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered)
return Response::RespUserLevelTooLow;
if (onlyBuddies)
if (!room->getServer()->getBuddyList(creatorInfo->getName()).contains(user->getName()))
return RespOnlyBuddies;
if (room->getServer()->getIgnoreList(creatorInfo->getName()).contains(user->getName()))
return RespInIgnoreList;
if (!room->getServer()->isInBuddyList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name())))
return Response::RespOnlyBuddies;
if (room->getServer()->isInIgnoreList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name())))
return Response::RespInIgnoreList;
if (spectator) {
if (!spectatorsAllowed)
return RespSpectatorsNotAllowed;
return Response::RespSpectatorsNotAllowed;
}
}
if (!spectator && (gameStarted || (getPlayerCount() >= getMaxPlayers())))
return RespGameFull;
return Response::RespGameFull;
return RespOk;
return Response::RespOk;
}
bool Server_Game::containsUser(const QString &userName) const
@ -233,7 +268,7 @@ bool Server_Game::containsUser(const QString &userName) const
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext())
if (playerIterator.next().value()->getUserInfo()->getName() == userName)
if (playerIterator.next().value()->getUserInfo()->name() == userName.toStdString())
return true;
return false;
}
@ -245,13 +280,17 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
const QList<int> &keyList = players.keys();
int playerId = keyList.isEmpty() ? 0 : (keyList.last() + 1);
Server_Player *newPlayer = new Server_Player(this, playerId, handler->getUserInfo(), spectator, handler);
Server_Player *newPlayer = new Server_Player(this, playerId, handler->copyUserInfo(true), spectator, handler);
newPlayer->moveToThread(thread());
sendGameEvent(new Event_Join(newPlayer->getProperties()));
Event_Join joinEvent;
joinEvent.mutable_player_properties()->CopyFrom(newPlayer->getProperties());
sendGameEventContainer(prepareGameEvent(joinEvent, -1));
players.insert(playerId, newPlayer);
if (newPlayer->getUserInfo()->getName() == creatorInfo->getName()) {
if (newPlayer->getUserInfo()->name() == creatorInfo->name()) {
hostId = playerId;
sendGameEvent(new Event_GameHostChanged(playerId));
sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), playerId));
}
if (broadcastUpdate)
@ -268,7 +307,7 @@ void Server_Game::removePlayer(Server_Player *player)
players.remove(player->getPlayerId());
removeArrowsToPlayer(player);
sendGameEvent(new Event_Leave(player->getPlayerId()));
sendGameEventContainer(prepareGameEvent(Event_Leave(), player->getPlayerId()));
bool playerActive = activePlayer == player->getPlayerId();
bool playerHost = hostId == player->getPlayerId();
bool spectator = player->getSpectator();
@ -289,7 +328,7 @@ void Server_Game::removePlayer(Server_Player *player)
}
if (newHostId != -1) {
hostId = newHostId;
sendGameEvent(new Event_GameHostChanged(hostId));
sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId));
}
}
stopGameIfFinished();
@ -319,7 +358,10 @@ void Server_Game::removeArrowsToPlayer(Server_Player *player)
toDelete.append(a);
}
for (int i = 0; i < toDelete.size(); ++i) {
sendGameEvent(new Event_DeleteArrow(p->getPlayerId(), toDelete[i]->getId()));
Event_DeleteArrow event;
event.set_arrow_id(toDelete[i]->getId());
sendGameEventContainer(prepareGameEvent(event, p->getPlayerId()));
p->deleteArrow(toDelete[i]->getId());
}
}
@ -334,7 +376,8 @@ bool Server_Game::kickPlayer(int playerId)
if (!playerToKick)
return false;
sendGameEventToPlayer(playerToKick, new Event_Kicked);
playerToKick->sendGameEvent(prepareGameEvent(Event_Kicked(), -1));
removePlayer(playerToKick);
return true;
@ -345,7 +388,11 @@ void Server_Game::setActivePlayer(int _activePlayer)
QMutexLocker locker(&gameMutex);
activePlayer = _activePlayer;
sendGameEvent(new Event_SetActivePlayer(activePlayer, activePlayer));
Event_SetActivePlayer event;
event.set_active_player_id(activePlayer);
sendGameEventContainer(prepareGameEvent(event, -1));
setActivePhase(0);
}
@ -359,13 +406,20 @@ void Server_Game::setActivePhase(int _activePhase)
QList<Server_Arrow *> toDelete = player->getArrows().values();
for (int i = 0; i < toDelete.size(); ++i) {
Server_Arrow *a = toDelete[i];
sendGameEvent(new Event_DeleteArrow(player->getPlayerId(), a->getId()));
Event_DeleteArrow event;
event.set_arrow_id(a->getId());
sendGameEventContainer(prepareGameEvent(event, player->getPlayerId()));
player->deleteArrow(a->getId());
}
}
activePhase = _activePhase;
sendGameEvent(new Event_SetActivePhase(-1, activePhase));
Event_SetActivePhase event;
event.set_phase(activePhase);
sendGameEventContainer(prepareGameEvent(event, -1));
}
void Server_Game::nextTurn()
@ -389,163 +443,161 @@ void Server_Game::postConnectionStatusUpdate(Server_Player *player, bool connect
{
QMutexLocker locker(&gameMutex);
sendGameEvent(new Event_ConnectionStateChanged(player->getPlayerId(), connectionStatus));
Event_ConnectionStateChanged event;
event.set_connected(connectionStatus);
sendGameEventContainer(prepareGameEvent(event, player->getPlayerId()));
}
QList<ServerInfo_Player *> Server_Game::getGameState(Server_Player *playerWhosAsking) const
QList<ServerInfo_Player> Server_Game::getGameState(Server_Player *playerWhosAsking) const
{
QMutexLocker locker(&gameMutex);
QList<ServerInfo_Player *> result;
QList<ServerInfo_Player> result;
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value();
ServerInfo_Player playerInfo;
playerInfo.mutable_properties()->CopyFrom(player->getProperties());
if (player == playerWhosAsking)
playerInfo.set_deck_list(player->getDeck()->writeToString_Native().toStdString());
QList<ServerInfo_Arrow *> arrowList;
QMapIterator<int, Server_Arrow *> arrowIterator(player->getArrows());
while (arrowIterator.hasNext()) {
Server_Arrow *arrow = arrowIterator.next().value();
Server_Card *targetCard = qobject_cast<Server_Card *>(arrow->getTargetItem());
if (targetCard)
arrowList.append(new ServerInfo_Arrow(
arrow->getId(),
arrow->getStartCard()->getZone()->getPlayer()->getPlayerId(),
arrow->getStartCard()->getZone()->getName(),
arrow->getStartCard()->getId(),
targetCard->getZone()->getPlayer()->getPlayerId(),
targetCard->getZone()->getName(),
targetCard->getId(),
arrow->getColor()
));
else
arrowList.append(new ServerInfo_Arrow(
arrow->getId(),
arrow->getStartCard()->getZone()->getPlayer()->getPlayerId(),
arrow->getStartCard()->getZone()->getName(),
arrow->getStartCard()->getId(),
qobject_cast<Server_Player *>(arrow->getTargetItem())->getPlayerId(),
QString(),
-1,
arrow->getColor()
));
ServerInfo_Arrow *arrowInfo = playerInfo.add_arrow_list();
arrowInfo->set_id(arrow->getId());
arrowInfo->set_start_player_id(arrow->getStartCard()->getZone()->getPlayer()->getPlayerId());
arrowInfo->set_start_zone(arrow->getStartCard()->getZone()->getName().toStdString());
arrowInfo->set_start_card_id(arrow->getStartCard()->getId());
arrowInfo->mutable_arrow_color()->CopyFrom(arrow->getColor().get_color());
if (targetCard) {
arrowInfo->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId());
arrowInfo->set_target_zone(targetCard->getZone()->getName().toStdString());
arrowInfo->set_target_card_id(targetCard->getId());
} else
arrowInfo->set_target_player_id(qobject_cast<Server_Player *>(arrow->getTargetItem())->getPlayerId());
}
QList<ServerInfo_Counter *> counterList;
QMapIterator<int, Server_Counter *> counterIterator(player->getCounters());
while (counterIterator.hasNext()) {
Server_Counter *counter = counterIterator.next().value();
counterList.append(new ServerInfo_Counter(counter->getId(), counter->getName(), counter->getColor(), counter->getRadius(), counter->getCount()));
ServerInfo_Counter *counterInfo = playerInfo.add_counter_list();
counterInfo->set_id(counter->getId());
counterInfo->set_name(counter->getName().toStdString());
counterInfo->mutable_counter_color()->CopyFrom(counter->getColor().get_color());
counterInfo->set_radius(counter->getRadius());
counterInfo->set_count(counter->getCount());
}
QList<ServerInfo_Zone *> zoneList;
QMapIterator<QString, Server_CardZone *> zoneIterator(player->getZones());
while (zoneIterator.hasNext()) {
Server_CardZone *zone = zoneIterator.next().value();
QList<ServerInfo_Card *> cardList;
ServerInfo_Zone *zoneInfo = playerInfo.add_zone_list();
zoneInfo->set_name(zone->getName().toStdString());
zoneInfo->set_type(zone->getType());
zoneInfo->set_with_coords(zone->hasCoords());
zoneInfo->set_card_count(zone->cards.size());
if (
(((playerWhosAsking == player) || (playerWhosAsking->getSpectator() && spectatorsSeeEverything)) && (zone->getType() != HiddenZone))
|| ((playerWhosAsking != player) && (zone->getType() == PublicZone))
(((playerWhosAsking == player) || (playerWhosAsking->getSpectator() && spectatorsSeeEverything)) && (zone->getType() != ServerInfo_Zone::HiddenZone))
|| ((playerWhosAsking != player) && (zone->getType() == ServerInfo_Zone::PublicZone))
) {
QListIterator<Server_Card *> cardIterator(zone->cards);
while (cardIterator.hasNext()) {
Server_Card *card = cardIterator.next();
ServerInfo_Card *cardInfo = zoneInfo->add_card_list();
QString displayedName = card->getFaceDown() ? QString() : card->getName();
cardInfo->set_id(card->getId());
cardInfo->set_name(displayedName.toStdString());
cardInfo->set_x(card->getX());
cardInfo->set_y(card->getY());
cardInfo->set_face_down(card->getFaceDown());
cardInfo->set_tapped(card->getTapped());
cardInfo->set_attacking(card->getAttacking());
cardInfo->set_color(card->getColor().toStdString());
cardInfo->set_pt(card->getPT().toStdString());
cardInfo->set_annotation(card->getAnnotation().toStdString());
cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange());
cardInfo->set_doesnt_untap(card->getDoesntUntap());
QList<ServerInfo_CardCounter *> cardCounterList;
QMapIterator<int, int> cardCounterIterator(card->getCounters());
while (cardCounterIterator.hasNext()) {
cardCounterIterator.next();
cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value()));
ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list();
counterInfo->set_id(cardCounterIterator.key());
counterInfo->set_value(cardCounterIterator.value());
}
int attachPlayerId = -1;
QString attachZone;
int attachCardId = -1;
if (card->getParentCard()) {
attachPlayerId = card->getParentCard()->getZone()->getPlayer()->getPlayerId();
attachZone = card->getParentCard()->getZone()->getName();
attachCardId = card->getParentCard()->getId();
cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId());
cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString());
cardInfo->set_attach_card_id(card->getParentCard()->getId());
}
cardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getFaceDown(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), card->getDoesntUntap(), cardCounterList, attachPlayerId, attachZone, attachCardId));
}
}
zoneList.append(new ServerInfo_Zone(zone->getName(), zone->getType(), zone->hasCoords(), zone->cards.size(), cardList));
}
result.append(new ServerInfo_Player(player->getProperties(), player == playerWhosAsking ? player->getDeck() : 0, zoneList, counterList, arrowList));
result.append(playerInfo);
}
return result;
}
void Server_Game::sendGameEvent(GameEvent *event, GameEventContext *context, Server_Player *exclude)
{
sendGameEventContainer(new GameEventContainer(QList<GameEvent *>() << event, -1, context), exclude);
}
void Server_Game::sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude, bool excludeOmniscient)
void Server_Game::sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients, int privatePlayerId)
{
QMutexLocker locker(&gameMutex);
cont->setGameId(gameId);
cont->set_game_id(gameId);
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) {
Server_Player *p = playerIterator.next().value();
if ((p != exclude) && !(excludeOmniscient && p->getSpectator() && spectatorsSeeEverything))
p->sendProtocolItem(cont, false);
}
delete cont;
}
void Server_Game::sendGameEventContainerOmniscient(GameEventContainer *cont, Server_Player *exclude)
{
QMutexLocker locker(&gameMutex);
cont->setGameId(gameId);
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) {
Server_Player *p = playerIterator.next().value();
if ((p != exclude) && (p->getSpectator() && spectatorsSeeEverything))
p->sendProtocolItem(cont, false);
const bool playerPrivate = (p->getPlayerId() == privatePlayerId) || (p->getSpectator() && spectatorsSeeEverything);
if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate))
p->sendGameEvent(cont);
}
delete cont;
}
void Server_Game::sendGameEventToPlayer(Server_Player *player, GameEvent *event)
GameEventContainer *Server_Game::prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context)
{
player->sendProtocolItem(new GameEventContainer(QList<GameEvent *>() << event, gameId));
GameEventContainer *cont = new GameEventContainer;
cont->set_game_id(gameId);
if (context)
cont->mutable_context()->CopyFrom(*context);
GameEvent *event = cont->add_event_list();
if (playerId != -1)
event->set_player_id(playerId);
event->GetReflection()->MutableMessage(event, gameEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(gameEvent);
return cont;
}
ServerInfo_Game *Server_Game::getInfo() const
ServerInfo_Game Server_Game::getInfo() const
{
QMutexLocker locker(&gameMutex);
if (players.isEmpty())
// Game is closing
return new ServerInfo_Game(room->getId(), getGameId(), QString(), false, 0, getMaxPlayers(), false, QList<GameTypeId *>(), 0, false, 0);
else {
// Game is open
QList<GameTypeId *> gameTypeList;
ServerInfo_Game result;
result.set_room_id(room->getId());
result.set_game_id(getGameId());
result.set_max_players(getMaxPlayers());
if (!players.isEmpty()) {
for (int i = 0; i < gameTypes.size(); ++i)
gameTypeList.append(new GameTypeId(gameTypes[i]));
result.add_game_types(gameTypes[i]);
return new ServerInfo_Game(
room->getId(),
getGameId(),
getDescription(),
!getPassword().isEmpty(),
getPlayerCount(),
getMaxPlayers(),
gameStarted,
gameTypeList,
new ServerInfo_User(getCreatorInfo(), false),
onlyBuddies,
onlyRegistered,
getSpectatorsAllowed(),
getSpectatorsNeedPassword(),
getSpectatorCount()
);
result.set_description(getDescription().toStdString());
result.set_with_password(!getPassword().isEmpty());
result.set_player_count(getPlayerCount());
result.set_started(gameStarted);
result.mutable_creator_info()->CopyFrom(*getCreatorInfo());
result.set_only_buddies(onlyBuddies);
result.set_only_registered(onlyRegistered);
result.set_spectators_allowed(getSpectatorsAllowed());
result.set_spectators_need_password(getSpectatorsNeedPassword());
result.set_spectators_count(getSpectatorCount());
}
return result;
}

View file

@ -28,6 +28,7 @@
#include "protocol.h"
#include "pb/response.pb.h"
#include "pb/serverinfo_player.pb.h"
#include "pb/serverinfo_game.pb.h"
class QTimer;
class GameEventContainer;
@ -65,7 +66,7 @@ public:
mutable QMutex gameMutex;
Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent);
~Server_Game();
ServerInfo_Game *getInfo() const;
ServerInfo_Game getInfo() const;
int getHostId() const { return hostId; }
ServerInfo_User *getCreatorInfo() const { return creatorInfo; }
bool getGameStarted() const { return gameStarted; }
@ -98,14 +99,10 @@ public:
QList<ServerInfo_Player> getGameState(Server_Player *playerWhosAsking) const;
GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId);
GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, const GameEventContext &context);
GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0);
GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext);
// void sendGameEvent(GameEvent *event, GameEventContext *context = 0, Server_Player *exclude = 0);
void sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude = 0, bool excludeOmniscient = false);
void sendGameEventContainerOmniscient(GameEventContainer *cont, Server_Player *exclude = 0);
void sendGameEventToPlayer(Server_Player *player, GameEvent *event);
void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1);
};
#endif

View file

@ -6,12 +6,19 @@
#include "server_game.h"
#include "server_protocolhandler.h"
#include "protocol.h"
#include "protocol_items.h"
#include "decklist.h"
#include "pb/response.pb.h"
#include "pb/command_move_card.pb.h"
#include "pb/serverinfo_user.pb.h"
#include "pb/event_attach_card.pb.h"
#include "pb/event_draw_cards.pb.h"
#include "pb/event_destroy_card.pb.h"
#include "pb/event_move_card.pb.h"
#include "pb/event_set_card_attr.pb.h"
#include "pb/context_move_card.pb.h"
#include <QDebug>
Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler)
Server_Player::Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_ProtocolHandler *_handler)
: game(_game), handler(_handler), userInfo(new ServerInfo_User(_userInfo)), deck(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false)
{
}
@ -32,18 +39,13 @@ void Server_Player::prepareDestroy()
playerMutex.unlock();
delete userInfo;
userInfo = 0;
clearZones();
deleteLater();
}
void Server_Player::moveToThread(QThread *thread)
{
QObject::moveToThread(thread);
userInfo->moveToThread(thread);
}
int Server_Player::newCardId()
{
QMutexLocker locker(&game->gameMutex);
@ -87,15 +89,15 @@ void Server_Player::setupZones()
// ------------------------------------------------------------------
// Create zones
Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, HiddenZone);
Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, ServerInfo_Zone::HiddenZone);
addZone(deckZone);
Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, HiddenZone);
Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, ServerInfo_Zone::HiddenZone);
addZone(sbZone);
addZone(new Server_CardZone(this, "table", true, PublicZone));
addZone(new Server_CardZone(this, "hand", false, PrivateZone));
addZone(new Server_CardZone(this, "stack", false, PublicZone));
addZone(new Server_CardZone(this, "grave", false, PublicZone));
addZone(new Server_CardZone(this, "rfg", false, PublicZone));
addZone(new Server_CardZone(this, "table", true, ServerInfo_Zone::PublicZone));
addZone(new Server_CardZone(this, "hand", false, ServerInfo_Zone::PrivateZone));
addZone(new Server_CardZone(this, "stack", false, ServerInfo_Zone::PublicZone));
addZone(new Server_CardZone(this, "grave", false, ServerInfo_Zone::PublicZone));
addZone(new Server_CardZone(this, "rfg", false, ServerInfo_Zone::PublicZone));
addCounter(new Server_Counter(0, "life", Color(255, 255, 255), 25, 20));
addCounter(new Server_Counter(1, "w", Color(255, 255, 150), 20, 0));
@ -188,7 +190,15 @@ ServerInfo_PlayerProperties Server_Player::getProperties()
{
QMutexLocker locker(&game->gameMutex);
return new ServerInfo_PlayerProperties(playerId, new ServerInfo_User(userInfo), spectator, conceded, readyStart, deck ? deck->getDeckHash() : QString());
ServerInfo_PlayerProperties result;
result.set_player_id(playerId);
result.mutable_user_info()->CopyFrom(*userInfo);
result.set_spectator(spectator);
result.set_conceded(conceded);
result.set_ready_start(readyStart);
result.set_deck_hash(deck ? deck->getDeckHash().toStdString() : std::string());
return result;
}
void Server_Player::setDeck(DeckList *_deck)
@ -244,7 +254,7 @@ bool Server_Player::deleteCounter(int counterId)
return true;
}
ResponseCode Server_Player::drawCards(BlaContainer *bla, int number)
Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int number)
{
QMutexLocker locker(&game->gameMutex);
@ -252,51 +262,55 @@ ResponseCode Server_Player::drawCards(BlaContainer *bla, int number)
Server_CardZone *handZone = zones.value("hand");
if (deckZone->cards.size() < number)
number = deckZone->cards.size();
QList<ServerInfo_Card *> cardListPrivate;
QList<ServerInfo_Card *> cardListOmniscient;
Event_DrawCards eventOthers;
eventOthers.set_number(number);
Event_DrawCards eventPrivate(eventOthers);
for (int i = 0; i < number; ++i) {
Server_Card *card = deckZone->cards.takeFirst();
handZone->cards.append(card);
lastDrawList.append(card->getId());
cardListPrivate.append(new ServerInfo_Card(card->getId(), card->getName()));
cardListOmniscient.append(new ServerInfo_Card(card->getId(), card->getName()));
ServerInfo_Card *cardInfo = eventPrivate.add_cards();
cardInfo->set_id(card->getId());
cardInfo->set_name(card->getName().toStdString());
}
bla->enqueueGameEventPrivate(new Event_DrawCards(playerId, cardListPrivate.size(), cardListPrivate), game->getGameId());
bla->enqueueGameEventOmniscient(new Event_DrawCards(playerId, cardListOmniscient.size(), cardListOmniscient), game->getGameId());
bla->enqueueGameEventPublic(new Event_DrawCards(playerId, cardListPrivate.size()), game->getGameId());
return RespOk;
ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId);
ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers);
return Response::RespOk;
}
ResponseCode Server_Player::undoDraw(BlaContainer *bla)
Response::ResponseCode Server_Player::undoDraw(GameEventStorage &ges)
{
QMutexLocker locker(&game->gameMutex);
if (lastDrawList.isEmpty())
return RespContextError;
return Response::RespContextError;
ResponseCode retVal;
Response::ResponseCode retVal;
CardToMove *cardToMove = new CardToMove;
cardToMove->set_card_id(lastDrawList.takeLast());
retVal = moveCard(bla, zones.value("hand"), QList<const CardToMove *>() << cardToMove, zones.value("deck"), 0, 0, false, true);
retVal = moveCard(ges, zones.value("hand"), QList<const CardToMove *>() << cardToMove, zones.value("deck"), 0, 0, false, true);
delete cardToMove;
return retVal;
}
ResponseCode Server_Player::moveCard(BlaContainer *bla, const QString &_startZone, const QList<const CardToMove *> &_cards, int targetPlayerId, const QString &_targetZone, int x, int y)
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 RespNameNotFound;
return Response::RespNameNotFound;
Server_CardZone *targetzone = targetPlayer->getZones().value(_targetZone);
if ((!startzone) || (!targetzone))
return RespNameNotFound;
return Response::RespNameNotFound;
return moveCard(bla, startzone, _cards, targetzone, x, y);
return moveCard(ges, startzone, _cards, targetzone, x, y);
}
class Server_Player::MoveCardCompareFunctor {
@ -320,13 +334,13 @@ public:
}
};
ResponseCode Server_Player::moveCard(BlaContainer *bla, Server_CardZone *startzone, const QList<const CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces, bool undoingDraw)
Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList<const CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces, bool undoingDraw)
{
QMutexLocker locker(&game->gameMutex);
// Disallow controller change to other zones than the table.
if (((targetzone->getType() != PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer()))
return RespContextError;
if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer()))
return Response::RespContextError;
if (!targetzone->hasCoords() && (x == -1))
x = targetzone->cards.size();
@ -337,9 +351,9 @@ ResponseCode Server_Player::moveCard(BlaContainer *bla, Server_CardZone *startzo
int position;
Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position);
if (!card)
return RespNameNotFound;
return Response::RespNameNotFound;
if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y))
return RespContextError;
return Response::RespContextError;
cardsToMove.append(QPair<Server_Card *, int>(card, position));
cardProperties.insert(card, _cards[i]);
}
@ -382,7 +396,7 @@ ResponseCode Server_Player::moveCard(BlaContainer *bla, Server_CardZone *startzo
// Make a copy of the list because the original one gets modified during the loop
QList<Server_Card *> attachedCards = card->getAttachedCards();
for (int i = 0; i < attachedCards.size(); ++i)
attachedCards[i]->getZone()->getPlayer()->unattachCard(bla, attachedCards[i]);
attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]);
}
if (startzone != targetzone) {
@ -402,9 +416,12 @@ ResponseCode Server_Player::moveCard(BlaContainer *bla, Server_CardZone *startzo
}
if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) {
bla->enqueueGameEventPrivate(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId(), -1, new Context_MoveCard);
bla->enqueueGameEventOmniscient(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId(), new Context_MoveCard);
bla->enqueueGameEventPublic(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId(), new Context_MoveCard);
Event_DestroyCard event;
event.set_zone_name(startzone->getName().toStdString());
event.set_card_id(card->getId());
ges.setGameEventContext(new Context_MoveCard);
ges.enqueueGameEvent(event, playerId);
card->deleteLater();
} else {
if (!targetzone->hasCoords()) {
@ -415,13 +432,13 @@ ResponseCode Server_Player::moveCard(BlaContainer *bla, Server_CardZone *startzo
targetzone->insertCard(card, newX, y);
bool targetBeingLookedAt = (targetzone->getType() != HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1);
bool sourceBeingLookedAt = (startzone->getType() != HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1);
bool targetBeingLookedAt = (targetzone->getType() != ServerInfo_Zone::HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1);
bool sourceBeingLookedAt = (startzone->getType() != ServerInfo_Zone::HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1);
bool targetHiddenToPlayer = thisCardProperties->face_down() || !targetBeingLookedAt;
bool targetHiddenToOthers = thisCardProperties->face_down() || (targetzone->getType() != PublicZone);
bool targetHiddenToOthers = thisCardProperties->face_down() || (targetzone->getType() != ServerInfo_Zone::PublicZone);
bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt;
bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != PublicZone);
bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != ServerInfo_Zone::PublicZone);
QString privateCardName, publicCardName;
if (!(sourceHiddenToPlayer && targetHiddenToPlayer))
@ -444,65 +461,85 @@ ResponseCode Server_Player::moveCard(BlaContainer *bla, Server_CardZone *startzo
privateCardName = QString();
}
int privatePosition = -1;
if (startzone->getType() == HiddenZone)
if (startzone->getType() == ServerInfo_Zone::HiddenZone)
privatePosition = position;
bla->enqueueGameEventPrivate(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, privateNewCardId, thisCardProperties->face_down()), game->getGameId(), -1, undoingDraw ? static_cast<GameEventContext *>(new Context_UndoDraw) : static_cast<GameEventContext *>(new Context_MoveCard));
bla->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, privateNewCardId, thisCardProperties->face_down()), game->getGameId(), undoingDraw ? static_cast<GameEventContext *>(new Context_UndoDraw) : static_cast<GameEventContext *>(new Context_MoveCard));
Event_MoveCard eventOthers;
eventOthers.set_start_zone(startzone->getName().toStdString());
eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId());
eventOthers.set_target_zone(targetzone->getName().toStdString());
eventOthers.set_x(newX);
eventOthers.set_y(y);
eventOthers.set_face_down(thisCardProperties->face_down());
Event_MoveCard eventPrivate(eventOthers);
eventPrivate.set_card_id(privateOldCardId);
eventPrivate.set_card_name(privateCardName.toStdString());
eventPrivate.set_position(privatePosition);
eventPrivate.set_new_card_id(privateNewCardId);
// Other players do not get to see the start and/or target position of the card if the respective
// part of the zone is being looked at. The information is not needed anyway because in hidden zones,
// all cards are equal.
if (
((startzone->getType() == HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1)))
|| (startzone->getType() == PublicZone)
((startzone->getType() == ServerInfo_Zone::HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1)))
|| (startzone->getType() == ServerInfo_Zone::PublicZone)
)
position = -1;
if ((targetzone->getType() == HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1)))
if ((targetzone->getType() == ServerInfo_Zone::HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1)))
newX = -1;
if ((startzone->getType() == PublicZone) || (targetzone->getType() == PublicZone))
bla->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, card->getId(), thisCardProperties->face_down()), game->getGameId(), undoingDraw ? static_cast<GameEventContext *>(new Context_UndoDraw) : static_cast<GameEventContext *>(new Context_MoveCard));
else
bla->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, -1, false), game->getGameId(), undoingDraw ? static_cast<GameEventContext *>(new Context_UndoDraw) : static_cast<GameEventContext *>(new Context_MoveCard));
eventOthers.set_position(position);
if ((startzone->getType() == ServerInfo_Zone::PublicZone) || (targetzone->getType() == ServerInfo_Zone::PublicZone)) {
eventOthers.set_card_id(oldCardId);
eventOthers.set_card_name(publicCardName.toStdString());
eventOthers.set_new_card_id(card->getId());
}
ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId);
ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers);
if (thisCardProperties->tapped())
setCardAttrHelper(bla, targetzone->getName(), card->getId(), "tapped", "1");
setCardAttrHelper(ges, targetzone->getName(), card->getId(), "tapped", "1");
QString ptString = QString::fromStdString(thisCardProperties->pt());
if (!ptString.isEmpty() && !thisCardProperties->face_down())
setCardAttrHelper(bla, targetzone->getName(), card->getId(), "pt", ptString);
setCardAttrHelper(ges, targetzone->getName(), card->getId(), "pt", ptString);
}
}
if (startzone->hasCoords() && fixFreeSpaces)
startzone->fixFreeSpaces(bla);
startzone->fixFreeSpaces(ges);
return RespOk;
return Response::RespOk;
}
void Server_Player::unattachCard(BlaContainer *bla, Server_Card *card)
void Server_Player::unattachCard(GameEventStorage &ges, Server_Card *card)
{
QMutexLocker locker(&game->gameMutex);
Server_CardZone *zone = card->getZone();
card->setParentCard(0);
bla->enqueueGameEventPrivate(new Event_AttachCard(getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId());
bla->enqueueGameEventPublic(new Event_AttachCard(getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId());
Event_AttachCard event;
event.set_start_zone(zone->getName().toStdString());
event.set_card_id(card->getId());
ges.enqueueGameEvent(event, playerId);
CardToMove *cardToMove = new CardToMove;
cardToMove->set_card_id(card->getId());
moveCard(bla, zone, QList<const CardToMove *>() << cardToMove, zone, -1, card->getY(), card->getFaceDown());
moveCard(ges, zone, QList<const CardToMove *>() << cardToMove, zone, -1, card->getY(), card->getFaceDown());
delete cardToMove;
}
ResponseCode Server_Player::setCardAttrHelper(BlaContainer *bla, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue)
Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue)
{
QMutexLocker locker(&game->gameMutex);
Server_CardZone *zone = getZones().value(zoneName);
if (!zone)
return RespNameNotFound;
return Response::RespNameNotFound;
if (!zone->hasCoords())
return RespContextError;
return Response::RespContextError;
QString result;
if (cardId == -1) {
@ -510,26 +547,31 @@ ResponseCode Server_Player::setCardAttrHelper(BlaContainer *bla, const QString &
while (CardIterator.hasNext()) {
result = CardIterator.next()->setAttribute(attrName, attrValue, true);
if (result.isNull())
return RespInvalidCommand;
return Response::RespInvalidCommand;
}
} else {
Server_Card *card = zone->getCard(cardId);
if (!card)
return RespNameNotFound;
return Response::RespNameNotFound;
result = card->setAttribute(attrName, attrValue, false);
if (result.isNull())
return RespInvalidCommand;
return Response::RespInvalidCommand;
}
bla->enqueueGameEventPrivate(new Event_SetCardAttr(getPlayerId(), zone->getName(), cardId, attrName, result), game->getGameId());
bla->enqueueGameEventPublic(new Event_SetCardAttr(getPlayerId(), zone->getName(), cardId, attrName, result), game->getGameId());
bla->enqueueGameEventOmniscient(new Event_SetCardAttr(getPlayerId(), zone->getName(), cardId, attrName, result), game->getGameId());
return RespOk;
Event_SetCardAttr event;
event.set_zone_name(zone->getName().toStdString());
event.set_card_id(cardId);
event.set_attr_name(attrName.toStdString());
event.set_attr_value(result.toStdString());
ges.enqueueGameEvent(event, playerId);
return Response::RespOk;
}
void Server_Player::sendProtocolItem(ProtocolItem *item, bool deleteItem)
void Server_Player::sendGameEvent(GameEventContainer *cont)
{
QMutexLocker locker(&playerMutex);
if (handler)
handler->sendProtocolItem(item, deleteItem);
handler->sendProtocolItem(*cont);
}

View file

@ -7,6 +7,8 @@
#include <QMap>
#include <QMutex>
#include "pb/response.pb.h"
class DeckList;
class Server_Game;
class Server_CardZone;
@ -14,11 +16,11 @@ class Server_Counter;
class Server_Arrow;
class Server_Card;
class Server_ProtocolHandler;
class ProtocolItem;
class ServerInfo_User;
class ServerInfo_PlayerProperties;
class CommandContainer;
class CardToMove;
class GameEventContainer;
class GameEventStorage;
class Server_Player : public Server_ArrowTarget {
@ -41,10 +43,9 @@ private:
bool readyStart;
bool conceded;
public:
Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler);
Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_ProtocolHandler *_handler);
~Server_Player();
void prepareDestroy();
void moveToThread(QThread *thread);
Server_ProtocolHandler *getProtocolHandler() const { return handler; }
void setProtocolHandler(Server_ProtocolHandler *_handler) { playerMutex.lock(); handler = _handler; playerMutex.unlock(); }
@ -87,7 +88,7 @@ public:
void unattachCard(GameEventStorage &ges, Server_Card *card);
Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, const QString &attrName, const QString &attrValue);
void sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
void sendGameEvent(GameEventContainer *event);
};
#endif

View file

@ -77,6 +77,7 @@
#include "pb/event_set_counter.pb.h"
#include "pb/event_dump_zone.pb.h"
#include "pb/event_stop_dump_zone.pb.h"
#include "pb/event_reveal_cards.pb.h"
#include "pb/context_deck_select.pb.h"
#include "pb/context_concede.pb.h"
#include "pb/context_ready_start.pb.h"
@ -124,12 +125,25 @@ void Server_ProtocolHandler::prepareDestroy()
gameListMutex.unlock();
delete userInfo;
QMapIterator<QString, ServerInfo_User *> i(buddyList);
while (i.hasNext())
delete i.next().value();
QMapIterator<QString, ServerInfo_User *> j(ignoreList);
while (j.hasNext())
delete j.next().value();
}
void Server_ProtocolHandler::setUserInfo(const ServerInfo_User &_userInfo)
{
userInfo = new ServerInfo_User;
userInfo->CopyFrom(_userInfo);
}
ServerInfo_User Server_ProtocolHandler::copyUserInfo(bool complete, bool moderatorInfo) const
{
ServerInfo_User result;
if (userInfo) {
result.CopyFrom(*userInfo);
if (!moderatorInfo)
result.clear_address();
if (!complete)
result.clear_avatar_bmp();
}
return result;
}
void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
@ -186,6 +200,13 @@ void Server_ProtocolHandler::sendProtocolItem(ServerMessage::MessageType type, c
}
}
SessionEvent *Server_ProtocolHandler::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent)
{
SessionEvent *event = new SessionEvent;
event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent);
return event;
}
Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
{
Response::ResponseCode finalResponseCode = Response::RespOk;
@ -499,19 +520,14 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
// XXX stimmt so nicht, beim alten Kopierkonstruktor wurde hier "true" übergeben
re->mutable_user_info()->CopyFrom(*userInfo);
QList<ServerInfo_User *> _buddyList, _ignoreList;
if (authState == PasswordRight) {
buddyList = server->getBuddyList(userName);
QMapIterator<QString, ServerInfo_User *> buddyIterator(buddyList);
QMapIterator<QString, ServerInfo_User> buddyIterator(server->getBuddyList(userName));
while (buddyIterator.hasNext())
re->add_buddy_list()->CopyFrom(*buddyIterator.next().value());
re->add_buddy_list()->CopyFrom(buddyIterator.next().value());
ignoreList = server->getIgnoreList(userName);
QMapIterator<QString, ServerInfo_User *> ignoreIterator(ignoreList);
QMapIterator<QString, ServerInfo_User> ignoreIterator(server->getIgnoreList(userName));
while (ignoreIterator.hasNext())
re->add_ignore_list()->CopyFrom(*ignoreIterator.next().value());
re->add_ignore_list()->CopyFrom(ignoreIterator.next().value());
}
server->serverMutex.lock();
@ -573,7 +589,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message
Server_ProtocolHandler *userHandler = server->getUsers().value(receiver);
if (!userHandler)
return Response::RespNameNotFound;
if (userHandler->getIgnoreList().contains(getUserName()))
if (server->isInIgnoreList(receiver, QString::fromStdString(userInfo->name())))
return Response::RespInIgnoreList;
Event_UserMessage event;
@ -856,7 +872,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdDeckSelect(const Command_DeckS
Event_PlayerPropertiesChanged event;
event.mutable_player_properties()->CopyFrom(player->getProperties());
ges.enqueueGameEventPublic(event, player->getPlayerId());
ges.enqueueGameEvent(event, player->getPlayerId());
Context_DeckSelect *context = new Context_DeckSelect;
context->set_deck_hash(deck->getDeckHash().toStdString());
@ -907,7 +923,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdConcede(const Command_Concede
Event_PlayerPropertiesChanged event;
event.mutable_player_properties()->CopyFrom(player->getProperties());
ges.enqueueGameEventPublic(event, player->getPlayerId());
ges.enqueueGameEvent(event, player->getPlayerId());
ges.setGameEventContext(new Context_Concede());
game->stopGameIfFinished();
@ -932,7 +948,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdReadyStart(const Command_Ready
Event_PlayerPropertiesChanged event;
event.mutable_player_properties()->CopyFrom(player->getProperties());
ges.enqueueGameEventPublic(event, player->getPlayerId());
ges.enqueueGameEvent(event, player->getPlayerId());
ges.setGameEventContext(new Context_ReadyStart());
game->startGameIfReady();
@ -946,7 +962,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdGameSay(const Command_GameSay
Event_GameSay event;
event.set_message(cmd.message());
ges.enqueueGameEventPublic(event, player->getPlayerId());
ges.enqueueGameEvent(event, player->getPlayerId());
return Response::RespOk;
}
@ -963,7 +979,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdShuffle(const Command_Shuffle
player->getZones().value("deck")->shuffle();
ges.enqueueGameEventPublic(Event_Shuffle(), player->getPlayerId());
ges.enqueueGameEvent(Event_Shuffle(), player->getPlayerId());
return Response::RespOk;
}
@ -1630,7 +1646,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdStopDumpZone(const Command_Sto
return Response::RespOk;
}
Response::ResponseCode Server_ProtocolHandler::cmdRevealCards(const Command_RevealCards &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges)
Response::ResponseCode Server_ProtocolHandler::cmdRevealCards(const Command_RevealCards &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges)
{
if (player->getSpectator())
return Response::RespFunctionNotAllowed;
@ -1664,39 +1680,54 @@ Response::ResponseCode Server_ProtocolHandler::cmdRevealCards(const Command_Reve
cardsToReveal.append(card);
}
Event_RevealCards eventOthers;
eventOthers.set_zone_name(zone->getName().toStdString());
if (cmd.has_card_id())
eventOthers.set_card_id(cmd.card_id());
if (cmd.has_player_id())
eventOthers.set_other_player_id(cmd.player_id());
Event_RevealCards eventPrivate(eventOthers);
QList<ServerInfo_Card *> respCardListPrivate, respCardListOmniscient;
for (int i = 0; i < cardsToReveal.size(); ++i) {
Server_Card *card = cardsToReveal[i];
ServerInfo_Card *cardInfo = eventPrivate.add_cards();
QList<ServerInfo_CardCounter *> cardCounterListPrivate, cardCounterListOmniscient;
cardInfo->set_id(card->getId());
cardInfo->set_name(card->getName().toStdString());
cardInfo->set_x(card->getX());
cardInfo->set_y(card->getY());
cardInfo->set_face_down(card->getFaceDown());
cardInfo->set_tapped(card->getTapped());
cardInfo->set_attacking(card->getAttacking());
cardInfo->set_color(card->getColor().toStdString());
cardInfo->set_pt(card->getPT().toStdString());
cardInfo->set_annotation(card->getAnnotation().toStdString());
cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange());
cardInfo->set_doesnt_untap(card->getDoesntUntap());
QList<ServerInfo_CardCounter *> cardCounterList;
QMapIterator<int, int> cardCounterIterator(card->getCounters());
while (cardCounterIterator.hasNext()) {
cardCounterIterator.next();
cardCounterListPrivate.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value()));
cardCounterListOmniscient.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value()));
ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list();
counterInfo->set_id(cardCounterIterator.key());
counterInfo->set_value(cardCounterIterator.value());
}
int attachPlayerId = -1;
QString attachZone;
int attachCardId = -1;
if (card->getParentCard()) {
attachPlayerId = card->getParentCard()->getZone()->getPlayer()->getPlayerId();
attachZone = card->getParentCard()->getZone()->getName();
attachCardId = card->getParentCard()->getId();
cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId());
cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString());
cardInfo->set_attach_card_id(card->getParentCard()->getId());
}
if (cmd.has_player_id())
respCardListPrivate.append(new ServerInfo_Card(card->getId(), card->getName(), card->getX(), card->getY(), card->getFaceDown(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), card->getDoesntUntap(), cardCounterListPrivate, attachPlayerId, attachZone, attachCardId));
respCardListOmniscient.append(new ServerInfo_Card(card->getId(), card->getName(), card->getX(), card->getY(), card->getFaceDown(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), card->getDoesntUntap(), cardCounterListOmniscient, attachPlayerId, attachZone, attachCardId));
}
if (!cmd.has_player_id())
bla->enqueueGameEventPublic(new Event_RevealCards(player->getPlayerId(), zone->getName(), cmd.card_id(), -1, respCardListOmniscient), game->getGameId());
else {
bla->enqueueGameEventPublic(new Event_RevealCards(player->getPlayerId(), zone->getName(), cmd.card_id(), otherPlayer->getPlayerId()), game->getGameId());
bla->enqueueGameEventPrivate(new Event_RevealCards(player->getPlayerId(), zone->getName(), cmd.card_id(), otherPlayer->getPlayerId(), respCardListPrivate), game->getGameId(), otherPlayer->getPlayerId());
bla->enqueueGameEventOmniscient(new Event_RevealCards(player->getPlayerId(), zone->getName(), cmd.card_id(), otherPlayer->getPlayerId(), respCardListOmniscient), game->getGameId());
}
if (cmd.has_player_id()) {
ges.enqueueGameEvent(eventPrivate, player->getPlayerId(), GameEventStorageItem::SendToPrivate, cmd.player_id());
ges.enqueueGameEvent(eventOthers, player->getPlayerId(), GameEventStorageItem::SendToOthers);
} else
ges.enqueueGameEvent(eventPrivate, player->getPlayerId());
return Response::RespOk;
}

View file

@ -93,10 +93,8 @@ protected:
bool acceptsUserListChanges;
bool acceptsRoomListChanges;
ServerInfo_User *userInfo;
QMap<QString, ServerInfo_User *> buddyList, ignoreList;
void prepareDestroy();
virtual bool getCompressionSupport() const = 0;
int sessionId;
private:
QString thisUserName;
@ -182,9 +180,7 @@ public:
ServerInfo_User copyUserInfo(bool complete, bool moderatorInfo = false) const;
const QString &getUserName() const { return thisUserName; }
virtual QString getAddress() const = 0;
void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; }
const QMap<QString, ServerInfo_User *> &getBuddyList() const { return buddyList; }
const QMap<QString, ServerInfo_User *> &getIgnoreList() const { return ignoreList; }
void setUserInfo(const ServerInfo_User &_userInfo);
int getSessionId() const { return sessionId; }
void setSessionId(int _sessionId) { sessionId = _sessionId; }
@ -197,7 +193,7 @@ public:
void sendProtocolItem(const RoomEvent &item);
void sendProtocolItem(ServerMessage::MessageType type, const ::google::protobuf::Message &item);
SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent);
};
#endif

View file

@ -3,6 +3,12 @@
#include "server_game.h"
#include <QDebug>
#include "pb/event_join_room.pb.h"
#include "pb/event_leave_room.pb.h"
#include "pb/event_list_games.pb.h"
#include "pb/event_room_say.pb.h"
#include <google/protobuf/descriptor.h>
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), roomMutex(QMutex::Recursive)
{
@ -26,33 +32,52 @@ Server *Server_Room::getServer() const
return static_cast<Server *>(parent());
}
ServerInfo_Room *Server_Room::getInfo(bool complete, bool showGameTypes) const
ServerInfo_Room Server_Room::getInfo(bool complete, bool showGameTypes) const
{
QMutexLocker locker(&roomMutex);
QList<ServerInfo_Game *> gameList;
QList<ServerInfo_User *> userList;
QList<ServerInfo_GameType *> gameTypeList;
ServerInfo_Room result;
result.set_room_id(id);
result.set_name(name.toStdString());
result.set_description(description.toStdString());
result.set_game_count(games.size());
result.set_player_count(size());
result.set_auto_join(autoJoin);
if (complete) {
QMapIterator<int, Server_Game *> gameIterator(games);
while (gameIterator.hasNext())
gameList.append(gameIterator.next().value()->getInfo());
result.add_game_list()->CopyFrom(gameIterator.next().value()->getInfo());
for (int i = 0; i < size(); ++i)
userList.append(new ServerInfo_User(at(i)->getUserInfo(), false));
result.add_user_list()->CopyFrom(at(i)->copyUserInfo(false));
}
if (complete || showGameTypes)
for (int i = 0; i < gameTypes.size(); ++i)
gameTypeList.append(new ServerInfo_GameType(i, gameTypes[i]));
for (int i = 0; i < gameTypes.size(); ++i) {
ServerInfo_GameType *gameTypeInfo = result.add_gametype_list();
gameTypeInfo->set_game_type_id(i);
gameTypeInfo->set_description(gameTypes[i].toStdString());
}
return new ServerInfo_Room(id, name, description, games.size(), size(), autoJoin, gameList, userList, gameTypeList);
return result;
}
RoomEvent *Server_Room::prepareRoomEvent(const ::google::protobuf::Message &roomEvent)
{
RoomEvent *event = new RoomEvent;
event->set_room_id(id);
event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent);
return event;
}
void Server_Room::addClient(Server_ProtocolHandler *client)
{
QMutexLocker locker(&roomMutex);
sendRoomEvent(new Event_JoinRoom(id, new ServerInfo_User(client->getUserInfo(), false)));
Event_JoinRoom event;
event.mutable_user_info()->CopyFrom(client->copyUserInfo(false));
sendRoomEvent(prepareRoomEvent(event));
append(client);
emit roomInfoChanged();
}
@ -62,13 +87,20 @@ void Server_Room::removeClient(Server_ProtocolHandler *client)
QMutexLocker locker(&roomMutex);
removeAt(indexOf(client));
sendRoomEvent(new Event_LeaveRoom(id, client->getUserInfo()->getName()));
Event_LeaveRoom event;
event.set_name(client->getUserInfo()->name());
sendRoomEvent(prepareRoomEvent(event));
emit roomInfoChanged();
}
void Server_Room::say(Server_ProtocolHandler *client, const QString &s)
{
sendRoomEvent(new Event_RoomSay(id, client->getUserInfo()->getName(), s));
Event_RoomSay event;
event.set_name(client->getUserInfo()->name());
event.set_message(s.toStdString());
sendRoomEvent(prepareRoomEvent(event));
}
void Server_Room::sendRoomEvent(RoomEvent *event)
@ -76,7 +108,7 @@ void Server_Room::sendRoomEvent(RoomEvent *event)
QMutexLocker locker(&roomMutex);
for (int i = 0; i < size(); ++i)
at(i)->sendProtocolItem(event, false);
at(i)->sendProtocolItem(*event);
delete event;
}
@ -84,11 +116,9 @@ void Server_Room::broadcastGameListUpdate(Server_Game *game)
{
QMutexLocker locker(&roomMutex);
Event_ListGames *event = new Event_ListGames(id, QList<ServerInfo_Game *>() << game->getInfo());
for (int i = 0; i < size(); i++)
at(i)->sendProtocolItem(event, false);
delete event;
Event_ListGames event;
event.add_game_list()->CopyFrom(game->getInfo());
sendRoomEvent(prepareRoomEvent(event));
}
Server_Game *Server_Room::createGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
@ -126,14 +156,14 @@ int Server_Room::getGamesCreatedByUser(const QString &userName) const
QMapIterator<int, Server_Game *> gamesIterator(games);
int result = 0;
while (gamesIterator.hasNext())
if (gamesIterator.next().value()->getCreatorInfo()->getName() == userName)
if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString())
++result;
return result;
}
QList<ServerInfo_Game *> Server_Room::getGamesOfUser(const QString &userName) const
QList<ServerInfo_Game> Server_Room::getGamesOfUser(const QString &userName) const
{
QList<ServerInfo_Game *> result;
QList<ServerInfo_Game> result;
QMapIterator<int, Server_Game *> gamesIterator(games);
while (gamesIterator.hasNext()) {
Server_Game *game = gamesIterator.next().value();