Filter other pilots ghost aircraft when flying in shared cockpit mode

When flying in shared cockpit mode, both pilots log into the network.
One as pilot to be visible to ATC and other pilots. The other one as
observer. For the observing user, the pilots aircraft needs to be filtered.
Filter algorithm is using the same schema as vPilot does.

ref T427
This commit is contained in:
Roland Winklmeier
2018-11-08 11:35:31 +01:00
committed by Klaus Basan
parent 420fc40fb2
commit ee8af9f4c6
5 changed files with 35 additions and 16 deletions

View File

@@ -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())
{ }

View File

@@ -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);

View File

@@ -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

View File

@@ -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; }

View File

@@ -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");