From 1ee6ea5c20bee5738a39717937e81ab07d42f2a0 Mon Sep 17 00:00:00 2001 From: Georg Zotti Date: Thu, 14 Sep 2023 16:34:20 +0200 Subject: [PATCH] RemoteSync: fix location update with landscape (Fix: #3274) This also required a few more changes in the plugin - rename an enum (now SYNC_ERROR) to even allow compilation (!?) - ClientHandler classes need client in constructor --- plugins/RemoteSync/src/SyncClient.cpp | 17 ++++--- plugins/RemoteSync/src/SyncClient.hpp | 2 + plugins/RemoteSync/src/SyncClientHandlers.cpp | 50 +++++++++++++------ plugins/RemoteSync/src/SyncClientHandlers.hpp | 9 ++-- plugins/RemoteSync/src/SyncMessages.hpp | 2 +- plugins/RemoteSync/src/SyncProtocol.cpp | 4 +- plugins/RemoteSync/src/SyncProtocol.hpp | 2 +- plugins/RemoteSync/src/SyncServer.cpp | 2 +- 8 files changed, 58 insertions(+), 30 deletions(-) diff --git a/plugins/RemoteSync/src/SyncClient.cpp b/plugins/RemoteSync/src/SyncClient.cpp index 73e2af611c123..e31ccf46b3813 100644 --- a/plugins/RemoteSync/src/SyncClient.cpp +++ b/plugins/RemoteSync/src/SyncClient.cpp @@ -37,22 +37,22 @@ SyncClient::SyncClient(SyncOptions options, const QStringList &excludeProperties timeoutTimerId(-1) { handlerHash.clear(); - handlerHash.insert(ERROR, new ClientErrorHandler(this)); + handlerHash.insert(SYNC_ERROR, new ClientErrorHandler(this)); handlerHash.insert(SERVER_CHALLENGE, new ClientAuthHandler(this)); handlerHash.insert(SERVER_CHALLENGERESPONSEVALID, new ClientAuthHandler(this)); handlerHash.insert(ALIVE, new ClientAliveHandler()); //these are the actual sync handlers if(options.testFlag(SyncTime)) - handlerHash[TIME] = new ClientTimeHandler(); + handlerHash[TIME] = new ClientTimeHandler(this); if(options.testFlag(SyncLocation)) - handlerHash[LOCATION] = new ClientLocationHandler(); + handlerHash[LOCATION] = new ClientLocationHandler(this); if(options.testFlag(SyncSelection)) - handlerHash[SELECTION] = new ClientSelectionHandler(); + handlerHash[SELECTION] = new ClientSelectionHandler(this); if(options.testFlag(SyncStelProperty)) - handlerHash[STELPROPERTY] = new ClientStelPropertyUpdateHandler(options.testFlag(SkipGUIProps), stelPropFilter); + handlerHash[STELPROPERTY] = new ClientStelPropertyUpdateHandler(this, options.testFlag(SkipGUIProps), stelPropFilter); if(options.testFlag(SyncView)) - handlerHash[VIEW] = new ClientViewHandler(); + handlerHash[VIEW] = new ClientViewHandler(this); //fill unused handlers with dummies for(int t = TIME;terrorStr = errorStr; } + +bool SyncClient::isPropertyFilteredAway(QString property) const +{ + return stelPropFilter.contains(property); +} diff --git a/plugins/RemoteSync/src/SyncClient.hpp b/plugins/RemoteSync/src/SyncClient.hpp index 334fccf35e14c..e0af90e771f76 100644 --- a/plugins/RemoteSync/src/SyncClient.hpp +++ b/plugins/RemoteSync/src/SyncClient.hpp @@ -56,6 +56,8 @@ class SyncClient : public QObject ~SyncClient() override; QString errorString() const { return errorStr; } + //! Check whether this property (format: "StelModule.property") is filtered away in the Client settings. + bool isPropertyFilteredAway(QString property) const; public slots: void connectToServer(const QString& host, const int port); diff --git a/plugins/RemoteSync/src/SyncClientHandlers.cpp b/plugins/RemoteSync/src/SyncClientHandlers.cpp index 039bd1b1e7566..ca3ca112393b2 100644 --- a/plugins/RemoteSync/src/SyncClientHandlers.cpp +++ b/plugins/RemoteSync/src/SyncClientHandlers.cpp @@ -18,6 +18,9 @@ */ #include "SyncClientHandlers.hpp" +#include "LandscapeMgr.hpp" +#include "StelLocationMgr.hpp" +#include "StelModuleMgr.hpp" #include "SyncClient.hpp" #include "SyncMessages.hpp" @@ -30,12 +33,6 @@ using namespace SyncProtocol; -ClientHandler::ClientHandler() - : client(nullptr) -{ - core = StelApp::getInstance().getCore(); -} - ClientHandler::ClientHandler(SyncClient *client) : client(client) { @@ -186,8 +183,11 @@ bool ClientLocationHandler::handleMessage(QDataStream &stream, SyncProtocol::tPa if(!ok) return false; + const StelLocation &loc=msg.stelLocation; + //replicated from StelCore::moveObserverTo - if(msg.totalDuration>0.0) + // N.B. This message may apparently come several times. In case a transition is already under way (planetName==SpaceShip), this would fail, so exclude it. + if(msg.totalDuration>0.0 && core->getCurrentLocation().planetName!="SpaceShip") { //for optimal results, the network latency should be subtracted from the timeToGo... @@ -198,24 +198,44 @@ bool ClientLocationHandler::handleMessage(QDataStream &stream, SyncProtocol::tPa curLoc.name = "."; } + //qDebug() << "Attempt to create Spaceship Observer from" << curLoc.planetName << "to" << msg.stelLocation.planetName ; //create a spaceship observer - SpaceShipObserver* newObs = new SpaceShipObserver(curLoc, msg.stelLocation, msg.totalDuration,msg.timeToGo); + SpaceShipObserver* newObs = new SpaceShipObserver(curLoc, loc, msg.totalDuration,msg.timeToGo); core->setObserver(newObs); newObs->update(0); } - else + else if(msg.totalDuration<=0.0) { //create a normal observer - core->setObserver(new StelObserver(msg.stelLocation)); + //qDebug() << "Attempt to create Normal Observer at" << msg.stelLocation.planetName ; + core->setObserver(new StelObserver(loc)); + } + + + // We run into a sync problem here: + // When attempting to e.g. return to default location, LocationDialog sets a new landscapeID (property message), then resets location (this locationHandler message) which overwrites the landscapeID. + // We must first find out whether currentLandscapeID is sync'ed, and if yes, just reset the just-set currentLandscapeID. And if that is zero, do the ZeroColor stuff. + + const bool dontSyncLandscape= (client->isPropertyFilteredAway("LandscapeMgr.currentLandscapeID")); + + QString landscapeID=dontSyncLandscape? QString() : GETSTELMODULE(LandscapeMgr)->getCurrentLandscapeID(); + + if (!dontSyncLandscape && landscapeID=="zero") + { + static const StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr(); + QColor color=locMgr.getColorForCoordinates(loc.getLongitude(), loc.getLatitude()); + landscapeID=QString("ZeroColor(%1)").arg(Vec3f(color).toStr()); } - emit core->targetLocationChanged(msg.stelLocation, QString()); - emit core->locationChanged(core->getCurrentLocation()); + if (loc.planetName=="Earth") + core->moveObserverTo(loc, 0., 1., GETSTELMODULE(LandscapeMgr)->getFlagLandscapeAutoSelection() ? landscapeID : QString()); + else + core->moveObserverTo(loc, 0., 1., loc.planetName); // Loads a default landscape for the planet. return true; } -ClientSelectionHandler::ClientSelectionHandler() +ClientSelectionHandler::ClientSelectionHandler(SyncClient *client): ClientHandler(client) { objMgr = &StelApp::getInstance().getStelObjectMgr(); } @@ -255,7 +275,7 @@ bool ClientSelectionHandler::handleMessage(QDataStream &stream, SyncProtocol::tP return true; } -ClientStelPropertyUpdateHandler::ClientStelPropertyUpdateHandler(bool skipGuiProps, const QStringList &excludeProps) +ClientStelPropertyUpdateHandler::ClientStelPropertyUpdateHandler(SyncClient *client, bool skipGuiProps, const QStringList &excludeProps): ClientHandler(client) { propMgr = StelApp::getInstance().getStelPropertyManager(); @@ -325,7 +345,7 @@ bool ClientStelPropertyUpdateHandler::handleMessage(QDataStream &stream, SyncPro return true; } -ClientViewHandler::ClientViewHandler() +ClientViewHandler::ClientViewHandler(SyncClient *client): ClientHandler(client) { mvMgr = core->getMovementMgr(); } diff --git a/plugins/RemoteSync/src/SyncClientHandlers.hpp b/plugins/RemoteSync/src/SyncClientHandlers.hpp index 3f953913be3b0..09d6bdf48daef 100644 --- a/plugins/RemoteSync/src/SyncClientHandlers.hpp +++ b/plugins/RemoteSync/src/SyncClientHandlers.hpp @@ -33,7 +33,6 @@ class ClientHandler : public QObject, public SyncMessageHandler Q_INTERFACES(SyncMessageHandler) public: - ClientHandler(); ClientHandler(SyncClient *client); protected: SyncClient* client; @@ -68,12 +67,14 @@ class ClientAliveHandler : public SyncMessageHandler class ClientTimeHandler : public ClientHandler { public: + ClientTimeHandler(SyncClient *client): ClientHandler(client){}; bool handleMessage(QDataStream &stream, SyncProtocol::tPayloadSize dataSize, SyncRemotePeer &peer) override; }; class ClientLocationHandler : public ClientHandler { public: + ClientLocationHandler(SyncClient *client): ClientHandler(client){}; bool handleMessage(QDataStream &stream, SyncProtocol::tPayloadSize dataSize, SyncRemotePeer &peer) override; }; @@ -81,7 +82,7 @@ class StelObjectMgr; class ClientSelectionHandler : public ClientHandler { public: - ClientSelectionHandler(); + ClientSelectionHandler(SyncClient *client); bool handleMessage(QDataStream &stream, SyncProtocol::tPayloadSize dataSize, SyncRemotePeer &peer) override; private: StelObjectMgr* objMgr; @@ -91,7 +92,7 @@ class StelPropertyMgr; class ClientStelPropertyUpdateHandler : public ClientHandler { public: - ClientStelPropertyUpdateHandler(bool skipGuiProps, const QStringList& excludeProps); + ClientStelPropertyUpdateHandler(SyncClient *client, bool skipGuiProps, const QStringList& excludeProps); bool handleMessage(QDataStream &stream, SyncProtocol::tPayloadSize dataSize, SyncRemotePeer &peer) override; private: StelPropertyMgr* propMgr; @@ -102,7 +103,7 @@ class StelMovementMgr; class ClientViewHandler : public ClientHandler { public: - ClientViewHandler(); + ClientViewHandler(SyncClient *client); bool handleMessage(QDataStream &stream, SyncProtocol::tPayloadSize dataSize, SyncRemotePeer &peer) override; private: StelMovementMgr* mvMgr; diff --git a/plugins/RemoteSync/src/SyncMessages.hpp b/plugins/RemoteSync/src/SyncMessages.hpp index 50badf0638376..e926dd3879bb9 100644 --- a/plugins/RemoteSync/src/SyncMessages.hpp +++ b/plugins/RemoteSync/src/SyncMessages.hpp @@ -33,7 +33,7 @@ class ErrorMessage : public SyncMessage ErrorMessage(); ErrorMessage(const QString& msg); - SyncProtocol::SyncMessageType getMessageType() const override { return SyncProtocol::ERROR; } + SyncProtocol::SyncMessageType getMessageType() const override { return SyncProtocol::SYNC_ERROR; } void serialize(QDataStream& stream) const override; bool deserialize(QDataStream& stream, SyncProtocol::tPayloadSize dataSize) override; diff --git a/plugins/RemoteSync/src/SyncProtocol.cpp b/plugins/RemoteSync/src/SyncProtocol.cpp index 059e7e0f37d4b..3466866c45b24 100644 --- a/plugins/RemoteSync/src/SyncProtocol.cpp +++ b/plugins/RemoteSync/src/SyncProtocol.cpp @@ -121,7 +121,7 @@ SyncRemotePeer::SyncRemotePeer(QAbstractSocket *socket, bool isServer, const QHa connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(sockStateChanged(QAbstractSocket::SocketState))); // silence CoverityScan... - msgHeader.msgType=SyncProtocol::ERROR; + msgHeader.msgType=SyncProtocol::SYNC_ERROR; msgHeader.dataSize=0; lastReceiveTime = QDateTime::currentMSecsSinceEpoch(); @@ -341,7 +341,7 @@ QString SyncMessage::toString() const QString SyncMessage::toString(SyncProtocol::SyncMessageType type) { switch (type) { - case SyncProtocol::ERROR: + case SyncProtocol::SYNC_ERROR: return "ERROR"; break; case SyncProtocol::SERVER_CHALLENGE: diff --git a/plugins/RemoteSync/src/SyncProtocol.hpp b/plugins/RemoteSync/src/SyncProtocol.hpp index b22d949393ce6..8919ef345f945 100644 --- a/plugins/RemoteSync/src/SyncProtocol.hpp +++ b/plugins/RemoteSync/src/SyncProtocol.hpp @@ -62,7 +62,7 @@ const qint64 SYNC_MAX_MESSAGE_SIZE = SYNC_HEADER_SIZE + SYNC_MAX_PAYLOAD_SIZE; //! The classes handling these messages are defined in SyncMessages.hpp enum SyncMessageType { - ERROR, //sent to the other party on protocol/auth error with a message, connection will be dropped afterwards + SYNC_ERROR, //sent to the other party on protocol/auth error with a message, connection will be dropped afterwards SERVER_CHALLENGE, //sent as a challenge to the client on establishment of connection CLIENT_CHALLENGE_RESPONSE, //sent as a reply to the challenge SERVER_CHALLENGERESPONSEVALID, //sent from the server to the client after valid client hello was received. diff --git a/plugins/RemoteSync/src/SyncServer.cpp b/plugins/RemoteSync/src/SyncServer.cpp index 8db7a79df3698..310ad567d3ed9 100644 --- a/plugins/RemoteSync/src/SyncServer.cpp +++ b/plugins/RemoteSync/src/SyncServer.cpp @@ -40,7 +40,7 @@ SyncServer::SyncServer(QObject* parent, bool allowVersionMismatch) //create message handlers handlerHash.clear(); - handlerHash[ERROR] = new ServerErrorHandler(); + handlerHash[SYNC_ERROR] = new ServerErrorHandler(); handlerHash[CLIENT_CHALLENGE_RESPONSE] = new ServerAuthHandler(this, allowVersionMismatch); handlerHash[ALIVE] = new ServerAliveHandler(); }