diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index 1364be4bc..1dbdad644 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -15,6 +15,7 @@ #include "blackcore/aircraftmatcher.h" #include "blackcore/application.h" #include "blackcore/webdataservices.h" +#include "blackcore/context/contextnetwork.h" #include "blackmisc/simulation/matchingutils.h" #include "blackmisc/aviation/aircraftparts.h" #include "blackmisc/aviation/aircraftsituation.h" @@ -696,12 +697,6 @@ namespace BlackCore if (isAircraft) { - if (callsign.isCopilotCallsign()) - { - this->copilotDetected(); - return; - } - CStatusMessageList reverseLookupMessages; CStatusMessageList *pReverseLookupMessages = this->isReverseLookupMessagesEnabled() ? &reverseLookupMessages : nullptr; CMatchingUtils::addLogDetailsToList(pReverseLookupMessages, callsign, @@ -717,12 +712,6 @@ namespace BlackCore void CAirspaceMonitor::onIcaoCodesReceived(const CCallsign &callsign, const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &livery) { Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "not in main thread"); - if (callsign.isCopilotCallsign()) - { - // We already know that plane by its normall callsign - this->copilotDetected(); - return; - } BLACK_VERIFY_X(callsign.isValid(), Q_FUNC_INFO, "invalid callsign"); if (!callsign.isValid()) { return; } @@ -947,6 +936,8 @@ namespace BlackCore const CCallsign callsign(situation.getCallsign()); Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Empty callsign"); + if (isCopilotAircraft(callsign)) { return; } + // update client info this->autoAdjustCientGndCapability(situation); @@ -993,6 +984,8 @@ namespace BlackCore // checks Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Empty callsign"); + if (isCopilotAircraft(callsign)) { return; } + if (CBuildConfig::isLocalDeveloperDebugBuild()) { Q_ASSERT_X(!situation.isNaNVectorDouble(), Q_FUNC_INFO, "Detected NaN"); @@ -1233,6 +1226,17 @@ namespace BlackCore return angle; } + bool CAirspaceMonitor::isCopilotAircraft(const CCallsign &callsign) const + { + if (!sApp || sApp->isShuttingDown() || !sApp->getIContextNetwork()) { return false; } + + // It is only relevant if we are logged in as observer + if (sApp->getIContextNetwork()->getLoginMode() != INetwork::LoginAsObserver) { return false; } + + const CCallsign ownCallsign = getOwnAircraft().getCallsign(); + return ownCallsign.isMaybeCopilotCallsign(callsign); + } + CAirspaceMonitor::FsInnPacket::FsInnPacket(const QString &aircraftIcaoDesignator, const QString &airlineIcaoDesignator, const QString &combinedCode, const QString &modelString) : aircraftIcaoDesignator(aircraftIcaoDesignator.trimmed().toUpper()), airlineIcaoDesignator(airlineIcaoDesignator.trimmed().toUpper()), combinedCode(combinedCode.trimmed().toUpper()), modelString(modelString.trimmed()) { } diff --git a/src/blackcore/airspacemonitor.h b/src/blackcore/airspacemonitor.h index dfd8babfc..b7b7f8a60 100644 --- a/src/blackcore/airspacemonitor.h +++ b/src/blackcore/airspacemonitor.h @@ -270,6 +270,8 @@ namespace BlackCore const QString &airlineIcao, const QString &liveryString, const QString &modelString, BlackMisc::Simulation::CAircraftModel::ModelType type, BlackMisc::CStatusMessageList *log); + bool isCopilotAircraft(const BlackMisc::Aviation::CCallsign &callsign) const; + //! Create aircraft in range, this is the only place where a new aircraft should be added void onAircraftUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CTransponder &transponder); diff --git a/src/blackmisc/aviation/callsign.cpp b/src/blackmisc/aviation/callsign.cpp index 501e00984..aa8764a1a 100644 --- a/src/blackmisc/aviation/callsign.cpp +++ b/src/blackmisc/aviation/callsign.cpp @@ -87,9 +87,11 @@ namespace BlackMisc return m_callsign.endsWith("SUP"); } - bool CCallsign::isCopilotCallsign() const + bool CCallsign::isMaybeCopilotCallsign(const CCallsign &pilotCallsign) const { - return (this->getTypeHint() == Aircraft) && this->isObserverCallsign(); + return m_callsign.startsWith(pilotCallsign.asString()) && + m_callsign.size() == pilotCallsign.asString().size() + 1 && + m_callsign.at(m_callsign.size() - 1) >= 'A' && m_callsign.at(m_callsign.size() - 1) <= 'Z'; } QString CCallsign::getIcaoCode() const diff --git a/src/blackmisc/aviation/callsign.h b/src/blackmisc/aviation/callsign.h index a865dfb6e..f7f41ad7f 100644 --- a/src/blackmisc/aviation/callsign.h +++ b/src/blackmisc/aviation/callsign.h @@ -84,8 +84,10 @@ namespace BlackMisc //! Supervisor? bool isSupervisorCallsign() const; - //! Pilot OBS callsign, normally a co-pilot - bool isCopilotCallsign() const; + //! Returns true if this is a co-pilot callsign of pilot. The logic is that the callsign is the same as the pilot one + //! but with a single character as suffix. + //! e.g Pilot logged in as DLH123, observer logged in as DLH123A + bool isMaybeCopilotCallsign(const CCallsign &pilotCallsign) const; //! Get callsign (normalized) const QString &asString() const { return m_callsign; } diff --git a/tests/blackmisc/aviation/testaviation/testaviation.cpp b/tests/blackmisc/aviation/testaviation/testaviation.cpp index 42f4aa6c7..7301a5daf 100644 --- a/tests/blackmisc/aviation/testaviation/testaviation.cpp +++ b/tests/blackmisc/aviation/testaviation/testaviation.cpp @@ -157,6 +157,15 @@ namespace BlackMiscTest QVERIFY2(cs1 == cs2, "Callsigns shall be equal"); QVERIFY2(cs1 != cs3, "Callsigns shall not be equal"); + CCallsign pilot("DLH123"); + CCallsign copilot1("DLH123A"); + CCallsign copilot2("DLH1233"); + CCallsign copilot3("DLH12"); + QVERIFY(copilot1.isMaybeCopilotCallsign(pilot)); + QVERIFY(!pilot.isMaybeCopilotCallsign(pilot)); + QVERIFY(!copilot2.isMaybeCopilotCallsign(pilot)); + QVERIFY(!copilot3.isMaybeCopilotCallsign(pilot)); + CCallsignSet set; set.push_back(cs1); QVERIFY2(set.size() == 1, "List shall be 1");