Kicking players at the beginning of a network game now works.

This commit is contained in:
lotodore
2007-06-07 21:19:06 +00:00
parent f886ebda86
commit fb274284f5
14 changed files with 122 additions and 45 deletions
+1
View File
@@ -385,6 +385,7 @@ Error Reason:
0x0006 - Join Game - Invalid Player Name 0x0006 - Join Game - Invalid Player Name
0xFF01 - General Error - Invalid packet 0xFF01 - General Error - Invalid packet
0xFF02 - General Error - Invalid state 0xFF02 - General Error - Invalid state
0xFF03 - General Error - Kicked from the server
0xFFFF - Other reason 0xFFFF - Other reason
-2
View File
@@ -444,8 +444,6 @@ void Log::logFlipHoleCardsMsg(QString playerName, int card1, int card2, int card
void Log::logPlayerLeftMsg(QString playerName) { void Log::logPlayerLeftMsg(QString playerName) {
HandInterface *currentHand = myW->getSession().getCurrentGame()->getCurrentHand();
myW->textBrowser_Log->append( "<i>"+playerName+" has left the game!</i>"); myW->textBrowser_Log->append( "<i>"+playerName+" has left the game!</i>");
if(myConfig->readConfigInt("LogOnOff")) { if(myConfig->readConfigInt("LogOnOff")) {
+6
View File
@@ -720,6 +720,7 @@ void mainWindowImpl::callCreateNetworkGameDialog() {
// gameData.guiSpeed = myCreateNetworkGameDialog->spinBox_gameSpeed->value(); // gameData.guiSpeed = myCreateNetworkGameDialog->spinBox_gameSpeed->value();
gameData.guiSpeed = 4; gameData.guiSpeed = 4;
myStartNetworkGameDialog->setSession(&myServerGuiInterface->getSession());
myStartNetworkGameDialog->treeWidget->clear(); myStartNetworkGameDialog->treeWidget->clear();
myServerGuiInterface->getSession().startNetworkServer(gameData); myServerGuiInterface->getSession().startNetworkServer(gameData);
@@ -2482,6 +2483,11 @@ void mainWindowImpl::networkError(int errorID, int osErrorID) {
tr("The server referred to an unknown player. Aborting."), tr("The server referred to an unknown player. Aborting."),
QMessageBox::Close); } QMessageBox::Close); }
break; break;
case ERR_NET_PLAYER_KICKED:
{ QMessageBox::warning(this, tr("Network Error"),
tr("You were kicked from the server."),
QMessageBox::Close); }
break;
default: { QMessageBox::warning(this, tr("Network Error"), default: { QMessageBox::warning(this, tr("Network Error"),
tr("An internal error occured."), tr("An internal error occured."),
QMessageBox::Close); } QMessageBox::Close); }
@@ -21,12 +21,10 @@
#include "session.h" #include "session.h"
#include "configfile.h" #include "configfile.h"
startNetworkGameDialogImpl::startNetworkGameDialogImpl(QWidget *parent, ConfigFile *config, Session *session) startNetworkGameDialogImpl::startNetworkGameDialogImpl(QWidget *parent, ConfigFile *config)
: QDialog(parent), myConfig(config), mySession(session) : QDialog(parent), myConfig(config)
{ {
assert(mySession); setupUi(this);
setupUi(this);
connect( pushButton_cancel, SIGNAL( clicked() ), this, SLOT( cancel() ) ); connect( pushButton_cancel, SIGNAL( clicked() ), this, SLOT( cancel() ) );
connect( pushButton_startGame, SIGNAL( clicked() ), this, SLOT( startGame() ) ); connect( pushButton_startGame, SIGNAL( clicked() ), this, SLOT( startGame() ) );
@@ -81,7 +79,8 @@ void startNetworkGameDialogImpl::kickPlayer() {
QMessageBox::Close); } QMessageBox::Close); }
} }
else { else {
// kickplayerFunktion(playerName.toStdString()); assert(mySession);
mySession->kickPlayer(playerName.toUtf8().constData());
} }
} }
pushButton_Kick->setEnabled(FALSE); pushButton_Kick->setEnabled(FALSE);
@@ -94,6 +93,11 @@ void startNetworkGameDialogImpl::checkPlayerQuantity() {
} }
void startNetworkGameDialogImpl::setSession(Session *session)
{
mySession = session;
}
void startNetworkGameDialogImpl::keyPressEvent ( QKeyEvent * event ) { void startNetworkGameDialogImpl::keyPressEvent ( QKeyEvent * event ) {
@@ -31,7 +31,7 @@ class ConfigFile;
class startNetworkGameDialogImpl: public QDialog, public Ui::startNetworkGameDialog { class startNetworkGameDialogImpl: public QDialog, public Ui::startNetworkGameDialog {
Q_OBJECT Q_OBJECT
public: public:
startNetworkGameDialogImpl(QWidget *parent = 0, ConfigFile *config = 0, Session *session = 0); startNetworkGameDialogImpl(QWidget *parent = 0, ConfigFile *config = 0);
public slots: public slots:
@@ -43,6 +43,8 @@ public slots:
void kickPlayer(); void kickPlayer();
void checkPlayerQuantity(); void checkPlayerQuantity();
void setSession(Session *session);
void keyPressEvent ( QKeyEvent*); void keyPressEvent ( QKeyEvent*);
void setMaxPlayerNumber ( int theValue ) { maxPlayerNumber = theValue; label_maxPlayerNumber->setText(QString::number(theValue,10)); } void setMaxPlayerNumber ( int theValue ) { maxPlayerNumber = theValue; label_maxPlayerNumber->setText(QString::number(theValue,10)); }
+9 -9
View File
@@ -379,7 +379,15 @@ AbstractClientStateReceiving::Process(ClientThread &client)
if (tmpPacket.get()) if (tmpPacket.get())
{ {
if (tmpPacket->ToNetPacketChatText()) if (tmpPacket->ToNetPacketError())
{
// Server reported an error.
NetPacketError::Data errorData;
tmpPacket->ToNetPacketError()->GetData(errorData);
// Show the error.
throw ClientException(errorData.errorCode, 0);
}
else if (tmpPacket->ToNetPacketChatText())
{ {
// Chat message - display it in the GUI. // Chat message - display it in the GUI.
NetPacketChatText::Data chatData; NetPacketChatText::Data chatData;
@@ -464,14 +472,6 @@ ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr<
client.SetState(ClientStateWaitGame::Instance()); client.SetState(ClientStateWaitGame::Instance());
retVal = MSG_SOCK_SESSION_DONE; retVal = MSG_SOCK_SESSION_DONE;
} }
else if (packet->ToNetPacketError())
{
// Server reported an error.
NetPacketError::Data errorData;
packet->ToNetPacketError()->GetData(errorData);
// Show the error.
throw ClientException(errorData.errorCode, 0);
}
return retVal; return retVal;
} }
+7
View File
@@ -59,6 +59,7 @@ using namespace std;
#define NET_ERR_JOIN_GAME_INVALID_PLAYER_NAME 0x0006 #define NET_ERR_JOIN_GAME_INVALID_PLAYER_NAME 0x0006
#define NET_ERR_GENERAL_INVALID_PACKET 0xFF01 #define NET_ERR_GENERAL_INVALID_PACKET 0xFF01
#define NET_ERR_GENERAL_INVALID_STATE 0xFF02 #define NET_ERR_GENERAL_INVALID_STATE 0xFF02
#define NET_ERR_GENERAL_PLAYER_KICKED 0xFF03
#define NET_ERR_OTHER 0xFFFF #define NET_ERR_OTHER 0xFFFF
#ifdef _MSC_VER #ifdef _MSC_VER
@@ -2111,6 +2112,9 @@ NetPacketError::SetData(const NetPacketError::Data &inData)
case ERR_SOCK_INVALID_STATE : case ERR_SOCK_INVALID_STATE :
tmpData->reason = htons(NET_ERR_GENERAL_INVALID_STATE); tmpData->reason = htons(NET_ERR_GENERAL_INVALID_STATE);
break; break;
case ERR_NET_PLAYER_KICKED :
tmpData->reason = htons(NET_ERR_GENERAL_PLAYER_KICKED);
break;
default : default :
tmpData->reason = htons(NET_ERR_OTHER); tmpData->reason = htons(NET_ERR_OTHER);
break; break;
@@ -2151,6 +2155,9 @@ NetPacketError::GetData(NetPacketError::Data &outData) const
case NET_ERR_GENERAL_INVALID_STATE : case NET_ERR_GENERAL_INVALID_STATE :
outData.errorCode = ERR_SOCK_INVALID_STATE; outData.errorCode = ERR_SOCK_INVALID_STATE;
break; break;
case NET_ERR_GENERAL_PLAYER_KICKED :
outData.errorCode = ERR_NET_PLAYER_KICKED;
break;
default : default :
outData.errorCode = ERR_SOCK_INTERNAL; outData.errorCode = ERR_SOCK_INTERNAL;
break; break;
+51 -19
View File
@@ -82,10 +82,10 @@ ServerRecvThread::AddConnection(boost::shared_ptr<ConnectData> data)
} }
void void
ServerRecvThread::AddNotification(unsigned message, unsigned param1, unsigned param2) ServerRecvThread::AddNotification(unsigned message, const string &param)
{ {
boost::mutex::scoped_lock lock(m_notificationQueueMutex); boost::mutex::scoped_lock lock(m_notificationQueueMutex);
m_notificationQueue.push_back(Notification(message, param1, param2)); m_notificationQueue.push_back(Notification(message, param));
} }
void void
@@ -145,6 +145,9 @@ ServerRecvThread::NotificationLoop()
case NOTIFY_GAME_START: case NOTIFY_GAME_START:
InternalStartGame(); InternalStartGame();
break; break;
case NOTIFY_KICK_PLAYER:
InternalKickPlayer(notification.param);
break;
} }
} }
} }
@@ -287,13 +290,24 @@ ServerRecvThread::InternalStartGame()
m_game.reset(new Game(&gui, factory, playerData, GetGameData(), GetStartData(), m_curGameId++)); m_game.reset(new Game(&gui, factory, playerData, GetGameData(), GetStartData(), m_curGameId++));
} }
void
ServerRecvThread::InternalKickPlayer(const string playerName)
{
if (!playerName.empty())
{
SessionWrapper tmpSession = GetSession(playerName);
SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
}
}
SessionWrapper SessionWrapper
ServerRecvThread::GetSession(SOCKET sock) ServerRecvThread::GetSession(SOCKET sock) const
{ {
SessionWrapper tmpSession; SessionWrapper tmpSession;
boost::mutex::scoped_lock lock(m_sessionMapMutex); boost::mutex::scoped_lock lock(m_sessionMapMutex);
SocketSessionMap::iterator pos = m_sessionMap.find(sock); SocketSessionMap::const_iterator pos = m_sessionMap.find(sock);
if (pos != m_sessionMap.end()) if (pos != m_sessionMap.end())
{ {
tmpSession = pos->second; tmpSession = pos->second;
@@ -301,6 +315,34 @@ ServerRecvThread::GetSession(SOCKET sock)
return tmpSession; return tmpSession;
} }
SessionWrapper
ServerRecvThread::GetSession(const string playerName) const
{
SessionWrapper tmpSession;
boost::mutex::scoped_lock lock(m_sessionMapMutex);
SocketSessionMap::const_iterator session_i = m_sessionMap.begin();
SocketSessionMap::const_iterator session_end = m_sessionMap.end();
while (session_i != session_end)
{
// Check all players which are fully connected.
if (session_i->second.sessionData->GetState() == SessionData::Established)
{
boost::shared_ptr<PlayerData> tmpPlayer(session_i->second.playerData);
assert(tmpPlayer.get());
if (tmpPlayer->GetName() == playerName)
{
tmpSession = session_i->second;
break;
}
}
++session_i;
}
return tmpSession;
}
void void
ServerRecvThread::AddSession(boost::shared_ptr<SessionData> sessionData) ServerRecvThread::AddSession(boost::shared_ptr<SessionData> sessionData)
{ {
@@ -415,25 +457,15 @@ ServerRecvThread::GetCurNumberOfPlayers() const
} }
bool bool
ServerRecvThread::IsPlayerConnected(const std::string &playerName) const ServerRecvThread::IsPlayerConnected(const string &playerName) const
{ {
bool retVal = false; bool retVal = false;
PlayerDataList playerList = GetPlayerDataList();
PlayerDataList::const_iterator player_i = playerList.begin(); SessionWrapper tmpSession = GetSession(playerName);
PlayerDataList::const_iterator player_end = playerList.end();
// Check by name - the name is unique. if (tmpSession.sessionData.get() && tmpSession.playerData.get())
while (player_i != player_end) retVal = true;
{
if ((*player_i)->GetName() == playerName)
{
retVal = true;
break;
}
++player_i;
}
return retVal; return retVal;
} }
@@ -612,7 +644,7 @@ ServerRecvThread::SetStartData(const StartData &startData)
} }
bool bool
ServerRecvThread::CheckPassword(const std::string &password) const ServerRecvThread::CheckPassword(const string &password) const
{ {
return (password == m_password); return (password == m_password);
} }
+12 -1
View File
@@ -28,6 +28,7 @@
#define ACCEPT_TIMEOUT_MSEC 50 #define ACCEPT_TIMEOUT_MSEC 50
#define NET_SERVER_LISTEN_BACKLOG 5 #define NET_SERVER_LISTEN_BACKLOG 5
using namespace std;
ServerThread::ServerThread(GuiInterface &gui, ConfigFile *config) ServerThread::ServerThread(GuiInterface &gui, ConfigFile *config)
: m_gui(gui) : m_gui(gui)
@@ -63,7 +64,17 @@ ServerThread::StartGame()
return; // TODO: throw exception return; // TODO: throw exception
// Thread-safe notification. // Thread-safe notification.
GetRecvThread().AddNotification(NOTIFY_GAME_START, 0, 0); GetRecvThread().AddNotification(NOTIFY_GAME_START, "");
}
void
ServerThread::KickPlayer(const string &playerName)
{
if (!IsRunning())
return; // TODO: throw exception
// Thread-safe notification.
GetRecvThread().AddNotification(NOTIFY_KICK_PLAYER, playerName);
} }
ServerCallback & ServerCallback &
+8 -6
View File
@@ -38,6 +38,7 @@
// Notifications // Notifications
#define NOTIFY_GAME_START 1 #define NOTIFY_GAME_START 1
#define NOTIFY_KICK_PLAYER 2
class ServerRecvState; class ServerRecvState;
class SenderThread; class SenderThread;
@@ -66,7 +67,7 @@ public:
void Init(const std::string &pwd, const GameData &gameData); void Init(const std::string &pwd, const GameData &gameData);
void AddConnection(boost::shared_ptr<ConnectData> data); void AddConnection(boost::shared_ptr<ConnectData> data);
void AddNotification(unsigned message, unsigned param1, unsigned param2); void AddNotification(unsigned message, const std::string &param);
ServerCallback &GetCallback(); ServerCallback &GetCallback();
@@ -78,11 +79,10 @@ protected:
struct Notification struct Notification
{ {
Notification(unsigned m, unsigned p1, unsigned p2) Notification(unsigned m, std::string p)
: message(m), param1(p1), param2(p2) {} : message(m), param(p) {}
unsigned message; unsigned message;
unsigned param1; std::string param;
unsigned param2;
}; };
typedef std::deque<boost::shared_ptr<ConnectData> > ConnectQueue; typedef std::deque<boost::shared_ptr<ConnectData> > ConnectQueue;
@@ -103,8 +103,10 @@ protected:
void CleanupSessionMap(); void CleanupSessionMap();
void InternalStartGame(); void InternalStartGame();
void InternalKickPlayer(const std::string playerName);
SessionWrapper GetSession(SOCKET sock); SessionWrapper GetSession(SOCKET sock) const;
SessionWrapper GetSession(const std::string playerName) const;
void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions have no player data void AddSession(boost::shared_ptr<SessionData> sessionData); // new Sessions have no player data
void SessionError(SessionWrapper session, int errorCode); void SessionError(SessionWrapper session, int errorCode);
void RejectNewConnection(boost::shared_ptr<ConnectData> connData); void RejectNewConnection(boost::shared_ptr<ConnectData> connData);
+1
View File
@@ -44,6 +44,7 @@ public:
void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd, void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd,
const GameData &gameData); const GameData &gameData);
void StartGame(); void StartGame();
void KickPlayer(const std::string &playerName);
ServerCallback &GetCallback(); ServerCallback &GetCallback();
GuiInterface &GetGui(); GuiInterface &GetGui();
+1
View File
@@ -53,6 +53,7 @@
#define ERR_NET_INVALID_CHAT_TEXT 110 #define ERR_NET_INVALID_CHAT_TEXT 110
#define ERR_NET_UNKNOWN_PLAYER_ID 111 #define ERR_NET_UNKNOWN_PLAYER_ID 111
#define ERR_NET_INVALID_ROUND 112 #define ERR_NET_INVALID_ROUND 112
#define ERR_NET_PLAYER_KICKED 113
// This is an internal message which is not reported. // This is an internal message which is not reported.
#define MSG_SOCK_INTERNAL_PENDING 0 #define MSG_SOCK_INTERNAL_PENDING 0
+12 -1
View File
@@ -203,12 +203,23 @@ void Session::sendClientPlayerAction()
myNetClient->SendPlayerAction(); myNetClient->SendPlayerAction();
} }
void Session::sendChatMessage(const std::string &message) { void Session::sendChatMessage(const std::string &message)
{
if (!myNetClient) if (!myNetClient)
return; // only act if client is running. return; // only act if client is running.
myNetClient->SendChatMessage(message); myNetClient->SendChatMessage(message);
} }
void Session::kickPlayer(const std::string &playerName)
{
if (!myNetServer)
{
assert(false);
return;
}
myNetServer->KickPlayer(playerName);
}
bool Session::isNetworkClientRunning() const bool Session::isNetworkClientRunning() const
{ {
// This, and every place which calls this, is a HACK. // This, and every place which calls this, is a HACK.
+1
View File
@@ -59,6 +59,7 @@ public:
int getCurrentGameID() const { return currentGameID; } int getCurrentGameID() const { return currentGameID; }
void sendChatMessage(const std::string &message); void sendChatMessage(const std::string &message);
void kickPlayer(const std::string &playerName);
bool isNetworkClientRunning() const; // TODO hack bool isNetworkClientRunning() const; // TODO hack