diff --git a/src/blackcore/aircraftmatcher.cpp b/src/blackcore/aircraftmatcher.cpp index 2c96ccde3..bab308749 100644 --- a/src/blackcore/aircraftmatcher.cpp +++ b/src/blackcore/aircraftmatcher.cpp @@ -405,18 +405,35 @@ namespace BlackCore { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Matching script: Matching stage script used")); const MatchingScriptReturnValues rv = CAircraftMatcher::matchingStageScript(remoteAircraft.getModel(), matchedModel, setup, modelSet, log); + CAircraftModel matchedModelMs = matchedModel; + if (rv.runScriptAndModified()) { - matchedModel = rv.model; + matchedModelMs = rv.model; didRunAndModifyMatchingScript = true; } if (rv.runScriptModifiedAndRerun()) { CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Matching script: Modified values and re-run requested")); + CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Matching script: Now using model: '%1'").arg(matchedModel.toQString(true))); + CSimulatedAircraft rerunAircraft(remoteAircraft); - rerunAircraft.setModel(matchedModel); - matchedModel = CAircraftMatcher::getClosestMatch(rerunAircraft, whatToLog, log, false); + rerunAircraft.setModel(matchedModelMs); + CStatusMessageList log2ndRun; + matchedModelMs = CAircraftMatcher::getClosestMatch(rerunAircraft, whatToLog, log ? &log2ndRun : nullptr, false); + if (log) { log->push_back(log2ndRun); } + + // the script can fuckup the model, leading to an empty model string or such + matchedModelMs.setCallsign(remoteAircraft.getCallsign()); + if (matchedModelMs.hasModelString()) + { + matchedModel = matchedModelMs; + } + else + { + CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QStringLiteral("Matching script: Ignoring model without model string after running the script")); + } } } else @@ -453,7 +470,10 @@ namespace BlackCore return matchedModel; } - CAircraftModel CAircraftMatcher::reverseLookupModel(const CCallsign &callsign, const CAircraftIcaoCode &networkAircraftIcao, const CAirlineIcaoCode &networkAirlineIcao, const QString &networkLiveryInfo, const QString &networkModelString, const CAircraftMatcherSetup &setup, CAircraftModel::ModelType type, CStatusMessageList *log) + CAircraftModel CAircraftMatcher::reverseLookupModel( + const CCallsign &callsign, const CAircraftIcaoCode &networkAircraftIcao, + const CAirlineIcaoCode &networkAirlineIcao, const QString &networkLiveryInfo, const QString &networkModelString, + const CAircraftMatcherSetup &setup, const CAircraftModelList &modelSet, CAircraftModel::ModelType type, CStatusMessageList *log) { Q_UNUSED(setup); @@ -462,19 +482,18 @@ namespace BlackCore CAircraftModel model(networkModelString, type, {}, networkAircraftIcao, livery); model.setCallsign(callsign); - model = CAircraftMatcher::reverseLookupModel(model, networkLiveryInfo, setup, log); + model = CAircraftMatcher::reverseLookupModel(model, networkLiveryInfo, setup, modelSet, log); model.setModelType(CAircraftModel::TypeReverseLookup); return model; } - MatchingScriptReturnValues CAircraftMatcher::reverseLookupScript(const CAircraftModel &inModel, const CAircraftMatcherSetup &setup, CStatusMessageList *log) + MatchingScriptReturnValues CAircraftMatcher::reverseLookupScript(const CAircraftModel &inModel, const CAircraftMatcherSetup &setup, const CAircraftModelList &modelSet, CStatusMessageList *log) { if (!setup.doRunMsReverseLookupScript()) { return MatchingScriptReturnValues(inModel); } if (!sApp || sApp->isShuttingDown() || !sApp->hasWebDataServices()) { return inModel; } const QString js = CFileUtils::readFileToString(setup.getMsReverseLookupFile()); - static const CAircraftModelList noModelSet; - const MatchingScriptReturnValues rv = CAircraftMatcher::matchingScript(js, inModel, inModel, setup, noModelSet, ReverseLookup, log); + const MatchingScriptReturnValues rv = CAircraftMatcher::matchingScript(js, inModel, inModel, setup, modelSet, ReverseLookup, log); return rv; } @@ -508,6 +527,7 @@ namespace BlackCore { CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Matching script (%1): '%2'").arg(msToString(ms), lf)); CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Matching script input model (%1): '%2'").arg(inModel.toQString(true))); + CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Matching script models: %1").arg(modelSet.coverageSummary())); } QJSEngine engine; @@ -526,7 +546,7 @@ namespace BlackCore MSInOutValues matchedObject(matchedModel); // same as inModel for reverse lookup matchedObject.evaluateChanges(inModel.getAircraftIcaoCode(), inModel.getAirlineIcaoCode()); MSInOutValues outObject(matchedModel); // set default values for out object - MSModelSet modelSetObject(modelSet); // empty in reverse lookup + MSModelSet modelSetObject(modelSet); // as passed modelSetObject.initByAircraftAndAirline(inModel.getAircraftIcaoCode(), inModel.getAirlineIcaoCode()); MSWebServices webServices; // web services encapsulated @@ -569,19 +589,6 @@ namespace BlackCore // rerun rv.rerun = reverseModelProcessed->isRerun(); - // changed model by model string? - if (reverseModelProcessed->hasChangedModelString(inModel.getModelString())) - { - const CAircraftModel model = sApp->getWebDataServices()->getModelForModelString(reverseModelProcessed->getModelString()); - if (model.hasValidDbKey()) - { - // found full model from DB - rv.model = model; - rv.modified = true; - break; - } - } - // changed model by model id? if (reverseModelProcessed->hasChangedModelId(inModel)) { @@ -595,6 +602,32 @@ namespace BlackCore } } + // changed model by model string? + if (reverseModelProcessed->hasChangedModelString(inModel.getModelString())) + { + const QString modelString = reverseModelProcessed->getModelString(); + const CAircraftModel model = sApp->getWebDataServices()->getModelForModelString(modelString); + if (model.hasValidDbKey()) + { + // found full model from DB + rv.model = model; + rv.modified = true; + break; + } + + // search for model string in set, even if it is not in the DB + const CAircraftModel modeSetModel = CAircraftMatcher::reverseLookupModelStringInSet(modelString, callsign, modelSet, true, log); + if (modeSetModel.hasModelString()) + { + CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Matching script using model from set: '%1'").arg(modelString)); + + // NON DB model from model set + rv.model = modeSetModel; + rv.modified = true; + break; + } + } + // changed aircraft ICAO if (reverseModelProcessed->hasChangedAircraftIcao(matchedModel.getAircraftIcaoCode())) { @@ -648,7 +681,7 @@ namespace BlackCore return rv; } - CAircraftModel CAircraftMatcher::reverseLookupModel(const CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const CAircraftMatcherSetup &setup, CStatusMessageList *log) + CAircraftModel CAircraftMatcher::reverseLookupModel(const CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const CAircraftMatcherSetup &setup, const CAircraftModelList &modelSet, CStatusMessageList *log) { if (!sApp || sApp->isShuttingDown() || !sApp->hasWebDataServices()) { return CAircraftModel(); } @@ -676,13 +709,24 @@ namespace BlackCore } else { + const QString modelString = modelToLookup.getModelString(); + // if we find the model here we have a fully defined DB model - const CAircraftModel modelFromDb = CAircraftMatcher::reverseLookupModelString(modelToLookup.getModelString(), callsign, setup.isReverseLookupModelString(), log); + const CAircraftModel modelFromDb = CAircraftMatcher::reverseLookupModelStringInDB(modelString, callsign, setup.isReverseLookupModelString(), log); if (modelFromDb.hasValidDbKey()) { model = modelFromDb; break; // done here } + + // const bool useNonDbEntries = setup.isDbDataOnly(); + const bool useNonDbEntries = true; + const CAircraftModel modelFromSet = CAircraftMatcher::reverseLookupModelStringInSet(modelString, callsign, modelSet, useNonDbEntries, log); + if (modelFromSet.hasModelString()) + { + model = modelFromSet; + break; // done here + } } } @@ -821,24 +865,26 @@ namespace BlackCore return model; } - CAircraftModel CAircraftMatcher::reverseLookupModelMs(const CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const CAircraftMatcherSetup &setup, CStatusMessageList *log) + CAircraftModel CAircraftMatcher::reverseLookupModelMs(const CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const CAircraftMatcherSetup &setup, const CAircraftModelList &modelSet, CStatusMessageList *log) { - CAircraftModel reverseModel = reverseLookupModel(modelToLookup, networkLiveryInfo, setup, log); + CAircraftModel reverseModel = reverseLookupModel(modelToLookup, networkLiveryInfo, setup, modelSet, log); if (!setup.doRunMsReverseLookupScript()) { return reverseModel; } const CCallsign cs = modelToLookup.getCallsign(); - const MatchingScriptReturnValues rv = CAircraftMatcher::reverseLookupScript(reverseModel, setup, log); + const MatchingScriptReturnValues rv = CAircraftMatcher::reverseLookupScript(reverseModel, setup, modelSet, log); if (rv.runScriptModifiedAndRerun()) { CLogUtilities::addLogDetailsToList(log, cs, QStringLiteral("Matching script: Modified value and requested rerun")); + + // no script the 2nd time CAircraftMatcherSetup setupRerun(setup); setupRerun.resetReverseLookup(); - reverseModel = CAircraftMatcher::reverseLookupModel(rv.model, networkLiveryInfo, setupRerun, log); + reverseModel = CAircraftMatcher::reverseLookupModel(rv.model, networkLiveryInfo, setupRerun, modelSet, log); return reverseModel; } return (rv.runScriptAndModified() ? rv.model : reverseModel); } - CAircraftModel CAircraftMatcher::reverseLookupModelString(const QString &modelString, const CCallsign &callsign, bool doLookupString, CStatusMessageList *log) + CAircraftModel CAircraftMatcher::reverseLookupModelStringInDB(const QString &modelString, const CCallsign &callsign, bool doLookupString, CStatusMessageList *log) { if (!sApp || sApp->isShuttingDown() || !sApp->hasWebDataServices()) { return CAircraftModel(); } if (!doLookupString) @@ -868,6 +914,48 @@ namespace BlackCore return model; } + CAircraftModel CAircraftMatcher::reverseLookupModelStringInSet(const QString &modelString, const CCallsign &callsign, const CAircraftModelList &modelSet, bool useNonDbEntries, CStatusMessageList *log) + { + if (!sApp || sApp->isShuttingDown() || !sApp->hasWebDataServices()) { return CAircraftModel(); } + if (modelString.isEmpty()) + { + if (log) { CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Empty model string for lookup in %1 models").arg(modelSet.size())); } + return CAircraftModel(); + } + if (modelSet.isEmpty()) + { + if (log) { CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Empty models, ignoring '%1'").arg(modelString)); } + return CAircraftModel(); + } + + CAircraftModel model = modelSet.findFirstByModelStringOrDefault(modelString, Qt::CaseInsensitive); + if (!model.hasModelString()) + { + if (log) { CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Model '%1' not found in %2 models").arg(modelString).arg(modelSet.size())); } + return CAircraftModel(); + } + + const bool isDBModel = model.hasValidDbKey(); + if (log) + { + if (isDBModel) + { + CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Found DB model in %1 models for model string '%2'").arg(modelSet.size()).arg(model.getModelStringAndDbKey())); + } + else + { + CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Found NON DB model in %1 models for model string '%2'").arg(modelSet.size()).arg(model.getModelString())); + } + } + + if (!isDBModel && !useNonDbEntries) { return CAircraftModel(); } // ignore DB entries + + // found + model.setCallsign(callsign); + model.setModelType(isDBModel ? CAircraftModel::TypeReverseLookup : CAircraftModel::TypeOwnSimulatorModel); + return model; + } + CAircraftModel CAircraftMatcher::reverseLookupModelId(int id, const CCallsign &callsign, CStatusMessageList *log) { if (!sApp || sApp->isShuttingDown() || !sApp->hasWebDataServices()) { return CAircraftModel(); } diff --git a/src/blackcore/aircraftmatcher.h b/src/blackcore/aircraftmatcher.h index 504779105..31bd81211 100644 --- a/src/blackcore/aircraftmatcher.h +++ b/src/blackcore/aircraftmatcher.h @@ -117,7 +117,7 @@ namespace BlackCore //! Run the network reverse lookup script //! \threadsafe //! \ingroup reverselookup - static BlackMisc::Simulation::MatchingScriptReturnValues reverseLookupScript(const BlackMisc::Simulation::CAircraftModel &inModel, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, BlackMisc::CStatusMessageList *log); + static BlackMisc::Simulation::MatchingScriptReturnValues reverseLookupScript(const BlackMisc::Simulation::CAircraftModel &inModel, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, const BlackMisc::Simulation::CAircraftModelList &modelSet, BlackMisc::CStatusMessageList *log); //! Run the matching stage lookup script //! \threadsafe @@ -138,6 +138,7 @@ namespace BlackCore const BlackMisc::Aviation::CAircraftIcaoCode &networkAircraftIcao, const BlackMisc::Aviation::CAirlineIcaoCode &networkAirlineIcao, const QString &networkLiveryInfo, const QString &networkModelString, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, + const BlackMisc::Simulation::CAircraftModelList &modelSet, BlackMisc::Simulation::CAircraftModel::ModelType type, BlackMisc::CStatusMessageList *log); @@ -149,6 +150,7 @@ namespace BlackCore const BlackMisc::Simulation::CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, + const BlackMisc::Simulation::CAircraftModelList &modelSet, BlackMisc::CStatusMessageList *log); //! Try to find the corresponding data in DB and get best information for following matching @@ -159,16 +161,26 @@ namespace BlackCore const BlackMisc::Simulation::CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, + const BlackMisc::Simulation::CAircraftModelList &modelSet, BlackMisc::CStatusMessageList *log); //! Try to find model by model string //! \threadsafe //! \ingroup reverselookup - static BlackMisc::Simulation::CAircraftModel reverseLookupModelString( + static BlackMisc::Simulation::CAircraftModel reverseLookupModelStringInDB( const QString &modelString, const BlackMisc::Aviation::CCallsign &callsign, bool doLookupString, BlackMisc::CStatusMessageList *log); + //! Try to find model by model string in set + //! \threadsafe + //! \remark mostly needed to work witn NON-DB values in matching script + //! \ingroup reverselookup + static BlackMisc::Simulation::CAircraftModel reverseLookupModelStringInSet( + const QString &modelString, + const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Simulation::CAircraftModelList &modelSet, + bool useNonDbEntries, BlackMisc::CStatusMessageList *log); + //! Try to find model by id //! \threadsafe //! \ingroup reverselookup diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index 8e1996396..4f561b68d 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -847,13 +847,14 @@ namespace BlackCore if (hasAnyId) { this->markAsSwiftClient(callsign); } CAircraftModel lookupModel; // result + const CAircraftModelList modelSet = this->getModelSet(); const CAircraftMatcherSetup setup = m_matchingSettings.get(); do { // directly check model string if (!modelString.isEmpty()) { - lookupModel = CAircraftMatcher::reverseLookupModelString(modelString, callsign, setup.isReverseLookupModelString(), log); + lookupModel = CAircraftMatcher::reverseLookupModelStringInDB(modelString, callsign, setup.isReverseLookupModelString(), log); if (lookupModel.hasValidDbKey()) { break; } // found by model string } @@ -930,7 +931,7 @@ namespace BlackCore // INFO: CModelMatcherComponent::reverseLookup() contains the simulated lookup // changed with T701: resolve first against model set, then all DB data // if an airline is ambiguous most likely the one in the set is the best choice - airlineIcao = CAircraftMatcher::failoverValidAirlineIcaoDesignatorModelsFirst(callsign, airlineIcaoString, airlineIcaoFromFp, true, airlineNameFromFp, telephonyFromFp, this->getModelSet(), log); + airlineIcao = CAircraftMatcher::failoverValidAirlineIcaoDesignatorModelsFirst(callsign, airlineIcaoString, airlineIcaoFromFp, true, airlineNameFromFp, telephonyFromFp, modelSet, log); // not found, create a seatch patterm if (!airlineIcao.isLoadedFromDb()) @@ -948,7 +949,7 @@ namespace BlackCore CLogUtilities::addLogDetailsToList(log, callsign, QStringLiteral("Used airline ICAO: '%1'").arg(airlineIcao.toQString(true)), CAirspaceMonitor::getLogCategories()); // matching script is used below - lookupModel = CAircraftMatcher::reverseLookupModel(callsign, aircraftIcao, airlineIcao, liveryString, modelString, setup, type, log); + lookupModel = CAircraftMatcher::reverseLookupModel(callsign, aircraftIcao, airlineIcao, liveryString, modelString, setup, modelSet, type, log); } while (false); @@ -958,7 +959,7 @@ namespace BlackCore // script if (runMatchinScript && setup.doRunMsReverseLookupScript()) { - const MatchingScriptReturnValues rv = CAircraftMatcher::reverseLookupScript(lookupModel, setup, log); + const MatchingScriptReturnValues rv = CAircraftMatcher::reverseLookupScript(lookupModel, setup, modelSet, log); if (rv.runScriptAndModified()) { if (rv.runScriptAndRerun()) diff --git a/src/blackgui/components/modelmatchercomponent.cpp b/src/blackgui/components/modelmatchercomponent.cpp index f4501d111..34c51c5b4 100644 --- a/src/blackgui/components/modelmatchercomponent.cpp +++ b/src/blackgui/components/modelmatchercomponent.cpp @@ -165,7 +165,9 @@ namespace BlackGui if (ui->cb_withReverseLookup->isChecked()) { const QString liveryString(ui->comp_LiverySelector->getRawCombinedCode()); - const CAircraftModel reverseModel = CAircraftMatcher::reverseLookupModelMs(remoteAircraft.getModel(), liveryString, m_matcher.getSetup(), &msgs); + const CAircraftModelList modelSet = m_matcher.getModelSet(); + const CAircraftMatcherSetup setup = m_matcher.getSetup(); + const CAircraftModel reverseModel = CAircraftMatcher::reverseLookupModelMs(remoteAircraft.getModel(), liveryString, setup, modelSet, &msgs); remoteAircraft.setModel(reverseModel); // current model } @@ -187,10 +189,11 @@ namespace BlackGui CStatusMessageList msgs; m_matcher.setDefaultModel(CModelMatcherComponent::defaultModel()); + const CAircraftModelList modelSet = m_matcher.getModelSet(); const CAircraftMatcherSetup setup = m_matcher.getSetup(); const CSimulatedAircraft remoteAircraft(createAircraft()); const QString livery(ui->comp_LiverySelector->getRawCombinedCode()); - const CAircraftModel matched = CAircraftMatcher::reverseLookupModelMs(remoteAircraft.getModel(), livery, setup, &msgs); + const CAircraftModel matched = CAircraftMatcher::reverseLookupModelMs(remoteAircraft.getModel(), livery, setup, modelSet, &msgs); ui->te_Results->setText(matched.toQString(true)); ui->tvp_ResultMessages->updateContainer(msgs); } @@ -275,12 +278,12 @@ namespace BlackGui return model; } - MatchingScriptReturnValues CModelMatcherComponent::matchingScript(const CAircraftModel &inModel, const CAircraftMatcherSetup &setup, CStatusMessageList &msgs) + MatchingScriptReturnValues CModelMatcherComponent::matchingScript(const CAircraftModel &inModel, const CAircraftMatcherSetup &setup, const CAircraftModelList &modelSet, CStatusMessageList &msgs) { // Script if (setup.doRunMsReverseLookupScript()) { - const MatchingScriptReturnValues rv = CAircraftMatcher::reverseLookupScript(inModel, setup, &msgs); + const MatchingScriptReturnValues rv = CAircraftMatcher::reverseLookupScript(inModel, setup, modelSet, &msgs); if (rv.runScriptAndModified()) { return rv; diff --git a/src/blackgui/components/modelmatchercomponent.h b/src/blackgui/components/modelmatchercomponent.h index b5df015fe..0d88b96ed 100644 --- a/src/blackgui/components/modelmatchercomponent.h +++ b/src/blackgui/components/modelmatchercomponent.h @@ -11,8 +11,8 @@ #ifndef BLACKGUI_COMPONENT_MODELMATCHERCOMPONENT_H #define BLACKGUI_COMPONENT_MODELMATCHERCOMPONENT_H -#include "blackcore/aircraftmatcher.h" #include "blackgui/blackguiexport.h" +#include "blackcore/aircraftmatcher.h" #include "blackmisc/simulation/settings/modelmatchersettings.h" #include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/simulation/simulatedaircraft.h" @@ -95,7 +95,7 @@ namespace BlackGui BlackMisc::Simulation::CAircraftModel defaultModel() const; //! Run matching script - static BlackMisc::Simulation::MatchingScriptReturnValues matchingScript(const BlackMisc::Simulation::CAircraftModel &inModel, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, BlackMisc::CStatusMessageList &msgs); + static BlackMisc::Simulation::MatchingScriptReturnValues matchingScript(const BlackMisc::Simulation::CAircraftModel &inModel, const BlackMisc::Simulation::CAircraftMatcherSetup &setup, const BlackMisc::Simulation::CAircraftModelList &modelSet, BlackMisc::CStatusMessageList &msgs); QScopedPointer ui; QPointer m_workbenchView; //!< an external workbenc diff --git a/src/blackmisc/simulation/aircraftmatchersetup.h b/src/blackmisc/simulation/aircraftmatchersetup.h index 580aef589..36d3b5857 100644 --- a/src/blackmisc/simulation/aircraftmatchersetup.h +++ b/src/blackmisc/simulation/aircraftmatchersetup.h @@ -134,6 +134,9 @@ namespace BlackMisc void resetReverseLookup(); //! @} + //! DB data? + bool isDbDataOnly() const { return this->getMatchingMode().testFlag(ExcludeNoDbData); } + //! Get matching files @{ const QString &getMsReverseLookupFile() const { return m_msReverseLookupFile; } const QString &getMsMatchingStageFile() const { return m_msMatchingStageFile; } @@ -230,7 +233,7 @@ namespace BlackMisc //! Mode by flags static MatchingMode matchingMode(bool revModelString, bool revLiveryIds, - bool byModelString, bool byIcaoDataAircraft1st, bool byIcaoDataAirline1st, + bool byModelString, bool byIcaoDataAircraft1st, bool byIcaoDataAirline1st, bool byFamily, bool byLivery, bool byCombinedType, bool byForceMilitary, bool byForceCivilian, bool byVtol, bool byGliderCategory, bool byMilitaryCategory, bool bySmallAircraftCategory,