From 6e933b089cea4183f20cdc73b0fc4eac3d136462 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 2 Feb 2018 20:59:48 +0100 Subject: [PATCH] Ref T243, track position updates to determine offset times directly in network vatlib * track position updates and keep records of offset times * hence parts and positions can already have a dynamic offset time * parts config received will include this offset time --- src/blackcore/network.h | 2 +- src/blackcore/vatsim/networkvatlib.cpp | 65 +++++++++++++++++++++++--- src/blackcore/vatsim/networkvatlib.h | 16 +++++++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/blackcore/network.h b/src/blackcore/network.h index 51fe25978..d054d2f21 100644 --- a/src/blackcore/network.h +++ b/src/blackcore/network.h @@ -525,7 +525,7 @@ namespace BlackCore /*! * We received an aircraft config packet. */ - void aircraftConfigPacketReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &incremental, bool isFull); + void aircraftConfigPacketReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &incremental, int currentOffsetTime); /*! * We received a raw message for debugging purposes diff --git a/src/blackcore/vatsim/networkvatlib.cpp b/src/blackcore/vatsim/networkvatlib.cpp index 7c930b097..3f73317bf 100644 --- a/src/blackcore/vatsim/networkvatlib.cpp +++ b/src/blackcore/vatsim/networkvatlib.cpp @@ -284,7 +284,8 @@ namespace BlackCore if (this->isDisconnected()) { - stopPositionTimers(); + this->stopPositionTimers(); + this->clearState(); } emit this->connectionStatusChanged(convertConnectionStatus(status), convertConnectionStatus(m_status)); @@ -452,6 +453,7 @@ namespace BlackCore { Q_ASSERT_X(isDisconnected(), Q_FUNC_INFO, "Can't connect while still connected"); if (!m_net) { initializeSession(); } + this->clearState(); QByteArray callsign = toFSD(m_loginMode == LoginAsObserver ? m_ownCallsign.getAsObserverCallsignString() : m_ownCallsign.asString()); @@ -491,13 +493,14 @@ namespace BlackCore void CNetworkVatlib::terminateConnection() { - stopPositionTimers(); + this->stopPositionTimers(); if (m_net && !isDisconnected()) { // Process all pending tasks before logging off process(); Vat_Logoff(m_net.data()); } + this->clearState(); } void CNetworkVatlib::sendTextMessages(const BlackMisc::Network::CTextMessageList &messages) @@ -867,7 +870,9 @@ namespace BlackCore void CNetworkVatlib::onPilotDisconnected(VatFsdClient *, const char *callsign, void *cbvar) { auto *self = cbvar_cast(cbvar); - emit self->pilotDisconnected(CCallsign(self->fromFSD(callsign), CCallsign::Aircraft)); + const CCallsign cs(self->fromFSD(callsign), CCallsign::Aircraft); + self->clearState(cs); + emit self->pilotDisconnected(cs); } void CNetworkVatlib::onControllerDisconnected(VatFsdClient *, const char *callsign, void *cbvar) @@ -889,8 +894,11 @@ namespace BlackCore CSpeed(position->groundSpeed, CSpeedUnit::kts()), CAltitude({ 0, nullptr }, CAltitude::MeanSeaLevel) ); + + //! we set a dynamically updating offset time here situation.setCurrentUtcTime(); - situation.setTimeOffsetMs(c_positionTimeOffsetMsec); + int offsetMs = self->markReceivedPositionAndGetOffsetTime(situation.getCallsign(), situation.getMSecsSinceEpoch()); + situation.setTimeOffsetMs(offsetMs); CTransponder::TransponderMode mode = CTransponder::StateStandby; switch (position->transponderMode) @@ -944,8 +952,8 @@ namespace BlackCore const QJsonObject config = doc.object().value("config").toObject(); if (config.empty()) return; - const bool isFull = config.take("is_full_data").toBool(false); - emit self->aircraftConfigPacketReceived(callsign, config, isFull); + const int offsetTimeMs = self->currentOffsetTime(callsign); + emit self->aircraftConfigPacketReceived(callsign, config, offsetTimeMs); } void CNetworkVatlib::onInterimPilotPositionUpdate(VatFsdClient *, const char *sender, const VatInterimPilotPosition *position, void *cbvar) @@ -963,6 +971,7 @@ namespace BlackCore situation.setCurrentUtcTime(); situation.setTimeOffsetMs(c_interimPositionTimeOffsetMsec); situation.setInterimFlag(true); + self->markReceivedPositionAndGetOffsetTime(situation.getCallsign(), situation.getMSecsSinceEpoch()); emit self->aircraftInterimPositionUpdate(situation); } @@ -1158,6 +1167,50 @@ namespace BlackCore } } + int CNetworkVatlib::markReceivedPositionAndGetOffsetTime(const CCallsign &callsign, qint64 markerTs) + { + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Need callsign"); + + if (markerTs < 0) { markerTs = QDateTime::currentMSecsSinceEpoch(); } + if (!m_lastPositionUpdate.contains(callsign)) + { + m_lastPositionUpdate.insert(callsign, markerTs); + return c_positionTimeOffsetMsec; + } + const qint64 oldTs = m_lastPositionUpdate.value(callsign); + m_lastPositionUpdate[callsign] = markerTs; + + const int diff = oldTs - markerTs; + const int offsetTime = (oldTs > 0 && diff > 0 && diff < c_interimPositionTimeOffsetMsec) ? + c_interimPositionTimeOffsetMsec : + c_positionTimeOffsetMsec; + m_lastOffsetTime[callsign] = offsetTime; + return offsetTime; + } + + int CNetworkVatlib::currentOffsetTime(const CCallsign &callsign) const + { + Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Need callsign"); + + if (!m_lastOffsetTime.contains(callsign)) { return c_positionTimeOffsetMsec; } + return m_lastOffsetTime.value(callsign); + } + + void CNetworkVatlib::clearState() + { + m_pendingAtisQueries.clear(); + m_lastPositionUpdate.clear(); + m_lastOffsetTime.clear(); + } + + void CNetworkVatlib::clearState(const CCallsign &callsign) + { + if (callsign.isEmpty()) { return; } + m_pendingAtisQueries.remove(callsign); + m_lastPositionUpdate.remove(callsign); + m_lastOffsetTime.remove(callsign); + } + void CNetworkVatlib::onInfoQueryRequestReceived(VatFsdClient *, const char *callsignString, VatClientQueryType type, const char *, void *cbvar) { auto *self = cbvar_cast(cbvar); diff --git a/src/blackcore/vatsim/networkvatlib.h b/src/blackcore/vatsim/networkvatlib.h index 59ca763e2..b12c3f585 100644 --- a/src/blackcore/vatsim/networkvatlib.h +++ b/src/blackcore/vatsim/networkvatlib.h @@ -141,6 +141,7 @@ namespace BlackCore static int constexpr c_processingIntervalMsec = 100; //!< interval for the processing timer static int constexpr c_updatePostionIntervalMsec = 5000; //!< interval for the position update timer (send our position to network) static int constexpr c_updateInterimPostionIntervalMsec = 1000; //!< interval for iterim position updates (send our position as interim position) + static bool getCmdLineClientIdAndKey(int &id, QString &key); void replyToFrequencyQuery(const BlackMisc::Aviation::CCallsign &callsign); @@ -224,6 +225,18 @@ namespace BlackCore //! released as normal text message. void maybeHandleAtisReply(const BlackMisc::Aviation::CCallsign &sender, const BlackMisc::Aviation::CCallsign &receiver, const QString &message); + //! Remember when last position was received + int markReceivedPositionAndGetOffsetTime(const BlackMisc::Aviation::CCallsign &callsign, qint64 markerTs = -1); + + //! Current offset time + int currentOffsetTime(const BlackMisc::Aviation::CCallsign &callsign) const; + + //! Clear state when connection is terminated + void clearState(); + + //! Clear state for callsign + void clearState(const BlackMisc::Aviation::CCallsign &callsign); + //! Deletion policy for QScopedPointer struct VatFsdClientDeleter { @@ -259,7 +272,10 @@ namespace BlackCore QDateTime m_queryTime = QDateTime::currentDateTimeUtc(); QStringList m_atisMessage; }; + QHash m_pendingAtisQueries; + QHash m_lastPositionUpdate; + QHash m_lastOffsetTime; BlackMisc::CSettingReadOnly m_fsdMessageSetting { this, &CNetworkVatlib::fsdMessageSettingsChanged }; QFile m_rawFsdMessageLogFile;