feat: Implementation of the msfs2024 model mapping is ready for testing

This commit is contained in:
tzobler
2025-11-07 22:09:24 +01:00
parent 6700f66e1c
commit f034d31694
12 changed files with 136 additions and 37 deletions

View File

@@ -1710,6 +1710,14 @@ namespace swift::core
const QString &livery)
{
Q_UNUSED(livery)
// TODO TZ remove after testing
CLogMessage(this).info(u"CAircraftMatcher::onIcaoCodesReceived CHECK:"
u"callsign %1 "
u"aircraftIcao %2 "
u"airlineIcao %3 "
u"livery %4 ")
<< callsign << aircraftIcao << airlineIcao << livery;
Q_ASSERT_X(sApp && sApp->hasWebDataServices(), Q_FUNC_INFO, "Missing web data services");
if (m_modelSet.isEmpty()) { return; } // ignore empty sets to not create silly stats
if (sessionId.isEmpty()) { return; }

View File

@@ -773,6 +773,14 @@ namespace swift::core
const QString &aircraftIcaoDesignator,
const QString &combinedAircraftType, const QString &modelString)
{
// TODO TZ remove when testing is done
CLogMessage(this).info(u"CAirspaceMonitor::onCustomFSInnPacketReceived CHECK:"
u"callsign %1 "
u"airlineIcaoDesignator %2 "
u"aircraftIcaoDesignator %3 "
u"modelString %4 ")
<< callsign << airlineIcaoDesignator << aircraftIcaoDesignator << modelString;
// it can happen this is called before any queries
// ES sends FsInn packets for callsigns such as ACCGER1, which are hard to distinguish
// 1) checking if they are already in the list checks again ATC position which is safe
@@ -834,9 +842,9 @@ namespace swift::core
// in order not to override swift livery string data, we ignore those
if (!usedModelString.isEmpty())
{
this->addOrUpdateAircraftInRange(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, QString(),
usedModelString, CAircraftModel::TypeFSInnData,
pReverseLookupMessages);
const CSimulatedAircraft aircraft = this->addOrUpdateAircraftInRange(
callsign, aircraftIcaoDesignator, airlineIcaoDesignator, QString(), usedModelString,
CAircraftModel::TypeFSInnData, pReverseLookupMessages);
this->addReverseLookupMessages(callsign, reverseLookupMessages);
}
this->sendReadyForModelMatching(callsign, ReceivedFsInnPacket); // from FSInn
@@ -846,6 +854,14 @@ namespace swift::core
void CAirspaceMonitor::onIcaoCodesReceived(const CCallsign &callsign, const QString &aircraftIcaoDesignator,
const QString &airlineIcaoDesignator, const QString &livery)
{
// TODO TZ remove when testing is done
CLogMessage(this).info(u"CAirspaceMonitor::onIcaoCodesReceived CHECK:"
u"callsign %1 "
u"aircraftIcaoDesignator %2 "
u"airlineIcaoDesignator %3 "
u"livery %4 ")
<< callsign << aircraftIcaoDesignator << airlineIcaoDesignator << livery;
Q_ASSERT_X(CThreadUtils::isInThisThread(this), Q_FUNC_INFO, "not in main thread");
if (!this->isConnectedAndNotShuttingDown()) { return; }
if (CBuildConfig::isLocalDeveloperDebugBuild())
@@ -865,13 +881,16 @@ 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);
if (aircraft.getModel().getModelType() != CAircraftModel::TypeManuallySet)
{
this->addReverseLookupMessages(callsign, reverseLookupMessages);
this->sendReadyForModelMatching(callsign, ReceivedIcaoCodes); // ICAO codes received
emit this->requestedNewAircraft(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery);
emit this->requestedNewAircraft(callsign, aircraftIcaoDesignator, airlineIcaoDesignator, livery);
}
}
CAircraftModel CAirspaceMonitor::reverseLookupModelWithFlightplanData(
@@ -1178,9 +1197,26 @@ namespace swift::core
const CSimulatedAircraft aircraft = this->getAircraftInRangeForCallsign(callsign);
if (aircraft.hasValidCallsign())
{
// TODO TZ at this point we have a poblem if the model has no DB key yet (msfs2024 liveries)
// only if we do not have a DB model yet
if (!aircraft.getModel().hasValidDbKey())
// int testType = aircraft.getModelType();1
CLogMessage(this).info(u"CAirspaceMonitor::addOrUpdateAircraftInRange CHECK:"
u"aircraft.getModelType %1 "
u"callsign %2 "
u"aircraftIcao %3 "
u"incomming modelType %4 ")
<< aircraft.getModelType() << callsign.toQString() << aircraftIcao << modelType;
if (!aircraft.getModel().hasValidDbKey() && aircraft.getModelType() != CAircraftModel::TypeManuallySet)
{
CLogMessage(this).warning(u"CAirspaceMonitor::reverseLookupModelWithFlightplanData "
u"aircraft.getModelType %1 "
u"callsign %2 "
u"aircraftIcao %3 "
u"incomming modelType %4 ")
<< aircraft.getModelType() << callsign.toQString() << aircraftIcao << modelType;
CAircraftModel model = this->reverseLookupModelWithFlightplanData(callsign, aircraftIcao, airlineIcao,
livery, modelString, modelType, log);
model.updateMissingParts(aircraft.getModel());

View File

@@ -1142,6 +1142,11 @@ namespace swift::core::context
if (c)
{
const CSimulatedAircraft aircraft(this->getAircraftInRangeForCallsign(callsign));
// TODO TZ
CLogMessage(this).info(u"CContextNetwork::updateAircraftModel model.getModelString %1 model.getModelLivery "
u"%2 model.getModelType %3 aircraft.getModelType '%4'")
<< model.getModelString() << model.getModelLivery() << model.getModelType() << aircraft.getModelType();
Q_ASSERT_X(!aircraft.getCallsign().isEmpty(), Q_FUNC_INFO, "missing callsign");
emit this->changedRemoteAircraftModel(aircraft, originator); // update aircraft model
}

View File

@@ -981,6 +981,15 @@ namespace swift::core
bool ISimulator::changeRemoteAircraftEnabled(const CSimulatedAircraft &aircraft)
{
if (this->isShuttingDown()) { return false; }
// TODO TZ remove after testing
CLogMessage(this).info(u"ISimulator::changeRemoteAircraftEnabled CHECK:"
u"aircraft.getModelType %1 "
u"aircraft.getModelString %2 "
u"aircraft.getLiveryString %3 ")
<< aircraft.getModelType() << aircraft.getModelString() << aircraft.getLiveryString();
;
return aircraft.isEnabled() ? this->physicallyAddRemoteAircraft(aircraft) :
this->physicallyRemoveRemoteAircraft(aircraft.getCallsign());
}

View File

@@ -41,6 +41,9 @@
#include "misc/logmessage.h"
#include "misc/network/connectionstatus.h"
#include "misc/network/entityflags.h"
// TODO TZ remove afte testing
#include "misc/network/server.h"
// TODO TZ end remove afte testing
#include "misc/network/serverlist.h"
#include "misc/simulation/aircraftmodel.h"
#include "misc/simulation/simulatedaircraft.h"
@@ -298,8 +301,14 @@ namespace swift::gui::components
{
if (!m_updatePilotOnServerChanges) { return; }
const bool vatsim = this->isVatsimNetworkTabSelected();
const CUser user = vatsim ? this->getCurrentVatsimServer().getUser() : server.getUser();
ui->form_Pilot->setUser(user);
// TODO TZ remove after testing
// const CUser user = vatsim ? this->getCurrentVatsimServer().getUser() : server.getUser();
const CUser user =
server.getServerType() != CServer::FSDServer ? this->getCurrentVatsimServer().getUser() : server.getUser();
if ((vatsim && server.getServerType() != CServer::FSDServer) ||
(!vatsim && server.getServerType() == CServer::FSDServer))
// End remove after testing
ui->form_Pilot->setUser(user);
}
void CLoginComponent::onSimulatorStatusChanged(int status)

View File

@@ -84,6 +84,7 @@ namespace swift::gui::components
&CMappingComponent::onModelsUpdateRequested);
connect(ui->tvp_AircraftModels, &CAircraftModelView::modelDataChanged, this,
&CMappingComponent::onRowCountChanged);
connect(ui->tvp_AircraftModels, &CAircraftModelView::clicked, this, &CMappingComponent::onModelSelectedInView);
connect(ui->tvp_AircraftModels, &CAircraftModelView::requestTempDisableModelsForMatching, this,
&CMappingComponent::onTempDisableModelsForMatchingRequested);
@@ -258,6 +259,12 @@ namespace swift::gui::components
ui->completer_ModelStrings->setModel(simAircraft.getModel());
}
void CMappingComponent::onModelSelectedInView(const QModelIndex &index)
{
const CAircraftModel model = ui->tvp_AircraftModels->at(index);
ui->completer_ModelStrings->setModel(model);
}
CCallsign CMappingComponent::validateRenderedCallsign()
{
const QString cs = ui->le_Callsign->text().trimmed();
@@ -326,7 +333,10 @@ namespace swift::gui::components
}
const CCallsign callsign(this->validateRenderedCallsign());
if (callsign.isEmpty()) { return; }
// Because of msfs2024, the model string contains the combination of title and livery.
const QString modelString = ui->completer_ModelStrings->getModelString();
if (modelString.isEmpty())
{
this->showOverlayHTMLMessage(CStatusMessage(this).validationError(u"Missing model for mapping"),
@@ -359,6 +369,13 @@ namespace swift::gui::components
if (aircraftFromBackend.getModelString() != modelString)
{
const CAircraftModelList models = sGui->getIContextSimulator()->getModelSetModelsStartingWith(modelString);
// TODO TZ DEBUG only for testing
const CStatusMessage msg = CStatusMessage(this).validationInfo(u"Found: %1 models for %2")
<< models.size() << modelString;
this->showOverlayMessage(msg, OverlayMessageMs);
// END testing
if (models.isEmpty())
{
const CStatusMessage msg = CStatusMessage(this).validationError(u"No model for title: '%1'")
@@ -368,6 +385,7 @@ namespace swift::gui::components
}
CAircraftModel model(models.front());
// found more than one model?
if (models.size() > 1)
{
if (models.containsModelString(modelString))
@@ -384,8 +402,10 @@ namespace swift::gui::components
model.setModelType(CAircraftModel::TypeManuallySet);
CLogMessage(this).info(u"Requesting changes for '%1'") << callsign.asString();
// enable in any case
// rendering-flag enable in any case
sGui->getIContextNetwork()->updateAircraftEnabled(aircraftFromBackend.getCallsign(), true);
// trigger model change
changed =
sGui->getIContextNetwork()->updateAircraftModel(aircraftFromBackend.getCallsign(), model, identifier());
}

View File

@@ -113,6 +113,9 @@ namespace swift::gui
//! Aircraft selected (in view)
void onAircraftSelectedInView(const QModelIndex &index);
//! Model selected (in view)
void onModelSelectedInView(const QModelIndex &index);
//! Save changed aircraft
void onSaveAircraft();

View File

@@ -412,7 +412,7 @@ namespace swift::misc
//! Get model Livery MSFS2024
const QString &getLiveryString() const { return m_models[CurrentModel].getModelLivery(); }
//! Get short model string (without livery)
//! Get short model string (without livery msfs2024)
const QString getShortModelString() const { return m_models[CurrentModel].getShortModelString(); }
//! Set model string
@@ -492,6 +492,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

View File

@@ -86,7 +86,7 @@ namespace swift::simplugin::msfs2024common
struct DataDefinitionOwnAircraftModel
{
char title[256]; //!< Aircraft model string
char livery[256]; //!< Aircraft model string
char livery[256]; //!< Aircraft livery string msfs2024
};
//! Data struct of aircraft model data
@@ -107,6 +107,7 @@ namespace swift::simplugin::msfs2024common
char atcAirlineNumber[64]; //!< airline number
char atcFlightNumber[8]; //!< flight number (168)
char title[256]; //!< Aircraft model string
char livery[256]; //!< Aircraft livery string msfs2024
};
//! Data struct of aircraft data (setable)

View File

@@ -430,20 +430,16 @@ namespace swift::simplugin::msfs2024common
// TODO TZ a message should be displayed here because the gui freezes during loading
// better: move to the background (e.g., use CWorker::fromTask(...)), avoid GUI freeze.
this->createNewModelList();
CLogMessage(this).info(u"%1 SimObjects and Liveries in vSimObjectsAndLiveries")
<< vSimObjectsAndLiveries.size();
// Cannot create children for a parent that is in a different thread.
// owner = this (QObject in main thread)
// auto *worker = CWorker::fromTask(this, "createNewModelList", [=]() {
// this->createNewModelList();
// return QVariant(); // void-Result
//});
// TODO TZ where to place this message?
// worker->then(this, [=] { CLogMessage(this).info(u"SimObjects and Liveries in vSimObjectsAndLiveries ready");
// });
auto *worker = CWorker::fromTask(this, "createNewModelList", [=]() {
this->createNewModelList();
return QVariant(); // void-Result
});
// TODO TZ where to place this message better?
worker->then(this, [=] { CLogMessage(this).info(u"SimObjects and Liveries in vSimObjectsAndLiveries ready"); });
}
void CSimulatorMsfs2024::createNewModelList()
@@ -475,6 +471,7 @@ namespace swift::simplugin::msfs2024common
model.setModelString(modelLivery.szSimObjectCombinedTitle);
model.setModelLivery(modelLivery.szLiveryName);
model.setModelType(CAircraftModel::TypeOwnSimulatorModel);
if (!modelkey) model.setModelType(CAircraftModel::TypeManuallySet);
model.setSimulator(this->getSimulatorInfo());
bool excluded = false;
@@ -528,7 +525,7 @@ namespace swift::simplugin::msfs2024common
// for (const QString &name : distributorNames) { distributorList.push_back(CDistributor(name)); }
CDistributorList distributorList = sGui->getWebDataServices()->getDistributors();
const CModelSetBuilder builder(this);
CModelSetBuilder builder(nullptr);
CModelSetBuilder::Builder options =
givenDistributorsOnly ? CModelSetBuilder::GivenDistributorsOnly : CModelSetBuilder::NoOptions;
if (dbDataOnly) { options |= CModelSetBuilder::OnlyDbData; }
@@ -1118,6 +1115,7 @@ namespace swift::simplugin::msfs2024common
});
}
// called decoupled from simconnect event queue very fast
void CSimulatorMsfs2024::updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject,
const DataDefinitionPosData &remoteAircraftData)
{
@@ -1170,6 +1168,7 @@ namespace swift::simplugin::msfs2024common
}
}
// called decoupled from simconnect event queue
void
CSimulatorMsfs2024::updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject,
const DataDefinitionRemoteAircraftModel &remoteAircraftModel)
@@ -1179,7 +1178,11 @@ namespace swift::simplugin::msfs2024common
CSimConnectObject &so = m_simConnectObjects[cs];
if (so.isPendingRemoved()) { return; }
const QString modelString(remoteAircraftModel.title);
// TODO TZ verify model and livery
QString combinedModelstring =
QString::fromUtf8(remoteAircraftModel.title) + " " + QString::fromUtf8(remoteAircraftModel.livery);
const QString modelString(combinedModelstring.trimmed());
const CLength cg(remoteAircraftModel.cgToGroundFt, CLengthUnit::ft());
so.setAircraftCG(cg);
so.setAircraftModelString(modelString);
@@ -1230,7 +1233,7 @@ namespace swift::simplugin::msfs2024common
this->updateCockpit(myAircraft.getCom1System(), myAircraft.getCom2System(), myXpdr, this->identifier());
}
void CSimulatorMsfs2024::updateMSFSTransponderMode(const DataDefinitionMSFSTransponderMode transponderMode)
void CSimulatorMsfs2024::updateMSFS2024TransponderMode(const DataDefinitionMSFSTransponderMode transponderMode)
{
auto mode = CTransponder::StateIdent;
if (!transponderMode.ident)
@@ -1390,9 +1393,10 @@ namespace swift::simplugin::msfs2024common
CLogMessage(this).warning(u"Model failed to be added: '%1' details: %2")
<< simObject.getAircraftModelString() << simObject.getAircraft().toQString(true);
CStatusMessage verifyMsg;
const bool verifiedAircraft = this->verifyFailedAircraftInfo(simObject, verifyMsg); // aircraft.cfg existing?
if (!verifyMsg.isEmpty()) { CLogMessage::preformatted(verifyMsg); }
// CStatusMessage verifyMsg;
// const bool verifiedAircraft = this->verifyFailedAircraftInfo(simObject, verifyMsg); // aircraft.cfg existing?
const bool verifiedAircraft = true;
// if (!verifyMsg.isEmpty()) { CLogMessage::preformatted(verifyMsg); }
CSimConnectObject simObjAddAgain(simObject);
simObjAddAgain.increaseAddingExceptions();
@@ -1411,6 +1415,7 @@ namespace swift::simplugin::msfs2024common
<< simObjAddAgain.getAddingExceptions() :
CLogMessage(this).warning(u"Model '%1' %2 failed verification and will be disabled")
<< simObjAddAgain.getAircraftModelString() << simObjAddAgain.toQString();
this->updateAircraftEnabled(simObjAddAgain.getCallsign(), false); // disable
emit this->physicallyAddingRemoteModelFailed(simObjAddAgain.getAircraft(), true, true,
msg); // verify failed
@@ -2007,8 +2012,8 @@ namespace swift::simplugin::msfs2024common
.arg(fsxPositionToString(initialPosition)));
}
const QByteArray modelStringBa = toFsxChar(modelString);
const QByteArray modelLiveryBa = toFsxChar(modelLiveryString);
const QByteArray modelStringBa = toFsxChar(modelString).trimmed();
const QByteArray modelLiveryBa = toFsxChar(modelLiveryString).trimmed();
const QByteArray csBa = toFsxChar(callsign.toQString().left(12));
CSimConnectObject::SimObjectType type = CSimConnectObject::AircraftNonAtc;

View File

@@ -553,7 +553,7 @@ namespace swift::simplugin::msfs2024common
void updateTransponderMode(const misc::aviation::CTransponder::TransponderMode xpdrMode);
//! Update transponder mode from MSFS
void updateMSFSTransponderMode(const DataDefinitionMSFSTransponderMode transponderMode);
void updateMSFS2024TransponderMode(const DataDefinitionMSFSTransponderMode transponderMode);
//! An AI aircraft was added in the simulator
bool simulatorReportedObjectAdded(DWORD objectId);

View File

@@ -297,7 +297,7 @@ namespace swift::simplugin::msfs2024common
{
const DataDefinitionMSFSTransponderMode *transponderMode =
reinterpret_cast<const DataDefinitionMSFSTransponderMode *>(&pObjData->dwData);
simulatorMsfs2024->updateMSFSTransponderMode(*transponderMode);
simulatorMsfs2024->updateMSFS2024TransponderMode(*transponderMode);
break;
}
default:
@@ -325,7 +325,7 @@ namespace swift::simplugin::msfs2024common
} // position
else if (subRequest == CSimConnectDefinitions::SimObjectModel)
{
static_assert(sizeof(DataDefinitionRemoteAircraftModel) == sizeof(double) + 168 + 256,
static_assert(sizeof(DataDefinitionRemoteAircraftModel) == sizeof(double) + 168 + 256 + 256,
"DataDefinitionRemoteAircraftModel has an incorrect size.");
const DataDefinitionRemoteAircraftModel *remoteAircraftModel =
reinterpret_cast<const DataDefinitionRemoteAircraftModel *>(&pObjData->dwData);