diff --git a/src/core/libircclient/include/libircclient.h b/src/core/libircclient/include/libircclient.h index dbaff1eb..82bff5c7 100644 --- a/src/core/libircclient/include/libircclient.h +++ b/src/core/libircclient/include/libircclient.h @@ -126,6 +126,7 @@ typedef void (*irc_dcc_callback_t) (irc_session_t * session, irc_dcc_t id, int s #define IN_INCLUDE_LIBIRC_H #include "libirc_errors.h" +#include "libirc_rfcnumeric.h" #include "libirc_events.h" #include "libirc_options.h" diff --git a/src/gui/generic/serverguiwrapper.cpp b/src/gui/generic/serverguiwrapper.cpp index 7198d3c7..1f71cea4 100644 --- a/src/gui/generic/serverguiwrapper.cpp +++ b/src/gui/generic/serverguiwrapper.cpp @@ -125,4 +125,8 @@ void ServerGuiWrapper::SignalNetClientWaitDialog() { if (myClientcb) myClientcb- 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::SignalIrcConnect(const string &server) { if (myIrccb) myIrccb->SignalIrcConnect(server); } +void ServerGuiWrapper::SignalIrcSelfJoined(const string &nickName, const std::string &channel) { if (myIrccb) myIrccb->SignalIrcSelfJoined(nickName, channel); } +void ServerGuiWrapper::SignalIrcPlayerJoined(const string &nickName) { if (myIrccb) myIrccb->SignalIrcPlayerJoined(nickName); } +void ServerGuiWrapper::SignalIrcPlayerLeft(const string &nickName) { if (myIrccb) myIrccb->SignalIrcPlayerLeft(nickName); } void ServerGuiWrapper::SignalIrcChatMsg(const string &nickName, const string &msg) { if (myIrccb) myIrccb->SignalIrcChatMsg(nickName, msg); } diff --git a/src/gui/generic/serverguiwrapper.h b/src/gui/generic/serverguiwrapper.h index 0bbd2af9..358c527a 100644 --- a/src/gui/generic/serverguiwrapper.h +++ b/src/gui/generic/serverguiwrapper.h @@ -110,6 +110,10 @@ public: void SignalNetServerSuccess(int actionID); void SignalNetServerError(int errorID, int osErrorID); + void SignalIrcConnect(const std::string &server); + void SignalIrcSelfJoined(const std::string &nickName, const std::string &channel); + void SignalIrcPlayerJoined(const std::string &nickName); + void SignalIrcPlayerLeft(const std::string &nickName); void SignalIrcChatMsg(const std::string &nickName, const std::string &msg); private: diff --git a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp index 775bba36..e2a1d547 100644 --- a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp +++ b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.cpp @@ -33,7 +33,13 @@ gameLobbyDialogImpl::gameLobbyDialogImpl(QWidget *parent, ConfigFile *c) connect( treeWidget_connectedPlayers, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem*) ), this, SLOT( playerSelected(QTreeWidgetItem*, QTreeWidgetItem*) ) ); connect( lineEdit_ChatInput, SIGNAL( returnPressed () ), this, SLOT( sendChatMessage() ) ); connect( lineEdit_ChatInput, SIGNAL( textChanged (QString) ), this, SLOT( checkChatInputLength(QString) ) ); - + + connect( this, SIGNAL( signalChatConnect(QString) ), myChat, SLOT( connected (QString) ) ); + connect( this, SIGNAL( signalChatSelfJoined(QString, QString) ), myChat, SLOT( selfJoined (QString, QString) ) ); + connect( this, SIGNAL( signalChatPlayerJoined (QString) ), myChat, SLOT( playerJoined (QString) ) ); + connect( this, SIGNAL( signalChatPlayerLeft (QString) ), myChat, SLOT( playerLeft (QString) ) ); + connect( this, SIGNAL( signalChatMessage (QString, QString) ), myChat, SLOT( displayMessage (QString, QString) ) ); + clearDialog(); } @@ -75,7 +81,7 @@ void gameLobbyDialogImpl::createGame() gameData.startMoney = myCreateInternetGameDialog->spinBox_startCash->value(); gameData.smallBlind = myCreateInternetGameDialog->getChangeCompleteBlindsDialog()->spinBox_firstSmallBlind->value(); gameData.handsBeforeRaise = myCreateInternetGameDialog->getChangeCompleteBlindsDialog()->spinBox_raiseSmallBlindEveryHands->value(); - gameData.guiSpeed = myCreateInternetGameDialog->spinBox_gameSpeed->value(); + gameData.guiSpeed = myCreateInternetGameDialog->spinBox_gameSpeed->value(); gameData.guiSpeed = myCreateInternetGameDialog->spinBox_gameSpeed->value(); gameData.playerActionTimeoutSec = myCreateInternetGameDialog->spinBox_netTimeOutPlayerAction->value(); @@ -267,6 +273,7 @@ void gameLobbyDialogImpl::clearDialog() pushButton_CreateGame->clearFocus(); lineEdit_ChatInput->setFocus(); + myChat->clearChat(); } void gameLobbyDialogImpl::checkPlayerQuantity() { @@ -391,7 +398,6 @@ void gameLobbyDialogImpl::kickPlayer() { } void gameLobbyDialogImpl::sendChatMessage() { myChat->sendMessage(); } -void gameLobbyDialogImpl::displayChatMessage(QString nickName, QString msg) { myChat->receiveMessage(nickName, msg); } void gameLobbyDialogImpl::checkChatInputLength(QString string) { myChat->checkInputLength(string); } void gameLobbyDialogImpl::keyPressEvent ( QKeyEvent * event ) { diff --git a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h index 88499ea7..6f0619f9 100644 --- a/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h +++ b/src/gui/qt/gamelobbydialog/gamelobbydialogimpl.h @@ -44,7 +44,14 @@ public: Session& getSession() { return *mySession; } void setMyW ( mainWindowImpl* theValue ) { myW = theValue; } - + +signals: + void signalChatConnect(QString server); + void signalChatSelfJoined(QString nickName, QString channel); + void signalChatPlayerJoined(QString nickName); + void signalChatPlayerLeft(QString nickName); + void signalChatMessage(QString nickName, QString msg); + public slots: void createGame(); @@ -79,7 +86,6 @@ public slots: void clearDialog(); void sendChatMessage(); - void displayChatMessage(QString nickName, QString msg); void checkChatInputLength(QString string); void keyPressEvent(QKeyEvent * event); diff --git a/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.cpp b/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.cpp index b983e0b3..25bcae83 100644 --- a/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.cpp +++ b/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.cpp @@ -27,8 +27,6 @@ using namespace std; LobbyChat::LobbyChat(gameLobbyDialogImpl* l) : myLobby(l) { - - connect(this, SIGNAL(signalChatMessage(QString, QString)), this, SLOT(receiveMessage(QString, QString))); } LobbyChat::~LobbyChat() @@ -38,15 +36,48 @@ LobbyChat::~LobbyChat() void LobbyChat::sendMessage() { - QString tmpMsg(myLobby->lineEdit_ChatInput->text()); - myLobby->getSession().sendIrcChatMessage(tmpMsg.toUtf8().constData()); - myLobby->lineEdit_ChatInput->setText(""); + if (myNick.size()) + { + QString tmpMsg(myLobby->lineEdit_ChatInput->text()); + if (tmpMsg.size()) + { + myLobby->getSession().sendIrcChatMessage(tmpMsg.toUtf8().constData()); + myLobby->lineEdit_ChatInput->setText(""); - // TODO: just temporary instead of callback - receiveMessage("(me)", tmpMsg); + displayMessage(myNick, tmpMsg); + } + } } -void LobbyChat::receiveMessage(QString playerName, QString message) { +void LobbyChat::connected(QString server) +{ + myLobby->textBrowser_ChatDisplay->append(tr("Successfully connected to") + " " + server + "."); +} + +void LobbyChat::selfJoined(QString ownName, QString channel) +{ + myNick = ownName; + myLobby->textBrowser_ChatDisplay->append(tr("Joined channel:") + " " + channel + " " + tr("as user") + " " + ownName + "."); + myLobby->textBrowser_ChatDisplay->append(""); + playerJoined(ownName); + myLobby->lineEdit_ChatInput->setEnabled(true); + myLobby->lineEdit_ChatInput->setFocus(); +} + +void LobbyChat::playerJoined(QString playerName) +{ + QTreeWidgetItem *item = new QTreeWidgetItem(myLobby->treeWidget_NickList, 0); + item->setData(0, Qt::DisplayRole, playerName); +} + +void LobbyChat::playerLeft(QString playerName) +{ + QList tmpList(myLobby->treeWidget_NickList->findItems(playerName, Qt::MatchExactly)); + if (!tmpList.empty()) + myLobby->treeWidget_NickList->takeTopLevelItem(myLobby->treeWidget_NickList->indexOfTopLevelItem(tmpList.front())); +} + +void LobbyChat::displayMessage(QString playerName, QString message) { myLobby->textBrowser_ChatDisplay->append(playerName + ": " + message); } @@ -58,7 +89,11 @@ void LobbyChat::checkInputLength(QString string) { void LobbyChat::clearChat() { + myNick = ""; + myLobby->treeWidget_NickList->clear(); myLobby->textBrowser_ChatDisplay->clear(); + myLobby->textBrowser_ChatDisplay->append(tr("Connecting to IRC server...")); + myLobby->lineEdit_ChatInput->setEnabled(false); /* QStringList wordList; wordList << "alpha" << "omega" << "omicron" << "zeta";*/ diff --git a/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.h b/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.h index c7992408..513563da 100644 --- a/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.h +++ b/src/gui/qt/gamelobbydialog/lobbychat/lobbychat.h @@ -35,19 +35,21 @@ public: ~LobbyChat(); -signals: - void signalChatMessage(QString playerName, QString msg); - public slots: void sendMessage(); - void receiveMessage(QString playerName, QString msg); + void connected(QString server); + void selfJoined(QString ownName, QString channel); + void playerJoined(QString playerName); + void playerLeft(QString playerName); + void displayMessage(QString playerName, QString msg); void checkInputLength(QString); void clearChat(); private: gameLobbyDialogImpl *myLobby; - + + QString myNick; // friend class GuiWrapper; }; diff --git a/src/gui/qt/guiwrapper.cpp b/src/gui/qt/guiwrapper.cpp index fece9d58..b4d3b144 100644 --- a/src/gui/qt/guiwrapper.cpp +++ b/src/gui/qt/guiwrapper.cpp @@ -139,5 +139,9 @@ void GuiWrapper::SignalNetClientWaitDialog() { myW->signalShowNetworkStartDialog void GuiWrapper::SignalNetServerSuccess(int actionID) { } void GuiWrapper::SignalNetServerError(int errorID, int osErrorID) { myW->signalNetServerError(errorID, osErrorID); } +void GuiWrapper::SignalIrcConnect(const string &server) { myW->signalIrcConnect(QString::fromUtf8(server.c_str())); } +void GuiWrapper::SignalIrcSelfJoined(const string &nickName, const string &channel) { myW->signalIrcSelfJoined(QString::fromUtf8(nickName.c_str()), QString::fromUtf8(channel.c_str())); } +void GuiWrapper::SignalIrcPlayerJoined(const std::string &nickName) { myW->signalIrcPlayerJoined(QString::fromUtf8(nickName.c_str())); } +void GuiWrapper::SignalIrcPlayerLeft(const std::string &nickName) { myW->signalIrcPlayerLeft(QString::fromUtf8(nickName.c_str())); } void GuiWrapper::SignalIrcChatMsg(const std::string &nickName, const std::string &msg) { myW->signalIrcChatMessage(QString::fromUtf8(nickName.c_str()), QString::fromUtf8(msg.c_str())); } diff --git a/src/gui/qt/guiwrapper.h b/src/gui/qt/guiwrapper.h index 241edd2b..a4c6ee70 100644 --- a/src/gui/qt/guiwrapper.h +++ b/src/gui/qt/guiwrapper.h @@ -118,6 +118,10 @@ public: void SignalNetServerSuccess(int actionID); void SignalNetServerError(int errorID, int osErrorID); + void SignalIrcConnect(const std::string &server); + void SignalIrcSelfJoined(const std::string &nickName, const std::string &channel); + void SignalIrcPlayerJoined(const std::string &nickName); + void SignalIrcPlayerLeft(const std::string &nickName); void SignalIrcChatMsg(const std::string &nickName, const std::string &msg); private: diff --git a/src/gui/qt/mainwindow/mainwindowimpl.cpp b/src/gui/qt/mainwindow/mainwindowimpl.cpp index 56743595..597a4e9e 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.cpp +++ b/src/gui/qt/mainwindow/mainwindowimpl.cpp @@ -677,7 +677,11 @@ mainWindowImpl::mainWindowImpl(ConfigFile *c, QMainWindow *parent) connect(this, SIGNAL(signalNetServerError(int, int)), this, SLOT(networkError(int, int))); connect(this, SIGNAL(signalNetClientGameStart(boost::shared_ptr)), this, SLOT(networkStart(boost::shared_ptr))); - connect(this, SIGNAL(signalIrcChatMessage(QString, QString)), myGameLobbyDialog, SLOT(displayChatMessage(QString, QString))); + connect(this, SIGNAL(signalIrcConnect(QString)), myGameLobbyDialog, SIGNAL(signalChatConnect(QString))); + connect(this, SIGNAL(signalIrcSelfJoined(QString, QString)), myGameLobbyDialog, SIGNAL(signalChatSelfJoined(QString, QString))); + connect(this, SIGNAL(signalIrcPlayerJoined(QString)), myGameLobbyDialog, SIGNAL(signalChatPlayerJoined(QString))); + connect(this, SIGNAL(signalIrcPlayerLeft(QString)), myGameLobbyDialog, SIGNAL(signalChatPlayerLeft(QString))); + connect(this, SIGNAL(signalIrcChatMessage(QString, QString)), myGameLobbyDialog, SIGNAL(signalChatMessage(QString, QString))); //Sound mySDLPlayer = new SDLPlayer(myConfig); diff --git a/src/gui/qt/mainwindow/mainwindowimpl.h b/src/gui/qt/mainwindow/mainwindowimpl.h index b77a8095..69a60c68 100755 --- a/src/gui/qt/mainwindow/mainwindowimpl.h +++ b/src/gui/qt/mainwindow/mainwindowimpl.h @@ -138,6 +138,10 @@ signals: void signalNetClientGameListPlayerLeft(unsigned gameId, unsigned playerId); void signalNetClientGameStart(boost::shared_ptr game); + void signalIrcConnect(QString server); + void signalIrcSelfJoined(QString nickName, QString channel); + void signalIrcPlayerJoined(QString nickName); + void signalIrcPlayerLeft(QString nickName); void signalIrcChatMessage(QString nickName, QString msg); public slots: diff --git a/src/net/common/ircthread.cpp b/src/net/common/ircthread.cpp index f6e37009..1751f987 100644 --- a/src/net/common/ircthread.cpp +++ b/src/net/common/ircthread.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include using namespace std; @@ -34,16 +36,78 @@ struct IrcContext string channel; }; -void -irc_connect(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned count) +void irc_auto_rename_nick(irc_session_t *session) { IrcContext *context = (IrcContext *) irc_get_ctx(session); + // Automatically rename the nick on collision. + // First: Try to append the string "Lobby". + if (context->nick.find("|Lobby") == string::npos) + context->nick = context->nick + "|Lobby"; + else + { + // This didn't work out. Append a number or increment it. + string::reverse_iterator end = context->nick.rbegin(); + if (!context->nick.empty() && isdigit(*end)) + { + if (*end != '9') + *end = (*end) + 1; + else + context->nick = context->nick + "0"; + } + else + context->nick = context->nick + "1"; + } + irc_cmd_nick(session, context->nick.c_str()); +} + +void irc_notify_player_list(irc_session_t *session, const char *players) +{ + IrcContext *context = (IrcContext *) irc_get_ctx(session); + + istringstream input(players); + string name; + input >> name; + while (!input.fail() && !input.eof()) + { + if (name != context->nick) + context->ircThread.GetCallback().SignalIrcPlayerJoined(name); + input >> name; + } +} + +void +irc_event_connect(irc_session_t *session, const char *irc_event, const char *origin, const char **params, unsigned count) +{ + IrcContext *context = (IrcContext *) irc_get_ctx(session); + + context->ircThread.GetCallback().SignalIrcConnect(origin); irc_cmd_join(session, context->channel.c_str(), 0); } void -irc_channel(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned count) +irc_event_join(irc_session_t *session, const char *irc_event, const char *origin, const char **params, unsigned count) +{ + // someone joined the channel. + IrcContext *context = (IrcContext *) irc_get_ctx(session); + + if (context->nick == origin) + context->ircThread.GetCallback().SignalIrcSelfJoined(context->nick, context->channel); + else + context->ircThread.GetCallback().SignalIrcPlayerJoined(origin); +} + +void +irc_event_leave(irc_session_t *session, const char *irc_event, const char *origin, const char **params, unsigned count) +{ + // someone left the channel. + IrcContext *context = (IrcContext *) irc_get_ctx(session); + + context->ircThread.GetCallback().SignalIrcPlayerLeft(origin); +} + +void +irc_event_channel(irc_session_t *session, const char *irc_event, const char *origin, const char **params, unsigned count) { IrcContext *context = (IrcContext *) irc_get_ctx(session); @@ -55,6 +119,23 @@ irc_channel(irc_session_t *session, const char *event, const char *origin, const } } +void +irc_event_numeric(irc_session_t * session, unsigned irc_event, const char *origin, const char **params, unsigned count) +{ + switch (irc_event) + { + case LIBIRC_RFC_ERR_NICKNAMEINUSE : + case LIBIRC_RFC_ERR_NICKCOLLISION : + irc_auto_rename_nick(session); + break; + case LIBIRC_RFC_RPL_TOPIC : + break; + case LIBIRC_RFC_RPL_NAMREPLY : + if (count >= 4) + irc_notify_player_list(session, params[3]); + break; + } +} IrcThread::IrcThread(IrcCallback &callback) : m_callback(callback) @@ -69,7 +150,7 @@ IrcThread::~IrcThread() void IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6, const std::string &nick, const std::string &channel) { - if (IsRunning()) + if (IsRunning() || serverAddress.empty() || nick.empty() || channel.empty()) return; // TODO: throw exception IrcContext &context = GetContext(); @@ -83,15 +164,15 @@ IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6 irc_callbacks_t callbacks; memset (&callbacks, 0, sizeof(callbacks)); - callbacks.event_connect = irc_connect; - //callbacks.event_join + callbacks.event_connect = irc_event_connect; + callbacks.event_join = irc_event_join; //callbacks.event_nick - //callbacks.event_quit - //callbacks.event_part + callbacks.event_quit = irc_event_leave; + callbacks.event_part = irc_event_leave; //callbacks.event_mode //callbacks.event_topic //callbacks.event_kick - callbacks.event_channel = irc_channel; + callbacks.event_channel = irc_event_channel; //callbacks.event_privmsg //callbacks.event_notice //callbacks.event_invite @@ -99,7 +180,7 @@ IrcThread::Init(const std::string &serverAddress, unsigned serverPort, bool ipv6 //callbacks.event_ctcp_rep //callbacks.event_ctcp_action //callbacks.event_unknown - //callbacks.event_numeric + callbacks.event_numeric = irc_event_numeric; //callbacks.event_dcc_chat_req //callbacks.event_dcc_send_req diff --git a/src/net/irccallback.h b/src/net/irccallback.h index f9dccb0e..08615a5b 100644 --- a/src/net/irccallback.h +++ b/src/net/irccallback.h @@ -28,6 +28,10 @@ class IrcCallback public: virtual ~IrcCallback(); + virtual void SignalIrcConnect(const std::string &server) = 0; + virtual void SignalIrcSelfJoined(const std::string &nickName, const std::string &channel) = 0; + virtual void SignalIrcPlayerJoined(const std::string &nickName) = 0; + virtual void SignalIrcPlayerLeft(const std::string &nickName) = 0; virtual void SignalIrcChatMsg(const std::string &nickName, const std::string &msg) = 0; }; diff --git a/src/session.cpp b/src/session.cpp index c52e17b7..fc1fe262 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -334,13 +334,17 @@ bool Session::isNetworkServerRunning() const GameInfo Session::getClientGameInfo(unsigned playerId) { - assert(myNetClient); - return myNetClient->GetGameInfo(playerId); + GameInfo info; + if (myNetClient) + info = myNetClient->GetGameInfo(playerId); + return info; } PlayerInfo Session::getClientPlayerInfo(unsigned playerId) { - assert(myNetClient); - return myNetClient->GetPlayerInfo(playerId); + PlayerInfo info; + if (myNetClient) + info = myNetClient->GetPlayerInfo(playerId); + return info; }