Chat messages are now working.

This commit is contained in:
lotodore
2007-05-25 16:03:12 +00:00
parent d01ecaf885
commit 13a731e041
21 changed files with 761 additions and 337 deletions
+46 -12
View File
@@ -146,8 +146,6 @@ Server Request/Notification: Player's Turn
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Game State: Game State:
0xF0 - Preflop Small Blind (no action requested)
0xF1 - Preflop Big Blind (no action requested)
0x00 - Preflop 0x00 - Preflop
0x01 - Flop 0x01 - Flop
0x02 - Turn 0x02 - Turn
@@ -168,23 +166,23 @@ Client Reply/Request: Player's Action
[ Game State is confirmed to ensure consistency. ] [ Game State is confirmed to ensure consistency. ]
Player Action: Player Action:
0 - None (e.g. Small Blind or Big Blind in Preflop) 0x00 - None (e.g. Small Blind or Big Blind in Preflop)
1 - Fold 0x01 - Fold
2 - Check 0x02 - Check
3 - Call 0x03 - Call
4 - Bet 0x04 - Bet
5 - Raise 0x05 - Raise
6 - All in 0x06 - All in
Player Bet: Player Bet:
0 - states fold, check, call, all in 0 (ignored) - states fold, check, call, all in
> 0 - states bet, raise > 0 - states bet, raise
Server Notification: Player's Action Done Server Notification: Player's Action Done
0 1 2 3 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 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 = 12 | | Message Type = 9 | Message Length = 28 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Game State | Player Id | | Game State | Player Id |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -199,6 +197,10 @@ Server Notification: Player's Action Done
| Current Hand Bets | | Current Hand Bets |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Additional Game States:
0xF0 - Preflop Small Blind (no action requested)
0xF1 - Preflop Big Blind (no action requested)
Server Reply: Player's Action Rejected Server Reply: Player's Action Rejected
@@ -228,6 +230,38 @@ Rejection Reason:
0xFFFF - Other reason 0xFFFF - Other reason
Client Request: Send Chat Text
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Text Length | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| \
\ Text (UTF-8) /
| +-------------------------------+
/ | padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Server Notification: Chat Text
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Text Length | Player Id |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| \
\ Text (UTF-8) /
| +-------------------------------+
/ | padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Server Reply: Error Server Reply: Error
0 1 2 3 0 1 2 3
+1 -2
View File
@@ -94,14 +94,13 @@ void ServerGuiWrapper::meInAction() {}
void ServerGuiWrapper::logPlayerActionMsg(string playerName, int action, int setValue) {} void ServerGuiWrapper::logPlayerActionMsg(string playerName, int action, int setValue) {}
void ServerGuiWrapper::logNewGameHandMsg(int gameID, int handID) {} void ServerGuiWrapper::logNewGameHandMsg(int gameID, int handID) {}
void ServerGuiWrapper::chatAppendMsg(std::string msg) {}
void ServerGuiWrapper::SignalNetClientConnect(int actionID) { if (myClientcb) myClientcb->SignalNetClientConnect(actionID); } void ServerGuiWrapper::SignalNetClientConnect(int actionID) { if (myClientcb) myClientcb->SignalNetClientConnect(actionID); }
void ServerGuiWrapper::SignalNetClientGameInfo(int actionID) { if (myClientcb) myClientcb->SignalNetClientGameInfo(actionID); } void ServerGuiWrapper::SignalNetClientGameInfo(int actionID) { if (myClientcb) myClientcb->SignalNetClientGameInfo(actionID); }
void ServerGuiWrapper::SignalNetClientError(int errorID, int osErrorID) { if (myClientcb) myClientcb->SignalNetClientError(errorID, osErrorID); } void ServerGuiWrapper::SignalNetClientError(int errorID, int osErrorID) { if (myClientcb) myClientcb->SignalNetClientError(errorID, osErrorID); }
void ServerGuiWrapper::SignalNetClientPlayerJoined(const string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerJoined(playerName); } void ServerGuiWrapper::SignalNetClientPlayerJoined(const string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerJoined(playerName); }
void ServerGuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerLeft(playerName); } void ServerGuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { if (myClientcb) myClientcb->SignalNetClientPlayerLeft(playerName); }
void ServerGuiWrapper::SignalNetClientGameStart(boost::shared_ptr<Game> game) { if (myClientcb) myClientcb->SignalNetClientGameStart(game); } void ServerGuiWrapper::SignalNetClientGameStart(boost::shared_ptr<Game> game) { if (myClientcb) myClientcb->SignalNetClientGameStart(game); }
void ServerGuiWrapper::SignalNetClientChatMsg(const string &playerName, const string &msg) { if (myClientcb) myClientcb->SignalNetClientChatMsg(playerName, msg); }
void ServerGuiWrapper::SignalNetServerSuccess(int actionID) { if (myServercb) myServercb->SignalNetServerSuccess(actionID); } void ServerGuiWrapper::SignalNetServerSuccess(int actionID) { if (myServercb) myServercb->SignalNetServerSuccess(actionID); }
void ServerGuiWrapper::SignalNetServerError(int errorID, int osErrorID) { if (myServercb) myServercb->SignalNetServerError(errorID, osErrorID); } void ServerGuiWrapper::SignalNetServerError(int errorID, int osErrorID) { if (myServercb) myServercb->SignalNetServerError(errorID, osErrorID); }
+1 -2
View File
@@ -77,13 +77,12 @@ public:
void logPlayerActionMsg(std::string playerName, int action, int setValue) ; void logPlayerActionMsg(std::string playerName, int action, int setValue) ;
void logNewGameHandMsg(int gameID, int handID) ; void logNewGameHandMsg(int gameID, int handID) ;
void chatAppendMsg(std::string msg);
void SignalNetClientConnect(int actionID); void SignalNetClientConnect(int actionID);
void SignalNetClientGameInfo(int actionID); void SignalNetClientGameInfo(int actionID);
void SignalNetClientError(int errorID, int osErrorID); void SignalNetClientError(int errorID, int osErrorID);
void SignalNetClientPlayerJoined(const std::string &playerName); void SignalNetClientPlayerJoined(const std::string &playerName);
void SignalNetClientPlayerLeft(const std::string &playerName); void SignalNetClientPlayerLeft(const std::string &playerName);
void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg);
void SignalNetClientGameStart(boost::shared_ptr<Game> game); void SignalNetClientGameStart(boost::shared_ptr<Game> game);
-4
View File
@@ -92,10 +92,6 @@ public:
//log.cpp //log.cpp
virtual void logPlayerActionMsg(std::string playName, int action, int setValue) =0; virtual void logPlayerActionMsg(std::string playName, int action, int setValue) =0;
virtual void logNewGameHandMsg(int gameID, int HandID) =0; virtual void logNewGameHandMsg(int gameID, int HandID) =0;
//chat
virtual void chatAppendMsg(std::string msg) =0;
}; };
#endif #endif
+1 -2
View File
@@ -92,14 +92,13 @@ void GuiWrapper::meInAction() { myW->signalMeInAction(); }
void GuiWrapper::logPlayerActionMsg(string playerName, int action, int setValue) { myLog->signalLogPlayerActionMsg(QString::fromUtf8(playerName.c_str()), action, setValue); } void GuiWrapper::logPlayerActionMsg(string playerName, int action, int setValue) { myLog->signalLogPlayerActionMsg(QString::fromUtf8(playerName.c_str()), action, setValue); }
void GuiWrapper::logNewGameHandMsg(int gameID, int handID) { myLog->signalLogNewGameHandMsg(gameID, handID); } void GuiWrapper::logNewGameHandMsg(int gameID, int handID) { myLog->signalLogNewGameHandMsg(gameID, handID); }
void GuiWrapper::chatAppendMsg(string msg) { myChat->receiveMessage(msg); }
void GuiWrapper::SignalNetClientConnect(int actionID) { myW->signalNetClientConnect(actionID); } void GuiWrapper::SignalNetClientConnect(int actionID) { myW->signalNetClientConnect(actionID); }
void GuiWrapper::SignalNetClientGameInfo(int actionID) { myW->signalNetClientGameInfo(actionID); } void GuiWrapper::SignalNetClientGameInfo(int actionID) { myW->signalNetClientGameInfo(actionID); }
void GuiWrapper::SignalNetClientError(int errorID, int osErrorID) { myW->signalNetClientError(errorID, osErrorID); } void GuiWrapper::SignalNetClientError(int errorID, int osErrorID) { myW->signalNetClientError(errorID, osErrorID); }
void GuiWrapper::SignalNetClientPlayerJoined(const string &playerName) { myW->signalNetClientPlayerJoined(QString::fromUtf8(playerName.c_str())); } void GuiWrapper::SignalNetClientPlayerJoined(const string &playerName) { myW->signalNetClientPlayerJoined(QString::fromUtf8(playerName.c_str())); }
void GuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { myW->signalNetClientPlayerLeft(QString::fromUtf8(playerName.c_str())); } void GuiWrapper::SignalNetClientPlayerLeft(const string &playerName) { myW->signalNetClientPlayerLeft(QString::fromUtf8(playerName.c_str())); }
void GuiWrapper::SignalNetClientGameStart(boost::shared_ptr<Game> game) { myW->signalNetClientGameStart(game); } void GuiWrapper::SignalNetClientGameStart(boost::shared_ptr<Game> game) { myW->signalNetClientGameStart(game); }
void GuiWrapper::SignalNetClientChatMsg(const string &playerName, const string &msg) { myChat->signalChatMessage(QString::fromUtf8(playerName.c_str()), QString::fromUtf8(msg.c_str())); }
void GuiWrapper::SignalNetServerSuccess(int actionID) { } void GuiWrapper::SignalNetServerSuccess(int actionID) { }
void GuiWrapper::SignalNetServerError(int errorID, int osErrorID) { } void GuiWrapper::SignalNetServerError(int errorID, int osErrorID) { }
+1 -2
View File
@@ -85,13 +85,12 @@ public:
void logPlayerActionMsg(std::string playerName, int action, int setValue) ; void logPlayerActionMsg(std::string playerName, int action, int setValue) ;
void logNewGameHandMsg(int gameID, int handID) ; void logNewGameHandMsg(int gameID, int handID) ;
void chatAppendMsg(std::string msg);
void SignalNetClientConnect(int actionID); void SignalNetClientConnect(int actionID);
void SignalNetClientGameInfo(int actionID); void SignalNetClientGameInfo(int actionID);
void SignalNetClientError(int errorID, int osErrorID); void SignalNetClientError(int errorID, int osErrorID);
void SignalNetClientPlayerJoined(const std::string &playerName); void SignalNetClientPlayerJoined(const std::string &playerName);
void SignalNetClientPlayerLeft(const std::string &playerName); void SignalNetClientPlayerLeft(const std::string &playerName);
void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg);
void SignalNetClientGameStart(boost::shared_ptr<Game> game); void SignalNetClientGameStart(boost::shared_ptr<Game> game);
+4 -3
View File
@@ -27,7 +27,8 @@ using namespace std;
Chat::Chat(mainWindowImpl* w, ConfigFile *c) : myW(w), myConfig(c) Chat::Chat(mainWindowImpl* w, ConfigFile *c) : myW(w), myConfig(c)
{ {
myW->setChat(this); myW->setChat(this);
connect(this, SIGNAL(signalChatMessage(QString, QString)), this, SLOT(receiveMessage(QString, QString)));
} }
Chat::~Chat() Chat::~Chat()
@@ -42,9 +43,9 @@ void Chat::sendMessage() {
myW->lineEdit_ChatInput->setText(""); myW->lineEdit_ChatInput->setText("");
} }
void Chat::receiveMessage(std::string message) { void Chat::receiveMessage(QString playerName, QString message) {
myW->textBrowser_Chat->append(QString::fromUtf8(message.c_str())); myW->textBrowser_Chat->append(playerName + ": " + message);
checkInvisible(); checkInvisible();
} }
+4 -1
View File
@@ -39,10 +39,13 @@ public:
~Chat(); ~Chat();
signals:
void signalChatMessage(QString playerName, QString msg);
public slots: public slots:
void sendMessage(); void sendMessage();
void receiveMessage(std::string); void receiveMessage(QString playerName, QString msg);
void checkInvisible(); void checkInvisible();
private: private:
+3 -1
View File
@@ -22,7 +22,7 @@
#define _CLIENTCALLBACK_H_ #define _CLIENTCALLBACK_H_
#include <string> #include <string>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
class Game; class Game;
@@ -38,6 +38,8 @@ public:
virtual void SignalNetClientGameStart(boost::shared_ptr<Game> game) = 0; virtual void SignalNetClientGameStart(boost::shared_ptr<Game> game) = 0;
virtual void SignalNetClientPlayerJoined(const std::string &playerName) = 0; virtual void SignalNetClientPlayerJoined(const std::string &playerName) = 0;
virtual void SignalNetClientPlayerLeft(const std::string &playerName) = 0; virtual void SignalNetClientPlayerLeft(const std::string &playerName) = 0;
virtual void SignalNetClientChatMsg(const std::string &playerName, const std::string &msg) = 0;
}; };
#endif #endif
+29 -15
View File
@@ -32,6 +32,7 @@ class ClientThread;
class ClientCallback; class ClientCallback;
class ResolverThread; class ResolverThread;
class Game; class Game;
class NetPacket;
class ClientState class ClientState
{ {
@@ -166,8 +167,24 @@ protected:
ClientStateStartSession(); ClientStateStartSession();
}; };
// Abstract State: Receiving
class AbstractClientStateReceiving : public ClientState
{
public:
virtual ~AbstractClientStateReceiving();
// select on socket.
virtual int Process(ClientThread &client);
protected:
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet) = 0;
AbstractClientStateReceiving();
};
// State: Wait for Session ACK. // State: Wait for Session ACK.
class ClientStateWaitSession : public ClientState class ClientStateWaitSession : public AbstractClientStateReceiving
{ {
public: public:
// Access the state singleton. // Access the state singleton.
@@ -175,17 +192,17 @@ public:
virtual ~ClientStateWaitSession(); virtual ~ClientStateWaitSession();
// select on socket.
virtual int Process(ClientThread &client);
protected: protected:
// Protected constructor - this is a singleton. // Protected constructor - this is a singleton.
ClientStateWaitSession(); ClientStateWaitSession();
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
}; };
// State: Wait for start of the game or start info. // State: Wait for start of the game or start info.
class ClientStateWaitGame : public ClientState class ClientStateWaitGame : public AbstractClientStateReceiving
{ {
public: public:
// Access the state singleton. // Access the state singleton.
@@ -193,17 +210,16 @@ public:
virtual ~ClientStateWaitGame(); virtual ~ClientStateWaitGame();
// select on socket.
virtual int Process(ClientThread &client);
protected: protected:
// Protected constructor - this is a singleton. // Protected constructor - this is a singleton.
ClientStateWaitGame(); ClientStateWaitGame();
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
}; };
// State: Wait for start of the next hand. // State: Wait for start of the next hand.
class ClientStateWaitHand : public ClientState class ClientStateWaitHand : public AbstractClientStateReceiving
{ {
public: public:
// Access the state singleton. // Access the state singleton.
@@ -211,17 +227,16 @@ public:
virtual ~ClientStateWaitHand(); virtual ~ClientStateWaitHand();
// select on socket.
virtual int Process(ClientThread &client);
protected: protected:
// Protected constructor - this is a singleton. // Protected constructor - this is a singleton.
ClientStateWaitHand(); ClientStateWaitHand();
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
}; };
// State: Hand Loop. // State: Hand Loop.
class ClientStateRunHand : public ClientState class ClientStateRunHand : public AbstractClientStateReceiving
{ {
public: public:
// Access the state singleton. // Access the state singleton.
@@ -229,14 +244,13 @@ public:
virtual ~ClientStateRunHand(); virtual ~ClientStateRunHand();
// select on socket.
virtual int Process(ClientThread &client);
protected: protected:
// Protected constructor - this is a singleton. // Protected constructor - this is a singleton.
ClientStateRunHand(); ClientStateRunHand();
virtual int InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet);
static int GetHighestSet(Game &curGame); static int GetHighestSet(Game &curGame);
static void SetHighestSet(Game &curGame, int highestSet); static void SetHighestSet(Game &curGame, int highestSet);
static int GetPlayersTurn(Game &curGame); static int GetPlayersTurn(Game &curGame);
+5 -1
View File
@@ -52,6 +52,7 @@ public:
const std::string &playerName); const std::string &playerName);
void SendPlayerAction(); void SendPlayerAction();
void SendChatMessage(const std::string &msg);
ClientCallback &GetCallback(); ClientCallback &GetCallback();
GuiInterface &GetGui(); GuiInterface &GetGui();
@@ -84,7 +85,9 @@ protected:
void AddPlayerData(boost::shared_ptr<PlayerData> playerData); void AddPlayerData(boost::shared_ptr<PlayerData> playerData);
void RemovePlayerData(unsigned playerId); void RemovePlayerData(unsigned playerId);
PlayerDataList GetMappedPlayerDataList() const; void MapPlayerDataList();
const PlayerDataList &GetPlayerDataList() const;
boost::shared_ptr<PlayerData> GetPlayerDataByUniqueId(unsigned id);
private: private:
@@ -105,6 +108,7 @@ private:
unsigned m_curGameId; unsigned m_curGameId;
int m_guiPlayerNum; int m_guiPlayerNum;
friend class AbstractClientStateReceiving;
friend class ClientStateInit; friend class ClientStateInit;
friend class ClientStateStartResolve; friend class ClientStateStartResolve;
friend class ClientStateResolving; friend class ClientStateResolving;
+106 -91
View File
@@ -357,6 +357,43 @@ ClientStateStartSession::Process(ClientThread &client)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
AbstractClientStateReceiving::AbstractClientStateReceiving()
{
}
AbstractClientStateReceiving::~AbstractClientStateReceiving()
{
}
int
AbstractClientStateReceiving::Process(ClientThread &client)
{
int retVal = MSG_SOCK_INTERNAL_PENDING;
// delegate to receiver helper class
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv(client.GetContext().GetSocket());
if (tmpPacket.get())
{
if (tmpPacket->ToNetPacketChatText())
{
// Chat message - display it in the GUI.
NetPacketChatText::Data chatData;
tmpPacket->ToNetPacketChatText()->GetData(chatData);
boost::shared_ptr<PlayerData> tmpPlayer = client.GetPlayerDataByUniqueId(chatData.playerId);
if (tmpPlayer.get())
client.GetCallback().SignalNetClientChatMsg(tmpPlayer->GetName(), chatData.text);
}
else
retVal = InternalProcess(client, tmpPacket);
}
return retVal;
}
//-----------------------------------------------------------------------------
ClientStateWaitSession & ClientStateWaitSession &
ClientStateWaitSession::Instance() ClientStateWaitSession::Instance()
{ {
@@ -373,43 +410,36 @@ ClientStateWaitSession::~ClientStateWaitSession()
} }
int int
ClientStateWaitSession::Process(ClientThread &client) ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
{ {
int retVal = MSG_SOCK_INTERNAL_PENDING; int retVal = MSG_SOCK_INTERNAL_PENDING;
ClientContext &context = client.GetContext(); ClientContext &context = client.GetContext();
// delegate to receiver helper class if (packet->ToNetPacketJoinGameAck())
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv(context.GetSocket());
if (tmpPacket.get())
{ {
if (tmpPacket->ToNetPacketJoinGameAck()) // Everything is fine - we joined the game.
{ // Initialize game configuration.
// Everything is fine - we joined the game. NetPacketJoinGameAck::Data joinGameAckData;
// Initialize game configuration. packet->ToNetPacketJoinGameAck()->GetData(joinGameAckData);
NetPacketJoinGameAck::Data joinGameAckData; client.SetGameData(joinGameAckData.gameData);
tmpPacket->ToNetPacketJoinGameAck()->GetData(joinGameAckData); client.SetGuiPlayerNum(joinGameAckData.yourPlayerNum);
client.SetGameData(joinGameAckData.gameData);
client.SetGuiPlayerNum(joinGameAckData.yourPlayerNum);
// TODO: Type Human is fixed here. // TODO: Type Human is fixed here.
boost::shared_ptr<PlayerData> playerData( boost::shared_ptr<PlayerData> playerData(
new PlayerData(joinGameAckData.yourPlayerUniqueId, joinGameAckData.yourPlayerNum, PLAYER_TYPE_HUMAN)); new PlayerData(joinGameAckData.yourPlayerUniqueId, joinGameAckData.yourPlayerNum, PLAYER_TYPE_HUMAN));
playerData->SetName(context.GetPlayerName()); playerData->SetName(context.GetPlayerName());
client.AddPlayerData(playerData); client.AddPlayerData(playerData);
client.SetState(ClientStateWaitGame::Instance()); client.SetState(ClientStateWaitGame::Instance());
retVal = MSG_SOCK_SESSION_DONE; retVal = MSG_SOCK_SESSION_DONE;
} }
else if (tmpPacket->ToNetPacketError()) else if (packet->ToNetPacketError())
{ {
// Server reported an error. // Server reported an error.
NetPacketError::Data errorData; NetPacketError::Data errorData;
tmpPacket->ToNetPacketError()->GetData(errorData); packet->ToNetPacketError()->GetData(errorData);
// Show the error. // Show the error.
throw ClientException(errorData.errorCode, 0); throw ClientException(errorData.errorCode, 0);
}
} }
return retVal; return retVal;
@@ -433,45 +463,39 @@ ClientStateWaitGame::~ClientStateWaitGame()
} }
int int
ClientStateWaitGame::Process(ClientThread &client) ClientStateWaitGame::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
{ {
int retVal = MSG_SOCK_INTERNAL_PENDING; int retVal = MSG_SOCK_INTERNAL_PENDING;
ClientContext &context = client.GetContext(); ClientContext &context = client.GetContext();
// delegate to receiver helper class if (packet->ToNetPacketGameStart())
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv(context.GetSocket());
if (tmpPacket.get())
{ {
if (tmpPacket->ToNetPacketGameStart()) // Start the network game as client.
{ NetPacketGameStart::Data gameStartData;
// Start the network game as client. packet->ToNetPacketGameStart()->GetData(gameStartData);
NetPacketGameStart::Data gameStartData;
tmpPacket->ToNetPacketGameStart()->GetData(gameStartData);
client.SetStartData(gameStartData.startData); client.SetStartData(gameStartData.startData);
client.SetState(ClientStateWaitHand::Instance()); client.SetState(ClientStateWaitHand::Instance());
retVal = MSG_NET_GAME_CLIENT_START; retVal = MSG_NET_GAME_CLIENT_START;
} }
else if (tmpPacket->ToNetPacketPlayerJoined()) else if (packet->ToNetPacketPlayerJoined())
{ {
// Another player joined the network game. // Another player joined the network game.
NetPacketPlayerJoined::Data netPlayerData; NetPacketPlayerJoined::Data netPlayerData;
tmpPacket->ToNetPacketPlayerJoined()->GetData(netPlayerData); packet->ToNetPacketPlayerJoined()->GetData(netPlayerData);
boost::shared_ptr<PlayerData> playerData( boost::shared_ptr<PlayerData> playerData(
new PlayerData(netPlayerData.playerId, netPlayerData.playerNumber, netPlayerData.ptype)); new PlayerData(netPlayerData.playerId, netPlayerData.playerNumber, netPlayerData.ptype));
playerData->SetName(netPlayerData.playerName); playerData->SetName(netPlayerData.playerName);
client.AddPlayerData(playerData); client.AddPlayerData(playerData);
} }
else if (tmpPacket->ToNetPacketPlayerLeft()) else if (packet->ToNetPacketPlayerLeft())
{ {
// Another player left the network game. // Another player left the network game.
NetPacketPlayerLeft::Data netPlayerData; NetPacketPlayerLeft::Data netPlayerData;
tmpPacket->ToNetPacketPlayerLeft()->GetData(netPlayerData); packet->ToNetPacketPlayerLeft()->GetData(netPlayerData);
client.RemovePlayerData(netPlayerData.playerId); client.RemovePlayerData(netPlayerData.playerId);
}
} }
// TODO: handle error packet // TODO: handle error packet
@@ -496,33 +520,27 @@ ClientStateWaitHand::~ClientStateWaitHand()
} }
int int
ClientStateWaitHand::Process(ClientThread &client) ClientStateWaitHand::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
{ {
int retVal = MSG_SOCK_INTERNAL_PENDING; int retVal = MSG_SOCK_INTERNAL_PENDING;
ClientContext &context = client.GetContext(); ClientContext &context = client.GetContext();
// Delegate to receiver helper class. if (packet->ToNetPacketHandStart())
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv(context.GetSocket());
if (tmpPacket.get())
{ {
if (tmpPacket->ToNetPacketHandStart()) // Hand was started.
{ // These are the cards. Good luck.
// Hand was started. NetPacketHandStart::Data tmpData;
// These are the cards. Good luck. packet->ToNetPacketHandStart()->GetData(tmpData);
NetPacketHandStart::Data tmpData; int myCards[2];
tmpPacket->ToNetPacketHandStart()->GetData(tmpData); myCards[0] = (int)tmpData.yourCards[0];
int myCards[2]; myCards[1] = (int)tmpData.yourCards[1];
myCards[0] = (int)tmpData.yourCards[0]; client.GetGame()->getPlayerArray()[0]->setMyCards(myCards);
myCards[1] = (int)tmpData.yourCards[1]; client.GetGame()->initHand();
client.GetGame()->getPlayerArray()[0]->setMyCards(myCards); client.GetGame()->startHand();
client.GetGame()->initHand(); client.GetGui().dealHoleCards();
client.GetGame()->startHand(); client.SetState(ClientStateRunHand::Instance());
client.GetGui().dealHoleCards();
client.SetState(ClientStateRunHand::Instance());
retVal = MSG_NET_GAME_CLIENT_HAND; retVal = MSG_NET_GAME_CLIENT_HAND;
}
} }
return MSG_SOCK_INTERNAL_PENDING; return MSG_SOCK_INTERNAL_PENDING;
@@ -546,20 +564,17 @@ ClientStateRunHand::~ClientStateRunHand()
} }
int int
ClientStateRunHand::Process(ClientThread &client) ClientStateRunHand::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
{ {
ClientContext &context = client.GetContext(); ClientContext &context = client.GetContext();
// Delegate to receiver helper class. if (packet.get())
boost::shared_ptr<NetPacket> tmpPacket = client.GetReceiver().Recv(context.GetSocket());
if (tmpPacket.get())
{ {
boost::shared_ptr<Game> curGame = client.GetGame(); boost::shared_ptr<Game> curGame = client.GetGame();
if (tmpPacket->ToNetPacketPlayersActionDone()) if (packet->ToNetPacketPlayersActionDone())
{ {
NetPacketPlayersActionDone::Data actionDoneData; NetPacketPlayersActionDone::Data actionDoneData;
tmpPacket->ToNetPacketPlayersActionDone()->GetData(actionDoneData); packet->ToNetPacketPlayersActionDone()->GetData(actionDoneData);
PlayerInterface *tmpPlayer = curGame->getPlayerByUniqueId(actionDoneData.playerId); PlayerInterface *tmpPlayer = curGame->getPlayerByUniqueId(actionDoneData.playerId);
assert(tmpPlayer); // TODO: throw exception assert(tmpPlayer); // TODO: throw exception
@@ -587,10 +602,10 @@ ClientStateRunHand::Process(ClientThread &client)
client.GetGui().refreshAction(); client.GetGui().refreshAction();
client.GetGui().refreshCash(); client.GetGui().refreshCash();
} }
else if (tmpPacket->ToNetPacketPlayersTurn()) else if (packet->ToNetPacketPlayersTurn())
{ {
NetPacketPlayersTurn::Data turnData; NetPacketPlayersTurn::Data turnData;
tmpPacket->ToNetPacketPlayersTurn()->GetData(turnData); packet->ToNetPacketPlayersTurn()->GetData(turnData);
PlayerInterface *tmpPlayer = curGame->getPlayerByUniqueId(turnData.playerId); PlayerInterface *tmpPlayer = curGame->getPlayerByUniqueId(turnData.playerId);
assert(tmpPlayer); // TODO: throw exception assert(tmpPlayer); // TODO: throw exception
+45 -4
View File
@@ -96,6 +96,19 @@ ClientThread::SendPlayerAction()
GetSender().Send(GetContext().GetSocket(), action); GetSender().Send(GetContext().GetSocket(), action);
} }
void
ClientThread::SendChatMessage(const std::string &msg)
{
// Warning: This function is called in the context of the GUI thread.
// Create a network packet containing the chat message.
boost::shared_ptr<NetPacket> chat(new NetPacketSendChatText);
NetPacketSendChatText::Data chatData;
chatData.text = msg;
static_cast<NetPacketSendChatText *>(chat.get())->SetData(chatData);
// The sender is thread-safe, so just dump the packet.
GetSender().Send(GetContext().GetSocket(), chat);
}
ClientCallback & ClientCallback &
ClientThread::GetCallback() ClientThread::GetCallback()
{ {
@@ -133,7 +146,8 @@ ClientThread::Main()
// EngineFactory erstellen // EngineFactory erstellen
boost::shared_ptr<EngineFactory> factory(new ClientEngineFactory); // LocalEngine erstellen boost::shared_ptr<EngineFactory> factory(new ClientEngineFactory); // LocalEngine erstellen
m_game.reset(new Game(&m_gui, factory, GetMappedPlayerDataList(), GetGameData(), GetStartData(), m_curGameId++)); MapPlayerDataList();
m_game.reset(new Game(&m_gui, factory, GetPlayerDataList(), GetGameData(), GetStartData(), m_curGameId++));
GetCallback().SignalNetClientGameStart(m_game); GetCallback().SignalNetClientGameStart(m_game);
} }
} }
@@ -268,8 +282,8 @@ ClientThread::RemovePlayerData(unsigned playerId)
GetCallback().SignalNetClientPlayerLeft(playerName); GetCallback().SignalNetClientPlayerLeft(playerName);
} }
PlayerDataList void
ClientThread::GetMappedPlayerDataList() const ClientThread::MapPlayerDataList()
{ {
PlayerDataList mappedList; PlayerDataList mappedList;
@@ -293,6 +307,33 @@ ClientThread::GetMappedPlayerDataList() const
// Sort the list by player number. // Sort the list by player number.
mappedList.sort(*boost::lambda::_1 < *boost::lambda::_2); mappedList.sort(*boost::lambda::_1 < *boost::lambda::_2);
return mappedList; m_playerDataList = mappedList;
SetGuiPlayerNum(0);
}
const PlayerDataList &
ClientThread::GetPlayerDataList() const
{
return m_playerDataList;
}
boost::shared_ptr<PlayerData>
ClientThread::GetPlayerDataByUniqueId(unsigned id)
{
boost::shared_ptr<PlayerData> tmpPlayer;
PlayerDataList::const_iterator i = m_playerDataList.begin();
PlayerDataList::const_iterator end = m_playerDataList.end();
while (i != end)
{
if ((*i)->GetUniqueId() == id)
{
tmpPlayer = *i;
break;
}
++i;
}
return tmpPlayer;
} }
+228 -8
View File
@@ -37,6 +37,8 @@ using namespace std;
#define NET_TYPE_PLAYERS_ACTION 0x0008 #define NET_TYPE_PLAYERS_ACTION 0x0008
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0009 #define NET_TYPE_PLAYERS_ACTION_DONE 0x0009
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x000A #define NET_TYPE_PLAYERS_ACTION_REJECTED 0x000A
#define NET_TYPE_SEND_CHAT_TEXT 0x000B
#define NET_TYPE_CHAT_TEXT 0x000C
#define NET_TYPE_ERROR 0x0400 #define NET_TYPE_ERROR 0x0400
@@ -75,7 +77,6 @@ struct GCC_PACKED NetPacketJoinGameData
u_int16_t playerFlags; u_int16_t playerFlags;
u_int16_t playerNameLength; u_int16_t playerNameLength;
u_int16_t reserved; u_int16_t reserved;
char password[1];
}; };
struct GCC_PACKED NetPacketJoinGameAckData struct GCC_PACKED NetPacketJoinGameAckData
@@ -105,7 +106,6 @@ struct GCC_PACKED NetPacketPlayerJoinedData
u_int16_t playerNumber; u_int16_t playerNumber;
u_int16_t playerFlags; u_int16_t playerFlags;
u_int16_t playerNameLength; u_int16_t playerNameLength;
char playerName[1];
}; };
struct GCC_PACKED NetPacketPlayerLeftData struct GCC_PACKED NetPacketPlayerLeftData
@@ -166,6 +166,21 @@ struct GCC_PACKED NetPacketPlayersActionRejectedData
u_int16_t reserved; u_int16_t reserved;
}; };
struct GCC_PACKED NetPacketSendChatTextData
{
NetPacketHeader head;
u_int16_t textLength;
u_int16_t reserved;
};
struct GCC_PACKED NetPacketChatTextData
{
NetPacketHeader head;
u_int16_t textLength;
u_int16_t playerId;
char text[1];
};
struct GCC_PACKED NetPacketErrorData struct GCC_PACKED NetPacketErrorData
{ {
NetPacketHeader head; NetPacketHeader head;
@@ -229,6 +244,12 @@ NetPacket::Create(char *data, unsigned &dataSize)
case NET_TYPE_PLAYERS_ACTION_REJECTED: case NET_TYPE_PLAYERS_ACTION_REJECTED:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketPlayersActionRejected); tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketPlayersActionRejected);
break; break;
case NET_TYPE_SEND_CHAT_TEXT:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketSendChatText);
break;
case NET_TYPE_CHAT_TEXT:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketChatText);
break;
case NET_TYPE_ERROR: case NET_TYPE_ERROR:
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketError); tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketError);
break; break;
@@ -373,6 +394,18 @@ NetPacket::ToNetPacketPlayersActionRejected() const
return NULL; return NULL;
} }
const NetPacketSendChatText *
NetPacket::ToNetPacketSendChatText() const
{
return NULL;
}
const NetPacketChatText *
NetPacket::ToNetPacketChatText() const
{
return NULL;
}
const NetPacketError * const NetPacketError *
NetPacket::ToNetPacketError() const NetPacket::ToNetPacketError() const
{ {
@@ -461,8 +494,9 @@ NetPacketJoinGame::SetData(const NetPacketJoinGame::Data &inData)
tmpData->passwordLength = htons(passwordLen); tmpData->passwordLength = htons(passwordLen);
tmpData->playerFlags = htons((inData.ptype == PLAYER_TYPE_HUMAN) ? NET_PLAYER_FLAG_HUMAN : 0); tmpData->playerFlags = htons((inData.ptype == PLAYER_TYPE_HUMAN) ? NET_PLAYER_FLAG_HUMAN : 0);
tmpData->playerNameLength = htons(playerNameLen); tmpData->playerNameLength = htons(playerNameLen);
memcpy(tmpData->password, inData.password.c_str(), passwordLen); char *passwordPtr = (char *)tmpData + sizeof(NetPacketJoinGameData);
memcpy(tmpData->password + ADD_PADDING(passwordLen), inData.playerName.c_str(), playerNameLen); memcpy(passwordPtr, inData.password.c_str(), passwordLen);
memcpy(passwordPtr + ADD_PADDING(passwordLen), inData.playerName.c_str(), playerNameLen);
} }
void void
@@ -478,8 +512,9 @@ NetPacketJoinGame::GetData(NetPacketJoinGame::Data &outData) const
outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER; outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER;
u_int16_t passwordLen = ntohs(tmpData->passwordLength); u_int16_t passwordLen = ntohs(tmpData->passwordLength);
outData.password = string(tmpData->password, passwordLen); char *passwordPtr = (char *)tmpData + sizeof(NetPacketJoinGameData);
outData.playerName = string(tmpData->password + ADD_PADDING(passwordLen), ntohs(tmpData->playerNameLength)); outData.password = string(passwordPtr, passwordLen);
outData.playerName = string(passwordPtr + ADD_PADDING(passwordLen), ntohs(tmpData->playerNameLength));
} }
const NetPacketJoinGame * const NetPacketJoinGame *
@@ -640,7 +675,8 @@ NetPacketPlayerJoined::SetData(const NetPacketPlayerJoined::Data &inData)
tmpData->playerId = htons(inData.playerId); tmpData->playerId = htons(inData.playerId);
tmpData->playerNumber = htons(inData.playerNumber); tmpData->playerNumber = htons(inData.playerNumber);
tmpData->playerNameLength = htons(playerNameLen); tmpData->playerNameLength = htons(playerNameLen);
memcpy(tmpData->playerName, inData.playerName.c_str(), playerNameLen); char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData);
memcpy(namePtr, inData.playerName.c_str(), playerNameLen);
} }
void void
@@ -653,7 +689,8 @@ NetPacketPlayerJoined::GetData(NetPacketPlayerJoined::Data &outData) const
outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER; outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER;
outData.playerId = ntohs(tmpData->playerId); outData.playerId = ntohs(tmpData->playerId);
outData.playerNumber = ntohs(tmpData->playerNumber); outData.playerNumber = ntohs(tmpData->playerNumber);
outData.playerName = string(tmpData->playerName, ntohs(tmpData->playerNameLength)); char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData);
outData.playerName = string(namePtr, ntohs(tmpData->playerNameLength));
} }
const NetPacketPlayerJoined * const NetPacketPlayerJoined *
@@ -1196,6 +1233,189 @@ NetPacketPlayersActionRejected::Check(const NetPacketHeader* data) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
NetPacketSendChatText::NetPacketSendChatText()
: NetPacket(NET_TYPE_SEND_CHAT_TEXT, sizeof(NetPacketSendChatTextData))
{
}
NetPacketSendChatText::~NetPacketSendChatText()
{
}
boost::shared_ptr<NetPacket>
NetPacketSendChatText::Clone() const
{
boost::shared_ptr<NetPacket> newPacket(new NetPacketSendChatText);
try
{
newPacket->SetRawData(GetRawData());
} catch (const NetException &)
{
// Need to return the new packet anyway.
}
return newPacket;
}
void
NetPacketSendChatText::SetData(const NetPacketSendChatText::Data &inData)
{
u_int16_t textLen = (u_int16_t)inData.text.length();
if (!textLen || textLen > MAX_CHAT_TEXT_SIZE)
throw NetException(ERR_NET_INVALID_CHAT_TEXT, 0);
// Resize the packet so that the data fits in.
Resize((u_int16_t)
(sizeof(NetPacketSendChatTextData) + ADD_PADDING(textLen)));
NetPacketSendChatTextData *tmpData = (NetPacketSendChatTextData *)GetRawData();
assert(tmpData);
// Set the data.
tmpData->textLength = htons(textLen);
char *textPtr = (char *)tmpData + sizeof(NetPacketSendChatTextData);
memcpy(textPtr, inData.text.c_str(), textLen);
}
void
NetPacketSendChatText::GetData(NetPacketSendChatText::Data &outData) const
{
// We assume that the data is valid. Validity has already been checked.
NetPacketSendChatTextData *tmpData = (NetPacketSendChatTextData *)GetRawData();
assert(tmpData);
char *textPtr = (char *)tmpData + sizeof(NetPacketSendChatTextData);
outData.text = string(textPtr, ntohs(tmpData->textLength));
}
const NetPacketSendChatText *
NetPacketSendChatText::ToNetPacketSendChatText() const
{
return this;
}
void
NetPacketSendChatText::Check(const NetPacketHeader* data) const
{
assert(data);
u_int16_t dataLen = ntohs(data->length);
if (dataLen < sizeof(NetPacketSendChatTextData))
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
NetPacketSendChatTextData *tmpData = (NetPacketSendChatTextData *)data;
int textLength = ntohs(tmpData->textLength);
// Generous checking - larger packets are allowed.
if (dataLen <
sizeof(NetPacketSendChatTextData)
+ ADD_PADDING(textLength))
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
// Check string sizes.
if (!textLength
|| textLength > MAX_CHAT_TEXT_SIZE)
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
}
//-----------------------------------------------------------------------------
NetPacketChatText::NetPacketChatText()
: NetPacket(NET_TYPE_CHAT_TEXT, sizeof(NetPacketChatTextData))
{
}
NetPacketChatText::~NetPacketChatText()
{
}
boost::shared_ptr<NetPacket>
NetPacketChatText::Clone() const
{
boost::shared_ptr<NetPacket> newPacket(new NetPacketChatText);
try
{
newPacket->SetRawData(GetRawData());
} catch (const NetException &)
{
// Need to return the new packet anyway.
}
return newPacket;
}
void
NetPacketChatText::SetData(const NetPacketChatText::Data &inData)
{
u_int16_t textLen = (u_int16_t)inData.text.length();
if (!textLen || textLen > MAX_CHAT_TEXT_SIZE)
throw NetException(ERR_NET_INVALID_CHAT_TEXT, 0);
// Resize the packet so that the data fits in.
Resize((u_int16_t)
(sizeof(NetPacketChatTextData) + ADD_PADDING(textLen)));
NetPacketChatTextData *tmpData = (NetPacketChatTextData *)GetRawData();
assert(tmpData);
// Set the data.
tmpData->playerId = htons(inData.playerId);
tmpData->textLength = htons(textLen);
char *textPtr = (char *)tmpData + sizeof(NetPacketChatTextData);
memcpy(textPtr, inData.text.c_str(), textLen);
}
void
NetPacketChatText::GetData(NetPacketChatText::Data &outData) const
{
// We assume that the data is valid. Validity has already been checked.
NetPacketChatTextData *tmpData = (NetPacketChatTextData *)GetRawData();
assert(tmpData);
outData.playerId = ntohs(tmpData->playerId);
char *textPtr = (char *)tmpData + sizeof(NetPacketChatTextData);
outData.text = string(textPtr, ntohs(tmpData->textLength));
}
const NetPacketChatText *
NetPacketChatText::ToNetPacketChatText() const
{
return this;
}
void
NetPacketChatText::Check(const NetPacketHeader* data) const
{
assert(data);
u_int16_t dataLen = ntohs(data->length);
if (dataLen < sizeof(NetPacketChatTextData))
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
NetPacketChatTextData *tmpData = (NetPacketChatTextData *)data;
int textLength = ntohs(tmpData->textLength);
// Generous checking - larger packets are allowed.
if (dataLen <
sizeof(NetPacketChatTextData)
+ ADD_PADDING(textLength))
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
// Check string sizes.
if (!textLength
|| textLength > MAX_CHAT_TEXT_SIZE)
{
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
}
}
//-----------------------------------------------------------------------------
NetPacketError::NetPacketError() NetPacketError::NetPacketError()
: NetPacket(NET_TYPE_ERROR, sizeof(NetPacketErrorData)) : NetPacket(NET_TYPE_ERROR, sizeof(NetPacketErrorData))
{ {
+200 -173
View File
@@ -41,6 +41,66 @@ ServerRecvState::~ServerRecvState()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ServerRecvStateReceiving::ServerRecvStateReceiving()
{
}
ServerRecvStateReceiving::~ServerRecvStateReceiving()
{
}
int
ServerRecvStateReceiving::Process(ServerRecvThread &server)
{
int retVal = MSG_SOCK_INTERNAL_PENDING;
SOCKET recvSock = server.Select();
if (recvSock != INVALID_SOCKET)
{
SessionWrapper session = server.GetSession(recvSock);
boost::shared_ptr<NetPacket> packet;
try
{
packet = server.GetReceiver().Recv(recvSock);
} catch (const NetException &)
{
if (session.sessionData.get())
{
// TODO: Deactivate player.
server.CloseSessionDelayed(session);
return retVal;
}
}
// Ignore if no session / no packet.
if (packet.get() && session.sessionData.get())
{
if (packet->ToNetPacketSendChatText()) // Chat text is always allowed.
{
if (session.playerData.get()) // Only forward if this player is known.
{
// Forward chat text to all players.
// TODO: Some limitation needed.
NetPacketSendChatText::Data inChatData;
packet->ToNetPacketSendChatText()->GetData(inChatData);
boost::shared_ptr<NetPacket> outChat(new NetPacketChatText);
NetPacketChatText::Data outChatData;
outChatData.playerId = session.playerData->GetUniqueId();
outChatData.text = inChatData.text;
static_cast<NetPacketChatText *>(outChat.get())->SetData(outChatData);
server.SendToAllPlayers(outChat);
}
}
else
retVal = InternalProcess(server, session, packet); // Let other class handle this.
}
}
return retVal;
}
//-----------------------------------------------------------------------------
ServerRecvStateInit & ServerRecvStateInit &
ServerRecvStateInit::Instance() ServerRecvStateInit::Instance()
{ {
@@ -71,137 +131,116 @@ ServerRecvStateInit::HandleNewConnection(ServerRecvThread &server, boost::shared
} }
int int
ServerRecvStateInit::Process(ServerRecvThread &server) ServerRecvStateInit::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{ {
int retVal = MSG_SOCK_INIT_DONE; int retVal = MSG_SOCK_INIT_DONE;
SOCKET recvSock = server.Select();
if (recvSock != INVALID_SOCKET) // Session should be in initial state.
if (session.sessionData->GetState() != SessionData::Init)
{ {
SessionWrapper session = server.GetSession(recvSock); server.SessionError(session, ERR_SOCK_INVALID_STATE);
boost::shared_ptr<NetPacket> packet; return retVal;
try
{
packet = server.GetReceiver().Recv(recvSock);
} catch (const NetException &)
{
if (session.sessionData.get())
{
server.CloseSessionDelayed(session);
return retVal;
}
}
// Ignore if no session / no packet.
if (packet.get() && session.sessionData.get())
{
// Session should be in initial state.
if (session.sessionData->GetState() != SessionData::Init)
{
server.SessionError(session, ERR_SOCK_INVALID_STATE);
return retVal;
}
// Only accept join game packets.
const NetPacketJoinGame *tmpPacket = packet->ToNetPacketJoinGame();
if (!tmpPacket)
{
server.SessionError(session, ERR_SOCK_INVALID_PACKET);
return retVal;
}
NetPacketJoinGame::Data joinGameData;
tmpPacket->GetData(joinGameData);
// Check the protocol version.
if (joinGameData.versionMajor != NET_VERSION_MAJOR)
{
server.SessionError(session, ERR_NET_VERSION_NOT_SUPPORTED);
return retVal;
}
size_t curNumPlayers = server.GetCurNumberOfPlayers();
// Check the number of players.
if (curNumPlayers >= (size_t)server.GetGameData().numberOfPlayers)
{
server.SessionError(session, ERR_NET_SERVER_FULL);
return retVal;
}
// Check the server password.
if (!server.CheckPassword(joinGameData.password))
{
server.SessionError(session, ERR_NET_INVALID_PASSWORD);
return retVal;
}
// Check whether the player name is correct.
// Paranoia check, this is also done in netpacket.
if (joinGameData.playerName.empty() || joinGameData.playerName.size() > MAX_NAME_SIZE)
{
server.SessionError(session, ERR_NET_INVALID_PLAYER_NAME);
return retVal;
}
// Check whether this player is already connected.
if (server.IsPlayerConnected(joinGameData.playerName))
{
server.SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
return retVal;
}
// Create player data object.
boost::shared_ptr<PlayerData> tmpPlayerData(
new PlayerData(m_curUniquePlayerId++, server.GetNextPlayerNumber(), joinGameData.ptype));
tmpPlayerData->SetName(joinGameData.playerName);
tmpPlayerData->SetNetSessionData(session.sessionData);
// Send ACK to client.
boost::shared_ptr<NetPacket> answer(new NetPacketJoinGameAck);
NetPacketJoinGameAck::Data joinGameAckData;
joinGameAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused.
joinGameAckData.yourPlayerUniqueId = tmpPlayerData->GetUniqueId();
joinGameAckData.yourPlayerNum = tmpPlayerData->GetNumber();
joinGameAckData.gameData = server.GetGameData();
static_cast<NetPacketJoinGameAck *>(answer.get())->SetData(joinGameAckData);
server.GetSender().Send(recvSock, answer);
// Send notifications for connected players to client.
PlayerDataList tmpPlayerList = server.GetPlayerDataList();
PlayerDataList::iterator player_i = tmpPlayerList.begin();
PlayerDataList::iterator player_end = tmpPlayerList.end();
while (player_i != player_end)
{
boost::shared_ptr<NetPacket> otherPlayerJoined(new NetPacketPlayerJoined);
NetPacketPlayerJoined::Data otherPlayerJoinedData;
otherPlayerJoinedData.playerId = (*player_i)->GetUniqueId();
otherPlayerJoinedData.playerName = (*player_i)->GetName();
otherPlayerJoinedData.playerNumber = (*player_i)->GetNumber();
otherPlayerJoinedData.ptype = (*player_i)->GetType();
static_cast<NetPacketPlayerJoined *>(otherPlayerJoined.get())->SetData(otherPlayerJoinedData);
server.GetSender().Send(session.sessionData->GetSocket(), otherPlayerJoined);
++player_i;
}
// Send "Player Joined" to other fully connected clients.
boost::shared_ptr<NetPacket> thisPlayerJoined(new NetPacketPlayerJoined);
NetPacketPlayerJoined::Data thisPlayerJoinedData;
thisPlayerJoinedData.playerId = tmpPlayerData->GetUniqueId();
thisPlayerJoinedData.playerName = tmpPlayerData->GetName();
thisPlayerJoinedData.playerNumber = tmpPlayerData->GetNumber();
thisPlayerJoinedData.ptype = tmpPlayerData->GetType();
static_cast<NetPacketPlayerJoined *>(thisPlayerJoined.get())->SetData(thisPlayerJoinedData);
server.SendToAllPlayers(thisPlayerJoined);
// Set player data for session.
server.SetSessionPlayerData(session.sessionData, tmpPlayerData);
// Session is now established.
session.sessionData->SetState(SessionData::Established);
}
} }
// Only accept join game packets.
const NetPacketJoinGame *tmpPacket = packet->ToNetPacketJoinGame();
if (!tmpPacket)
{
server.SessionError(session, ERR_SOCK_INVALID_PACKET);
return retVal;
}
NetPacketJoinGame::Data joinGameData;
tmpPacket->GetData(joinGameData);
// Check the protocol version.
if (joinGameData.versionMajor != NET_VERSION_MAJOR)
{
server.SessionError(session, ERR_NET_VERSION_NOT_SUPPORTED);
return retVal;
}
size_t curNumPlayers = server.GetCurNumberOfPlayers();
// Check the number of players.
if (curNumPlayers >= (size_t)server.GetGameData().numberOfPlayers)
{
server.SessionError(session, ERR_NET_SERVER_FULL);
return retVal;
}
// Check the server password.
if (!server.CheckPassword(joinGameData.password))
{
server.SessionError(session, ERR_NET_INVALID_PASSWORD);
return retVal;
}
// Check whether the player name is correct.
// Paranoia check, this is also done in netpacket.
if (joinGameData.playerName.empty() || joinGameData.playerName.size() > MAX_NAME_SIZE)
{
server.SessionError(session, ERR_NET_INVALID_PLAYER_NAME);
return retVal;
}
// Check whether this player is already connected.
if (server.IsPlayerConnected(joinGameData.playerName))
{
server.SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
return retVal;
}
// Create player data object.
boost::shared_ptr<PlayerData> tmpPlayerData(
new PlayerData(m_curUniquePlayerId++, server.GetNextPlayerNumber(), joinGameData.ptype));
tmpPlayerData->SetName(joinGameData.playerName);
tmpPlayerData->SetNetSessionData(session.sessionData);
// Send ACK to client.
boost::shared_ptr<NetPacket> answer(new NetPacketJoinGameAck);
NetPacketJoinGameAck::Data joinGameAckData;
joinGameAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused.
joinGameAckData.yourPlayerUniqueId = tmpPlayerData->GetUniqueId();
joinGameAckData.yourPlayerNum = tmpPlayerData->GetNumber();
joinGameAckData.gameData = server.GetGameData();
static_cast<NetPacketJoinGameAck *>(answer.get())->SetData(joinGameAckData);
server.GetSender().Send(session.sessionData->GetSocket(), answer);
// Send notifications for connected players to client.
PlayerDataList tmpPlayerList = server.GetPlayerDataList();
PlayerDataList::iterator player_i = tmpPlayerList.begin();
PlayerDataList::iterator player_end = tmpPlayerList.end();
while (player_i != player_end)
{
boost::shared_ptr<NetPacket> otherPlayerJoined(new NetPacketPlayerJoined);
NetPacketPlayerJoined::Data otherPlayerJoinedData;
otherPlayerJoinedData.playerId = (*player_i)->GetUniqueId();
otherPlayerJoinedData.playerName = (*player_i)->GetName();
otherPlayerJoinedData.playerNumber = (*player_i)->GetNumber();
otherPlayerJoinedData.ptype = (*player_i)->GetType();
static_cast<NetPacketPlayerJoined *>(otherPlayerJoined.get())->SetData(otherPlayerJoinedData);
server.GetSender().Send(session.sessionData->GetSocket(), otherPlayerJoined);
++player_i;
}
// Send "Player Joined" to other fully connected clients.
boost::shared_ptr<NetPacket> thisPlayerJoined(new NetPacketPlayerJoined);
NetPacketPlayerJoined::Data thisPlayerJoinedData;
thisPlayerJoinedData.playerId = tmpPlayerData->GetUniqueId();
thisPlayerJoinedData.playerName = tmpPlayerData->GetName();
thisPlayerJoinedData.playerNumber = tmpPlayerData->GetNumber();
thisPlayerJoinedData.ptype = tmpPlayerData->GetType();
static_cast<NetPacketPlayerJoined *>(thisPlayerJoined.get())->SetData(thisPlayerJoinedData);
server.SendToAllPlayers(thisPlayerJoined);
// Set player data for session.
server.SetSessionPlayerData(session.sessionData, tmpPlayerData);
// Session is now established.
session.sessionData->SetState(SessionData::Established);
return retVal; return retVal;
} }
@@ -463,62 +502,50 @@ ServerRecvStateWaitPlayerAction::~ServerRecvStateWaitPlayerAction()
{ {
} }
void
ServerRecvStateWaitPlayerAction::HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> connData)
{
// C++ really sucks concerning multiple inheritance *sigh*.
// So this is a copy & paste from ServerRecvStateRunning.
// Do not accept new connections in this state.
server.RejectNewConnection(connData);
}
int int
ServerRecvStateWaitPlayerAction::Process(ServerRecvThread &server) ServerRecvStateWaitPlayerAction::InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet)
{ {
int retVal = MSG_SOCK_INTERNAL_PENDING; int retVal = MSG_SOCK_INTERNAL_PENDING;
SOCKET recvSock = server.Select();
if (recvSock != INVALID_SOCKET) if (packet->ToNetPacketPlayersAction())
{ {
SessionWrapper session = server.GetSession(recvSock); NetPacketPlayersAction::Data actionData;
boost::shared_ptr<NetPacket> packet; packet->ToNetPacketPlayersAction()->GetData(actionData);
try
{ Game &curGame = server.GetGame();
packet = server.GetReceiver().Recv(recvSock); PlayerInterface *tmpPlayer = curGame.getPlayerByUniqueId(session.playerData->GetUniqueId());
} catch (const NetException &) assert(tmpPlayer); // TODO throw exception
{
if (session.sessionData.get())
{
server.CloseSessionDelayed(session);
return retVal;
}
}
// Ignore if no session / no packet. tmpPlayer->setMyAction(actionData.playerAction);
if (packet.get() && session.sessionData.get()) tmpPlayer->setMySet(actionData.playerBet);
{
if (packet->ToNetPacketPlayersAction())
{
NetPacketPlayersAction::Data actionData;
packet->ToNetPacketPlayersAction()->GetData(actionData);
Game &curGame = server.GetGame();
PlayerInterface *tmpPlayer = curGame.getPlayerByUniqueId(session.playerData->GetUniqueId());
assert(tmpPlayer); // TODO throw exception
tmpPlayer->setMyAction(actionData.playerAction); if (tmpPlayer->getMySet() > GetHighestSet(curGame))
tmpPlayer->setMySet(actionData.playerBet); SetHighestSet(curGame, tmpPlayer->getMySet());
if (tmpPlayer->getMySet() > GetHighestSet(curGame)) boost::shared_ptr<NetPacket> notifyActionDone(new NetPacketPlayersActionDone);
SetHighestSet(curGame, tmpPlayer->getMySet()); NetPacketPlayersActionDone::Data actionDoneData;
actionDoneData.gameState = static_cast<GameState>(curGame.getCurrentHand()->getActualRound());
actionDoneData.playerId = session.playerData->GetUniqueId();
actionDoneData.playerAction = actionData.playerAction;
actionDoneData.totalPlayerBet = tmpPlayer->getMySet();
actionDoneData.playerMoney = tmpPlayer->getMyCash();
actionDoneData.potSize = curGame.getCurrentHand()->getBoard()->getPot();
actionDoneData.curHandBets = curGame.getCurrentHand()->getBoard()->getSets();
static_cast<NetPacketPlayersActionDone *>(notifyActionDone.get())->SetData(actionDoneData);
server.SendToAllPlayers(notifyActionDone);
boost::shared_ptr<NetPacket> notifyActionDone(new NetPacketPlayersActionDone); server.SetState(ServerRecvStateStartRound::Instance());
NetPacketPlayersActionDone::Data actionDoneData; retVal = MSG_NET_GAME_SERVER_ACTION;
actionDoneData.gameState = static_cast<GameState>(curGame.getCurrentHand()->getActualRound());
actionDoneData.playerId = session.playerData->GetUniqueId();
actionDoneData.playerAction = actionData.playerAction;
actionDoneData.totalPlayerBet = tmpPlayer->getMySet();
actionDoneData.playerMoney = tmpPlayer->getMyCash();
actionDoneData.potSize = curGame.getCurrentHand()->getBoard()->getPot();
actionDoneData.curHandBets = curGame.getCurrentHand()->getBoard()->getSets();
static_cast<NetPacketPlayersActionDone *>(notifyActionDone.get())->SetData(actionDoneData);
server.SendToAllPlayers(notifyActionDone);
server.SetState(ServerRecvStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION;
}
}
} }
return retVal; return retVal;
+52
View File
@@ -33,6 +33,7 @@
#define MAX_PACKET_SIZE 256 #define MAX_PACKET_SIZE 256
#define MAX_NAME_SIZE 64 #define MAX_NAME_SIZE 64
#define MAX_PASSWORD_SIZE 64 #define MAX_PASSWORD_SIZE 64
#define MAX_CHAT_TEXT_SIZE 128
struct NetPacketHeader; struct NetPacketHeader;
@@ -47,6 +48,8 @@ class NetPacketPlayersTurn;
class NetPacketPlayersAction; class NetPacketPlayersAction;
class NetPacketPlayersActionDone; class NetPacketPlayersActionDone;
class NetPacketPlayersActionRejected; class NetPacketPlayersActionRejected;
class NetPacketSendChatText;
class NetPacketChatText;
class NetPacketError; class NetPacketError;
class NetPacket class NetPacket
@@ -76,6 +79,8 @@ public:
virtual const NetPacketPlayersAction *ToNetPacketPlayersAction() const; virtual const NetPacketPlayersAction *ToNetPacketPlayersAction() const;
virtual const NetPacketPlayersActionDone *ToNetPacketPlayersActionDone() const; virtual const NetPacketPlayersActionDone *ToNetPacketPlayersActionDone() const;
virtual const NetPacketPlayersActionRejected *ToNetPacketPlayersActionRejected() const; virtual const NetPacketPlayersActionRejected *ToNetPacketPlayersActionRejected() const;
virtual const NetPacketSendChatText *ToNetPacketSendChatText() const;
virtual const NetPacketChatText *ToNetPacketChatText() const;
virtual const NetPacketError *ToNetPacketError() const; virtual const NetPacketError *ToNetPacketError() const;
protected: protected:
@@ -343,6 +348,53 @@ protected:
virtual void Check(const NetPacketHeader* data) const; virtual void Check(const NetPacketHeader* data) const;
}; };
class NetPacketSendChatText : public NetPacket
{
public:
struct Data
{
std::string text;
};
NetPacketSendChatText();
virtual ~NetPacketSendChatText();
virtual boost::shared_ptr<NetPacket> Clone() const;
void SetData(const Data &inData);
void GetData(Data &outData) const;
virtual const NetPacketSendChatText *ToNetPacketSendChatText() const;
protected:
virtual void Check(const NetPacketHeader* data) const;
};
class NetPacketChatText : public NetPacket
{
public:
struct Data
{
u_int16_t playerId;
std::string text;
};
NetPacketChatText();
virtual ~NetPacketChatText();
virtual boost::shared_ptr<NetPacket> Clone() const;
void SetData(const Data &inData);
void GetData(Data &outData) const;
virtual const NetPacketChatText *ToNetPacketChatText() const;
protected:
virtual void Check(const NetPacketHeader* data) const;
};
class NetPacketError : public NetPacket class NetPacketError : public NetPacket
{ {
public: public:
+27 -10
View File
@@ -21,7 +21,7 @@
#ifndef _SERVERRECVSTATE_H_ #ifndef _SERVERRECVSTATE_H_
#define _SERVERRECVSTATE_H_ #define _SERVERRECVSTATE_H_
#include <net/connectdata.h> #include <net/serverrecvthread.h>
#include <playerdata.h> #include <playerdata.h>
#define SERVER_INITIAL_STATE ServerRecvStateInit #define SERVER_INITIAL_STATE ServerRecvStateInit
@@ -29,7 +29,6 @@
class Game; class Game;
class PlayerInterface; class PlayerInterface;
class ServerRecvThread;
class ServerCallback; class ServerCallback;
class ServerRecvState class ServerRecvState
@@ -44,8 +43,25 @@ public:
virtual int Process(ServerRecvThread &server) = 0; virtual int Process(ServerRecvThread &server) = 0;
}; };
// Abstract State: Receiving.
class ServerRecvStateReceiving : public ServerRecvState
{
public:
virtual ~ServerRecvStateReceiving();
// Globally handle packets which are allowed in all running states.
// Calls InternalProcess if packet has not been processed.
virtual int Process(ServerRecvThread &server);
protected:
ServerRecvStateReceiving();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet) = 0;
};
// State: Initialization. // State: Initialization.
class ServerRecvStateInit : public ServerRecvState class ServerRecvStateInit : public ServerRecvStateReceiving
{ {
public: public:
// Access the state singleton. // Access the state singleton.
@@ -56,14 +72,13 @@ public:
// //
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data); virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data);
//
virtual int Process(ServerRecvThread &server);
protected: protected:
// Protected constructor - this is a singleton. // Protected constructor - this is a singleton.
ServerRecvStateInit(); ServerRecvStateInit();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
private: private:
unsigned m_curUniquePlayerId; unsigned m_curUniquePlayerId;
@@ -75,10 +90,11 @@ class ServerRecvStateRunning : public ServerRecvState
public: public:
virtual ~ServerRecvStateRunning(); virtual ~ServerRecvStateRunning();
// // Reject new connections.
virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data); virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data);
protected: protected:
ServerRecvStateRunning(); ServerRecvStateRunning();
}; };
@@ -140,7 +156,7 @@ protected:
}; };
// State: Wait for a player action. // State: Wait for a player action.
class ServerRecvStateWaitPlayerAction : public ServerRecvStateRunning class ServerRecvStateWaitPlayerAction : public ServerRecvStateReceiving
{ {
public: public:
// Access the state singleton. // Access the state singleton.
@@ -148,14 +164,15 @@ public:
virtual ~ServerRecvStateWaitPlayerAction(); virtual ~ServerRecvStateWaitPlayerAction();
// virtual void HandleNewConnection(ServerRecvThread &server, boost::shared_ptr<ConnectData> data);
virtual int Process(ServerRecvThread &server);
protected: protected:
// Protected constructor - this is a singleton. // Protected constructor - this is a singleton.
ServerRecvStateWaitPlayerAction(); ServerRecvStateWaitPlayerAction();
virtual int InternalProcess(ServerRecvThread &server, SessionWrapper session, boost::shared_ptr<NetPacket> packet);
static int GetHighestSet(Game &curGame); static int GetHighestSet(Game &curGame);
static void SetHighestSet(Game &curGame, int highestSet); static void SetHighestSet(Game &curGame, int highestSet);
}; };
+1
View File
@@ -163,6 +163,7 @@ private:
ConfigFile *m_playerConfig; ConfigFile *m_playerConfig;
friend class ServerRecvStateInit; friend class ServerRecvStateInit;
friend class ServerRecvStateReceiving;
friend class ServerRecvStateRunning; friend class ServerRecvStateRunning;
friend class ServerRecvStateStartGame; friend class ServerRecvStateStartGame;
friend class ServerRecvStateStartHand; friend class ServerRecvStateStartHand;
+1
View File
@@ -48,6 +48,7 @@
#define ERR_NET_INVALID_PASSWORD_STR 105 #define ERR_NET_INVALID_PASSWORD_STR 105
#define ERR_NET_PLAYER_NAME_IN_USE 106 #define ERR_NET_PLAYER_NAME_IN_USE 106
#define ERR_NET_INVALID_PLAYER_NAME 107 #define ERR_NET_INVALID_PLAYER_NAME 107
#define ERR_NET_INVALID_CHAT_TEXT 108
// 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
+5 -5
View File
@@ -185,12 +185,12 @@ void Session::terminateNetworkServer()
void Session::sendClientPlayerAction() void Session::sendClientPlayerAction()
{ {
if (!myNetClient) if (!myNetClient)
return; return; // only act if client is running.
myNetClient->SendPlayerAction(); myNetClient->SendPlayerAction();
} }
void Session::sendChatMessage(std::string message) { void Session::sendChatMessage(const std::string &message) {
if (!myNetClient)
//hi lothar --> zum testen schick ich es gleich wieder zurück an die gui. wie du siehst klappt es ;-) return; // only act if client is running.
myGui->chatAppendMsg(message); myNetClient->SendChatMessage(message);
} }
+1 -1
View File
@@ -59,7 +59,7 @@ public:
void setCurrentGameID(const int& theValue) { currentGameID = theValue; } void setCurrentGameID(const int& theValue) { currentGameID = theValue; }
int getCurrentGameID() const { return currentGameID; } int getCurrentGameID() const { return currentGameID; }
void sendChatMessage(std::string message); void sendChatMessage(const std::string &message);
private: private: