607 lines
19 KiB
C++
607 lines
19 KiB
C++
#include "server_player.h"
|
|
#include "server_card.h"
|
|
#include "server_counter.h"
|
|
#include "server_arrow.h"
|
|
#include "server_cardzone.h"
|
|
#include "server_game.h"
|
|
#include "server_protocolhandler.h"
|
|
#include "decklist.h"
|
|
#include "color.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_player_properties_changed.pb.h"
|
|
#include "pb/event_set_card_attr.pb.h"
|
|
#include "pb/context_connection_state_changed.pb.h"
|
|
#include "pb/context_move_card.pb.h"
|
|
#include "pb/context_undo_draw.pb.h"
|
|
#include <QDebug>
|
|
|
|
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), pingTime(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false)
|
|
{
|
|
}
|
|
|
|
Server_Player::~Server_Player()
|
|
{
|
|
}
|
|
|
|
void Server_Player::prepareDestroy()
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
delete deck;
|
|
|
|
playerMutex.lock();
|
|
if (handler)
|
|
handler->playerRemovedFromGame(game);
|
|
playerMutex.unlock();
|
|
|
|
delete userInfo;
|
|
userInfo = 0;
|
|
|
|
clearZones();
|
|
|
|
deleteLater();
|
|
}
|
|
|
|
int Server_Player::newCardId()
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
return nextCardId++;
|
|
}
|
|
|
|
int Server_Player::newCounterId() const
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
int id = 0;
|
|
QMapIterator<int, Server_Counter *> i(counters);
|
|
while (i.hasNext()) {
|
|
Server_Counter *c = i.next().value();
|
|
if (c->getId() > id)
|
|
id = c->getId();
|
|
}
|
|
return id + 1;
|
|
}
|
|
|
|
int Server_Player::newArrowId() const
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
int id = 0;
|
|
QMapIterator<int, Server_Arrow *> i(arrows);
|
|
while (i.hasNext()) {
|
|
Server_Arrow *a = i.next().value();
|
|
if (a->getId() > id)
|
|
id = a->getId();
|
|
}
|
|
return id + 1;
|
|
}
|
|
|
|
void Server_Player::setupZones()
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
// This may need to be customized according to the game rules.
|
|
// ------------------------------------------------------------------
|
|
|
|
// Create zones
|
|
Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, ServerInfo_Zone::HiddenZone);
|
|
addZone(deckZone);
|
|
Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, ServerInfo_Zone::HiddenZone);
|
|
addZone(sbZone);
|
|
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", makeColor(255, 255, 255), 25, 20));
|
|
addCounter(new Server_Counter(1, "w", makeColor(255, 255, 150), 20, 0));
|
|
addCounter(new Server_Counter(2, "u", makeColor(150, 150, 255), 20, 0));
|
|
addCounter(new Server_Counter(3, "b", makeColor(150, 150, 150), 20, 0));
|
|
addCounter(new Server_Counter(4, "r", makeColor(250, 150, 150), 20, 0));
|
|
addCounter(new Server_Counter(5, "g", makeColor(150, 255, 150), 20, 0));
|
|
addCounter(new Server_Counter(6, "x", makeColor(255, 255, 255), 20, 0));
|
|
addCounter(new Server_Counter(7, "storm", makeColor(255, 255, 255), 20, 0));
|
|
|
|
initialCards = 7;
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
// Assign card ids and create deck from decklist
|
|
InnerDecklistNode *listRoot = deck->getRoot();
|
|
nextCardId = 0;
|
|
for (int i = 0; i < listRoot->size(); ++i) {
|
|
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
|
Server_CardZone *z;
|
|
if (currentZone->getName() == "main")
|
|
z = deckZone;
|
|
else if (currentZone->getName() == "side")
|
|
z = sbZone;
|
|
else
|
|
continue;
|
|
|
|
for (int j = 0; j < currentZone->size(); ++j) {
|
|
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
|
if (!currentCard)
|
|
continue;
|
|
for (int k = 0; k < currentCard->getNumber(); ++k)
|
|
z->cards.append(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z));
|
|
}
|
|
}
|
|
|
|
const QList<MoveCard_ToZone> &sideboardPlan = deck->getCurrentSideboardPlan();
|
|
for (int i = 0; i < sideboardPlan.size(); ++i) {
|
|
const MoveCard_ToZone &m = sideboardPlan[i];
|
|
const QString startZone = QString::fromStdString(m.start_zone());
|
|
const QString targetZone = QString::fromStdString(m.target_zone());
|
|
|
|
Server_CardZone *start, *target;
|
|
if (startZone == "main")
|
|
start = deckZone;
|
|
else if (startZone == "side")
|
|
start = sbZone;
|
|
else
|
|
continue;
|
|
if (targetZone == "main")
|
|
target = deckZone;
|
|
else if (targetZone == "side")
|
|
target = sbZone;
|
|
else
|
|
continue;
|
|
|
|
for (int j = 0; j < start->cards.size(); ++j)
|
|
if (start->cards[j]->getName() == QString::fromStdString(m.card_name())) {
|
|
Server_Card *card = start->cards[j];
|
|
start->cards.removeAt(j);
|
|
target->cards.append(card);
|
|
break;
|
|
}
|
|
}
|
|
|
|
deckZone->shuffle();
|
|
}
|
|
|
|
void Server_Player::clearZones()
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
QMapIterator<QString, Server_CardZone *> zoneIterator(zones);
|
|
while (zoneIterator.hasNext())
|
|
delete zoneIterator.next().value();
|
|
zones.clear();
|
|
|
|
QMapIterator<int, Server_Counter *> counterIterator(counters);
|
|
while (counterIterator.hasNext())
|
|
delete counterIterator.next().value();
|
|
counters.clear();
|
|
|
|
QMapIterator<int, Server_Arrow *> arrowIterator(arrows);
|
|
while (arrowIterator.hasNext())
|
|
delete arrowIterator.next().value();
|
|
arrows.clear();
|
|
|
|
lastDrawList.clear();
|
|
}
|
|
|
|
ServerInfo_PlayerProperties Server_Player::getProperties()
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
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);
|
|
if (deck)
|
|
result.set_deck_hash(deck->getDeckHash().toStdString());
|
|
result.set_ping_seconds(pingTime);
|
|
|
|
return result;
|
|
}
|
|
|
|
void Server_Player::setDeck(DeckList *_deck)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
delete deck;
|
|
deck = _deck;
|
|
}
|
|
|
|
void Server_Player::addZone(Server_CardZone *zone)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
zones.insert(zone->getName(), zone);
|
|
}
|
|
|
|
void Server_Player::addArrow(Server_Arrow *arrow)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
arrows.insert(arrow->getId(), arrow);
|
|
}
|
|
|
|
bool Server_Player::deleteArrow(int arrowId)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
Server_Arrow *arrow = arrows.value(arrowId, 0);
|
|
if (!arrow)
|
|
return false;
|
|
arrows.remove(arrowId);
|
|
delete arrow;
|
|
return true;
|
|
}
|
|
|
|
void Server_Player::addCounter(Server_Counter *counter)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
counters.insert(counter->getId(), counter);
|
|
}
|
|
|
|
bool Server_Player::deleteCounter(int counterId)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
Server_Counter *counter = counters.value(counterId, 0);
|
|
if (!counter)
|
|
return false;
|
|
counters.remove(counterId);
|
|
delete counter;
|
|
return true;
|
|
}
|
|
|
|
Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int number)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
Server_CardZone *deckZone = zones.value("deck");
|
|
Server_CardZone *handZone = zones.value("hand");
|
|
if (deckZone->cards.size() < number)
|
|
number = deckZone->cards.size();
|
|
|
|
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());
|
|
|
|
ServerInfo_Card *cardInfo = eventPrivate.add_cards();
|
|
cardInfo->set_id(card->getId());
|
|
cardInfo->set_name(card->getName().toStdString());
|
|
}
|
|
|
|
ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId);
|
|
ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers);
|
|
|
|
return Response::RespOk;
|
|
}
|
|
|
|
Response::ResponseCode Server_Player::undoDraw(GameEventStorage &ges)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
if (lastDrawList.isEmpty())
|
|
return Response::RespContextError;
|
|
|
|
Response::ResponseCode retVal;
|
|
CardToMove *cardToMove = new CardToMove;
|
|
cardToMove->set_card_id(lastDrawList.takeLast());
|
|
retVal = moveCard(ges, zones.value("hand"), QList<const CardToMove *>() << cardToMove, zones.value("deck"), 0, 0, false, true);
|
|
delete cardToMove;
|
|
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;
|
|
public:
|
|
MoveCardCompareFunctor(int _x) : x(_x) { }
|
|
inline bool operator()(QPair<Server_Card *, int> a, QPair<Server_Card *, int> b)
|
|
{
|
|
if (a.second < x) {
|
|
if (b.second >= x)
|
|
return false;
|
|
else
|
|
return (a.second > b.second);
|
|
} else {
|
|
if (b.second < x)
|
|
return true;
|
|
else
|
|
return (a.second < b.second);
|
|
}
|
|
}
|
|
};
|
|
|
|
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() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer()))
|
|
return Response::RespContextError;
|
|
|
|
if (!targetzone->hasCoords() && (x == -1))
|
|
x = targetzone->cards.size();
|
|
|
|
QList<QPair<Server_Card *, int> > cardsToMove;
|
|
QMap<Server_Card *, const CardToMove *> cardProperties;
|
|
for (int i = 0; i < _cards.size(); ++i) {
|
|
int position;
|
|
Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position);
|
|
if (!card)
|
|
return Response::RespNameNotFound;
|
|
if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y))
|
|
return Response::RespContextError;
|
|
cardsToMove.append(QPair<Server_Card *, int>(card, position));
|
|
cardProperties.insert(card, _cards[i]);
|
|
}
|
|
|
|
MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x);
|
|
qSort(cardsToMove.begin(), cardsToMove.end(), cmp);
|
|
|
|
bool secondHalf = false;
|
|
int xIndex = -1;
|
|
for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) {
|
|
Server_Card *card = cardsToMove[cardIndex].first;
|
|
const CardToMove *thisCardProperties = cardProperties.value(card);
|
|
int originalPosition = cardsToMove[cardIndex].second;
|
|
int position = startzone->removeCard(card);
|
|
if (startzone->getName() == "hand") {
|
|
if (undoingDraw)
|
|
lastDrawList.removeAt(lastDrawList.indexOf(card->getId()));
|
|
else if (lastDrawList.contains(card->getId()))
|
|
lastDrawList.clear();
|
|
}
|
|
|
|
if ((startzone == targetzone) && !startzone->hasCoords()) {
|
|
if (!secondHalf && (originalPosition < x)) {
|
|
xIndex = -1;
|
|
secondHalf = true;
|
|
} else if (secondHalf)
|
|
--xIndex;
|
|
else
|
|
++xIndex;
|
|
} else
|
|
++xIndex;
|
|
int newX = x + xIndex;
|
|
|
|
// Attachment relationships can be retained when moving a card onto the opponent's table
|
|
if (startzone->getName() != targetzone->getName()) {
|
|
// Delete all attachment relationships
|
|
if (card->getParentCard())
|
|
card->setParentCard(0);
|
|
|
|
// 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(ges, attachedCards[i]);
|
|
}
|
|
|
|
if (startzone != targetzone) {
|
|
// Delete all arrows from and to the card
|
|
const QList<Server_Player *> &players = game->getPlayers().values();
|
|
for (int i = 0; i < players.size(); ++i) {
|
|
QList<int> arrowsToDelete;
|
|
QMapIterator<int, Server_Arrow *> arrowIterator(players[i]->getArrows());
|
|
while (arrowIterator.hasNext()) {
|
|
Server_Arrow *arrow = arrowIterator.next().value();
|
|
if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card))
|
|
arrowsToDelete.append(arrow->getId());
|
|
}
|
|
for (int j = 0; j < arrowsToDelete.size(); ++j)
|
|
players[i]->deleteArrow(arrowsToDelete[j]);
|
|
}
|
|
}
|
|
|
|
if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) {
|
|
Event_DestroyCard event;
|
|
event.set_zone_name(startzone->getName().toStdString());
|
|
event.set_card_id(card->getId());
|
|
ges.enqueueGameEvent(event, playerId);
|
|
|
|
card->deleteLater();
|
|
} else {
|
|
if (!targetzone->hasCoords()) {
|
|
y = 0;
|
|
card->resetState();
|
|
} else
|
|
newX = targetzone->getFreeGridColumn(newX, y, card->getName());
|
|
|
|
targetzone->insertCard(card, newX, y);
|
|
|
|
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() != ServerInfo_Zone::PublicZone);
|
|
bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt;
|
|
bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != ServerInfo_Zone::PublicZone);
|
|
|
|
QString privateCardName, publicCardName;
|
|
if (!(sourceHiddenToPlayer && targetHiddenToPlayer))
|
|
privateCardName = card->getName();
|
|
if (!(sourceHiddenToOthers && targetHiddenToOthers))
|
|
publicCardName = card->getName();
|
|
|
|
int oldCardId = card->getId();
|
|
if (thisCardProperties->face_down() || (targetzone->getPlayer() != startzone->getPlayer()))
|
|
card->setId(targetzone->getPlayer()->newCardId());
|
|
card->setFaceDown(thisCardProperties->face_down());
|
|
|
|
// The player does not get to see which card he moved if it moves between two parts of hidden zones which
|
|
// are not being looked at.
|
|
int privateNewCardId = card->getId();
|
|
int privateOldCardId = oldCardId;
|
|
if (!targetBeingLookedAt && !sourceBeingLookedAt) {
|
|
privateOldCardId = -1;
|
|
privateNewCardId = -1;
|
|
privateCardName = QString();
|
|
}
|
|
int privatePosition = -1;
|
|
if (startzone->getType() == ServerInfo_Zone::HiddenZone)
|
|
privatePosition = position;
|
|
|
|
Event_MoveCard eventOthers;
|
|
eventOthers.set_start_zone(startzone->getName().toStdString());
|
|
eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId());
|
|
if (startzone != targetzone)
|
|
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() == ServerInfo_Zone::HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1)))
|
|
|| (startzone->getType() == ServerInfo_Zone::PublicZone)
|
|
)
|
|
position = -1;
|
|
if ((targetzone->getType() == ServerInfo_Zone::HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1)))
|
|
newX = -1;
|
|
|
|
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(ges, targetzone->getName(), card->getId(), AttrTapped, "1");
|
|
QString ptString = QString::fromStdString(thisCardProperties->pt());
|
|
if (!ptString.isEmpty() && !thisCardProperties->face_down())
|
|
setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrPT, ptString);
|
|
}
|
|
}
|
|
if (undoingDraw)
|
|
ges.setGameEventContext(Context_UndoDraw());
|
|
else
|
|
ges.setGameEventContext(Context_MoveCard());
|
|
|
|
if (startzone->hasCoords() && fixFreeSpaces)
|
|
startzone->fixFreeSpaces(ges);
|
|
|
|
return Response::RespOk;
|
|
}
|
|
|
|
void Server_Player::unattachCard(GameEventStorage &ges, Server_Card *card)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
Server_CardZone *zone = card->getZone();
|
|
|
|
card->setParentCard(0);
|
|
|
|
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(ges, zone, QList<const CardToMove *>() << cardToMove, zone, -1, card->getY(), card->getFaceDown());
|
|
delete cardToMove;
|
|
}
|
|
|
|
Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, const QString &zoneName, int cardId, CardAttribute attribute, const QString &attrValue)
|
|
{
|
|
QMutexLocker locker(&game->gameMutex);
|
|
|
|
Server_CardZone *zone = getZones().value(zoneName);
|
|
if (!zone)
|
|
return Response::RespNameNotFound;
|
|
if (!zone->hasCoords())
|
|
return Response::RespContextError;
|
|
|
|
QString result;
|
|
if (cardId == -1) {
|
|
QListIterator<Server_Card *> CardIterator(zone->cards);
|
|
while (CardIterator.hasNext()) {
|
|
result = CardIterator.next()->setAttribute(attribute, attrValue, true);
|
|
if (result.isNull())
|
|
return Response::RespInvalidCommand;
|
|
}
|
|
} else {
|
|
Server_Card *card = zone->getCard(cardId);
|
|
if (!card)
|
|
return Response::RespNameNotFound;
|
|
result = card->setAttribute(attribute, attrValue, false);
|
|
if (result.isNull())
|
|
return Response::RespInvalidCommand;
|
|
}
|
|
|
|
Event_SetCardAttr event;
|
|
event.set_zone_name(zone->getName().toStdString());
|
|
if (cardId != -1)
|
|
event.set_card_id(cardId);
|
|
event.set_attribute(attribute);
|
|
event.set_attr_value(result.toStdString());
|
|
ges.enqueueGameEvent(event, playerId);
|
|
|
|
return Response::RespOk;
|
|
}
|
|
|
|
void Server_Player::sendGameEvent(GameEventContainer *cont)
|
|
{
|
|
QMutexLocker locker(&playerMutex);
|
|
|
|
if (handler)
|
|
handler->sendProtocolItem(*cont);
|
|
}
|
|
|
|
void Server_Player::setProtocolHandler(Server_ProtocolHandler *_handler)
|
|
{
|
|
playerMutex.lock();
|
|
handler = _handler;
|
|
playerMutex.unlock();
|
|
|
|
pingTime = _handler ? 0 : -1;
|
|
|
|
Event_PlayerPropertiesChanged event;
|
|
event.mutable_player_properties()->set_ping_seconds(pingTime);
|
|
|
|
GameEventStorage ges;
|
|
ges.setGameEventContext(Context_ConnectionStateChanged());
|
|
ges.enqueueGameEvent(event, playerId);
|
|
ges.sendToGame(game);
|
|
}
|