From 2519a876809403e98b19d9152de6f7b9e7ace112 Mon Sep 17 00:00:00 2001 From: tzobler Date: Sat, 31 Jan 2026 12:22:41 +0100 Subject: [PATCH] refactor: Extend aircraft model classes for MSFS24 --- src/core/aircraftmatcher.cpp | 5 +++- src/core/airspacemonitor.cpp | 27 ++++++++++++----- src/misc/simulation/aircraftmodel.cpp | 36 +++++++++++++++++++++++ src/misc/simulation/aircraftmodel.h | 25 +++++++++++++++- src/misc/simulation/aircraftmodellist.cpp | 12 ++++++++ src/misc/simulation/aircraftmodellist.h | 3 ++ src/misc/simulation/simulatedaircraft.h | 9 ++++++ 7 files changed, 107 insertions(+), 10 deletions(-) diff --git a/src/core/aircraftmatcher.cpp b/src/core/aircraftmatcher.cpp index 8d1163a91..e03ea86ca 100644 --- a/src/core/aircraftmatcher.cpp +++ b/src/core/aircraftmatcher.cpp @@ -1657,7 +1657,10 @@ namespace swift::core if (modelsCleaned.isEmpty()) { // error to force popup - CLogMessage(this).error(u"No models for matching ('%1'), swift without a model set will not work!") + // TODO TZ extend commend + CLogMessage(this).error( + u"No models for matching ('%1'), swift without a model set will not work! Note: If you are using " + u"MSFS2024 and starting the GUI for the first time, it may take some time for the model set to load.") << simulator.toQString(); } else if (!duplicateModels.isEmpty()) diff --git a/src/core/airspacemonitor.cpp b/src/core/airspacemonitor.cpp index a4ccacfe0..5daf683eb 100644 --- a/src/core/airspacemonitor.cpp +++ b/src/core/airspacemonitor.cpp @@ -547,6 +547,12 @@ namespace swift::core if (!this->isConnectedAndNotShuttingDown()) { return; } Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "missing callsign"); + CStatusMessageList reverseLookupMessages; + CCallsign::addLogDetailsToList(&reverseLookupMessages, callsign, + QStringLiteral("CAirspaceMonitor::sendReadyForModelMatching Flag: %1").arg(rf), + CAirspaceMonitor::getLogCategories()); + // TODO remove + // set flag and init ts Readiness &readiness = this->addMatchingReadinessFlag(callsign, rf); @@ -863,13 +869,18 @@ namespace swift::core CAirspaceMonitor::getLogCategories()); const CClient client = this->getClientOrDefaultForCallsign(callsign); - this->addOrUpdateAircraftInRange(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery, - client.getQueriedModelString(), CAircraftModel::TypeQueriedFromNetwork, - pReverseLookupMessages); - this->addReverseLookupMessages(callsign, reverseLookupMessages); - this->sendReadyForModelMatching(callsign, ReceivedIcaoCodes); // ICAO codes received + const CSimulatedAircraft aircraft = this->addOrUpdateAircraftInRange( + callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery, client.getQueriedModelString(), + CAircraftModel::TypeQueriedFromNetwork, pReverseLookupMessages); - emit this->requestedNewAircraft(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery); + // we do not change manually assigned models + if (aircraft.getModel().getModelType() != CAircraftModel::TypeManuallySet) + { + this->addReverseLookupMessages(callsign, reverseLookupMessages); + this->sendReadyForModelMatching(callsign, ReceivedIcaoCodes); // ICAO codes received + + emit this->requestedNewAircraft(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery); + } } CAircraftModel CAirspaceMonitor::reverseLookupModelWithFlightplanData( @@ -1176,8 +1187,8 @@ namespace swift::core const CSimulatedAircraft aircraft = this->getAircraftInRangeForCallsign(callsign); if (aircraft.hasValidCallsign()) { - // only if we do not have a DB model yet - if (!aircraft.getModel().hasValidDbKey()) + // we do not change manually assigned models (msfs2024) + if (!aircraft.getModel().hasValidDbKey() && aircraft.getModelType() != CAircraftModel::TypeManuallySet) { CAircraftModel model = this->reverseLookupModelWithFlightplanData(callsign, aircraftIcao, airlineIcao, livery, modelString, modelType, log); diff --git a/src/misc/simulation/aircraftmodel.cpp b/src/misc/simulation/aircraftmodel.cpp index 78685515e..9485c67ae 100644 --- a/src/misc/simulation/aircraftmodel.cpp +++ b/src/misc/simulation/aircraftmodel.cpp @@ -42,6 +42,10 @@ namespace swift::misc::simulation : m_modelString(model.trimmed().toUpper()), m_modelType(type) {} + CAircraftModel::CAircraftModel(const QString &model, const QString &livery, CAircraftModel::ModelType type) + : m_modelString(model.trimmed().toUpper()), m_modelLivery(livery.trimmed().toUpper()), m_modelType(type) + {} + CAircraftModel::CAircraftModel(const QString &model, CAircraftModel::ModelType type, const CAircraftIcaoCode &icao, const CLivery &livery) : m_aircraftIcao(icao), m_livery(livery), m_modelString(model.trimmed().toUpper()), m_modelType(type) @@ -241,6 +245,12 @@ namespace swift::misc::simulation return this->getAllModelStringsAndAliases() % " " % this->getDbKeyAsStringInParentheses(); } + QString CAircraftModel::getMsfs2024ModelString() + { + m_modelString = m_modelString.trimmed().toUpper() % u" " % m_modelLivery.trimmed().toUpper(); + return m_modelString; + } + bool CAircraftModel::isVtol() const { return this->getAircraftIcaoCode().isVtol(); } QVariant CAircraftModel::propertyByIndex(swift::misc::CPropertyIndexRef index) const @@ -588,6 +598,23 @@ namespace swift::misc::simulation return (sim.isFG()) ? this->getSwiftLiveryString(true, false, false) : this->getSwiftLiveryString(); } + QString CAircraftModel::getShortModelString() const + { + + QString shortModelString = m_modelString; + if (m_modelString.contains(m_modelLivery)) + { + int lastIndex = m_modelString.lastIndexOf(m_modelLivery); + + if (lastIndex != -1) + { + const QString newModelString = m_modelString.left(lastIndex); + shortModelString = newModelString; + } + } + return shortModelString; + } + DBTripleIds CAircraftModel::parseNetworkLiveryString(const QString &liveryString) { // "swift_m22l33a11" @@ -770,6 +797,13 @@ namespace swift::misc::simulation return (p.contains(path, cs)); } + bool CAircraftModel::matchesModelStringAndLivery(const QString &modelString, const QString &modelLivery, + Qt::CaseSensitivity sensitivity) const + { + return (stringCompare(modelString, m_modelString, sensitivity) && + stringCompare(modelLivery, m_modelLivery, sensitivity)); + } + bool CAircraftModel::matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const { return stringCompare(modelString, m_modelString, sensitivity); @@ -1003,6 +1037,7 @@ namespace swift::misc::simulation const QString modelName(json.value(prefix % u"name").toString()); const QString modelMode(json.value(prefix % u"mode").toString()); const QString parts(json.value(prefix % u"parts").toString()); + const QString modelLivery(json.value(prefix % u"modellivery").toString()); // check for undefined to rule out 0ft values const QJsonValue cgjv = json.value(prefix % u"cgft"); @@ -1012,6 +1047,7 @@ namespace swift::misc::simulation const CSimulatorInfo simInfo = CSimulatorInfo::fromDatabaseJson(json, prefix); CAircraftModel model(modelString, CAircraftModel::TypeDatabaseEntry, simInfo, modelName, modelDescription); model.setModelStringAlias(modelStringAlias); + model.setModelLivery(modelLivery); // msfs2024 model.setModelModeAsString(modelMode); model.setSupportedParts(parts); model.setCG(cg); diff --git a/src/misc/simulation/aircraftmodel.h b/src/misc/simulation/aircraftmodel.h index 575751e07..c289a672a 100644 --- a/src/misc/simulation/aircraftmodel.h +++ b/src/misc/simulation/aircraftmodel.h @@ -83,7 +83,8 @@ namespace swift::misc TypeManuallySet, //!< manually set, e.g. from GUI TypeOwnSimulatorModel, //!< represents own simulator model (AI model, model on disk) TypeVPilotRuleBased, //!< based on a vPilot rule - TypeTerrainProbe //!< peudo aircraft used for terrain probing (FSX) + TypeTerrainProbe, //!< peudo aircraft used for terrain probing (FSX) + TypeOwnSimulatorLivery //!< represents own simulator model livery (msfs2024) }; //! Mode, decides if a model is supposed to be used in the model set for model matching @@ -136,6 +137,9 @@ namespace swift::misc //! Constructor. CAircraftModel(const QString &model, ModelType type); + //! Constructor. + CAircraftModel(const QString &model, const QString &livery, ModelType type); + //! Constructor. CAircraftModel(const QString &model, ModelType type, const aviation::CAircraftIcaoCode &icao, const aviation::CLivery &livery); @@ -181,12 +185,21 @@ namespace swift::misc //! Model key, either queried or loaded from simulator model const QString &getModelString() const { return m_modelString; } + //! Model Livery, part of model string in MSFS 2024 + const QString &getModelLivery() const { return m_modelLivery; } + //! Model string and DB key (if available) QString getModelStringAndDbKey() const; //! Model string void setModelString(const QString &modelString) { m_modelString = modelString.trimmed().toUpper(); } + //! Model livery msfs2024 + void setModelLivery(const QString &modelLivery) { m_modelLivery = modelLivery.trimmed().toUpper(); } + + //! Model livery whitout part for lifery msfs2024 + QString getShortModelString() const; + //! Model key, either queried or loaded from simulator model const QString &getModelStringAlias() const { return m_modelStringAlias; } @@ -196,6 +209,9 @@ namespace swift::misc //! Get model string and aliases QString getAllModelStringsAliasesAndDbKey() const; + //! Get model string and Livery + QString getMsfs2024ModelString(); + //! Model string alias void setModelStringAlias(const QString &alias) { m_modelStringAlias = alias.trimmed().toUpper(); } @@ -419,6 +435,10 @@ namespace swift::misc //! Matches model string? bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const; + //! Matches model string and livery? + bool matchesModelStringAndLivery(const QString &modelString, const QString &modelLivery, + Qt::CaseSensitivity sensitivity) const; + //! Matches model string or alias? bool matchesModelStringOrAlias(const QString &modelString, Qt::CaseSensitivity sensitivity) const; @@ -567,11 +587,13 @@ namespace swift::misc CSimulatorInfo m_simulator; //!< model for given simulator CDistributor m_distributor; //!< who designed or distributed the model QString m_modelString; //!< Simulator model key, unique + QString m_modelLivery; //!< Simulator livery (msfs2024) QString m_modelStringAlias; //!< Simulator model key alias, unique QString m_name; //!< Model name QString m_description; //!< descriptive text QString m_fileName; //!< file name QString m_supportedParts; //!< supported parts + QString m_shortModelString; //!< cached short model string qint64 m_fileTimestamp = -1; //!< file timestamp of originating file (if applicable) ModelType m_modelType = TypeUnknown; //!< model string is coming representing ...? ModelMode m_modelMode = Include; //!< model mode (include / exclude) @@ -591,6 +613,7 @@ namespace swift::misc SWIFT_METAMEMBER(supportedParts), SWIFT_METAMEMBER(modelString, 0, CaseInsensitiveComparison), SWIFT_METAMEMBER(modelStringAlias, 0, CaseInsensitiveComparison), + SWIFT_METAMEMBER(modelLivery, 0, CaseInsensitiveComparison), SWIFT_METAMEMBER(name), SWIFT_METAMEMBER(description, 0, DisabledForComparison), SWIFT_METAMEMBER(fileName, 0, DisabledForComparison), diff --git a/src/misc/simulation/aircraftmodellist.cpp b/src/misc/simulation/aircraftmodellist.cpp index 3acdad57e..e8c16e818 100644 --- a/src/misc/simulation/aircraftmodellist.cpp +++ b/src/misc/simulation/aircraftmodellist.cpp @@ -901,6 +901,18 @@ namespace swift::misc::simulation return ms; } + QStringList CAircraftModelList::getModelStringAndLiveryList(bool sort) const + { + QStringList ms; + for (const CAircraftModel &model : *this) + { + if (!model.hasModelString()) { continue; } + ms.append(model.getModelString() + "{" + model.getModelLivery() + "}"); + } + if (sort) { ms.sort(Qt::CaseInsensitive); } + return ms; + } + QSet CAircraftModelList::getModelStringSet() const { CSetBuilder ms; diff --git a/src/misc/simulation/aircraftmodellist.h b/src/misc/simulation/aircraftmodellist.h index a429e27cd..2046f21c1 100644 --- a/src/misc/simulation/aircraftmodellist.h +++ b/src/misc/simulation/aircraftmodellist.h @@ -393,6 +393,9 @@ namespace swift::misc //! Model strings QStringList getModelStringList(bool sort = true) const; + //! Model strings and Livery codes + QStringList getModelStringAndLiveryList(bool sort = true) const; + //! Model strings as set QSet getModelStringSet() const; diff --git a/src/misc/simulation/simulatedaircraft.h b/src/misc/simulation/simulatedaircraft.h index 0ecf5ba99..91d7d666b 100644 --- a/src/misc/simulation/simulatedaircraft.h +++ b/src/misc/simulation/simulatedaircraft.h @@ -406,6 +406,12 @@ namespace swift::misc //! Get model string const QString &getModelString() const { return m_models[CurrentModel].getModelString(); } + //! Get model Livery MSFS2024 + const QString &getLiveryString() const { return m_models[CurrentModel].getModelLivery(); } + + //! Get short model string (without livery msfs2024) + const QString getShortModelString() const { return m_models[CurrentModel].getShortModelString(); } + //! Set model string void setModelString(const QString &modelString); @@ -483,6 +489,9 @@ namespace swift::misc //! \copydoc swift::misc::mixin::Icon::toIcon() CIcons::IconIndex toIcon() const { return m_callsign.toIcon(); } + //! Get model type + int getModelType() const { return m_models[CurrentModel].getModelType(); } + private: static constexpr int CurrentModel = 0; //!< m_models static constexpr int NetworkModel = 1; //!< m_models