Commit 4895f2b4 authored by Max-Wilhelm Bruker's avatar Max-Wilhelm Bruker
Browse files

server code cleanup, changed in-game ping event to not use any bandwidth as long as nothing changes

parent a64df4a0
......@@ -762,7 +762,6 @@ void MessageLogWidget::containerProcessingDone()
void MessageLogWidget::connectToPlayer(Player *player)
{
connect(player, SIGNAL(logConnectionStateChanged(Player *, bool)), this, SLOT(logConnectionStateChanged(Player *, bool)));
connect(player, SIGNAL(logSay(Player *, QString)), this, SLOT(logSay(Player *, QString)));
connect(player, SIGNAL(logShuffle(Player *, CardZone *)), this, SLOT(logShuffle(Player *, CardZone *)));
connect(player, SIGNAL(logRollDie(Player *, int, int)), this, SLOT(logRollDie(Player *, int, int)));
......
......@@ -41,7 +41,6 @@
#include "pb/serverinfo_zone.pb.h"
#include "pb/context_move_card.pb.h"
#include "pb/context_undo_draw.pb.h"
#include "pb/event_connection_state_changed.pb.h"
#include "pb/event_game_say.pb.h"
#include "pb/event_shuffle.pb.h"
#include "pb/event_roll_die.pb.h"
......@@ -814,11 +813,6 @@ void Player::setCardAttrHelper(const GameEventContext &context, CardItem *card,
}
}
void Player::eventConnectionStateChanged(const Event_ConnectionStateChanged &event)
{
emit logConnectionStateChanged(this, event.connected());
}
void Player::eventGameSay(const Event_GameSay &event)
{
emit logSay(this, QString::fromStdString(event.message()));
......@@ -1159,7 +1153,6 @@ void Player::eventRevealCards(const Event_RevealCards &event)
void Player::processGameEvent(GameEvent::GameEventType type, const GameEvent &event, const GameEventContext &context)
{
switch (type) {
case GameEvent::CONNECTION_STATE_CHANGED: eventConnectionStateChanged(event.GetExtension(Event_ConnectionStateChanged::ext)); break;
case GameEvent::GAME_SAY: eventGameSay(event.GetExtension(Event_GameSay::ext)); break;
case GameEvent::SHUFFLE: eventShuffle(event.GetExtension(Event_Shuffle::ext)); break;
case GameEvent::ROLL_DIE: eventRollDie(event.GetExtension(Event_RollDie::ext)); break;
......
......@@ -77,7 +77,6 @@ class Player : public QObject, public QGraphicsItem {
signals:
void newCardAdded(AbstractCardItem *card);
// Log events
void logConnectionStateChanged(Player *player, bool connectionState);
void logSay(Player *player, QString message);
void logShuffle(Player *player, CardZone *zone);
void logRollDie(Player *player, int sides, int roll);
......
......@@ -81,26 +81,40 @@ void PlayerListWidget::addPlayer(const ServerInfo_PlayerProperties &player)
sortItems(1, Qt::AscendingOrder);
}
void PlayerListWidget::updatePlayerProperties(const ServerInfo_PlayerProperties &prop)
void PlayerListWidget::updatePlayerProperties(const ServerInfo_PlayerProperties &prop, int playerId)
{
QTreeWidgetItem *player = players.value(prop.player_id(), 0);
if (playerId == -1)
playerId = prop.player_id();
QTreeWidgetItem *player = players.value(playerId, 0);
if (!player)
return;
player->setIcon(1, prop.spectator() ? spectatorIcon : playerIcon);
player->setData(1, Qt::UserRole, !prop.spectator());
player->setData(2, Qt::UserRole, prop.conceded());
player->setData(2, Qt::UserRole + 1, prop.ready_start());
player->setIcon(2, gameStarted ? (prop.conceded() ? concededIcon : QIcon()) : (prop.ready_start() ? readyIcon : notReadyIcon));
player->setData(3, Qt::UserRole, prop.user_info().user_level());
player->setIcon(3, QIcon(UserLevelPixmapGenerator::generatePixmap(12, prop.user_info().user_level())));
player->setText(4, QString::fromStdString(prop.user_info().name()));
const QString country = QString::fromStdString(prop.user_info().country());
if (!country.isEmpty())
player->setIcon(4, QIcon(CountryPixmapGenerator::generatePixmap(12, country)));
player->setData(4, Qt::UserRole, QString::fromStdString(prop.user_info().name()));
player->setData(4, Qt::UserRole + 1, prop.player_id());
player->setText(5, QString::fromStdString(prop.deck_hash()));
if (prop.has_spectator()) {
player->setIcon(1, prop.spectator() ? spectatorIcon : playerIcon);
player->setData(1, Qt::UserRole, !prop.spectator());
}
if (prop.has_conceded())
player->setData(2, Qt::UserRole, prop.conceded());
if (prop.has_ready_start())
player->setData(2, Qt::UserRole + 1, prop.ready_start());
if (prop.has_conceded() && prop.has_ready_start())
player->setIcon(2, gameStarted ? (prop.conceded() ? concededIcon : QIcon()) : (prop.ready_start() ? readyIcon : notReadyIcon));
if (prop.has_user_info()) {
player->setData(3, Qt::UserRole, prop.user_info().user_level());
player->setIcon(3, QIcon(UserLevelPixmapGenerator::generatePixmap(12, prop.user_info().user_level())));
player->setText(4, QString::fromStdString(prop.user_info().name()));
const QString country = QString::fromStdString(prop.user_info().country());
if (!country.isEmpty())
player->setIcon(4, QIcon(CountryPixmapGenerator::generatePixmap(12, country)));
player->setData(4, Qt::UserRole, QString::fromStdString(prop.user_info().name()));
}
if (prop.has_player_id())
player->setData(4, Qt::UserRole + 1, prop.player_id());
if (prop.has_deck_hash())
player->setText(5, QString::fromStdString(prop.deck_hash()));
if (prop.has_ping_seconds())
player->setIcon(0, QIcon(PingPixmapGenerator::generatePixmap(12, prop.ping_seconds(), 10)));
}
void PlayerListWidget::removePlayer(int playerId)
......@@ -123,14 +137,6 @@ void PlayerListWidget::setActivePlayer(int playerId)
}
}
void PlayerListWidget::updatePing(int playerId, int pingTime)
{
QTreeWidgetItem *twi = players.value(playerId, 0);
if (!twi)
return;
twi->setIcon(0, QIcon(PingPixmapGenerator::generatePixmap(12, pingTime, 10)));
}
void PlayerListWidget::setGameStarted(bool _gameStarted, bool resuming)
{
gameStarted = _gameStarted;
......
......@@ -41,8 +41,7 @@ public:
void addPlayer(const ServerInfo_PlayerProperties &player);
void removePlayer(int playerId);
void setActivePlayer(int playerId);
void updatePing(int playerId, int pingTime);
void updatePlayerProperties(const ServerInfo_PlayerProperties &prop);
void updatePlayerProperties(const ServerInfo_PlayerProperties &prop, int playerId = -1);
void setGameStarted(bool _gameStarted, bool resuming);
void showContextMenu(const QPoint &pos, const QModelIndex &index);
};
......
......@@ -5,6 +5,7 @@
#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QTimer>
#include "tab_game.h"
#include "tab_supervisor.h"
#include "cardinfowidget.h"
......@@ -50,8 +51,9 @@
#include "pb/event_game_closed.pb.h"
#include "pb/event_set_active_player.pb.h"
#include "pb/event_set_active_phase.pb.h"
#include "pb/event_ping.pb.h"
#include "pb/context_deck_select.pb.h"
#include "pb/context_connection_state_changed.pb.h"
#include "pb/context_ping_changed.pb.h"
#include "get_pb_extension.h"
ReadyStartButton::ReadyStartButton(QWidget *parent)
......@@ -208,6 +210,11 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
resuming(event.resuming()),
currentPhase(-1)
{
gameTimer = new QTimer(this);
gameTimer->setInterval(1000);
connect(gameTimer, SIGNAL(timeout()), this, SLOT(incrementGameTime()));
gameTimer->start();
phasesToolbar = new PhasesToolbar;
phasesToolbar->hide();
connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this, SLOT(sendGameCommand(const ::google::protobuf::Message &, int)));
......@@ -361,6 +368,17 @@ void TabGame::closeRequest()
actLeaveGame();
}
void TabGame::incrementGameTime()
{
int seconds = ++secondsElapsed;
int minutes = seconds / 60;
seconds -= minutes * 60;
int hours = minutes / 60;
minutes -= hours * 60;
timeElapsedLabel->setText(QString::number(hours).rightJustified(2, '0') + ":" + QString::number(minutes).rightJustified(2, '0') + ":" + QString::number(seconds).rightJustified(2, '0'));
}
void TabGame::adminLockChanged(bool lock)
{
bool v = !(spectator && !spectatorsCanTalk && lock);
......@@ -496,7 +514,6 @@ void TabGame::processGameEventContainer(const GameEventContainer &cont, Abstract
case GameEvent::GAME_CLOSED: eventGameClosed(event.GetExtension(Event_GameClosed::ext), playerId, context); break;
case GameEvent::SET_ACTIVE_PLAYER: eventSetActivePlayer(event.GetExtension(Event_SetActivePlayer::ext), playerId, context); break;
case GameEvent::SET_ACTIVE_PHASE: eventSetActivePhase(event.GetExtension(Event_SetActivePhase::ext), playerId, context); break;
case GameEvent::PING: eventPing(event.GetExtension(Event_Ping::ext), playerId, context); break;
default: {
Player *player = players.value(playerId, 0);
......@@ -650,6 +667,9 @@ void TabGame::eventGameStateChanged(const Event_GameStateChanged &event, int /*e
player->processCardAttachment(playerInfo);
}
}
secondsElapsed = event.seconds_elapsed();
if (event.game_started() && !started) {
startGame(!gameStateKnown);
if (gameStateKnown)
......@@ -669,7 +689,7 @@ void TabGame::eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &
Player *player = players.value(eventPlayerId, 0);
if (!player)
return;
playerListWidget->updatePlayerProperties(event.player_properties());
playerListWidget->updatePlayerProperties(event.player_properties(), eventPlayerId);
const GameEventContext::ContextType contextType = static_cast<const GameEventContext::ContextType>(getPbExtension(context));
switch (contextType) {
......@@ -697,6 +717,10 @@ void TabGame::eventPlayerPropertiesChanged(const Event_PlayerPropertiesChanged &
messageLog->logDeckSelect(player, QString::fromStdString(context.GetExtension(Context_DeckSelect::ext).deck_hash()));
break;
}
case GameEventContext::CONNECTION_STATE_CHANGED: {
messageLog->logConnectionStateChanged(player, event.player_properties().ping_seconds() != -1);
break;
}
default: ;
}
}
......@@ -809,20 +833,6 @@ void TabGame::eventSetActivePhase(const Event_SetActivePhase &event, int /*event
emit userEvent();
}
void TabGame::eventPing(const Event_Ping &event, int /*eventPlayerId*/, const GameEventContext & /*context*/)
{
const int pingListSize = event.ping_list_size();
for (int i = 0; i < pingListSize; ++i)
playerListWidget->updatePing(event.ping_list(i).player_id(), event.ping_list(i).ping_time());
int seconds = event.seconds_elapsed();
int minutes = seconds / 60;
seconds -= minutes * 60;
int hours = minutes / 60;
minutes -= hours * 60;
timeElapsedLabel->setText(QString::number(hours).rightJustified(2, '0') + ":" + QString::number(minutes).rightJustified(2, '0') + ":" + QString::number(seconds).rightJustified(2, '0'));
}
void TabGame::newCardAdded(AbstractCardItem *card)
{
connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfo, SLOT(setCard(AbstractCardItem *)));
......
......@@ -13,6 +13,7 @@ class DeckView;
class GameScene;
class CardInfoWidget;
class MessageLogWidget;
class QTimer;
class QSplitter;
class QLabel;
class QLineEdit;
......@@ -89,6 +90,8 @@ public:
class TabGame : public Tab {
Q_OBJECT
private:
QTimer *gameTimer;
int secondsElapsed;
QList<AbstractClient *> clients;
int gameId;
QString gameDescription;
......@@ -152,6 +155,7 @@ signals:
void containerProcessingDone();
void openMessageDialog(const QString &userName, bool focus);
private slots:
void incrementGameTime();
void adminLockChanged(bool lock);
void newCardAdded(AbstractCardItem *card);
......
......@@ -41,15 +41,16 @@ SET(PROTO_FILES
command_stop_dump_zone.proto
command_undo_draw.proto
context_concede.proto
context_connection_state_changed.proto
context_deck_select.proto
context_move_card.proto
context_mulligan.proto
context_ping_changed.proto
context_ready_start.proto
context_undo_draw.proto
event_add_to_list.proto
event_attach_card.proto
event_connection_closed.proto
event_connection_state_changed.proto
event_create_arrow.proto
event_create_counter.proto
event_create_token.proto
......@@ -72,7 +73,6 @@ SET(PROTO_FILES
event_list_games.proto
event_list_rooms.proto
event_move_card.proto
event_ping.proto
event_player_properties_changed.proto
event_remove_from_list.proto
event_reveal_cards.proto
......
import "game_event_context.proto";
message Context_ConnectionStateChanged {
extend GameEventContext {
optional Context_ConnectionStateChanged ext = 1007;
}
}
import "game_event_context.proto";
message Context_PingChanged {
extend GameEventContext {
optional Context_PingChanged ext = 1006;
}
}
import "game_event.proto";
message Event_ConnectionStateChanged {
extend GameEvent {
optional Event_ConnectionStateChanged ext = 1006;
}
optional bool connected = 1;
}
......@@ -9,4 +9,5 @@ message Event_GameStateChanged {
optional bool game_started = 2;
optional sint32 active_player_id = 3;
optional sint32 active_phase = 4;
optional uint32 seconds_elapsed = 5;
}
import "game_event.proto";
import "serverinfo_playerping.proto";
message Event_Ping {
extend GameEvent {
optional Event_Ping ext = 1008;
}
optional uint32 seconds_elapsed = 1;
repeated ServerInfo_PlayerPing ping_list = 2;
}
......@@ -6,9 +6,7 @@ message GameEvent {
GAME_HOST_CHANGED = 1003;
KICKED = 1004;
GAME_STATE_CHANGED = 1005;
CONNECTION_STATE_CHANGED = 1006;
PLAYER_PROPERTIES_CHANGED = 1007;
PING = 1008;
GAME_SAY = 1009;
CREATE_ARROW = 2000;
DELETE_ARROW = 2001;
......
......@@ -6,6 +6,8 @@ message GameEventContext {
UNDO_DRAW = 1003;
MOVE_CARD = 1004;
MULLIGAN = 1005;
PING_CHANGED = 1006;
CONNECTION_STATE_CHANGED = 1007;
}
extensions 100 to max;
}
......@@ -7,4 +7,5 @@ message ServerInfo_PlayerProperties {
optional bool conceded = 4;
optional bool ready_start = 5;
optional string deck_hash = 6;
optional sint32 ping_seconds = 7;
}
......@@ -26,12 +26,13 @@
#include "server_cardzone.h"
#include "server_counter.h"
#include "decklist.h"
#include "pb/context_connection_state_changed.pb.h"
#include "pb/context_ping_changed.pb.h"
#include "pb/event_player_properties_changed.pb.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"
......@@ -77,9 +78,10 @@ Server_Game::~Server_Game()
void Server_Game::pingClockTimeout()
{
QMutexLocker locker(&gameMutex);
++secondsElapsed;
Event_Ping event;
event.set_seconds_elapsed(++secondsElapsed);
GameEventStorage ges;
ges.setGameEventContext(Context_PingChanged());
QList<ServerInfo_PlayerPing *> pingList;
QMapIterator<int, Server_Player *> playerIterator(players);
......@@ -89,19 +91,28 @@ void Server_Game::pingClockTimeout()
Server_Player *player = playerIterator.next().value();
if (!player->getSpectator())
++playerCount;
int pingTime;
if (player->getProtocolHandler()) {
pingTime = player->getProtocolHandler()->getLastCommandTime();
if (!player->getSpectator())
allPlayersInactive = false;
} else
pingTime = -1;
ServerInfo_PlayerPing *pingInfo = event.add_ping_list();
pingInfo->set_player_id(player->getPlayerId());
pingInfo->set_ping_time(pingTime);
const int oldPingTime = player->getPingTime();
player->playerMutex.lock();
int newPingTime;
if (player->getProtocolHandler())
newPingTime = player->getProtocolHandler()->getLastCommandTime();
else
newPingTime = -1;
player->playerMutex.unlock();
if ((newPingTime != -1) && !player->getSpectator())
allPlayersInactive = false;
if ((abs(oldPingTime - newPingTime) > 1) || ((newPingTime == -1) && (oldPingTime != -1)) || ((newPingTime != -1) && (oldPingTime == -1))) {
player->setPingTime(newPingTime);
Event_PlayerPropertiesChanged event;
event.mutable_player_properties()->set_ping_seconds(newPingTime);
ges.enqueueGameEvent(event, player->getPlayerId());
}
}
sendGameEventContainer(prepareGameEvent(event, -1));
ges.sendToGame(this);
const int maxTime = room->getServer()->getMaxGameInactivityTime();
if (allPlayersInactive) {
......@@ -165,6 +176,7 @@ void Server_Game::doStartGameIfReady()
while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value();
Event_GameStateChanged event;
event.set_seconds_elapsed(secondsElapsed);
event.set_game_started(true);
event.set_active_player_id(0);
event.set_active_phase(0);
......@@ -229,6 +241,7 @@ void Server_Game::stopGameIfFinished()
while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value();
Event_GameStateChanged event;
event.set_seconds_elapsed(secondsElapsed);
event.set_game_started(false);
QListIterator<ServerInfo_Player> gameStateIterator(getGameState(player));
while (gameStateIterator.hasNext())
......@@ -438,15 +451,6 @@ void Server_Game::nextTurn()
setActivePlayer(keys[listPos]);
}
void Server_Game::postConnectionStatusUpdate(Server_Player *player, bool connectionStatus)
{
QMutexLocker locker(&gameMutex);
Event_ConnectionStateChanged event;
event.set_connected(connectionStatus);
sendGameEventContainer(prepareGameEvent(event, player->getPlayerId()));
}
QList<ServerInfo_Player> Server_Game::getGameState(Server_Player *playerWhosAsking) const
{
QMutexLocker locker(&gameMutex);
......
......@@ -95,7 +95,7 @@ public:
void setActivePlayer(int _activePlayer);
void setActivePhase(int _activePhase);
void nextTurn();
void postConnectionStatusUpdate(Server_Player *player, bool connectionStatus);
int getSecondsElapsed() const { return secondsElapsed; }
QList<ServerInfo_Player> getGameState(Server_Player *playerWhosAsking) const;
......
......@@ -14,13 +14,15 @@
#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), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false)
: game(_game), handler(_handler), userInfo(new ServerInfo_User(_userInfo)), deck(0), pingTime(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false)
{
}
......@@ -201,6 +203,7 @@ ServerInfo_PlayerProperties Server_Player::getProperties()
result.set_ready_start(readyStart);
if (deck)
result.set_deck_hash(deck->getDeckHash().toStdString());
result.set_ping_seconds(pingTime);
return result;
}
......@@ -585,3 +588,20 @@ void Server_Player::sendGameEvent(GameEventContainer *cont)
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);
}
......@@ -27,7 +27,6 @@ class GameEventStorage;
class Server_Player : public Server_ArrowTarget {
Q_OBJECT
private:
mutable QMutex playerMutex;
class MoveCardCompareFunctor;
Server_Game *game;
Server_ProtocolHandler *handler;
......@@ -37,6 +36,7 @@ private:
QMap<int, Server_Counter *> counters;
QMap<int, Server_Arrow *> arrows;
QList<int> lastDrawList;
int pingTime;
int playerId;
bool spectator;
int initialCards;
......@@ -44,11 +44,12 @@ private:
bool readyStart;
bool conceded;
public:
mutable QMutex playerMutex;
Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_ProtocolHandler *_handler);
~Server_Player();
void prepareDestroy();
Server_ProtocolHandler *getProtocolHandler() const { return handler; }
void setProtocolHandler(Server_ProtocolHandler *_handler) { playerMutex.lock(); handler = _handler; playerMutex.unlock(); }
void setProtocolHandler(Server_ProtocolHandler *_handler);
void setPlayerId(int _id) { playerId = _id; }
int getInitialCards() const { return initialCards; }
......@@ -66,7 +67,9 @@ public:
const QMap<QString, Server_CardZone *> &getZones() const { return zones; }
const QMap<int, Server_Counter *> &getCounters() const { return counters; }
const QMap<int, Server_Arrow *> &getArrows() const { return arrows; }
int getPingTime() const { return pingTime; }
void setPingTime(int _pingTime) { pingTime = _pingTime; }
ServerInfo_PlayerProperties getProperties();
int newCardId();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment