From 39920c1b71c3e6a5457dc6de2b0ba70363bc1fe5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 3 Oct 2022 11:17:58 +0100 Subject: [PATCH] Show the version running when connecting to incompatible remote server --- qrenderdoc/Code/Interface/RemoteHost.cpp | 15 +++++++- qrenderdoc/Code/Interface/RemoteHost.h | 6 ++++ .../Code/pyrenderdoc/qrenderdoc_stub.cpp | 5 +++ qrenderdoc/Windows/Dialogs/RemoteManager.cpp | 9 ++++- qrenderdoc/Windows/MainWindow.cpp | 5 ++- renderdoc/api/replay/renderdoc_tostr.inl | 2 +- renderdoc/core/remote_server.cpp | 34 +++++++++++++++++-- 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/qrenderdoc/Code/Interface/RemoteHost.cpp b/qrenderdoc/Code/Interface/RemoteHost.cpp index 00b135985..ae4220219 100644 --- a/qrenderdoc/Code/Interface/RemoteHost.cpp +++ b/qrenderdoc/Code/Interface/RemoteHost.cpp @@ -43,7 +43,7 @@ struct RemoteHostData } RemoteHostData() : refcount(1) {} - rdcstr m_friendlyName, m_runCommand, m_lastCapturePath; + rdcstr m_friendlyName, m_runCommand, m_lastCapturePath, m_versionError; bool m_serverRunning = false, m_connected = false, m_busy = false, m_versionMismatch = false; }; @@ -122,6 +122,7 @@ void RemoteHost::CheckStatus() { QMutexLocker autolock(&m_data->mutex); m_data->m_serverRunning = m_data->m_versionMismatch = m_data->m_busy = false; + m_data->m_versionError.clear(); return; } @@ -157,23 +158,27 @@ void RemoteHost::UpdateStatus(ResultDetails result) { m_data->m_serverRunning = true; m_data->m_versionMismatch = m_data->m_busy = false; + m_data->m_versionError.clear(); } else if(result.code == ResultCode::NetworkRemoteBusy) { m_data->m_serverRunning = true; m_data->m_busy = true; m_data->m_versionMismatch = false; + m_data->m_versionError.clear(); } else if(result.code == ResultCode::NetworkVersionMismatch) { m_data->m_serverRunning = true; m_data->m_busy = true; m_data->m_versionMismatch = true; + m_data->m_versionError = result.Message(); } else { m_data->m_serverRunning = false; m_data->m_versionMismatch = m_data->m_busy = false; + m_data->m_versionError.clear(); } } @@ -226,6 +231,14 @@ bool RemoteHost::IsVersionMismatch() const return m_data->m_versionMismatch; } +rdcstr RemoteHost::VersionMismatchError() const +{ + QMutexLocker autolock(&m_data->mutex); + if(m_data->m_versionError.empty()) + return "Version Mismatch"; + return m_data->m_versionError; +} + rdcstr RemoteHost::FriendlyName() const { QMutexLocker autolock(&m_data->mutex); diff --git a/qrenderdoc/Code/Interface/RemoteHost.h b/qrenderdoc/Code/Interface/RemoteHost.h index 398f385c0..0a17d5d37 100644 --- a/qrenderdoc/Code/Interface/RemoteHost.h +++ b/qrenderdoc/Code/Interface/RemoteHost.h @@ -92,6 +92,12 @@ public: )"); bool IsVersionMismatch() const; + DOCUMENT(R"( +:return: The version mismatch error. +:rtype: str +)"); + rdcstr VersionMismatchError() const; + DOCUMENT(R"( :return: The hostname of this host. :rtype: str diff --git a/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp b/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp index 6870008d9..a19b997d3 100644 --- a/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp +++ b/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp @@ -222,6 +222,11 @@ bool RemoteHost::IsVersionMismatch() const return false; } +rdcstr RemoteHost::VersionMismatchError() const +{ + return rdcstr(); +} + rdcstr RemoteHost::FriendlyName() const { return rdcstr(); diff --git a/qrenderdoc/Windows/Dialogs/RemoteManager.cpp b/qrenderdoc/Windows/Dialogs/RemoteManager.cpp index bbca3b846..ea86f2d50 100644 --- a/qrenderdoc/Windows/Dialogs/RemoteManager.cpp +++ b/qrenderdoc/Windows/Dialogs/RemoteManager.cpp @@ -149,11 +149,18 @@ void RemoteManager::setRemoteServerLive(RDTreeWidgetItem *node, bool live, bool QString text = live ? tr("Remote server running") : tr("No remote server"); if(host.IsConnected()) + { text += tr(" (Active Context)"); + } else if(host.IsVersionMismatch()) - text += tr(" (Version Mismatch)"); + { + QString message = host.VersionMismatchError(); + text += QFormatStr(" (%1)").arg(message); + } else if(host.IsBusy()) + { text += tr(" (Busy)"); + } node->setText(1, text); diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index f6e21c50a..f79ce32fc 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -1892,7 +1892,7 @@ void MainWindow::FillRemotesMenu(QMenu *menu, bool includeLocalhost) if(host.IsConnected()) action->setText(tr("%1 (Connected)").arg(host.Name())); else if(host.IsServerRunning() && host.IsVersionMismatch()) - action->setText(tr("%1 (Bad Version)").arg(host.Name())); + action->setText(tr("%1 (%2)").arg(host.Name(), host.VersionMismatchError())); else if(host.IsServerRunning() && host.IsBusy()) action->setText(tr("%1 (Busy)").arg(host.Name())); else if(host.IsServerRunning()) @@ -2101,8 +2101,7 @@ void MainWindow::setRemoteHost(int hostIdx) } else if(host.IsVersionMismatch()) { - statusText->setText( - tr("Remote server is not running RenderDoc %1").arg(lit(FULL_VERSION_STRING))); + statusText->setText(host.VersionMismatchError()); } else if(host.IsBusy()) { diff --git a/renderdoc/api/replay/renderdoc_tostr.inl b/renderdoc/api/replay/renderdoc_tostr.inl index 7b0620d19..bc75f8c6b 100644 --- a/renderdoc/api/replay/renderdoc_tostr.inl +++ b/renderdoc/api/replay/renderdoc_tostr.inl @@ -57,7 +57,7 @@ rdcstr DoStringise(const ResultCode &el) "Process is incompatible with this build of RenderDoc"); STRINGISE_ENUM_CLASS_NAMED(NetworkIOFailed, "Network I/O operation failed"); STRINGISE_ENUM_CLASS_NAMED(NetworkRemoteBusy, "Remote side of network connection is busy"); - STRINGISE_ENUM_CLASS_NAMED(NetworkVersionMismatch, "Version mismatch between network clients"); + STRINGISE_ENUM_CLASS_NAMED(NetworkVersionMismatch, "Incompatible version"); STRINGISE_ENUM_CLASS_NAMED(FileIOFailed, "File I/O failed"); STRINGISE_ENUM_CLASS_NAMED( FileIncompatibleVersion, diff --git a/renderdoc/core/remote_server.cpp b/renderdoc/core/remote_server.cpp index 7d1cca0fb..4944ab394 100644 --- a/renderdoc/core/remote_server.cpp +++ b/renderdoc/core/remote_server.cpp @@ -45,16 +45,22 @@ RDOC_CONFIG(bool, RemoteServer_DebugLogging, false, "Output a verbose logging file in the system's temporary folder containing the " "traffic to and from the remote server."); +#define MAKE_REMOTE_SERVER_VERSION(maj, min) uint32_t((maj)*1000) + (min) + static const uint32_t RemoteServerProtocolVersion = - uint32_t(RENDERDOC_VERSION_MAJOR * 1000) + RENDERDOC_VERSION_MINOR; + MAKE_REMOTE_SERVER_VERSION(RENDERDOC_VERSION_MAJOR, RENDERDOC_VERSION_MINOR); enum RemoteServerPacket { + // fixed packets. These are used cross-version so MUST NOT CHANGE eRemoteServer_Noop = 1, eRemoteServer_Handshake, eRemoteServer_VersionMismatch, eRemoteServer_Busy, + eRemoteServer_VersionMismatch2, // sent for versions 1.23 and above, including the version info + // variable packets. These are used only after a handshake has been established with an identical + // version so can be freely changed eRemoteServer_Ping, eRemoteServer_RemoteDriverList, eRemoteServer_TakeOwnershipCapture, @@ -97,6 +103,7 @@ rdcstr DoStringise(const RemoteServerPacket &el) STRINGISE_ENUM_NAMED(eRemoteServer_Handshake, "Handshake"); STRINGISE_ENUM_NAMED(eRemoteServer_VersionMismatch, "VersionMismatch"); STRINGISE_ENUM_NAMED(eRemoteServer_Busy, "Busy"); + STRINGISE_ENUM_NAMED(eRemoteServer_VersionMismatch2, "VersionMismatch"); STRINGISE_ENUM_NAMED(eRemoteServer_Ping, "Ping"); STRINGISE_ENUM_NAMED(eRemoteServer_RemoteDriverList, "RemoteDriverList"); @@ -199,6 +206,15 @@ static bool HandleHandshakeClient(ActiveClient &activeClient, ClientThread *thre RDCLOG("Connection using protocol %u, but we are running %u", version, RemoteServerProtocolVersion); + // as of 1.23 we started serialising our version so the other end knows what it's talking + // to. + if(version >= MAKE_REMOTE_SERVER_VERSION(1, 23)) + { + SCOPED_SERIALISE_CHUNK(eRemoteServer_VersionMismatch2); + + SERIALISE_ELEMENT(RemoteServerProtocolVersion); + } + else { SCOPED_SERIALISE_CHUNK(eRemoteServer_VersionMismatch); } @@ -1192,6 +1208,12 @@ RENDERDOC_CreateRemoteServerConnection(const rdcstr &URL, IRemoteServer **rend) RemoteServerPacket type = ser.ReadChunk(); + uint32_t remoteVersion = 0; + if(type == eRemoteServer_VersionMismatch2) + { + SERIALISE_ELEMENT(remoteVersion); + } + ser.EndChunk(); if(type == eRemoteServer_Busy) @@ -1200,10 +1222,16 @@ RENDERDOC_CreateRemoteServerConnection(const rdcstr &URL, IRemoteServer **rend) return RDResult(ResultCode::NetworkRemoteBusy); } - if(type == eRemoteServer_VersionMismatch) + if(type == eRemoteServer_VersionMismatch || type == eRemoteServer_VersionMismatch2) { SAFE_DELETE(sock); - return RDResult(ResultCode::NetworkVersionMismatch); + + rdcstr ver = StringFormat::Fmt("Server on v%d.%d", remoteVersion / 1000, remoteVersion % 1000); + + if(remoteVersion == 0) + ver = "Server older than v1.23"; + + return RDResult(ResultCode::NetworkVersionMismatch, ver); } if(ser.IsErrored() || type != eRemoteServer_Handshake)