From 9f6bf5206e5b6e51126e86ce10555da75e68a828 Mon Sep 17 00:00:00 2001 From: lotodore Date: Wed, 5 Sep 2007 19:14:34 +0000 Subject: [PATCH] The checkbox "fill up with computer players" is now working (protocol has been changed to implement this). Lobby dialog is now also used after joining the game. Leaving game not possible yet. --- docs/net_protocol.txt | 46 +++++--- .../connecttoserverdialogimpl.cpp | 110 +++++++++--------- .../gamelobbydialog/gamelobbydialogimpl.cpp | 102 +++++++++++++--- .../qt/gamelobbydialog/gamelobbydialogimpl.h | 6 + src/gui/qt/mainwindow/mainwindowimpl.cpp | 6 +- .../startnetworkgamedialogimpl.cpp | 6 +- .../startnetworkgamedialogimpl.h | 2 +- src/net/clientthread.h | 6 +- src/net/common/clientthread.cpp | 39 ++++--- src/net/common/netpacket.cpp | 60 +++++++--- src/net/common/servergamestate.cpp | 27 +++-- src/net/netpacket.h | 7 ++ src/session.cpp | 12 +- src/session.h | 6 +- 14 files changed, 288 insertions(+), 147 deletions(-) diff --git a/docs/net_protocol.txt b/docs/net_protocol.txt index 64e6bd18..0f6069c0 100644 --- a/docs/net_protocol.txt +++ b/docs/net_protocol.txt @@ -1,4 +1,5 @@ Changelog: +09-05-2007: Minimum packet length is now definitely 8. 08-26-2007: Server sends player name only on request. Player id is used in all other cases. 08-20-2007: Create Game is answered by Join Game Ack. @@ -23,7 +24,7 @@ PokerTH general message format: | +-------------------------------+ / | padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -Minimum length is 4. Maximum length is 256. +Minimum length is 8. Maximum length is 256. Client Request: Init @@ -300,13 +301,28 @@ Client Request: Kick Player +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Client Request: Leave Current Game + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Message Type = 15 | Message Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Client Request: Start Event 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 15 | Message Length = 4 | + | Message Type = 16 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Start Flags | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Start Flags: + 0x01 set: Fill up with computer opponents. Server Notification: Game Start @@ -314,7 +330,7 @@ Server Notification: Game Start 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 16 | Message Length | + | Message Type = 17 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Start Dealer Player Id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -345,7 +361,7 @@ Server Notification: Hand Start 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 17 | Message Length = 8 | + | Message Type = 18 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Your 1st Card | Your 2nd Card | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -359,7 +375,7 @@ Server Request/Notification: Player's Turn 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 18 | Message Length = 8 | + | Message Type = 19 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -378,7 +394,7 @@ Client Reply/Request: Player's Action 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 19 | Message Length = 12 | + | Message Type = 20 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game State | Player Action | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -403,7 +419,7 @@ Server Notification: Player's Action Done 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 20 | Message Length = 20 | + | Message Type = 21 | Message Length = 20 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -424,7 +440,7 @@ Server Reply: Player's Action Rejected 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 21 | Message Length = 16 | + | Message Type = 22 | Message Length = 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game State | Player Action | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -452,7 +468,7 @@ Server Notification: Deal Flop Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 22 | Message Length = 12 | + | Message Type = 23 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Flop 1st Card | Flop 2nd Card | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -465,7 +481,7 @@ Server Notification: Deal Turn Card 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 23 | Message Length = 8 | + | Message Type = 24 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Turn Card | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -476,7 +492,7 @@ Server Notification: Deal River Card 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 24 | Message Length = 8 | + | Message Type = 25 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | River Card | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -487,7 +503,7 @@ Server Notification: All In Show Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 25 | Message Length | + | Message Type = 26 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number Of PlayerCards Records | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -509,7 +525,7 @@ Server Notification: End Of Hand Show Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 26 | Message Length | + | Message Type = 27 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Number Of PlayerResult Records | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -543,7 +559,7 @@ Server Notification: End Of Hand Hide Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 27 | Message Length = 16 | + | Message Type = 28 | Message Length = 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -558,7 +574,7 @@ Server Notification: End Of Game 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 28 | Message Length = 8 | + | Message Type = 29 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Winner Player Id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp b/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp index 6fe2b168..44c2fbed 100644 --- a/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp +++ b/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp @@ -1,60 +1,62 @@ -/*************************************************************************** - * Copyright (C) 2006 by FThauer FHammer * - * f.thauer@web.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "connecttoserverdialogimpl.h" -// #include "configfile.h" -#include - -connectToServerDialogImpl::connectToServerDialogImpl(QWidget *parent) - : QDialog(parent) -{ - - setupUi(this); -} - +/*************************************************************************** + * Copyright (C) 2006 by FThauer FHammer * + * f.thauer@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "connecttoserverdialogimpl.h" +#include + +connectToServerDialogImpl::connectToServerDialogImpl(QWidget *parent) + : QDialog(parent) +{ + + setupUi(this); +} + void connectToServerDialogImpl::exec() { label_actionMessage->setText(""); - progressBar->setValue(0); + progressBar->setValue(0); QDialog::exec(); } - -void connectToServerDialogImpl::refresh(int actionID) { - - switch (actionID) { - - case MSG_SOCK_INIT_DONE: { label_actionMessage->setText("Resolving address..."); } - break; - case MSG_SOCK_RESOLVE_DONE: { label_actionMessage->setText("Connecting to server..."); } - break; - case MSG_SOCK_CONNECT_DONE: { label_actionMessage->setText("Starting session..."); } - break; - case MSG_SOCK_SESSION_DONE: { label_actionMessage->setText("Connection established!"); } - break; - - default: { label_actionMessage->setText("Please wait..."); } - } - - progressBar->setValue(actionID*(100/MSG_SOCK_LIMIT_CONNECT)); - - if (actionID == MSG_SOCK_LIMIT_CONNECT) - QTimer::singleShot(1000, this, SLOT(accept())); -} - + +void connectToServerDialogImpl::refresh(int actionID) { + + bool skip = false; + switch (actionID) { + + case MSG_SOCK_INIT_DONE: { label_actionMessage->setText(tr("Resolving address...")); } + break; + case MSG_SOCK_RESOLVE_DONE: { label_actionMessage->setText(tr("Connecting to server...")); } + break; + case MSG_SOCK_CONNECT_DONE: { label_actionMessage->setText(tr("Starting session...")); } + break; + case MSG_SOCK_SESSION_DONE: { label_actionMessage->setText(tr("Connection established!")); } + break; + default: skip = true; + } + + if (!skip) + { + progressBar->setValue(actionID*(100/MSG_SOCK_LIMIT_CONNECT)); + + if (actionID == MSG_SOCK_LIMIT_CONNECT) + QTimer::singleShot(1000, this, SLOT(accept())); + } +} + diff --git a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp index e36b7466..e82226a7 100644 --- a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp +++ b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp @@ -4,7 +4,7 @@ // Description: // // -// Author: FThauer FHammer , (C) 2007 +// Author: FThauer FHammer LMay , (C) 2007 // // Copyright: See COPYING file that comes with this distribution // @@ -13,6 +13,7 @@ #include "session.h" #include "configfile.h" #include "gamedata.h" +#include gameLobbyDialogImpl::gameLobbyDialogImpl(QWidget *parent, ConfigFile *c) : QDialog(parent), myW(NULL), myConfig(c), mySession(NULL), currentGameName(""), isAdmin(false) @@ -22,6 +23,9 @@ gameLobbyDialogImpl::gameLobbyDialogImpl(QWidget *parent, ConfigFile *c) connect( pushButton_CreateGame, SIGNAL( clicked() ), this, SLOT( createGame() ) ); connect( pushButton_JoinGame, SIGNAL( clicked() ), this, SLOT( joinGame() ) ); connect( treeWidget_GameList, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem*) ), this, SLOT( gameSelected(QTreeWidgetItem*, QTreeWidgetItem*) ) ); + connect( pushButton_StartGame, SIGNAL( clicked() ), this, SLOT( startGame() ) ); + connect( pushButton_Kick, SIGNAL( clicked() ), this, SLOT( kickPlayer() ) ); + connect( treeWidget_connectedPlayers, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem*) ), this, SLOT( playerSelected(QTreeWidgetItem*, QTreeWidgetItem*) ) ); clearDialog(); } @@ -50,7 +54,7 @@ void gameLobbyDialogImpl::createGame() myCreateInternetGameDialog->exec(); if (myCreateInternetGameDialog->result() == QDialog::Accepted ) { - + GameData gameData; // Set Game Data gameData.maxNumberOfPlayers = myCreateInternetGameDialog->spinBox_quantityPlayers->value(); @@ -59,12 +63,19 @@ void gameLobbyDialogImpl::createGame() gameData.handsBeforeRaise = myCreateInternetGameDialog->spinBox_handsBeforeRaiseSmallBlind->value(); gameData.guiSpeed = myCreateInternetGameDialog->spinBox_gameSpeed->value(); gameData.playerActionTimeoutSec = myCreateInternetGameDialog->spinBox_netTimeOutPlayerAction->value(); - - mySession->clientCreateGame(gameData, myConfig->readConfigString("MyName") + "'s game", myCreateInternetGameDialog->lineEdit_Password->text().toUtf8().constData()); currentGameName = QString::fromUtf8(myConfig->readConfigString("MyName").c_str()) + QString("'s game"); - accept(); + // Update dialog + gameModeDialogUpdate(); + + label_SmallBlind->setText(QString::number(gameData.smallBlind)); + label_StartCash->setText(QString::number(gameData.startMoney)); + label_MaximumNumberOfPlayers->setText(QString::number(gameData.maxNumberOfPlayers)); + label_HandsToRaiseSmallBlind->setText(QString::number(gameData.handsBeforeRaise)); + label_TimeoutForPlayerAction->setText(QString::number(gameData.playerActionTimeoutSec)); + + mySession->clientCreateGame(gameData, myConfig->readConfigString("MyName") + "'s game", myCreateInternetGameDialog->lineEdit_Password->text().toUtf8().constData()); } } @@ -73,12 +84,19 @@ void gameLobbyDialogImpl::joinGame() QTreeWidgetItem *item = treeWidget_GameList->currentItem(); if (item) { - QString gameName = item->text(0); - assert(mySession); - mySession->clientJoinGame(gameName.toUtf8().constData(), ""); + mySession->clientJoinGame(item->data(0, Qt::UserRole).toUInt(), ""); - accept(); + // Update dialog + gameModeDialogUpdate(); + } +} + +void gameLobbyDialogImpl::refresh(int actionID) { + + if (actionID == MSG_NET_GAME_CLIENT_START) + { + QTimer::singleShot(500, this, SLOT(accept())); } } @@ -204,13 +222,17 @@ void gameLobbyDialogImpl::clearDialog() label_TimeoutForPlayerAction->setText(""); treeWidget_GameList->clear(); + treeWidget_GameList->show(); treeWidget_connectedPlayers->clear(); - pushButton_JoinGame->setEnabled(false); pushButton_Leave->hide(); pushButton_Kick->hide(); + pushButton_Kick->setEnabled(false); pushButton_StartGame->hide(); checkBox_fillUpWithComputerOpponents->hide(); + pushButton_CreateGame->show(); + pushButton_JoinGame->show(); + pushButton_JoinGame->setEnabled(false); treeWidget_GameList->setColumnWidth(0,250); treeWidget_GameList->setColumnWidth(1,75); @@ -221,13 +243,18 @@ void gameLobbyDialogImpl::clearDialog() void gameLobbyDialogImpl::checkPlayerQuantity() { -// if (treeWidget->topLevelItemCount() >= 2 && isAdmin) { -// pushButton_startGame->setEnabled(true); -// } -// else { -// pushButton_startGame->setEnabled(false); -// } - + if(isAdmin){ + pushButton_Kick->show(); + pushButton_StartGame->show(); + checkBox_fillUpWithComputerOpponents->show(); + + if (treeWidget_connectedPlayers->topLevelItemCount() >= 2) { + pushButton_StartGame->setEnabled(true); + } + else { + pushButton_StartGame->setEnabled(false); + } + } } void gameLobbyDialogImpl::joinedNetworkGame(unsigned playerId, QString playerName, int rights) { @@ -284,3 +311,44 @@ void gameLobbyDialogImpl::removePlayer(unsigned playerId, QString) { checkPlayerQuantity(); } +void gameLobbyDialogImpl::gameModeDialogUpdate() { + groupBox_GameInfo->setEnabled(true); + groupBox_GameInfo->setTitle(currentGameName); + treeWidget_GameList->clear(); + treeWidget_GameList->hide(); + treeWidget_connectedPlayers->clear(); + pushButton_CreateGame->hide(); + pushButton_JoinGame->hide(); + pushButton_Leave->show(); +} + +void gameLobbyDialogImpl::playerSelected(QTreeWidgetItem* item, QTreeWidgetItem*) { + + if (item) + pushButton_Kick->setEnabled(isAdmin); +} + +void gameLobbyDialogImpl::startGame() { + assert(mySession); + mySession->sendStartEvent(checkBox_fillUpWithComputerOpponents->isChecked()); +} + +void gameLobbyDialogImpl::kickPlayer() { + + QTreeWidgetItem *item = treeWidget_connectedPlayers->currentItem(); + if (item) + { + QString playerName = item->text(0); + if(playerName == QString::fromUtf8(myConfig->readConfigString("MyName").c_str())) { + { QMessageBox::warning(this, tr("Server Error"), + tr("You should not kick yourself from this game!"), + QMessageBox::Close); } + } + else { + assert(mySession); + mySession->kickPlayer(item->data(0, Qt::UserRole).toUInt()); + } + } + pushButton_Kick->setEnabled(false); +} + diff --git a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h index d7625dfa..7d0f554a 100644 --- a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h +++ b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h @@ -63,6 +63,12 @@ public slots: void updatePlayer(unsigned, QString); void removePlayer(unsigned, QString); + void playerSelected(QTreeWidgetItem*, QTreeWidgetItem*); + void refresh(int actionID); + void startGame(); + void kickPlayer(); + + void gameModeDialogUpdate(); void clearDialog(); private: diff --git a/src/gui/qt/mainwindow/mainwindowimpl.cpp b/src/gui/qt/mainwindow/mainwindowimpl.cpp index 74bc1788..dbfd6c41 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.cpp +++ b/src/gui/qt/mainwindow/mainwindowimpl.cpp @@ -647,6 +647,7 @@ mainWindowImpl::mainWindowImpl(ConfigFile *c, QMainWindow *parent) connect(this, SIGNAL(signalNetClientConnect(int)), myConnectToServerDialog, SLOT(refresh(int))); connect(this, SIGNAL(signalNetClientGameInfo(int)), myStartNetworkGameDialog, SLOT(refresh(int))); + connect(this, SIGNAL(signalNetClientGameInfo(int)), myGameLobbyDialog, SLOT(refresh(int))); connect(this, SIGNAL(signalNetClientSelfJoined(unsigned, QString, int)), myStartNetworkGameDialog, SLOT(joinedNetworkGame(unsigned, QString, int))); connect(this, SIGNAL(signalNetClientPlayerJoined(unsigned, QString, int)), myStartNetworkGameDialog, SLOT(addConnectedPlayer(unsigned, QString, int))); @@ -845,9 +846,8 @@ void mainWindowImpl::callGameLobbyDialog() { if (myGameLobbyDialog->result() == QDialog::Accepted) { - if(myGameLobbyDialog->getCurrentGameName() != "") - myStartNetworkGameDialog->setWindowTitle(myGameLobbyDialog->getCurrentGameName()); - showNetworkStartDialog(); + //some gui modifications + networkGameModification(); } else { diff --git a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp index 3abf1091..a56628a2 100644 --- a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp +++ b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006 by FThauer FHammer * + * Copyright (C) 2006 by FThauer FHammer LMay * * f.thauer@web.de * * * * This program is free software; you can redistribute it and/or modify * @@ -46,7 +46,7 @@ void startNetworkGameDialogImpl::exec() { void startNetworkGameDialogImpl::startGame() { assert(mySession); - mySession->sendStartEvent(); + mySession->sendStartEvent(checkBox_fillUpWithComputerOpponents->isChecked()); } void startNetworkGameDialogImpl::cancel() { @@ -131,7 +131,7 @@ void startNetworkGameDialogImpl::kickPlayer() { } else { assert(mySession); - mySession->kickPlayer(playerName.toUtf8().constData()); + mySession->kickPlayer(item->data(0, Qt::UserRole).toUInt()); } } pushButton_Kick->setEnabled(false); diff --git a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h index b048e99c..e4a34077 100644 --- a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h +++ b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h @@ -33,7 +33,7 @@ class ConfigFile; class startNetworkGameDialogImpl: public QDialog, public Ui::startNetworkGameDialog { Q_OBJECT public: - startNetworkGameDialogImpl(QWidget *parent = 0, ConfigFile *config = 0); + startNetworkGameDialogImpl(QWidget *parent = 0, ConfigFile *config = 0); void setSession(Session *session); diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 6a704728..1e0ee658 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -54,12 +54,12 @@ public: const std::string &pwd, const std::string &playerName); - void SendKickPlayer(const std::string &playerName); - void SendStartEvent(); + void SendKickPlayer(unsigned playerId); + void SendStartEvent(bool fillUpWithCpuPlayers); void SendPlayerAction(); void SendChatMessage(const std::string &msg); void SendJoinFirstGame(const std::string &password); - void SendJoinGame(const std::string &name, const std::string &password); + void SendJoinGame(unsigned gameId, const std::string &password); void SendCreateGame(const GameData &gameData, const std::string &name, const std::string &password); GameInfo GetGameInfo(unsigned playerId) const; diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index 4018f4e8..1794515b 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -87,29 +87,32 @@ ClientThread::Init( } void -ClientThread::SendKickPlayer(const string &playerName) +ClientThread::SendKickPlayer(unsigned playerId) { - boost::shared_ptr tmpPlayer = GetPlayerDataByName(playerName); - if (tmpPlayer.get()) - { - boost::shared_ptr request(new NetPacketKickPlayer); - NetPacketKickPlayer::Data requestData; - requestData.playerId = tmpPlayer->GetUniqueId(); - static_cast(request.get())->SetData(requestData); - boost::mutex::scoped_lock lock(m_outPacketListMutex); - m_outPacketList.push_back(request); - } + boost::shared_ptr request(new NetPacketKickPlayer); + NetPacketKickPlayer::Data requestData; + requestData.playerId = playerId; + static_cast(request.get())->SetData(requestData); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(request); } void -ClientThread::SendStartEvent() +ClientThread::SendStartEvent(bool fillUpWithCpuPlayers) { // Warning: This function is called in the context of the GUI thread. // Create a network packet for the server start event. - boost::shared_ptr startEvent(new NetPacketStartEvent); - // Just dump the packet. - boost::mutex::scoped_lock lock(m_outPacketListMutex); - m_outPacketList.push_back(startEvent); + boost::shared_ptr start(new NetPacketStartEvent); + NetPacketStartEvent::Data startData; + startData.fillUpWithCpuPlayers = fillUpWithCpuPlayers; + try + { + static_cast(start.get())->SetData(startData); + boost::mutex::scoped_lock lock(m_outPacketListMutex); + m_outPacketList.push_back(start); + } catch (const NetException &) + { + } } void @@ -177,16 +180,16 @@ ClientThread::SendJoinFirstGame(const std::string &password) } void -ClientThread::SendJoinGame(const std::string &name, const std::string &password) +ClientThread::SendJoinGame(unsigned gameId, const std::string &password) { // Warning: This function is called in the context of the GUI thread. // Create a network packet to request joining a game. boost::shared_ptr join(new NetPacketJoinGame); NetPacketJoinGame::Data joinData; joinData.password = password; + joinData.gameId = gameId; try { - joinData.gameId = GetGameIdByName(name); static_cast(join.get())->SetData(joinData); boost::mutex::scoped_lock lock(m_outPacketListMutex); m_outPacketList.push_back(join); diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 1c0351d5..6bc92bde 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -41,20 +41,21 @@ using namespace std; #define NET_TYPE_PLAYER_JOINED 0x000C #define NET_TYPE_PLAYER_LEFT 0x000D #define NET_TYPE_KICK_PLAYER 0x000E -#define NET_TYPE_START_EVENT 0x000F -#define NET_TYPE_GAME_START 0x0010 -#define NET_TYPE_HAND_START 0x0011 -#define NET_TYPE_PLAYERS_TURN 0x0012 -#define NET_TYPE_PLAYERS_ACTION 0x0013 -#define NET_TYPE_PLAYERS_ACTION_DONE 0x0014 -#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0015 -#define NET_TYPE_DEAL_FLOP_CARDS 0x0016 -#define NET_TYPE_DEAL_TURN_CARD 0x0017 -#define NET_TYPE_DEAL_RIVER_CARD 0x0018 -#define NET_TYPE_ALL_IN_SHOW_CARDS 0x0019 -#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001A -#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001B -#define NET_TYPE_END_OF_GAME 0x001C +#define NET_TYPE_LEAVE_CURRENT_GAME 0x000F +#define NET_TYPE_START_EVENT 0x0010 +#define NET_TYPE_GAME_START 0x0011 +#define NET_TYPE_HAND_START 0x0012 +#define NET_TYPE_PLAYERS_TURN 0x0013 +#define NET_TYPE_PLAYERS_ACTION 0x0014 +#define NET_TYPE_PLAYERS_ACTION_DONE 0x0015 +#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0016 +#define NET_TYPE_DEAL_FLOP_CARDS 0x0017 +#define NET_TYPE_DEAL_TURN_CARD 0x0018 +#define NET_TYPE_DEAL_RIVER_CARD 0x0019 +#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001A +#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001B +#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001C +#define NET_TYPE_END_OF_GAME 0x001D #define NET_TYPE_SEND_CHAT_TEXT 0x0200 #define NET_TYPE_CHAT_TEXT 0x0201 @@ -66,6 +67,8 @@ using namespace std; #define NET_PLAYER_FLAG_HUMAN 0x01 #define NET_PLAYER_FLAG_ADMIN 0x02 +#define NET_START_FLAG_FILL_WITH_CPU_PLAYERS 0x01 + #define NET_ERR_JOIN_GAME_VERSION_NOT_SUPPORTED 0x0001 #define NET_ERR_JOIN_GAME_SERVER_FULL 0x0002 #define NET_ERR_JOIN_GAME_ALREADY_RUNNING 0x0003 @@ -216,9 +219,17 @@ struct GCC_PACKED NetPacketKickPlayerData u_int32_t playerId; }; +struct GCC_PACKED NetPacketLeaveCurrentGameData +{ + NetPacketHeader head; + u_int32_t reserved; +}; + struct GCC_PACKED NetPacketStartEventData { NetPacketHeader head; + u_int16_t startFlags; + u_int16_t reserved; }; struct GCC_PACKED NetPacketGameStartData @@ -1964,6 +1975,27 @@ NetPacketStartEvent::Clone() const return newPacket; } +void +NetPacketStartEvent::SetData(const NetPacketStartEvent::Data &inData) +{ + NetPacketStartEventData *tmpData = (NetPacketStartEventData *)GetRawData(); + + // Set the data. + tmpData->startFlags = htons(inData.fillUpWithCpuPlayers ? NET_START_FLAG_FILL_WITH_CPU_PLAYERS : 0); + + // Check the packet - just in case. + Check(GetRawData()); +} + +void +NetPacketStartEvent::GetData(NetPacketStartEvent::Data &outData) const +{ + // We assume that the data is valid. Validity has already been checked. + NetPacketStartEventData *tmpData = (NetPacketStartEventData *)GetRawData(); + + outData.fillUpWithCpuPlayers = (ntohs(tmpData->startFlags) & NET_START_FLAG_FILL_WITH_CPU_PLAYERS); +} + const NetPacketStartEvent * NetPacketStartEvent::ToNetPacketStartEvent() const { diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 03326799..d783cdc9 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -293,20 +293,27 @@ ServerGameStateInit::InternalProcess(ServerGameThread &server, SessionWrapper se if (packet->ToNetPacketStartEvent()) { + NetPacketStartEvent::Data startData; + packet->ToNetPacketStartEvent()->GetData(startData); + server.ResetComputerPlayerList(); - int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers(); - for (int i = 1; i <= remainingSlots; i++) + + if (startData.fillUpWithCpuPlayers) { - boost::shared_ptr tmpPlayerData( - new PlayerData(server.GetLobbyThread().GetNextUniquePlayerId(), 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL)); + int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers(); + for (int i = 1; i <= remainingSlots; i++) + { + boost::shared_ptr tmpPlayerData( + new PlayerData(server.GetLobbyThread().GetNextUniquePlayerId(), 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL)); - ostringstream name; - name << SERVER_COMPUTER_PLAYER_NAME << i; - tmpPlayerData->SetName(name.str()); - server.AddComputerPlayer(tmpPlayerData); + ostringstream name; + name << SERVER_COMPUTER_PLAYER_NAME << i; + tmpPlayerData->SetName(name.str()); + server.AddComputerPlayer(tmpPlayerData); - // Send "Player Joined" to other fully connected clients. - server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData), SessionData::Game); + // Send "Player Joined" to other fully connected clients. + server.SendToAllPlayers(CreateNetPacketPlayerJoined(*tmpPlayerData), SessionData::Game); + } } server.InternalStartGame(); diff --git a/src/net/netpacket.h b/src/net/netpacket.h index 83f2716c..cca421d3 100644 --- a/src/net/netpacket.h +++ b/src/net/netpacket.h @@ -477,12 +477,19 @@ protected: class NetPacketStartEvent : public NetPacket { public: + struct Data + { + bool fillUpWithCpuPlayers; + }; NetPacketStartEvent(); virtual ~NetPacketStartEvent(); virtual boost::shared_ptr Clone() const; + void SetData(const Data &inData); + void GetData(Data &outData) const; + virtual const NetPacketStartEvent *ToNetPacketStartEvent() const; protected: diff --git a/src/session.cpp b/src/session.cpp index d83e800d..968e7980 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -186,11 +186,11 @@ void Session::clientCreateGame(const GameData &gameData, const string &name, con myNetClient->SendCreateGame(gameData, name, password); } -void Session::clientJoinGame(const std::string &name, const std::string &password) +void Session::clientJoinGame(unsigned gameId, const std::string &password) { if (!myNetClient) return; // only act if client is running. - myNetClient->SendJoinGame(name, password); + myNetClient->SendJoinGame(gameId, password); } void Session::startNetworkServer() @@ -234,11 +234,11 @@ void Session::waitForNetworkServer(unsigned timeoutMsec) } } -void Session::sendStartEvent() +void Session::sendStartEvent(bool fillUpWithCpuPlayers) { if (!myNetClient) return; // only act if client is running. - myNetClient->SendStartEvent(); + myNetClient->SendStartEvent(fillUpWithCpuPlayers); } void Session::sendClientPlayerAction() @@ -255,11 +255,11 @@ void Session::sendChatMessage(const std::string &message) myNetClient->SendChatMessage(message); } -void Session::kickPlayer(const std::string &playerName) +void Session::kickPlayer(unsigned playerId) { if (!myNetClient) return; // only act if client is running. - myNetClient->SendKickPlayer(playerName); + myNetClient->SendKickPlayer(playerId); } bool Session::isNetworkClientRunning() const diff --git a/src/session.h b/src/session.h index ae61bbaf..0b765fa6 100755 --- a/src/session.h +++ b/src/session.h @@ -50,10 +50,10 @@ public: void startNetworkClientForLocalServer(const GameData &gameData); void terminateNetworkClient(); void clientCreateGame(const GameData &gameData, const std::string &name, const std::string &password); - void clientJoinGame(const std::string &name, const std::string &password); + void clientJoinGame(unsigned gameId, const std::string &password); void startNetworkServer(); - void sendStartEvent(); + void sendStartEvent(bool fillUpWithCpuPlayers); void terminateNetworkServer(); void waitForNetworkServer(unsigned timeoutMsec); @@ -63,7 +63,7 @@ public: int getCurrentGameID() const { return currentGameID; } void sendChatMessage(const std::string &message); - void kickPlayer(const std::string &playerName); + void kickPlayer(unsigned playerId); bool isNetworkClientRunning() const; // TODO hack bool isNetworkServerRunning() const; // TODO hack