From 56b24e09eb8e948b8edf20f1789f24816a6a91b9 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 26 Aug 2007 22:41:37 +0000 Subject: [PATCH] Major design change in network protocol: Player information is now requested by clients whenever it is needed. The server only sends player ids. The client has a cache with player information. --- docs/net_protocol.txt | 123 +++-- src/gui/generic/serverguiwrapper.cpp | 1 + src/gui/generic/serverguiwrapper.h | 1 + src/gui/qt/guiwrapper.cpp | 4 + src/gui/qt/guiwrapper.h | 1 + src/gui/qt/mainwindow/mainwindowimpl.cpp | 6 + src/gui/qt/mainwindow/mainwindowimpl.h | 1 + .../startnetworkgamedialogimpl.cpp | 8 + .../startnetworkgamedialogimpl.h | 1 + src/net/clientcallback.h | 1 + src/net/clientthread.h | 8 +- src/net/common/clientstate.cpp | 34 +- src/net/common/clientthread.cpp | 47 ++ src/net/common/netpacket.cpp | 445 +++++++++++++++--- src/net/common/servergamestate.cpp | 22 +- src/net/common/serverlobbythread.cpp | 40 +- src/net/netpacket.h | 106 ++++- src/net/serverlobbythread.h | 1 + src/playerdata.h | 9 + 19 files changed, 755 insertions(+), 104 deletions(-) diff --git a/docs/net_protocol.txt b/docs/net_protocol.txt index c925ff30..da37e4eb 100644 --- a/docs/net_protocol.txt +++ b/docs/net_protocol.txt @@ -1,4 +1,6 @@ Changelog: +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. 08-14-2007: Supporting multiple games per server. Player id is now 32 bit to avoid collisions. @@ -21,7 +23,7 @@ PokerTH general message format: | +-------------------------------+ / | padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -Minimum length is 8. Maximum length is 256. +Minimum length is 4. Maximum length is 256. Client Request: Init @@ -81,9 +83,17 @@ Server Notification: Game List New +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Message Type = 3 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Game Mode | Game Name Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Game Mode | Game Name Length | + | Max Number of Players | Small Blind | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Hands before raise | Proposed GUI Speed | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player Action Timeout | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Start Money | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | \ \ Game Name (UTF-8) / @@ -114,12 +124,69 @@ Server Notification: Game List Update +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Server Notification: Game List Player Joined + + 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 = 5 | Message Length = 12 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Game ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +Server Notification: Game List Player Left + + 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 = 6 | Message Length = 12 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Game ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +Client Request: Retrieve Player Info + + 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 = 7 | Message Length = 8 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +Server Reply: Player Info + + 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 = 8 | Message Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player Flags | Player Name Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | \ + \ Player Name (UTF-8) / + | +-------------------------------+ + / | padding | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Player Flags: + 0x01 set: Player is human + + Client Request: Create 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 = 5 | Message Length | + | Message Type = 9 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Password Length | Game Name Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -154,7 +221,7 @@ Client Request: Join 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 = 6 | Message Length | + | Message Type = 10 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -172,7 +239,7 @@ Server Reply: Join Game Ack 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 = 7 | Message Length = 24 | + | Message Type = 11 | Message Length = 24 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -185,26 +252,18 @@ Server Reply: Join Game Ack | Start Money | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Server Notification: Player Joined 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 = 8 | Message Length | + | Message Type = 12 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Player Flags | Player Rights | + | Player Rights | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Player Name Length | Reserved | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | \ - \ Player Name (UTF-8) / - | +-------------------------------+ - / | padding | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -Player Flags: - 0x01 set: Player is human Player Rights: 0x01 set: Player is admin for this game @@ -214,7 +273,7 @@ Server Notification: Player Left 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 = 9 | Message Length = 8 | + | Message Type = 13 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -225,7 +284,7 @@ Client Request: Kick Player 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 = 10 | Message Length = 8 | + | Message Type = 14 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -236,7 +295,7 @@ 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 = 11 | Message Length = 4 | + | Message Type = 15 | Message Length = 4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -245,7 +304,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 = 12 | Message Length | + | Message Type = 16 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Start Dealer Player Id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -276,7 +335,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 = 13 | Message Length = 8 | + | Message Type = 17 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Your 1st Card | Your 2nd Card | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -290,7 +349,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 = 14 | Message Length = 8 | + | Message Type = 18 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -309,7 +368,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 = 15 | Message Length = 12 | + | Message Type = 19 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game State | Player Action | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -334,7 +393,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 = 16 | Message Length = 20 | + | Message Type = 20 | Message Length = 20 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -355,7 +414,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 = 17 | Message Length = 16 | + | Message Type = 21 | Message Length = 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game State | Player Action | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -383,7 +442,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 = 18 | Message Length = 12 | + | Message Type = 22 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Flop 1st Card | Flop 2nd Card | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -396,7 +455,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 = 19 | Message Length = 8 | + | Message Type = 23 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Turn Card | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -407,7 +466,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 = 20 | Message Length = 8 | + | Message Type = 24 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | River Card | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -418,7 +477,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 = 21 | Message Length | + | Message Type = 25 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number Of PlayerCards Records | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -440,7 +499,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 = 22 | Message Length | + | Message Type = 26 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Number Of PlayerResult Records | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -474,7 +533,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 = 23 | Message Length = 16 | + | Message Type = 27 | Message Length = 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -489,7 +548,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 = 24 | Message Length = 8 | + | Message Type = 28 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Winner Player Id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/src/gui/generic/serverguiwrapper.cpp b/src/gui/generic/serverguiwrapper.cpp index f0ca09d5..cdba4003 100644 --- a/src/gui/generic/serverguiwrapper.cpp +++ b/src/gui/generic/serverguiwrapper.cpp @@ -110,6 +110,7 @@ void ServerGuiWrapper::SignalNetClientGameInfo(int actionID) { if (myClientcb) m void ServerGuiWrapper::SignalNetClientError(int errorID, int osErrorID) { if (myClientcb) myClientcb->SignalNetClientError(errorID, osErrorID); } void ServerGuiWrapper::SignalNetClientSelfJoined(const string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientSelfJoined(playerName, rights); } void ServerGuiWrapper::SignalNetClientPlayerJoined(const string &playerName, PlayerRights rights) { if (myClientcb) myClientcb->SignalNetClientPlayerJoined(playerName, rights); } +void ServerGuiWrapper::SignalNetClientPlayerChanged(const std::string &oldPlayerName, const std::string &newPlayerName) { if (myClientcb) myClientcb->SignalNetClientPlayerChanged(oldPlayerName, newPlayerName); } void ServerGuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerLeft(playerName); } void ServerGuiWrapper::SignalNetClientGameListNew(const string &gameName) { if (myClientcb) myClientcb->SignalNetClientGameListNew(gameName); } void ServerGuiWrapper::SignalNetClientGameListRemove(const string &gameName) { if (myClientcb) myClientcb->SignalNetClientGameListRemove(gameName); } diff --git a/src/gui/generic/serverguiwrapper.h b/src/gui/generic/serverguiwrapper.h index ec8621a9..8bb82ddd 100644 --- a/src/gui/generic/serverguiwrapper.h +++ b/src/gui/generic/serverguiwrapper.h @@ -94,6 +94,7 @@ public: void SignalNetClientError(int errorID, int osErrorID); void SignalNetClientSelfJoined(const std::string &playerName, PlayerRights rights); void SignalNetClientPlayerJoined(const std::string &playerName, PlayerRights rights); + void SignalNetClientPlayerChanged(const std::string &oldPlayerName, const std::string &newPlayerName); void SignalNetClientPlayerLeft(const std::string &playerName); void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg); void SignalNetClientWaitDialog(); diff --git a/src/gui/qt/guiwrapper.cpp b/src/gui/qt/guiwrapper.cpp index 0a8e1127..41188ec8 100644 --- a/src/gui/qt/guiwrapper.cpp +++ b/src/gui/qt/guiwrapper.cpp @@ -113,6 +113,10 @@ void GuiWrapper::SignalNetClientGameInfo(int actionID) { myW->signalNetClientGam void GuiWrapper::SignalNetClientError(int errorID, int osErrorID) { myW->signalNetClientError(errorID, osErrorID); } void GuiWrapper::SignalNetClientSelfJoined(const string &playerName, PlayerRights rights) { myW->signalNetClientSelfJoined(QString::fromUtf8(playerName.c_str()), rights); } void GuiWrapper::SignalNetClientPlayerJoined(const string &playerName, PlayerRights rights) { myW->signalNetClientPlayerJoined(QString::fromUtf8(playerName.c_str()), rights); } +void GuiWrapper::SignalNetClientPlayerChanged(const string &oldPlayerName, const string &newPlayerName) +{ + myW->signalNetClientPlayerChanged(QString::fromUtf8(oldPlayerName.c_str()), QString::fromUtf8(newPlayerName.c_str())); +} void GuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { QString tmpName(QString::fromUtf8(playerName.c_str())); diff --git a/src/gui/qt/guiwrapper.h b/src/gui/qt/guiwrapper.h index b17e7681..77e2b192 100644 --- a/src/gui/qt/guiwrapper.h +++ b/src/gui/qt/guiwrapper.h @@ -101,6 +101,7 @@ public: void SignalNetClientError(int errorID, int osErrorID); void SignalNetClientSelfJoined(const std::string &playerName, PlayerRights rights); void SignalNetClientPlayerJoined(const std::string &playerName, PlayerRights rights); + void SignalNetClientPlayerChanged(const std::string &oldPlayerName, const std::string &newPlayerName); void SignalNetClientPlayerLeft(const std::string &playerName); void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg); void SignalNetClientWaitDialog(); diff --git a/src/gui/qt/mainwindow/mainwindowimpl.cpp b/src/gui/qt/mainwindow/mainwindowimpl.cpp index fbfe328d..242d2361 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.cpp +++ b/src/gui/qt/mainwindow/mainwindowimpl.cpp @@ -651,7 +651,13 @@ mainWindowImpl::mainWindowImpl(ConfigFile *c, QMainWindow *parent) connect(this, SIGNAL(signalNetClientGameInfo(int)), myStartNetworkGameDialog, SLOT(refresh(int))); connect(this, SIGNAL(signalNetClientSelfJoined(QString, int)), myStartNetworkGameDialog, SLOT(joinedNetworkGame(QString, int))); connect(this, SIGNAL(signalNetClientPlayerJoined(QString, int)), myStartNetworkGameDialog, SLOT(addConnectedPlayer(QString, int))); + connect(this, SIGNAL(signalNetClientPlayerChanged(QString, QString)), myStartNetworkGameDialog, SLOT(updatePlayer(QString, QString))); connect(this, SIGNAL(signalNetClientPlayerLeft(QString)), myStartNetworkGameDialog, SLOT(removePlayer(QString))); + + connect(this, SIGNAL(signalNetClientSelfJoined(QString, int)), myGameLobbyDialog, SLOT(joinedNetworkGame(QString, int))); + connect(this, SIGNAL(signalNetClientPlayerJoined(QString, int)), myGameLobbyDialog, SLOT(addConnectedPlayer(QString, int))); + connect(this, SIGNAL(signalNetClientPlayerChanged(QString, QString)), myGameLobbyDialog, SLOT(updatePlayer(QString, QString))); + connect(this, SIGNAL(signalNetClientPlayerLeft(QString)), myGameLobbyDialog, SLOT(removePlayer(QString))); connect(this, SIGNAL(signalNetClientGameListNew(QString)), myGameLobbyDialog, SLOT(addGame(QString))); connect(this, SIGNAL(signalNetClientGameListRemove(QString)), myGameLobbyDialog, SLOT(removeGame(QString))); diff --git a/src/gui/qt/mainwindow/mainwindowimpl.h b/src/gui/qt/mainwindow/mainwindowimpl.h index c67aff26..30b6365b 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.h +++ b/src/gui/qt/mainwindow/mainwindowimpl.h @@ -128,6 +128,7 @@ signals: void signalNetServerError(int errorID, int osErrorID); void signalNetClientSelfJoined(QString playerName, int rights); void signalNetClientPlayerJoined(QString playerName, int rights); + void signalNetClientPlayerChanged(QString oldPlayerName, QString newPlayerName); void signalNetClientPlayerLeft(QString playerName); void signalNetClientGameListNew(QString gameName); void signalNetClientGameListRemove(QString gameName); diff --git a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp index 50f59995..ba07aad4 100644 --- a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp +++ b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.cpp @@ -74,6 +74,14 @@ void startNetworkGameDialogImpl::addConnectedPlayer(QString playerName, int righ checkPlayerQuantity(); } +void startNetworkGameDialogImpl::updatePlayer(QString oldPlayerName, QString newPlayerName) +{ + QList list = treeWidget->findItems(oldPlayerName, Qt::MatchExactly, 0); + if(!list.empty()) { + list[0]->setText(0, newPlayerName); + } +} + void startNetworkGameDialogImpl::removePlayer(QString playerName) { QList list = treeWidget->findItems(playerName, Qt::MatchExactly, 0); diff --git a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h index 698e57fc..47c9acf3 100644 --- a/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h +++ b/src/gui/qt/startnetworkgamedialog/startnetworkgamedialogimpl.h @@ -47,6 +47,7 @@ public slots: void refresh(int actionID); void joinedNetworkGame(QString playerName, int rights); void addConnectedPlayer(QString playerName, int rights); + void updatePlayer(QString oldPlayerName, QString newPlayerName); void removePlayer(QString playerName); void playerSelected(QTreeWidgetItem*, int); void kickPlayer(); diff --git a/src/net/clientcallback.h b/src/net/clientcallback.h index 7219f3af..3406d462 100644 --- a/src/net/clientcallback.h +++ b/src/net/clientcallback.h @@ -42,6 +42,7 @@ public: virtual void SignalNetClientGameStart(boost::shared_ptr game) = 0; virtual void SignalNetClientSelfJoined(const std::string &playerName, PlayerRights rights) = 0; virtual void SignalNetClientPlayerJoined(const std::string &playerName, PlayerRights rights) = 0; + virtual void SignalNetClientPlayerChanged(const std::string &oldPlayerName, const std::string &newPlayerName) = 0; virtual void SignalNetClientPlayerLeft(const std::string &playerName) = 0; virtual void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg) = 0; diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 96216316..e4b88d4f 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include class ClientContext; class ClientState; @@ -68,6 +68,7 @@ public: protected: typedef std::map GameMap; typedef std::list > NetPacketList; + typedef std::map PlayerInfoMap; // Main function of the thread. virtual void Main(); @@ -75,6 +76,10 @@ protected: void AddPacket(boost::shared_ptr packet); void SendPacketLoop(); + PlayerInfo GetCachedPlayerInfo(unsigned id) const; + void RequestPlayerInfo(unsigned id, const PlayerInfo &tempInfo); + void SetPlayerInfo(unsigned id, const PlayerInfo &info); + const ClientContext &GetContext() const; ClientContext &GetContext(); @@ -132,6 +137,7 @@ private: mutable boost::mutex m_gameMapMutex; boost::shared_ptr m_game; + PlayerInfoMap m_playerInfoMap; unsigned m_curGameId; unsigned m_guiPlayerId; diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index 1189f740..b4201269 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -31,6 +31,8 @@ #include #include +#include + using namespace std; #define CLIENT_WAIT_TIMEOUT_MSEC 50 @@ -378,7 +380,13 @@ AbstractClientStateReceiving::Process(ClientThread &client) if (tmpPacket.get()) { - if (tmpPacket->ToNetPacketError()) + if (tmpPacket->ToNetPacketPlayerInfo()) + { + NetPacketPlayerInfo::Data infoData; + tmpPacket->ToNetPacketPlayerInfo()->GetData(infoData); + client.SetPlayerInfo(infoData.playerId, infoData.playerInfo); + } + else if (tmpPacket->ToNetPacketError()) { // Server reported an error. NetPacketError::Data errorData; @@ -564,9 +572,27 @@ ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptrToNetPacketPlayerJoined()->GetData(netPlayerData); - boost::shared_ptr playerData( - new PlayerData(netPlayerData.playerId, 0, netPlayerData.ptype, netPlayerData.prights)); - playerData->SetName(netPlayerData.playerName); + boost::shared_ptr playerData; + try + { + PlayerInfo info = client.GetCachedPlayerInfo(netPlayerData.playerId); + playerData.reset( + new PlayerData(netPlayerData.playerId, 0, info.ptype, netPlayerData.prights)); + playerData->SetName(info.playerName); + } catch (const NetException &) + { + ostringstream name; + name << "#" << netPlayerData.playerId; + + // Request player info. + PlayerInfo info; + info.playerName = name.str(); + client.RequestPlayerInfo(netPlayerData.playerId, info); + // Use temporary data until the PlayerInfo request is completed. + playerData.reset( + new PlayerData(netPlayerData.playerId, 0, info.ptype, netPlayerData.prights)); + playerData->SetName(info.playerName); + } client.AddPlayerData(playerData); } diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index 1eb685f8..98b3bf32 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -300,6 +300,53 @@ ClientThread::SendPacketLoop() } } +PlayerInfo +ClientThread::GetCachedPlayerInfo(unsigned id) const +{ + PlayerInfoMap::const_iterator pos = m_playerInfoMap.find(id); + if (pos == m_playerInfoMap.end()) + throw NetException(ERR_NET_UNKNOWN_PLAYER_ID, 0); + return pos->second; +} + +void +ClientThread::RequestPlayerInfo(unsigned id, const PlayerInfo &tempInfo) +{ + boost::shared_ptr req(new NetPacketRetrievePlayerInfo); + NetPacketRetrievePlayerInfo::Data reqData; + reqData.playerId = id; + static_cast(req.get())->SetData(reqData); + GetSender().Send(GetContext().GetSocket(), req); + + m_playerInfoMap[id] = tempInfo; +} + +void +ClientThread::SetPlayerInfo(unsigned id, const PlayerInfo &info) +{ + PlayerInfoMap::iterator pos = m_playerInfoMap.find(id); + + // Update info cache. + if (pos != m_playerInfoMap.end()) + { + GetCallback().SignalNetClientPlayerChanged(pos->second.playerName, info.playerName); + + pos->second = info; + } + else + { + m_playerInfoMap.insert(PlayerInfoMap::value_type(id, info)); + } + + // Update player data for current game. + boost::shared_ptr playerData = GetPlayerDataByUniqueId(id); + if (playerData.get()) + { + playerData->SetName(info.playerName); + playerData->SetType(info.ptype); + } +} + const ClientContext & ClientThread::GetContext() const { diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 53d1fd10..28722021 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -31,26 +31,30 @@ using namespace std; #define NET_TYPE_INIT_ACK 0x0002 #define NET_TYPE_GAME_LIST_NEW 0x0003 #define NET_TYPE_GAME_LIST_UPDATE 0x0004 -#define NET_TYPE_CREATE_GAME 0x0005 -#define NET_TYPE_JOIN_GAME 0x0006 -#define NET_TYPE_JOIN_GAME_ACK 0x0007 -#define NET_TYPE_PLAYER_JOINED 0x0008 -#define NET_TYPE_PLAYER_LEFT 0x0009 -#define NET_TYPE_KICK_PLAYER 0x000A -#define NET_TYPE_START_EVENT 0x000B -#define NET_TYPE_GAME_START 0x000C -#define NET_TYPE_HAND_START 0x000D -#define NET_TYPE_PLAYERS_TURN 0x000E -#define NET_TYPE_PLAYERS_ACTION 0x000F -#define NET_TYPE_PLAYERS_ACTION_DONE 0x0010 -#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0011 -#define NET_TYPE_DEAL_FLOP_CARDS 0x0012 -#define NET_TYPE_DEAL_TURN_CARD 0x0013 -#define NET_TYPE_DEAL_RIVER_CARD 0x0014 -#define NET_TYPE_ALL_IN_SHOW_CARDS 0x0015 -#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x0016 -#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x0017 -#define NET_TYPE_END_OF_GAME 0x0018 +#define NET_TYPE_GAME_LIST_PLAYER_JOINED 0x0005 +#define NET_TYPE_GAME_LIST_PLAYER_LEFT 0x0006 +#define NET_TYPE_RETRIEVE_PLAYER_INFO 0x0007 +#define NET_TYPE_PLAYER_INFO 0x0008 +#define NET_TYPE_CREATE_GAME 0x0009 +#define NET_TYPE_JOIN_GAME 0x000A +#define NET_TYPE_JOIN_GAME_ACK 0x000B +#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_SEND_CHAT_TEXT 0x0200 #define NET_TYPE_CHAT_TEXT 0x0201 @@ -108,6 +112,13 @@ struct GCC_PACKED NetPacketGameListNewData u_int32_t gameId; u_int16_t gameMode; u_int16_t gameNameLength; + u_int16_t maxNumberOfPlayers; + u_int16_t smallBlind; + u_int16_t handsBeforeRaise; + u_int16_t proposedGuiSpeed; + u_int16_t playerActionTimeout; + u_int16_t reserved; + u_int32_t startMoney; }; struct GCC_PACKED NetPacketGameListUpdateData @@ -118,6 +129,34 @@ struct GCC_PACKED NetPacketGameListUpdateData u_int16_t reserved; }; +struct GCC_PACKED NetPacketGameListPlayerJoinedData +{ + NetPacketHeader head; + u_int32_t gameId; + u_int32_t playerId; +}; + +struct GCC_PACKED NetPacketGameListPlayerLeftData +{ + NetPacketHeader head; + u_int32_t gameId; + u_int32_t playerId; +}; + +struct GCC_PACKED NetPacketRetrievePlayerInfoData +{ + NetPacketHeader head; + u_int32_t playerId; +}; + +struct GCC_PACKED NetPacketPlayerInfoData +{ + NetPacketHeader head; + u_int32_t playerId; + u_int16_t playerFlags; + u_int16_t playerNameLength; +}; + struct GCC_PACKED NetPacketCreateGameData { NetPacketHeader head; @@ -157,9 +196,7 @@ struct GCC_PACKED NetPacketPlayerJoinedData { NetPacketHeader head; u_int32_t playerId; - u_int16_t playerFlags; u_int16_t playerRights; - u_int16_t playerNameLength; u_int16_t reserved; }; @@ -377,6 +414,18 @@ NetPacket::Create(char *data, unsigned &dataSize) case NET_TYPE_GAME_LIST_UPDATE: tmpPacket = boost::shared_ptr(new NetPacketGameListUpdate); break; + case NET_TYPE_GAME_LIST_PLAYER_JOINED: + tmpPacket = boost::shared_ptr(new NetPacketGameListPlayerJoined); + break; + case NET_TYPE_GAME_LIST_PLAYER_LEFT: + tmpPacket = boost::shared_ptr(new NetPacketGameListPlayerLeft); + break; + case NET_TYPE_RETRIEVE_PLAYER_INFO: + tmpPacket = boost::shared_ptr(new NetPacketRetrievePlayerInfo); + break; + case NET_TYPE_PLAYER_INFO: + tmpPacket = boost::shared_ptr(new NetPacketPlayerInfo); + break; case NET_TYPE_CREATE_GAME: tmpPacket = boost::shared_ptr(new NetPacketCreateGame); break; @@ -554,6 +603,30 @@ NetPacket::ToNetPacketGameListUpdate() const return NULL; } +const NetPacketGameListPlayerJoined * +NetPacket::ToNetPacketGameListPlayerJoined() const +{ + return NULL; +} + +const NetPacketGameListPlayerLeft * +NetPacket::ToNetPacketGameListPlayerLeft() const +{ + return NULL; +} + +const NetPacketRetrievePlayerInfo * +NetPacket::ToNetPacketRetrievePlayerInfo() const +{ + return NULL; +} + +const NetPacketPlayerInfo * +NetPacket::ToNetPacketPlayerInfo() const +{ + return NULL; +} + const NetPacketCreateGame * NetPacket::ToNetPacketCreateGame() const { @@ -951,9 +1024,16 @@ NetPacketGameListNew::SetData(const NetPacketGameListNew::Data &inData) NetPacketGameListNewData *tmpData = (NetPacketGameListNewData *)GetRawData(); // Set the data. - tmpData->gameId = htonl(inData.gameId); - tmpData->gameMode = htons(inData.gameMode); - tmpData->gameNameLength = htons(gameNameLen); + tmpData->gameId = htonl(inData.gameId); + tmpData->gameMode = htons(inData.gameMode); + tmpData->gameNameLength = htons(gameNameLen); + tmpData->maxNumberOfPlayers = htons(inData.gameData.maxNumberOfPlayers); + tmpData->smallBlind = htons(inData.gameData.smallBlind); + tmpData->handsBeforeRaise = htons(inData.gameData.handsBeforeRaise); + tmpData->proposedGuiSpeed = htons(inData.gameData.guiSpeed); + tmpData->playerActionTimeout = htons(inData.gameData.playerActionTimeoutSec); + tmpData->startMoney = htonl(inData.gameData.startMoney); + char *gameNamePtr = (char *)tmpData + sizeof(NetPacketGameListNewData); memcpy(gameNamePtr, inData.gameName.c_str(), gameNameLen); @@ -967,9 +1047,16 @@ NetPacketGameListNew::GetData(NetPacketGameListNew::Data &outData) const // We assume that the data is valid. Validity has already been checked. NetPacketGameListNewData *tmpData = (NetPacketGameListNewData *)GetRawData(); - outData.gameId = ntohl(tmpData->gameId); - outData.gameMode = static_cast(ntohs(tmpData->gameMode)); - u_int16_t gameNameLen = ntohs(tmpData->gameNameLength); + outData.gameId = ntohl(tmpData->gameId); + outData.gameMode = static_cast(ntohs(tmpData->gameMode)); + u_int16_t gameNameLen = ntohs(tmpData->gameNameLength); + outData.gameData.maxNumberOfPlayers = ntohs(tmpData->maxNumberOfPlayers); + outData.gameData.smallBlind = ntohs(tmpData->smallBlind); + outData.gameData.handsBeforeRaise = ntohs(tmpData->handsBeforeRaise); + outData.gameData.guiSpeed = ntohs(tmpData->proposedGuiSpeed); + outData.gameData.playerActionTimeoutSec = ntohs(tmpData->playerActionTimeout); + outData.gameData.startMoney = ntohl(tmpData->startMoney); + char *gameNamePtr = (char *)tmpData + sizeof(NetPacketGameListNewData); outData.gameName = string(gameNamePtr, gameNameLen); } @@ -1069,6 +1156,273 @@ NetPacketGameListUpdate::InternalCheck(const NetPacketHeader* data) const //----------------------------------------------------------------------------- +NetPacketGameListPlayerJoined::NetPacketGameListPlayerJoined() +: NetPacket(NET_TYPE_GAME_LIST_PLAYER_JOINED, sizeof(NetPacketGameListPlayerJoinedData), sizeof(NetPacketGameListPlayerJoinedData)) +{ +} + +NetPacketGameListPlayerJoined::~NetPacketGameListPlayerJoined() +{ +} + +boost::shared_ptr +NetPacketGameListPlayerJoined::Clone() const +{ + boost::shared_ptr newPacket(new NetPacketGameListPlayerJoined); + try + { + newPacket->SetRawData(GetRawData()); + } catch (const NetException &) + { + // Need to return the new packet anyway. + } + return newPacket; +} + +void +NetPacketGameListPlayerJoined::SetData(const NetPacketGameListPlayerJoined::Data &inData) +{ + NetPacketGameListPlayerJoinedData *tmpData = (NetPacketGameListPlayerJoinedData *)GetRawData(); + + // Set the data. + tmpData->gameId = htonl(inData.gameId); + tmpData->playerId = htonl(inData.playerId); + + // Check the packet - just in case. + Check(GetRawData()); +} + +void +NetPacketGameListPlayerJoined::GetData(NetPacketGameListPlayerJoined::Data &outData) const +{ + // We assume that the data is valid. Validity has already been checked. + NetPacketGameListPlayerJoinedData *tmpData = (NetPacketGameListPlayerJoinedData *)GetRawData(); + + outData.gameId = ntohl(tmpData->gameId); + outData.playerId = ntohl(tmpData->playerId); +} + +const NetPacketGameListPlayerJoined * +NetPacketGameListPlayerJoined::ToNetPacketGameListPlayerJoined() const +{ + return this; +} + +void +NetPacketGameListPlayerJoined::InternalCheck(const NetPacketHeader* data) const +{ + // Nothing to do. +} + +//----------------------------------------------------------------------------- + +NetPacketGameListPlayerLeft::NetPacketGameListPlayerLeft() +: NetPacket(NET_TYPE_GAME_LIST_PLAYER_LEFT, sizeof(NetPacketGameListPlayerLeftData), sizeof(NetPacketGameListPlayerLeftData)) +{ +} + +NetPacketGameListPlayerLeft::~NetPacketGameListPlayerLeft() +{ +} + +boost::shared_ptr +NetPacketGameListPlayerLeft::Clone() const +{ + boost::shared_ptr newPacket(new NetPacketGameListPlayerLeft); + try + { + newPacket->SetRawData(GetRawData()); + } catch (const NetException &) + { + // Need to return the new packet anyway. + } + return newPacket; +} + +void +NetPacketGameListPlayerLeft::SetData(const NetPacketGameListPlayerLeft::Data &inData) +{ + NetPacketGameListPlayerLeftData *tmpData = (NetPacketGameListPlayerLeftData *)GetRawData(); + + // Set the data. + tmpData->gameId = htonl(inData.gameId); + tmpData->playerId = htonl(inData.playerId); + + // Check the packet - just in case. + Check(GetRawData()); +} + +void +NetPacketGameListPlayerLeft::GetData(NetPacketGameListPlayerLeft::Data &outData) const +{ + // We assume that the data is valid. Validity has already been checked. + NetPacketGameListPlayerLeftData *tmpData = (NetPacketGameListPlayerLeftData *)GetRawData(); + + outData.gameId = ntohl(tmpData->gameId); + outData.playerId = ntohl(tmpData->playerId); +} + +const NetPacketGameListPlayerLeft * +NetPacketGameListPlayerLeft::ToNetPacketGameListPlayerLeft() const +{ + return this; +} + +void +NetPacketGameListPlayerLeft::InternalCheck(const NetPacketHeader* data) const +{ + // Nothing to do. +} + +//----------------------------------------------------------------------------- + +NetPacketRetrievePlayerInfo::NetPacketRetrievePlayerInfo() +: NetPacket(NET_TYPE_RETRIEVE_PLAYER_INFO, sizeof(NetPacketRetrievePlayerInfoData), sizeof(NetPacketRetrievePlayerInfoData)) +{ +} + +NetPacketRetrievePlayerInfo::~NetPacketRetrievePlayerInfo() +{ +} + +boost::shared_ptr +NetPacketRetrievePlayerInfo::Clone() const +{ + boost::shared_ptr newPacket(new NetPacketRetrievePlayerInfo); + try + { + newPacket->SetRawData(GetRawData()); + } catch (const NetException &) + { + // Need to return the new packet anyway. + } + return newPacket; +} + +void +NetPacketRetrievePlayerInfo::SetData(const NetPacketRetrievePlayerInfo::Data &inData) +{ + NetPacketRetrievePlayerInfoData *tmpData = (NetPacketRetrievePlayerInfoData *)GetRawData(); + + // Set the data. + tmpData->playerId = htonl(inData.playerId); + + // Check the packet - just in case. + Check(GetRawData()); +} + +void +NetPacketRetrievePlayerInfo::GetData(NetPacketRetrievePlayerInfo::Data &outData) const +{ + // We assume that the data is valid. Validity has already been checked. + NetPacketRetrievePlayerInfoData *tmpData = (NetPacketRetrievePlayerInfoData *)GetRawData(); + + outData.playerId = ntohl(tmpData->playerId); +} + +const NetPacketRetrievePlayerInfo * +NetPacketRetrievePlayerInfo::ToNetPacketRetrievePlayerInfo() const +{ + return this; +} + +void +NetPacketRetrievePlayerInfo::InternalCheck(const NetPacketHeader* data) const +{ + // Nothing to do. +} + +//----------------------------------------------------------------------------- + +NetPacketPlayerInfo::NetPacketPlayerInfo() +: NetPacket(NET_TYPE_PLAYER_INFO, sizeof(NetPacketPlayerInfoData), MAX_PACKET_SIZE) +{ +} + +NetPacketPlayerInfo::~NetPacketPlayerInfo() +{ +} + +boost::shared_ptr +NetPacketPlayerInfo::Clone() const +{ + boost::shared_ptr newPacket(new NetPacketPlayerInfo); + try + { + newPacket->SetRawData(GetRawData()); + } catch (const NetException &) + { + // Need to return the new packet anyway. + } + return newPacket; +} + +void +NetPacketPlayerInfo::SetData(const NetPacketPlayerInfo::Data &inData) +{ + u_int16_t playerNameLen = (u_int16_t)inData.playerInfo.playerName.length(); + + if (!playerNameLen || playerNameLen > MAX_NAME_SIZE) + throw NetException(ERR_NET_INVALID_PLAYER_NAME, 0); + + // Resize the packet so that the data fits in. + Resize((u_int16_t) + (sizeof(NetPacketPlayerInfoData) + ADD_PADDING(playerNameLen))); + + NetPacketPlayerInfoData *tmpData = (NetPacketPlayerInfoData *)GetRawData(); + + // Set the data. + tmpData->playerId = htonl(inData.playerId); + tmpData->playerFlags = htons(inData.playerInfo.ptype); + tmpData->playerNameLength = htons(playerNameLen); + char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData); + memcpy(namePtr, inData.playerInfo.playerName.c_str(), playerNameLen); + + // Check the packet - just in case. + Check(GetRawData()); +} + +void +NetPacketPlayerInfo::GetData(NetPacketPlayerInfo::Data &outData) const +{ + // We assume that the data is valid. Validity has already been checked. + NetPacketPlayerInfoData *tmpData = (NetPacketPlayerInfoData *)GetRawData(); + + outData.playerId = ntohl(tmpData->playerId); + outData.playerInfo.ptype = static_cast(ntohs(tmpData->playerFlags)); + char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerInfoData); + outData.playerInfo.playerName = string(namePtr, ntohs(tmpData->playerNameLength)); +} + +const NetPacketPlayerInfo * +NetPacketPlayerInfo::ToNetPacketPlayerInfo() const +{ + return this; +} + +void +NetPacketPlayerInfo::InternalCheck(const NetPacketHeader* data) const +{ + u_int16_t dataLen = ntohs(data->length); + NetPacketPlayerInfoData *tmpData = (NetPacketPlayerInfoData *)data; + int playerNameLength = ntohs(tmpData->playerNameLength); + // Exact checking this time. + if (dataLen != + sizeof(NetPacketPlayerInfoData) + + ADD_PADDING(playerNameLength)) + { + throw NetException(ERR_SOCK_INVALID_PACKET, 0); + } + // Check string sizes. + if (!playerNameLength + || playerNameLength > MAX_NAME_SIZE) + { + throw NetException(ERR_SOCK_INVALID_PACKET, 0); + } +} + +//----------------------------------------------------------------------------- + NetPacketCreateGame::NetPacketCreateGame() : NetPacket(NET_TYPE_CREATE_GAME, sizeof(NetPacketCreateGameData), MAX_PACKET_SIZE) { @@ -1377,7 +1731,7 @@ NetPacketJoinGameAck::InternalCheck(const NetPacketHeader* data) const //----------------------------------------------------------------------------- NetPacketPlayerJoined::NetPacketPlayerJoined() -: NetPacket(NET_TYPE_PLAYER_JOINED, sizeof(NetPacketPlayerJoinedData), MAX_PACKET_SIZE) +: NetPacket(NET_TYPE_PLAYER_JOINED, sizeof(NetPacketPlayerJoinedData), sizeof(NetPacketPlayerJoinedData)) { } @@ -1402,24 +1756,11 @@ NetPacketPlayerJoined::Clone() const void NetPacketPlayerJoined::SetData(const NetPacketPlayerJoined::Data &inData) { - u_int16_t playerNameLen = (u_int16_t)inData.playerName.length(); - - if (!playerNameLen || playerNameLen > MAX_NAME_SIZE) - throw NetException(ERR_NET_INVALID_PLAYER_NAME, 0); - - // Resize the packet so that the data fits in. - Resize((u_int16_t) - (sizeof(NetPacketPlayerJoinedData) + ADD_PADDING(playerNameLen))); - NetPacketPlayerJoinedData *tmpData = (NetPacketPlayerJoinedData *)GetRawData(); // Set the data. tmpData->playerId = htonl(inData.playerId); - tmpData->playerFlags = htons(inData.ptype); tmpData->playerRights = htons(inData.prights); - tmpData->playerNameLength = htons(playerNameLen); - char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData); - memcpy(namePtr, inData.playerName.c_str(), playerNameLen); // Check the packet - just in case. Check(GetRawData()); @@ -1432,10 +1773,7 @@ NetPacketPlayerJoined::GetData(NetPacketPlayerJoined::Data &outData) const NetPacketPlayerJoinedData *tmpData = (NetPacketPlayerJoinedData *)GetRawData(); outData.playerId = ntohl(tmpData->playerId); - outData.ptype = static_cast(ntohs(tmpData->playerFlags)); outData.prights = static_cast(ntohs(tmpData->playerRights)); - char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData); - outData.playerName = string(namePtr, ntohs(tmpData->playerNameLength)); } const NetPacketPlayerJoined * @@ -1447,22 +1785,7 @@ NetPacketPlayerJoined::ToNetPacketPlayerJoined() const void NetPacketPlayerJoined::InternalCheck(const NetPacketHeader* data) const { - u_int16_t dataLen = ntohs(data->length); - NetPacketPlayerJoinedData *tmpData = (NetPacketPlayerJoinedData *)data; - int playerNameLength = ntohs(tmpData->playerNameLength); - // Exact checking this time. - if (dataLen != - sizeof(NetPacketPlayerJoinedData) - + ADD_PADDING(playerNameLength)) - { - throw NetException(ERR_SOCK_INVALID_PACKET, 0); - } - // Check string sizes. - if (!playerNameLength - || playerNameLength > MAX_NAME_SIZE) - { - throw NetException(ERR_SOCK_INVALID_PACKET, 0); - } + // Nothing to do. } //----------------------------------------------------------------------------- diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index a96ce00d..c292d7fe 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -148,8 +148,26 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server) // Process packet if one was received. if (packet.get()) { + if (packet->ToNetPacketRetrievePlayerInfo()) + { + NetPacketRetrievePlayerInfo::Data reqData; + packet->ToNetPacketRetrievePlayerInfo()->GetData(reqData); + + SessionWrapper tmpSession = server.GetSessionManager().GetSessionByUniquePlayerId(reqData.playerId); + if (tmpSession.sessionData.get() && tmpSession.playerData.get()) + { + // Send player info to client. + boost::shared_ptr info(new NetPacketPlayerInfo); + NetPacketPlayerInfo::Data infoData; + infoData.playerId = tmpSession.playerData->GetUniqueId(); + infoData.playerInfo.ptype = tmpSession.playerData->GetType(); + infoData.playerInfo.playerName = tmpSession.playerData->GetName(); + static_cast(info.get())->SetData(infoData); + server.GetSender().Send(session.sessionData->GetSocket(), info); + } + } // Chat text is always allowed. - if (packet->ToNetPacketSendChatText()) + else if (packet->ToNetPacketSendChatText()) { if (session.playerData.get()) // Only forward if this player is known. { @@ -312,8 +330,6 @@ ServerGameStateInit::CreateNetPacketPlayerJoined(const PlayerData &playerData) boost::shared_ptr thisPlayerJoined(new NetPacketPlayerJoined); NetPacketPlayerJoined::Data thisPlayerJoinedData; thisPlayerJoinedData.playerId = playerData.GetUniqueId(); - thisPlayerJoinedData.playerName = playerData.GetName(); - thisPlayerJoinedData.ptype = playerData.GetType(); thisPlayerJoinedData.prights = playerData.GetRights(); static_cast(thisPlayerJoined.get())->SetData(thisPlayerJoinedData); return thisPlayerJoined; diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 3e40c768..ddbd5a5f 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -190,7 +190,9 @@ ServerLobbyThread::ProcessLoop() SessionError(session, ERR_SOCK_INVALID_STATE); else { - if (packet->ToNetPacketCreateGame()) + if (packet->ToNetPacketRetrievePlayerInfo()) + HandleNetPacketRetrievePlayerInfo(session, *packet->ToNetPacketRetrievePlayerInfo()); + else if (packet->ToNetPacketCreateGame()) HandleNetPacketCreateGame(session, *packet->ToNetPacketCreateGame()); else if (packet->ToNetPacketJoinGame()) HandleNetPacketJoinGame(session, *packet->ToNetPacketJoinGame()); @@ -266,6 +268,41 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn session.sessionData->SetState(SessionData::Established); } +void +ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket) +{ + NetPacketRetrievePlayerInfo::Data request; + tmpPacket.GetData(request); + + // Find player in lobby or in a game. + SessionWrapper tmpSession = m_sessionManager.GetSessionByUniquePlayerId(request.playerId); + if (!tmpSession.sessionData.get() || !tmpSession.playerData.get()) + { + GameMap::const_iterator game_i = m_gameMap.begin(); + GameMap::const_iterator game_end = m_gameMap.end(); + while (game_i != game_end) + { + tmpSession = game_i->second->GetSessionManager().GetSessionByUniquePlayerId(request.playerId); + if (tmpSession.sessionData.get() && tmpSession.playerData.get()) + break; + ++game_i; + } + } + + if (tmpSession.sessionData.get() && tmpSession.playerData.get()) + { + // Send player info to client. + boost::shared_ptr info(new NetPacketPlayerInfo); + NetPacketPlayerInfo::Data infoData; + infoData.playerId = tmpSession.playerData->GetUniqueId(); + infoData.playerInfo.ptype = tmpSession.playerData->GetType(); + infoData.playerInfo.playerName = tmpSession.playerData->GetName(); + static_cast(info.get())->SetData(infoData); + GetSender().Send(session.sessionData->GetSocket(), info); + } + // TODO: handle error +} + void ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket) { @@ -517,6 +554,7 @@ ServerLobbyThread::CreateNetPacketGameListNew(const ServerGameThread &game) packetData.gameId = game.GetId(); packetData.gameMode = GAME_MODE_CREATED; packetData.gameName = game.GetName(); + packetData.gameData = game.GetGameData(); static_cast(packet.get())->SetData(packetData); return packet; } diff --git a/src/net/netpacket.h b/src/net/netpacket.h index a2786059..4658f084 100644 --- a/src/net/netpacket.h +++ b/src/net/netpacket.h @@ -44,6 +44,10 @@ class NetPacketInit; class NetPacketInitAck; class NetPacketGameListNew; class NetPacketGameListUpdate; +class NetPacketGameListPlayerJoined; +class NetPacketGameListPlayerLeft; +class NetPacketRetrievePlayerInfo; +class NetPacketPlayerInfo; class NetPacketCreateGame; class NetPacketJoinGame; class NetPacketJoinGameAck; @@ -89,6 +93,10 @@ public: virtual const NetPacketInitAck *ToNetPacketInitAck() const; virtual const NetPacketGameListNew *ToNetPacketGameListNew() const; virtual const NetPacketGameListUpdate *ToNetPacketGameListUpdate() const; + virtual const NetPacketGameListPlayerJoined *ToNetPacketGameListPlayerJoined() const; + virtual const NetPacketGameListPlayerLeft *ToNetPacketGameListPlayerLeft() const; + virtual const NetPacketRetrievePlayerInfo *ToNetPacketRetrievePlayerInfo() const; + virtual const NetPacketPlayerInfo *ToNetPacketPlayerInfo() const; virtual const NetPacketCreateGame *ToNetPacketCreateGame() const; virtual const NetPacketJoinGame *ToNetPacketJoinGame() const; virtual const NetPacketJoinGameAck *ToNetPacketJoinGameAck() const; @@ -185,6 +193,7 @@ public: u_int32_t gameId; GameMode gameMode; std::string gameName; + GameData gameData; }; NetPacketGameListNew(); @@ -226,6 +235,101 @@ protected: virtual void InternalCheck(const NetPacketHeader* data) const; }; +class NetPacketGameListPlayerJoined : public NetPacket +{ +public: + struct Data + { + u_int32_t gameId; + u_int32_t playerId; + }; + + NetPacketGameListPlayerJoined(); + virtual ~NetPacketGameListPlayerJoined(); + + virtual boost::shared_ptr Clone() const; + + void SetData(const Data &inData); + void GetData(Data &outData) const; + + virtual const NetPacketGameListPlayerJoined *ToNetPacketGameListPlayerJoined() const; + +protected: + + virtual void InternalCheck(const NetPacketHeader* data) const; +}; + +class NetPacketGameListPlayerLeft : public NetPacket +{ +public: + struct Data + { + u_int32_t gameId; + u_int32_t playerId; + }; + + NetPacketGameListPlayerLeft(); + virtual ~NetPacketGameListPlayerLeft(); + + virtual boost::shared_ptr Clone() const; + + void SetData(const Data &inData); + void GetData(Data &outData) const; + + virtual const NetPacketGameListPlayerLeft *ToNetPacketGameListPlayerLeft() const; + +protected: + + virtual void InternalCheck(const NetPacketHeader* data) const; +}; + +class NetPacketRetrievePlayerInfo : public NetPacket +{ +public: + struct Data + { + u_int32_t playerId; + }; + + NetPacketRetrievePlayerInfo(); + virtual ~NetPacketRetrievePlayerInfo(); + + virtual boost::shared_ptr Clone() const; + + void SetData(const Data &inData); + void GetData(Data &outData) const; + + virtual const NetPacketRetrievePlayerInfo *ToNetPacketRetrievePlayerInfo() const; + +protected: + + virtual void InternalCheck(const NetPacketHeader* data) const; +}; + +class NetPacketPlayerInfo : public NetPacket +{ +public: + struct Data + { + u_int32_t playerId; + PlayerInfo playerInfo; + }; + + NetPacketPlayerInfo(); + virtual ~NetPacketPlayerInfo(); + + virtual boost::shared_ptr Clone() const; + + void SetData(const Data &inData); + void GetData(Data &outData) const; + + virtual const NetPacketPlayerInfo *ToNetPacketPlayerInfo() const; + +protected: + + virtual void InternalCheck(const NetPacketHeader* data) const; +}; + class NetPacketCreateGame : public NetPacket { public: @@ -306,9 +410,7 @@ public: struct Data { u_int32_t playerId; - PlayerType ptype; PlayerRights prights; - std::string playerName; }; NetPacketPlayerJoined(); diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index 7952f694..7c740e72 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -72,6 +72,7 @@ protected: void ProcessLoop(); void HandleNetPacketInit(SessionWrapper session, const NetPacketInit &tmpPacket); + void HandleNetPacketRetrievePlayerInfo(SessionWrapper session, const NetPacketRetrievePlayerInfo &tmpPacket); void HandleNetPacketCreateGame(SessionWrapper session, const NetPacketCreateGame &tmpPacket); void HandleNetPacketJoinGame(SessionWrapper session, const NetPacketJoinGame &tmpPacket); void CloseSessionLoop(); diff --git a/src/playerdata.h b/src/playerdata.h index 3e27a8f2..7bec57a8 100644 --- a/src/playerdata.h +++ b/src/playerdata.h @@ -40,6 +40,13 @@ enum PlayerRights PLAYER_RIGHTS_ADMIN }; +struct PlayerInfo +{ + PlayerInfo() : ptype(PLAYER_TYPE_HUMAN) {} + std::string playerName; + PlayerType ptype; +}; + class PlayerData { public: @@ -60,6 +67,8 @@ public: {m_netSessionData = session;} PlayerType GetType() const {return m_type;} + void SetType(PlayerType type) + {m_type = type;} PlayerRights GetRights() const {return m_rights;} void SetRights(PlayerRights rights)