From aa08b44343c5d455b015f2e5ac4cd9ea7d0e348e Mon Sep 17 00:00:00 2001 From: defnax <9952056+defnax@users.noreply.github.com> Date: Wed, 7 Jan 2026 17:06:10 +0100 Subject: [PATCH 1/6] new changes for gxs & gxstunnel --- RetroChessPlugin.cpp | 6 ++ RetroChessPlugin.h | 4 ++ gui/RetroChessChatWidgetHolder.cpp | 40 ++++++----- gui/chess.cpp | 87 +++++++++++++++++++++-- gui/chess.h | 4 ++ gui/tile.cpp | 6 +- interface/rsRetroChess.h | 9 +++ services/p3RetroChess.cc | 107 ++++++++++++++++++++++++++++- services/p3RetroChess.h | 36 +++++++++- services/rsRetroChessItems.h | 1 + 10 files changed, 271 insertions(+), 29 deletions(-) diff --git a/RetroChessPlugin.cpp b/RetroChessPlugin.cpp index 5bd9144..a2f3765 100644 --- a/RetroChessPlugin.cpp +++ b/RetroChessPlugin.cpp @@ -32,6 +32,7 @@ #include "gui/RetroChessChatWidgetHolder.h" #include +#include #include #include @@ -90,6 +91,7 @@ RetroChessPlugin::RetroChessPlugin() void RetroChessPlugin::setInterfaces(RsPlugInInterfaces &interfaces) { mPeers = interfaces.mPeers; + mGxsTunnels = interfaces.mGxsTunnels; } /*ConfigPage *RetroChessPlugin::qt_config_page() const @@ -145,6 +147,10 @@ p3Service *RetroChessPlugin::p3_service() const void RetroChessPlugin::setPlugInHandler(RsPluginHandler *pgHandler) { mPlugInHandler = pgHandler; + + if (mGxsTunnels) { + mGxsTunnels->registerClientService(RETRO_CHESS_GXS_TUNNEL_SERVICE_ID, mGxsTunnelClient); + } } QIcon *RetroChessPlugin::qt_icon() const diff --git a/RetroChessPlugin.h b/RetroChessPlugin.h index c2e6fee..ed05ad7 100644 --- a/RetroChessPlugin.h +++ b/RetroChessPlugin.h @@ -26,6 +26,7 @@ /*libretroshare"*/ #include +#include #include "gui/NEMainpage.h" @@ -76,6 +77,9 @@ class RetroChessPlugin: public RsPlugin mutable QIcon *mIcon; mutable MainPage* mainpage ; + RsGxsTunnelService *mGxsTunnels; + RsGxsTunnelClientService *mGxsTunnelClient; + RetroChessNotify *mRetroChessNotify ; RetroChessGUIHandler *mRetroChessGUIHandler ; }; diff --git a/gui/RetroChessChatWidgetHolder.cpp b/gui/RetroChessChatWidgetHolder.cpp index 29e7b8c..2cc1166 100644 --- a/gui/RetroChessChatWidgetHolder.cpp +++ b/gui/RetroChessChatWidgetHolder.cpp @@ -30,6 +30,7 @@ #include "RetroChessChatWidgetHolder.h" +#include #include #include @@ -41,7 +42,6 @@ RetroChessChatWidgetHolder::RetroChessChatWidgetHolder(ChatWidget *chatWidget, R QIcon icon ; icon.addPixmap(QPixmap(IMAGE_RetroChess)) ; - playChessButton = new QToolButton ; playChessButton->setIcon(icon) ; playChessButton->setToolTip(tr("Invite Friend to Chess")); @@ -111,29 +111,37 @@ void RetroChessChatWidgetHolder::chessnotify(RsPeerId from_peer_id) void RetroChessChatWidgetHolder::chessPressed() { - RsPeerId peer_id = mChatWidget->getChatId().toPeerId();//TODO support GXSID - if (rsRetroChess->hasInviteFrom(peer_id)) - { + ChatId chatId = mChatWidget->getChatId(); + if (chatId.isDistantChatId()) { + rsRetroChess->sendGxsInvite(chatId.toGxsId()); + } else { + RsPeerId peer_id = chatId.toPeerId(); + + if (rsRetroChess->hasInviteFrom(peer_id)){ + rsRetroChess->acceptedInvite(peer_id); + mRetroChessNotify->notifyChessStart(peer_id); + return; + } - rsRetroChess->acceptedInvite(peer_id); - mRetroChessNotify->notifyChessStart(peer_id); - return; + rsRetroChess->sendInvite(peer_id); - } - rsRetroChess->sendInvite(peer_id); - - QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); - mChatWidget->addChatMsg(true, tr("Chess Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + mChatWidget->addChatMsg(true, tr("Chess Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() , tr("You're now inviting %1 to play Chess").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + } } void RetroChessChatWidgetHolder::chessStart() { - RsPeerId peer_id = mChatWidget->getChatId().toPeerId();//TODO support GXSID - - rsRetroChess->acceptedInvite(peer_id); - mRetroChessNotify->notifyChessStart(peer_id); + ChatId chatId = mChatWidget->getChatId(); + if (chatId.isDistantChatId()) { + rsRetroChess->acceptedInviteGxs(chatId.toDistantChatId()); + } else { + RsPeerId peer_id = chatId.toPeerId(); + rsRetroChess->acceptedInvite(peer_id); + mRetroChessNotify->notifyChessStart(peer_id); + } return; } diff --git a/gui/chess.cpp b/gui/chess.cpp index 68277e0..5ab2312 100644 --- a/gui/chess.cpp +++ b/gui/chess.cpp @@ -26,10 +26,69 @@ #include "gui/common/AvatarDefs.h" #include "../services/p3RetroChess.h" +// NEW: Constructor for Distant GXS Identity +RetroChessWindow::RetroChessWindow(const RsGxsId &gxsId, int player, QWidget *parent) : + QWidget(parent), + m_ui(new Ui::RetroChessWindow), + mGxsId(gxsId), + mIsGxs(true) +{ + m_ui->setupUi(this); + mPeerId = gxsId.toStdString(); // Use string representation for internal tracking + + m_ui->m_player1_result->hide(); + m_ui->m_player2_result->hide(); + m_ui->m_status_bar->hide(); + + m_flag_finished = 0; // set as unfinish + + //tile = { { NULL } }; + count=0; + turn=1; // white first + max=0; + texp = new int[60]; + + setGeometry(0,0,1370,700); + + // Resolve our own primary GXS ID + std::list ownIds; + rsIdentity->getOwnIds(ownIds); + RsGxsId myGxsId = ownIds.empty() ? RsGxsId() : ownIds.front(); + + if (player) { // local player as black + // Note: For GXS we track identities rather than PeerIds + player_str = " (1)"; + m_localplayer_turn = 0; + + RsIdentityDetails d1, d2; + rsIdentity->getIdDetails(myGxsId, d1); + rsIdentity->getIdDetails(gxsId, d2); + p1name = d1.mNickname; + p2name = d2.mNickname; + } else { // local player as white + player_str = " (2)"; + m_localplayer_turn = 1; + + RsIdentityDetails d1, d2; + rsIdentity->getIdDetails(gxsId, d1); + rsIdentity->getIdDetails(myGxsId, d2); + p1name = d1.mNickname; + p2name = d2.mNickname; + } + + QString title = QString::fromUtf8(p2name.c_str()) + " Playing Chess against " + QString::fromUtf8(p1name.c_str()) + player_str; + + setWindowTitle(title); + initAccessories(); + playerTurnNotice(); + initChessBoard(); +} + RetroChessWindow::RetroChessWindow(std::string peerid, int player, QWidget *parent) : QWidget(parent), m_ui( new Ui::RetroChessWindow() ), - mPeerId(peerid) + mPeerId(peerid), + mIsGxs(false) //ui(new Ui::RetroChessWindow) { m_ui->setupUi( this ); @@ -125,7 +184,11 @@ void RetroChessWindow::initAccessories() void RetroChessWindow::closeEvent(QCloseEvent *event) { // send leave message - rsRetroChess->player_leave(this->mPeerId); + if (mIsGxs) { + rsRetroChess->player_leave_gxs(this->mGxsId); + } else { + rsRetroChess->player_leave(mPeerId); + } QWidget::closeEvent(event); } @@ -998,10 +1061,22 @@ int RetroChessWindow::resultJudge() void RetroChessWindow::showPlayerLeaveMsg() { - std::string player_name = rsPeers->getPeerName( RsPeerId(mPeerId )); - QString status_msg(player_name.c_str()); - status_msg += " has left"; - m_ui->m_status_bar->setText( status_msg ); + QString name; + if (mIsGxs) { + // Resolve GXS nickname + RsIdentityDetails details; + if (rsIdentity->getIdDetails(mGxsId, details)) { + name = QString::fromUtf8(details.mNickname.c_str()); + } else { + name = tr("Distant Friend"); + } + } else { + // Resolve Peer name + name = QString::fromStdString(rsPeers->getPeerName(RsPeerId(mPeerId))); + } + + QString status_msg = name + tr(" has left"); + m_ui->m_status_bar->setText(status_msg); m_ui->m_status_bar->setVisible(true); } diff --git a/gui/chess.h b/gui/chess.h index 6e30272..5576813 100644 --- a/gui/chess.h +++ b/gui/chess.h @@ -27,6 +27,7 @@ #include #include "retroshare/rspeers.h" +#include "retroshare/rsidentity.h" #include @@ -55,9 +56,12 @@ class RetroChessWindow : public QWidget public: std::string mPeerId; explicit RetroChessWindow(std::string peerid, int player = 0, QWidget *parent = 0); + explicit RetroChessWindow(const RsGxsId &gxsId, int player = 0, QWidget *parent = 0); ~RetroChessWindow(); int currentplayer; int myid; + RsGxsId mGxsId; // Store GXS identity if using a tunnel + bool mIsGxs; //from global diff --git a/gui/tile.cpp b/gui/tile.cpp index 681af84..dd0bd16 100644 --- a/gui/tile.cpp +++ b/gui/tile.cpp @@ -48,7 +48,11 @@ void Tile::mousePressEvent(QMouseEvent *event) if((chess_window_p)->m_localplayer_turn == (chess_window_p)->turn) { validate( ++(chess_window_p)->count ); - rsRetroChess->chess_click(peer_id, this->row,this->col,(chess_window_p)->count); + if ((chess_window_p)->mIsGxs) { + rsRetroChess->chess_click_gxs((chess_window_p)->mGxsId, this->row,this->col, (chess_window_p)->count); + } else { + rsRetroChess->chess_click((chess_window_p)->mPeerId, this->row,this->col, (chess_window_p)->count); + } } // not local player's turn } diff --git a/interface/rsRetroChess.h b/interface/rsRetroChess.h index 3e715d7..10ac9df 100644 --- a/interface/rsRetroChess.h +++ b/interface/rsRetroChess.h @@ -53,6 +53,15 @@ class RsRetroChess virtual void acceptedInvite(RsPeerId peerID) = 0; virtual void gotInvite(RsPeerId peerID) = 0; virtual void sendInvite(RsPeerId peerID) = 0; + + // New GXSID & Tunneling methods + virtual void chess_click_gxs(const RsGxsId &gxs_id, int col, int row, int count) = 0; + virtual void player_leave_gxs(const RsGxsId &gxs_id) = 0; + virtual void requestGxsTunnel(const RsGxsId &gxsId) = 0; + virtual void sendGxsInvite(const RsGxsId &gxsId) = 0; + virtual void addChessFriend(const RsGxsId &gxsId) = 0; + virtual void acceptedInviteGxs(const RsGxsId &gxsId) = 0; + }; diff --git a/services/p3RetroChess.cc b/services/p3RetroChess.cc index 912ec51..385468f 100644 --- a/services/p3RetroChess.cc +++ b/services/p3RetroChess.cc @@ -25,6 +25,7 @@ #include "pqi/p3linkmgr.h" #include #include +#include "retroshare/rsmsgs.h" #include // for std::istringstream @@ -111,10 +112,11 @@ int p3RetroChess::tick() #ifdef DEBUG_RetroChess std::cerr << "ticking p3RetroChess" << std::endl; #endif + // Call your GXS polling logic + handleGxsTick(); - //processIncoming(); - //sendPackets(); - + // Call the base class tick if necessary, or return 0 + // Returning 0 tells the core this service is idle for this slice return 0; } @@ -417,3 +419,102 @@ RsSerialiser *p3RetroChess::setupSerialiser() return rsSerialiser ; } + +void p3RetroChess::chess_click_gxs(const RsGxsId &gxs_id, int col, int row, int count) +{ + if (mActiveTunnels.find(gxs_id) == mActiveTunnels.end()) { + // Tunnel not ready, try to re-open + sendGxsInvite(gxs_id); + return; + } + + RsGxsTunnelId tunnel_id = mActiveTunnels[gxs_id]; + + // Create a data item for the move + RsRetroChessDataItem *item = new RsRetroChessDataItem(); + item->m_msg = QString("%1,%2,%3").arg(col).arg(row).arg(count).toStdString(); + + // Send raw data through the secured tunnel + mGxsTunnel->sendData(tunnel_id, item); +} + +void p3RetroChess::requestGxsTunnel(const RsGxsId &gxsId) +{ + // Implementation: This triggers the async tunnel request + sendGxsInvite(gxsId); +} + +void p3RetroChess::sendGxsInvite(const RsGxsId &to_gxs_id) +{ + RsGxsId from_gxs_id; + std::list ownIds; + rsIdentity->getOwnIds(ownIds); + if (ownIds.empty()) return; + from_gxs_id = ownIds.front(); + + RsGxsTunnelId tunnel_id; + uint32_t error_code; + + // Open a tunnel using mGxsTunnel (Async Request) + if (mGxsTunnel->requestSecuredTunnel( + to_gxs_id, from_gxs_id, tunnel_id, + RETRO_CHESS_GXS_TUNNEL_SERVICE_ID, error_code)) + { + mPendingTunnels[to_gxs_id] = tunnel_id; + std::cout << "Chess Tunnel requested. Pending ID: " << tunnel_id << std::endl; + } +} + +void p3RetroChess::handleGxsTick() +{ + // Periodically check status of pending tunnels + auto it = mPendingTunnels.begin(); + while (it != mPendingTunnels.end()) { + RsGxsTunnelInfo tinfo; + if (mGxsTunnel->getTunnelInfo(it->second, tinfo)) { + if (tinfo.status == RS_GXS_TUNNEL_STATUS_CONNECTED) { + // 1.c - Established! Move to active and notify UI + mActiveTunnels[it->first] = it->second; + mRetroChessNotify->notifyGxsTunnelReady(it->first); + it = mPendingTunnels.erase(it); + continue; + } else if (tinfo.status == RS_GXS_TUNNEL_STATUS_CLOSED || tinfo.status == RS_GXS_TUNNEL_STATUS_FAILED) { + it = mPendingTunnels.erase(it); + continue; + } + } + ++it; + } +} + +// Update this signature to include gxs_id and am_I_client_side +void p3RetroChess::handleRawData(const RsGxsId& gxs_id, + const RsGxsTunnelId& tunnel_id, + bool am_I_client_side, + const uint8_t *data, + uint32_t data_size) +{ + // Use the de-serialization constructor + uint32_t temp_size = data_size; + RsRetroChessDataItem item((void*)data, temp_size); + + QString qMsg = QString::fromStdString(item.m_msg); + QStringList parts = qMsg.split(","); + + if (parts.size() == 3) { + int col = parts[0].toInt(); + int row = parts[1].toInt(); + int count = parts[2].toInt(); + + // Use the gxs_id provided by the tunnel to notify the UI + mRetroChessNotify->notifyChessMoveGxs(gxs_id, col, row, count); + } +} + +void p3RetroChess::player_leave_gxs(const RsGxsId &gxs_id) { + // Logic to close tunnel + if(mActiveTunnels.count(gxs_id)) { + mGxsTunnel->closeExistingTunnel(mActiveTunnels[gxs_id], RETRO_CHESS_GXS_TUNNEL_SERVICE_ID); + mActiveTunnels.erase(gxs_id); + } +} \ No newline at end of file diff --git a/services/p3RetroChess.h b/services/p3RetroChess.h index 2ff1387..3174e82 100644 --- a/services/p3RetroChess.h +++ b/services/p3RetroChess.h @@ -30,12 +30,16 @@ #include "serialiser/rstlvbase.h" #include "rsitems/rsconfigitems.h" #include "plugins/rspqiservice.h" +#include "retroshare/rsidentity.h" +#include + #include class p3LinkMgr; class RetroChessNotify ; - +// Use a valid 16-bit Service ID (below 0xFFFF) +#define RETRO_CHESS_GXS_TUNNEL_SERVICE_ID 0xC4E5 //!The RS VoIP Test service. /** @@ -61,7 +65,7 @@ class p3RetroChess: public RsPQIService, public RsRetroChess * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar * @see NotifyBase */ - virtual int tick(); + virtual int tick() override;; virtual int status(); virtual bool recvItem(RsItem *item); @@ -101,13 +105,39 @@ class p3RetroChess: public RsPQIService, public RsRetroChess void gotInvite(RsPeerId peerID); void acceptedInvite(RsPeerId peerID); void sendInvite(RsPeerId peerID); -private: + void player_leave_gxs(const RsGxsId &gxs_id); + void addChessFriend(const RsGxsId &gxsId); + void sendGxsInvite(const RsGxsId &toGxsId); + void acceptedInviteGxs(const RsGxsId &gxsId); + void chess_click_gxs(const RsGxsId &gxs_id, int col, int row, int count); + virtual void requestGxsTunnel(const RsGxsId &gxsId) override; + + // Async tunnel management + void handleGxsTick(); // Called periodically by the core + + virtual uint32_t getGxsTunnelServiceId() const override { + return RETRO_CHESS_GXS_TUNNEL_SERVICE_ID; + } + + // Fix handleRawData signature + void handleRawData(const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id, bool am_I_client_side, const uint8_t *data, uint32_t data_size); + +private: + // Helper to find which friend sent the data based on the tunnel ID + RsGxsId findGxsIdByTunnel(const RsGxsTunnelId& tunnel_id); std::set invitesTo; std::set invitesFrom; + void handleData(RsRetroChessDataItem*) ; + // Tracks GXS IDs that we are currently trying to connect to + std::map mPendingTunnels; + // Tracks established tunnels ready for data + std::map mActiveTunnels; + + RsGxsTunnelService *mGxsTunnels; RsMutex mRetroChessMtx; //RsPeerId mPeerID; diff --git a/services/rsRetroChessItems.h b/services/rsRetroChessItems.h index 1e4a563..6166419 100644 --- a/services/rsRetroChessItems.h +++ b/services/rsRetroChessItems.h @@ -98,6 +98,7 @@ class RsRetroChessDataItem: public RsRetroChessItem uint32_t flags ; uint32_t data_size ; std::string m_msg; + RsGxsId m_gxsId; // Optional: track origin GXS ID in the item }; From 064508acc5e74b3d5d1abc0c026c073757d49e1c Mon Sep 17 00:00:00 2001 From: defnax <9952056+defnax@users.noreply.github.com> Date: Sun, 11 Jan 2026 00:48:10 +0100 Subject: [PATCH 2/6] update gxs notify & tunnel check --- RetroChessPlugin.cpp | 1 + gui/RetroChessNotify.cpp | 10 ++++++++++ gui/RetroChessNotify.h | 3 +++ 3 files changed, 14 insertions(+) diff --git a/RetroChessPlugin.cpp b/RetroChessPlugin.cpp index a2f3765..6f17215 100644 --- a/RetroChessPlugin.cpp +++ b/RetroChessPlugin.cpp @@ -130,6 +130,7 @@ ChatWidgetHolder *RetroChessPlugin::qt_get_chat_widget_holder(ChatWidget *chatWi case ChatWidget::CHATTYPE_UNKNOWN: case ChatWidget::CHATTYPE_LOBBY: case ChatWidget::CHATTYPE_DISTANT: + return new RetroChessChatWidgetHolder(chatWidget, mRetroChessNotify); break; } diff --git a/gui/RetroChessNotify.cpp b/gui/RetroChessNotify.cpp index 8b2fb5a..74ed28d 100644 --- a/gui/RetroChessNotify.cpp +++ b/gui/RetroChessNotify.cpp @@ -51,3 +51,13 @@ void RetroChessNotify::notifyChessInvite(const RsPeerId &peer_id) emit chessInvited(peer_id) ; } + +void RetroChessNotify::notifyChessMoveGxs(const RsGxsId &gxs_id, int col, int row, int count) +{ + emit chessMoveGxs(gxs_id, col, row, count); +} + +void RetroChessNotify::notifyGxsTunnelReady(const RsGxsId &gxs_id) +{ + emit gxsTunnelReady(gxs_id); +} diff --git a/gui/RetroChessNotify.h b/gui/RetroChessNotify.h index 4fdd0fa..5bb0d5a 100644 --- a/gui/RetroChessNotify.h +++ b/gui/RetroChessNotify.h @@ -47,6 +47,9 @@ class RetroChessNotify : public QObject void chessStart(const RsPeerId &peer_id) ; void chessInvited(const RsPeerId &peer_id) ; + void chessMoveGxs(const RsGxsId &gxs_id, int col, int row, int count); + void gxsTunnelReady(const RsGxsId &gxs_id); + public slots: }; From be315434879a8eef8967c6ffadd4fc5b7b917453 Mon Sep 17 00:00:00 2001 From: defnax <9952056+defnax@users.noreply.github.com> Date: Sun, 11 Jan 2026 00:49:08 +0100 Subject: [PATCH 3/6] changes for handlerawdata --- services/p3RetroChess.cc | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/services/p3RetroChess.cc b/services/p3RetroChess.cc index 385468f..956128c 100644 --- a/services/p3RetroChess.cc +++ b/services/p3RetroChess.cc @@ -440,8 +440,13 @@ void p3RetroChess::chess_click_gxs(const RsGxsId &gxs_id, int col, int row, int void p3RetroChess::requestGxsTunnel(const RsGxsId &gxsId) { - // Implementation: This triggers the async tunnel request - sendGxsInvite(gxsId); + // Check if we already have a tunnel + if (mActiveTunnels.count(gxsId)) { + mRetroChessNotify->notifyGxsTunnelReady(gxsId); + return; + } + // Otherwise, start the async tunnel request + this->sendGxsInvite(gxsId); } void p3RetroChess::sendGxsInvite(const RsGxsId &to_gxs_id) @@ -494,10 +499,25 @@ void p3RetroChess::handleRawData(const RsGxsId& gxs_id, const uint8_t *data, uint32_t data_size) { - // Use the de-serialization constructor + // Identify who sent the data using the Tunnel ID helper + // This ensures we have a record of this tunnel in our mActiveTunnels map + RsGxsId sender_id = findGxsIdByTunnel(tunnel_id); + + // Fallback: If the map lookup fails but the API provided a valid gxs_id, use that + if (sender_id.isNull() && !gxs_id.isNull()) { + sender_id = gxs_id; + } + + if (sender_id.isNull()) { + std::cerr << "p3RetroChess::handleRawData: Received data from unknown tunnel " << tunnel_id << std::endl; + return; + } + + // Deserialize the raw bytes into the Chess Data Item uint32_t temp_size = data_size; RsRetroChessDataItem item((void*)data, temp_size); + // Parse the move protocol (Format: "col,row,count") QString qMsg = QString::fromStdString(item.m_msg); QStringList parts = qMsg.split(","); @@ -506,8 +526,8 @@ void p3RetroChess::handleRawData(const RsGxsId& gxs_id, int row = parts[1].toInt(); int count = parts[2].toInt(); - // Use the gxs_id provided by the tunnel to notify the UI - mRetroChessNotify->notifyChessMoveGxs(gxs_id, col, row, count); + // Notify the GUI with the resolved GXS Identity + mRetroChessNotify->notifyChessMoveGxs(sender_id, col, row, count); } } @@ -517,4 +537,13 @@ void p3RetroChess::player_leave_gxs(const RsGxsId &gxs_id) { mGxsTunnel->closeExistingTunnel(mActiveTunnels[gxs_id], RETRO_CHESS_GXS_TUNNEL_SERVICE_ID); mActiveTunnels.erase(gxs_id); } +} + +RsGxsId p3RetroChess::findGxsIdByTunnel(const RsGxsTunnelId& tunnel_id) +{ + std::map::iterator it; + for (it = mActiveTunnels.begin(); it != mActiveTunnels.end(); ++it) { + if (it->second == tunnel_id) return it->first; + } + return RsGxsId(); } \ No newline at end of file From a1a2e2a6cd0e837e612d44edf32a69a2be80c342 Mon Sep 17 00:00:00 2001 From: jolavillette Date: Sun, 11 Jan 2026 09:29:11 +0100 Subject: [PATCH 4/6] fix compilation of gxschess-v2 branch --- RetroChessPlugin.cpp | 22 +++++++----- RetroChessPlugin.h | 3 +- gui/RetroChessChatWidgetHolder.cpp | 4 +-- gui/RetroChessNotify.h | 5 +++ gui/chess.cpp | 7 ++++ services/p3RetroChess.cc | 58 +++++++++++++++++++----------- services/p3RetroChess.h | 9 +++-- services/rsRetroChessItems.h | 2 +- 8 files changed, 74 insertions(+), 36 deletions(-) diff --git a/RetroChessPlugin.cpp b/RetroChessPlugin.cpp index 6f17215..967ba79 100644 --- a/RetroChessPlugin.cpp +++ b/RetroChessPlugin.cpp @@ -139,19 +139,23 @@ ChatWidgetHolder *RetroChessPlugin::qt_get_chat_widget_holder(ChatWidget *chatWi p3Service *RetroChessPlugin::p3_service() const { - if(mRetroChess == NULL) - rsRetroChess = mRetroChess = new p3RetroChess(mPlugInHandler,mRetroChessNotify) ; // , 3600 * 24 * 30 * 6); // 6 Months - - return mRetroChess ; + if(mRetroChess == NULL) + { + // Create the service + rsRetroChess = mRetroChess = new p3RetroChess(mPlugInHandler, mRetroChessNotify); + + // Register it for GXS Tunnels immediately if the interface is available + if (mGxsTunnels) { + mGxsTunnels->registerClientService(RETRO_CHESS_GXS_TUNNEL_SERVICE_ID, mRetroChess); + } + } + return mRetroChess; } void RetroChessPlugin::setPlugInHandler(RsPluginHandler *pgHandler) { - mPlugInHandler = pgHandler; - - if (mGxsTunnels) { - mGxsTunnels->registerClientService(RETRO_CHESS_GXS_TUNNEL_SERVICE_ID, mGxsTunnelClient); - } + mPlugInHandler = pgHandler; + // No need to register here if done in p3_service } QIcon *RetroChessPlugin::qt_icon() const diff --git a/RetroChessPlugin.h b/RetroChessPlugin.h index ed05ad7..0b0c0a1 100644 --- a/RetroChessPlugin.h +++ b/RetroChessPlugin.h @@ -78,8 +78,7 @@ class RetroChessPlugin: public RsPlugin mutable MainPage* mainpage ; RsGxsTunnelService *mGxsTunnels; - RsGxsTunnelClientService *mGxsTunnelClient; - + RsGxsTunnelService::RsGxsTunnelClientService *mGxsTunnelClient; RetroChessNotify *mRetroChessNotify ; RetroChessGUIHandler *mRetroChessGUIHandler ; }; diff --git a/gui/RetroChessChatWidgetHolder.cpp b/gui/RetroChessChatWidgetHolder.cpp index 2cc1166..cad590c 100644 --- a/gui/RetroChessChatWidgetHolder.cpp +++ b/gui/RetroChessChatWidgetHolder.cpp @@ -113,7 +113,7 @@ void RetroChessChatWidgetHolder::chessPressed() { ChatId chatId = mChatWidget->getChatId(); if (chatId.isDistantChatId()) { - rsRetroChess->sendGxsInvite(chatId.toGxsId()); + rsRetroChess->sendGxsInvite(RsGxsId(chatId.toDistantChatId().toStdString())); } else { RsPeerId peer_id = chatId.toPeerId(); @@ -136,7 +136,7 @@ void RetroChessChatWidgetHolder::chessStart() { ChatId chatId = mChatWidget->getChatId(); if (chatId.isDistantChatId()) { - rsRetroChess->acceptedInviteGxs(chatId.toDistantChatId()); + rsRetroChess->acceptedInviteGxs(RsGxsId(chatId.toDistantChatId().toStdString())); } else { RsPeerId peer_id = chatId.toPeerId(); rsRetroChess->acceptedInvite(peer_id); diff --git a/gui/RetroChessNotify.h b/gui/RetroChessNotify.h index 5bb0d5a..e2f70a8 100644 --- a/gui/RetroChessNotify.h +++ b/gui/RetroChessNotify.h @@ -40,6 +40,11 @@ class RetroChessNotify : public QObject void notifyReceivedMsg(const RsPeerId &peer_id, QString str) ; void notifyChessStart(const RsPeerId &peer_id) ; void notifyChessInvite(const RsPeerId &peer_id) ; + /** Notify the UI of a chess move received via a GXS tunnel */ + void notifyChessMoveGxs(const RsGxsId &gxs_id, int col, int row, int count); + + /** Notify the UI that a GXS tunnel is now ready for use */ + void notifyGxsTunnelReady(const RsGxsId &gxs_id); signals: void NeMsgArrived(const RsPeerId &peer_id, QString str) ; // emitted when the peer gets a msg diff --git a/gui/chess.cpp b/gui/chess.cpp index 5ab2312..e606cba 100644 --- a/gui/chess.cpp +++ b/gui/chess.cpp @@ -33,6 +33,13 @@ RetroChessWindow::RetroChessWindow(const RsGxsId &gxsId, int player, QWidget *pa mGxsId(gxsId), mIsGxs(true) { + QString player_str; + if (player == 1) { + player_str = " (1)"; + } else if (player == 2) { + player_str = " (2)"; + } + m_ui->setupUi(this); mPeerId = gxsId.toStdString(); // Use string representation for internal tracking diff --git a/services/p3RetroChess.cc b/services/p3RetroChess.cc index 956128c..e042378 100644 --- a/services/p3RetroChess.cc +++ b/services/p3RetroChess.cc @@ -25,7 +25,7 @@ #include "pqi/p3linkmgr.h" #include #include -#include "retroshare/rsmsgs.h" +//#include "retroshare/rsmsgs.h" #include // for std::istringstream @@ -247,8 +247,6 @@ void p3RetroChess::msg_all(std::string msg) // mServiceControl->getPeersConnected(getServiceInfo().mServiceType, onlineIds); rsPeers->getOnlineList(onlineIds); - double ts = getCurrentTS(); - #ifdef DEBUG_RetroChess std::cerr << "p3RetroChess::msg_all() @ts: " << ts; std::cerr << std::endl; @@ -274,9 +272,6 @@ void p3RetroChess::broadcast_paint(int x, int y) // mServiceControl->getPeersConnected(getServiceInfo().mServiceType, onlineIds); rsPeers->getOnlineList(onlineIds); - double ts = getCurrentTS(); - - std::cout << "READY TO PAINT: " << onlineIds.size() << "\n"; /* prepare packets */ std::list::iterator it; @@ -435,14 +430,14 @@ void p3RetroChess::chess_click_gxs(const RsGxsId &gxs_id, int col, int row, int item->m_msg = QString("%1,%2,%3").arg(col).arg(row).arg(count).toStdString(); // Send raw data through the secured tunnel - mGxsTunnel->sendData(tunnel_id, item); + mGxsTunnels->sendData(tunnel_id, RETRO_CHESS_GXS_TUNNEL_SERVICE_ID, (const uint8_t*)item->m_msg.c_str(), item->m_msg.size()); } void p3RetroChess::requestGxsTunnel(const RsGxsId &gxsId) { // Check if we already have a tunnel if (mActiveTunnels.count(gxsId)) { - mRetroChessNotify->notifyGxsTunnelReady(gxsId); + mNotify->notifyGxsTunnelReady(gxsId); return; } // Otherwise, start the async tunnel request @@ -461,7 +456,7 @@ void p3RetroChess::sendGxsInvite(const RsGxsId &to_gxs_id) uint32_t error_code; // Open a tunnel using mGxsTunnel (Async Request) - if (mGxsTunnel->requestSecuredTunnel( + if (mGxsTunnels->requestSecuredTunnel( to_gxs_id, from_gxs_id, tunnel_id, RETRO_CHESS_GXS_TUNNEL_SERVICE_ID, error_code)) { @@ -472,23 +467,25 @@ void p3RetroChess::sendGxsInvite(const RsGxsId &to_gxs_id) void p3RetroChess::handleGxsTick() { - // Periodically check status of pending tunnels auto it = mPendingTunnels.begin(); while (it != mPendingTunnels.end()) { - RsGxsTunnelInfo tinfo; - if (mGxsTunnel->getTunnelInfo(it->second, tinfo)) { - if (tinfo.status == RS_GXS_TUNNEL_STATUS_CONNECTED) { - // 1.c - Established! Move to active and notify UI + RsGxsTunnelService::GxsTunnelInfo tinfo; + if (mGxsTunnels->getTunnelInfo(it->second, tinfo)) { + // Check if the tunnel is "Connected" (CAN_TALK) + if (tinfo.tunnel_status == RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK) { mActiveTunnels[it->first] = it->second; - mRetroChessNotify->notifyGxsTunnelReady(it->first); + mNotify->notifyGxsTunnelReady(it->first); it = mPendingTunnels.erase(it); continue; - } else if (tinfo.status == RS_GXS_TUNNEL_STATUS_CLOSED || tinfo.status == RS_GXS_TUNNEL_STATUS_FAILED) { + } + // Check for "Closed/Failed" status + else if (tinfo.tunnel_status == RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED || + tinfo.tunnel_status == RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN) { it = mPendingTunnels.erase(it); continue; } } - ++it; + ++it; } } @@ -527,14 +524,14 @@ void p3RetroChess::handleRawData(const RsGxsId& gxs_id, int count = parts[2].toInt(); // Notify the GUI with the resolved GXS Identity - mRetroChessNotify->notifyChessMoveGxs(sender_id, col, row, count); + mNotify->notifyChessMoveGxs(sender_id, col, row, count); } } void p3RetroChess::player_leave_gxs(const RsGxsId &gxs_id) { // Logic to close tunnel if(mActiveTunnels.count(gxs_id)) { - mGxsTunnel->closeExistingTunnel(mActiveTunnels[gxs_id], RETRO_CHESS_GXS_TUNNEL_SERVICE_ID); + mGxsTunnels->closeExistingTunnel(mActiveTunnels[gxs_id], RETRO_CHESS_GXS_TUNNEL_SERVICE_ID); mActiveTunnels.erase(gxs_id); } } @@ -546,4 +543,25 @@ RsGxsId p3RetroChess::findGxsIdByTunnel(const RsGxsTunnelId& tunnel_id) if (it->second == tunnel_id) return it->first; } return RsGxsId(); -} \ No newline at end of file +} + +// services/p3RetroChess.cc + +void p3RetroChess::notifyTunnelStatus(const RsGxsTunnelId& /*tunnel_id*/, uint32_t /*tunnel_status*/) +{ +} + +void p3RetroChess::receiveData(const RsGxsTunnelId& id, unsigned char *data, uint32_t data_size) +{ + this->handleRawData(RsGxsId(), id, false, (const uint8_t*)data, data_size); +} + +void p3RetroChess::connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) +{ + mGxsTunnels = tunnel_service; +} + +bool p3RetroChess::acceptDataFromPeer(const RsGxsId& /*gxs_id*/, const RsGxsTunnelId& /*tunnel_id*/, bool /*am_I_client_side*/) +{ + return true; +} diff --git a/services/p3RetroChess.h b/services/p3RetroChess.h index 3174e82..56dd940 100644 --- a/services/p3RetroChess.h +++ b/services/p3RetroChess.h @@ -47,7 +47,7 @@ class RetroChessNotify ; * This is only used to test Latency for the moment. */ -class p3RetroChess: public RsPQIService, public RsRetroChess +class p3RetroChess: public RsPQIService, public RsRetroChess, public RsGxsTunnelService::RsGxsTunnelClientService // Maybe we inherit from these later - but not needed for now. //, public p3Config, public pqiMonitor { @@ -116,13 +116,18 @@ class p3RetroChess: public RsPQIService, public RsRetroChess // Async tunnel management void handleGxsTick(); // Called periodically by the core - virtual uint32_t getGxsTunnelServiceId() const override { + virtual uint32_t getGxsTunnelServiceId() const { return RETRO_CHESS_GXS_TUNNEL_SERVICE_ID; } // Fix handleRawData signature void handleRawData(const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id, bool am_I_client_side, const uint8_t *data, uint32_t data_size); + virtual void notifyTunnelStatus(const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status) override; + virtual void receiveData(const RsGxsTunnelId& id, unsigned char *data, uint32_t data_size) override; + virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) override; + virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id, bool am_I_client_side) override; + private: // Helper to find which friend sent the data based on the tunnel ID RsGxsId findGxsIdByTunnel(const RsGxsTunnelId& tunnel_id); diff --git a/services/rsRetroChessItems.h b/services/rsRetroChessItems.h index 6166419..623e992 100644 --- a/services/rsRetroChessItems.h +++ b/services/rsRetroChessItems.h @@ -55,7 +55,7 @@ /**************************************************************************/ -const uint16_t RS_SERVICE_TYPE_RetroChess_PLUGIN = 0xc4e55; +const uint16_t RS_SERVICE_TYPE_RetroChess_PLUGIN = 0xc4e5; const uint8_t RS_PKT_SUBTYPE_RetroChess_DATA = 0x01; From da76f46e3046ce2f47fb3c22aa50c853515a4349 Mon Sep 17 00:00:00 2001 From: defnax <9952056+defnax@users.noreply.github.com> Date: Sun, 11 Jan 2026 11:01:02 +0100 Subject: [PATCH 5/6] Fixed compile --- interface/rsRetroChess.h | 2 +- services/p3RetroChess.cc | 13 +++++++++++++ services/p3RetroChess.h | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/interface/rsRetroChess.h b/interface/rsRetroChess.h index 10ac9df..861029c 100644 --- a/interface/rsRetroChess.h +++ b/interface/rsRetroChess.h @@ -59,7 +59,7 @@ class RsRetroChess virtual void player_leave_gxs(const RsGxsId &gxs_id) = 0; virtual void requestGxsTunnel(const RsGxsId &gxsId) = 0; virtual void sendGxsInvite(const RsGxsId &gxsId) = 0; - virtual void addChessFriend(const RsGxsId &gxsId) = 0; + //virtual void addChessFriend(const RsGxsId &gxsId) = 0; virtual void acceptedInviteGxs(const RsGxsId &gxsId) = 0; }; diff --git a/services/p3RetroChess.cc b/services/p3RetroChess.cc index e042378..ecf021e 100644 --- a/services/p3RetroChess.cc +++ b/services/p3RetroChess.cc @@ -465,6 +465,19 @@ void p3RetroChess::sendGxsInvite(const RsGxsId &to_gxs_id) } } +void p3RetroChess::acceptedInviteGxs(const RsGxsId &gxsId) +{ + std::cout << "p3RetroChess: Accepted GXS invite from " << gxsId << std::endl; + + // If we don't have an active tunnel yet, request one now + if (mActiveTunnels.find(gxsId) == mActiveTunnels.end()) { + requestGxsTunnel(gxsId); + } else { + // If tunnel is already ready, tell the GUI to start the game + mNotify->notifyGxsTunnelReady(gxsId); + } +} + void p3RetroChess::handleGxsTick() { auto it = mPendingTunnels.begin(); diff --git a/services/p3RetroChess.h b/services/p3RetroChess.h index 56dd940..58fd7a0 100644 --- a/services/p3RetroChess.h +++ b/services/p3RetroChess.h @@ -107,7 +107,7 @@ class p3RetroChess: public RsPQIService, public RsRetroChess, public RsGxsTunnel void sendInvite(RsPeerId peerID); void player_leave_gxs(const RsGxsId &gxs_id); - void addChessFriend(const RsGxsId &gxsId); + //void addChessFriend(const RsGxsId &gxsId); void sendGxsInvite(const RsGxsId &toGxsId); void acceptedInviteGxs(const RsGxsId &gxsId); void chess_click_gxs(const RsGxsId &gxs_id, int col, int row, int count); From 14c042594cc5f78b2d832571a169902c58b2cd63 Mon Sep 17 00:00:00 2001 From: defnax <9952056+defnax@users.noreply.github.com> Date: Sun, 11 Jan 2026 14:58:57 +0100 Subject: [PATCH 6/6] Added some notifys --- gui/NEMainpage.cpp | 8 +++ gui/NEMainpage.h | 1 + gui/RetroChessChatWidgetHolder.cpp | 93 +++++++++++++++++++++++++++++- gui/RetroChessChatWidgetHolder.h | 2 + gui/RetroChessNotify.cpp | 5 ++ gui/RetroChessNotify.h | 4 ++ 6 files changed, 110 insertions(+), 3 deletions(-) diff --git a/gui/NEMainpage.cpp b/gui/NEMainpage.cpp index 51f8a38..a0386dc 100644 --- a/gui/NEMainpage.cpp +++ b/gui/NEMainpage.cpp @@ -50,6 +50,7 @@ NEMainpage::NEMainpage(QWidget *parent, RetroChessNotify *notify) : connect(mNotify, SIGNAL(NeMsgArrived(RsPeerId,QString)), this, SLOT(NeMsgArrived(RsPeerId,QString))); connect(mNotify, SIGNAL(chessStart(RsPeerId)), this, SLOT(chessStart(RsPeerId))); + connect(mNotify, SIGNAL(chessStartGxs(RsGxsId)), this, SLOT(showChessWindowGxs(RsGxsId))); connect(ui->friendSelectionWidget, SIGNAL(itemSelectionChanged()), this, SLOT(friendSelectionChanged())); // enable/disable the invite button @@ -178,6 +179,13 @@ void NEMainpage::create_chess_window(std::string peer_id, int player_id) ui->active_games->addItem(QString::fromStdString(peer_id)); } +void NEMainpage::showChessWindowGxs(const RsGxsId &gxs_id) +{ + // Open the window with the GXS constructor + RetroChessWindow *win = new RetroChessWindow(gxs_id, 0); + win->show(); +} + // enable the invite button when selected a friend void NEMainpage::enable_inviteButton() { diff --git a/gui/NEMainpage.h b/gui/NEMainpage.h index cf6d72f..8dce420 100644 --- a/gui/NEMainpage.h +++ b/gui/NEMainpage.h @@ -58,6 +58,7 @@ private slots: void friendSelectionChanged(); void NeMsgArrived(const RsPeerId &peer_id, QString str); void chessStart(const RsPeerId &peer_id); + void showChessWindowGxs(const RsGxsId &gxs_id); void on_broadcastButton_clicked(); diff --git a/gui/RetroChessChatWidgetHolder.cpp b/gui/RetroChessChatWidgetHolder.cpp index cad590c..970a210 100644 --- a/gui/RetroChessChatWidgetHolder.cpp +++ b/gui/RetroChessChatWidgetHolder.cpp @@ -51,6 +51,10 @@ RetroChessChatWidgetHolder::RetroChessChatWidgetHolder(ChatWidget *chatWidget, R mChatWidget->addChatBarWidget(playChessButton); connect(playChessButton, SIGNAL(clicked()), this, SLOT(chessPressed())); connect(notify, SIGNAL(chessInvited(RsPeerId)), this, SLOT(chessnotify(RsPeerId))); + connect(notify, SIGNAL(chessInvitedGxs(RsGxsId)), this, SLOT(chessnotifyGxs(RsGxsId))); + // When the p3RetroChess service detects the tunnel is CONNECTED, + // it calls notifyGxsTunnelReady, which emits this signal: + connect(notify, SIGNAL(gxsTunnelReady(RsGxsId)), this, SLOT(handleGxsTunnelReady(RsGxsId))); } @@ -109,11 +113,74 @@ void RetroChessChatWidgetHolder::chessnotify(RsPeerId from_peer_id) } } +void RetroChessChatWidgetHolder::chessnotifyGxs(const RsGxsId &from_gxs_id) +{ + ChatId chatId = mChatWidget->getChatId(); + + // Check if the current chat window matches the GXS ID of the person who invited us + if (!chatId.isDistantChatId()) { + return; + } + + // You need a way to check if an invite exists. + // If you haven't implemented hasInviteFromGxs, you can use the active tunnel status. + if (true) // In GXS, the receipt of the signal itself implies an invite + { + if (mChatWidget) + { + // Get the name from the GXS Identity system + std::string identityName; + RsGxsId nameId = from_gxs_id; + // Attempt to get a readable name for the GXS ID + // If rsIdentity doesn't have a direct getName, we use a placeholder or the ID string + QString buttonName = QString::fromStdString(from_gxs_id.toStdString()).left(8); + + // Clear old buttons for this chat to avoid duplicates + button_map::iterator it = buttonMapTakeChess.begin(); + while (it != buttonMapTakeChess.end()) + { + it = buttonMapTakeChess.erase(it); + } + + // Add the system message and the "Accept" button to the chat history + mChatWidget->addChatMsg(true, tr("Chess Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), + tr("%1 is inviting you to start Chess via GXS. Accept?").arg(buttonName), + ChatWidget::MSGTYPE_SYSTEM); + + RSButtonOnText *button = mChatWidget->getNewButtonOnTextBrowser(tr("Accept GXS Invite")); + button->setToolTip(tr("Accept Chess Invitation")); + + // Apply your specific green styling + button->setStyleSheet(QString("border: 1px solid #199909;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " + "stop: 0 #22c70d, stop: 1 #116a06);")); + + button->updateImage(); + + // Connect to the logic that starts the game/tunnel + connect(button, SIGNAL(clicked()), this, SLOT(chessStart())); + connect(button, SIGNAL(mouseEnter()), this, SLOT(botMouseEnter())); + connect(button, SIGNAL(mouseLeave()), this, SLOT(botMouseLeave())); + + buttonMapTakeChess.insert(buttonName, button); + } + } +} + void RetroChessChatWidgetHolder::chessPressed() { ChatId chatId = mChatWidget->getChatId(); + QString peerName; if (chatId.isDistantChatId()) { rsRetroChess->sendGxsInvite(RsGxsId(chatId.toDistantChatId().toStdString())); + + mChatWidget->addChatMsg(true, tr("RetroChess"), QDateTime::currentDateTime(), + QDateTime::currentDateTime(), + tr("Requesting secure game tunnel..."), + ChatWidget::MSGTYPE_SYSTEM); } else { RsPeerId peer_id = chatId.toPeerId(); @@ -125,10 +192,10 @@ void RetroChessChatWidgetHolder::chessPressed() rsRetroChess->sendInvite(peer_id); - QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); - mChatWidget->addChatMsg(true, tr("Chess Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() - , tr("You're now inviting %1 to play Chess").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); } + mChatWidget->addChatMsg(true, tr("Chess Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("You're now inviting %1 to play Chess").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); } @@ -137,6 +204,15 @@ void RetroChessChatWidgetHolder::chessStart() ChatId chatId = mChatWidget->getChatId(); if (chatId.isDistantChatId()) { rsRetroChess->acceptedInviteGxs(RsGxsId(chatId.toDistantChatId().toStdString())); + + // We wait for the service to signal handleGxsTunnelReady. + mChatWidget->addChatMsg(true, tr("RetroChess"), QDateTime::currentDateTime(), + QDateTime::currentDateTime(), + tr("Establishing secure GXS tunnel..."), + ChatWidget::MSGTYPE_SYSTEM); + + // Notify the UI to open the Chess window for this GXS ID + mRetroChessNotify->notifyChessStartGxs(RsGxsId(chatId.toDistantChatId().toStdString())); } else { RsPeerId peer_id = chatId.toPeerId(); rsRetroChess->acceptedInvite(peer_id); @@ -145,6 +221,17 @@ void RetroChessChatWidgetHolder::chessStart() return; } +void RetroChessChatWidgetHolder::handleGxsTunnelReady(const RsGxsId &gxs_id) +{ + ChatId chatId = mChatWidget->getChatId(); + if (chatId.isDistantChatId()) { + // Now the tunnel is safe to use. Open the window. + mRetroChessNotify->notifyChessStartGxs(gxs_id); + + if (playChessButton) playChessButton->hide(); + } +} + void RetroChessChatWidgetHolder::botMouseEnter() { RSButtonOnText *source = qobject_cast(QObject::sender()); diff --git a/gui/RetroChessChatWidgetHolder.h b/gui/RetroChessChatWidgetHolder.h index 958ba88..0909c46 100644 --- a/gui/RetroChessChatWidgetHolder.h +++ b/gui/RetroChessChatWidgetHolder.h @@ -39,6 +39,8 @@ public slots: void chessStart(); void chessnotify(RsPeerId from_peer_id); + void chessnotifyGxs(const RsGxsId &from_gxs_id); + void handleGxsTunnelReady(const RsGxsId &gxs_id); private slots: void botMouseEnter(); diff --git a/gui/RetroChessNotify.cpp b/gui/RetroChessNotify.cpp index 74ed28d..0770945 100644 --- a/gui/RetroChessNotify.cpp +++ b/gui/RetroChessNotify.cpp @@ -61,3 +61,8 @@ void RetroChessNotify::notifyGxsTunnelReady(const RsGxsId &gxs_id) { emit gxsTunnelReady(gxs_id); } + +void RetroChessNotify::notifyChessStartGxs(const RsGxsId &gxs_id) +{ + emit chessStartGxs(gxs_id); +} diff --git a/gui/RetroChessNotify.h b/gui/RetroChessNotify.h index e2f70a8..bf32d18 100644 --- a/gui/RetroChessNotify.h +++ b/gui/RetroChessNotify.h @@ -46,6 +46,8 @@ class RetroChessNotify : public QObject /** Notify the UI that a GXS tunnel is now ready for use */ void notifyGxsTunnelReady(const RsGxsId &gxs_id); + void notifyChessStartGxs(const RsGxsId &gxs_id); + signals: void NeMsgArrived(const RsPeerId &peer_id, QString str) ; // emitted when the peer gets a msg @@ -55,6 +57,8 @@ class RetroChessNotify : public QObject void chessMoveGxs(const RsGxsId &gxs_id, int col, int row, int count); void gxsTunnelReady(const RsGxsId &gxs_id); + void chessStartGxs(const RsGxsId &gxs_id); + public slots: };