Skip to content

Commit 4bfc444

Browse files
committed
fix: msfs2020 simconnect interface restored
1 parent 3858ee4 commit 4bfc444

7 files changed

Lines changed: 170 additions & 1 deletion

File tree

src/plugins/simulator/fscommon/simulatorfscommon.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ namespace swift::simplugin::fscommon
5454
0; //!< own aircraft updates, even with 50 updates/sec long enough even for 32bit
5555
int m_skipCockpitUpdateCycles = 0; //!< skip some update cycles to allow changes in simulator cockpit to be set
5656
bool m_simPaused = false; //!< simulator paused?
57+
bool m_simTimeSynced = false; //!< time synchronized?
58+
swift::misc::physical_quantities::CTime m_syncTimeOffset; //!< time offset
59+
swift::misc::aviation::CAirportList m_airportsInRangeFromSimulator; //!< airports in range of own aircraft
5760

5861
// cockpit as set in SIM
5962
swift::misc::aviation::CComSystem m_simCom1; //!< cockpit COM1 state in simulator

src/plugins/simulator/fsxcommon/simconnectdatadefinition.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,15 @@ namespace swift::simplugin::fsxcommon
209209
bool isOnGround() const { return this->aboveGroundFt() < 1.0; }
210210
};
211211

212+
//! Data struct simulator environment
213+
struct DataDefinitionSimEnvironment
214+
{
215+
qint32 zuluTimeSeconds; //!< Simulator zulu (GMT) time in secs.
216+
qint32 zuluYear; //!< Simulator zulu (GMT) year.
217+
qint32 zuluMonth; //!< Simulator zulu (GMT) month.
218+
qint32 zuluDayOfMonth; //!< Simulator zulu (GMT) day of the month.
219+
};
220+
212221
//! The whole SB data area
213222
//! \remark vPilot SB area https://forums.vatsim.net/viewtopic.php?p=519580
214223
//! \remark SB offsets http://www.squawkbox.ca/doc/sdk/fsuipc.php
@@ -291,6 +300,7 @@ namespace swift::simplugin::fsxcommon
291300
{
292301
RequestOwnAircraft,
293302
RequestOwnAircraftTitle,
303+
RequestSimEnvironment,
294304
RequestSbData, //!< SB client area / XPDR mode
295305
RequestMSFSTransponder, //!< MSFS XPDR mode/ident
296306
RequestFacility,

src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,14 @@ namespace swift::simplugin::fsxcommon
527527
SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
528528
"Cannot request title", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
529529

530-
if (!this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS())
530+
hr += this->logAndTraceSendId(
531+
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestSimEnvironment,
532+
CSimConnectDefinitions::DataSimEnvironment, SIMCONNECT_OBJECT_ID_USER,
533+
SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
534+
"Cannot request sim.env.", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
535+
536+
if (!this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS() &&
537+
!this->getSimulatorPluginInfo().getSimulatorInfo().isMSFS2024())
531538
{
532539
// Request the data from SB only when its changed and only ONCE so we don't have to run a 1sec event to
533540
// get/set this info ;) there was a bug with SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, see
@@ -2208,6 +2215,39 @@ namespace swift::simplugin::fsxcommon
22082215
return ok;
22092216
}
22102217

2218+
void CSimulatorFsxCommon::triggerUpdateAirports(const CAirportList &airports)
2219+
{
2220+
if (this->isShuttingDownOrDisconnected()) { return; }
2221+
if (airports.isEmpty()) { return; }
2222+
QPointer<CSimulatorFsxCommon> myself(this);
2223+
QTimer::singleShot(0, this, [=] {
2224+
if (!myself) { return; }
2225+
this->updateAirports(airports);
2226+
});
2227+
}
2228+
2229+
void CSimulatorFsxCommon::updateAirports(const CAirportList &airports)
2230+
{
2231+
if (airports.isEmpty()) { return; }
2232+
2233+
static const CLength maxDistance(200.0, CLengthUnit::NM());
2234+
const CCoordinateGeodetic posAircraft(this->getOwnAircraftPosition());
2235+
2236+
for (const CAirport &airport : airports)
2237+
{
2238+
CAirport consolidatedAirport(airport);
2239+
const CLength d = consolidatedAirport.calculcateAndUpdateRelativeDistanceAndBearing(posAircraft);
2240+
if (d > maxDistance) { continue; }
2241+
// consolidatedAirport.updateMissingParts(this->getWebServiceAirport(airport.getIcao()));
2242+
// m_airportsInRangeFromSimulator.replaceOrAddByIcao(consolidatedAirport);
2243+
// if (m_airportsInRangeFromSimulator.size() > this->maxAirportsInRange())
2244+
//{
2245+
// m_airportsInRangeFromSimulator.sortByDistanceToReferencePosition();
2246+
// m_airportsInRangeFromSimulator.truncate(this->maxAirportsInRange());
2247+
// }
2248+
}
2249+
}
2250+
22112251
bool CSimulatorFsxCommon::sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObject,
22122252
const CAircraftParts &parts)
22132253
{
@@ -2511,6 +2551,61 @@ namespace swift::simplugin::fsxcommon
25112551
return true;
25122552
}
25132553

2554+
void CSimulatorFsxCommon::synchronizeTime(const DataDefinitionSimEnvironment *simEnv)
2555+
{
2556+
if (!m_simTimeSynced) { return; }
2557+
if (!this->isConnected()) { return; }
2558+
if (m_syncTimeDeferredCounter > 0)
2559+
{
2560+
--m_syncTimeDeferredCounter;
2561+
return; // wait some time before we snyc again
2562+
}
2563+
2564+
const int zh = simEnv->zuluTimeSeconds / 3600;
2565+
const int zm = (simEnv->zuluTimeSeconds - (zh * 3600)) / 60;
2566+
const QDateTime simDateTime({ simEnv->zuluYear, simEnv->zuluMonth, simEnv->zuluDayOfMonth }, { zh, zm },
2567+
Qt::UTC);
2568+
2569+
QDateTime currentDateTime = QDateTime::currentDateTimeUtc();
2570+
if (!m_syncTimeOffset.isZeroEpsilonConsidered())
2571+
{
2572+
int offsetSeconds = m_syncTimeOffset.valueInteger(CTimeUnit::s());
2573+
currentDateTime = currentDateTime.addSecs(offsetSeconds);
2574+
}
2575+
2576+
if (qAbs(simDateTime.secsTo(currentDateTime)) < 120)
2577+
{
2578+
// checked and no relevant difference
2579+
m_syncTimeDeferredCounter = 10; // wait some time to check again
2580+
return;
2581+
}
2582+
2583+
const DWORD h = static_cast<DWORD>(currentDateTime.time().hour());
2584+
const DWORD m = static_cast<DWORD>(currentDateTime.time().minute());
2585+
const DWORD y = static_cast<DWORD>(currentDateTime.date().year());
2586+
const DWORD d = static_cast<DWORD>(currentDateTime.date().dayOfYear());
2587+
2588+
const HRESULT hr1 = SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluHours, h,
2589+
SIMCONNECT_GROUP_PRIORITY_STANDARD,
2590+
SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
2591+
const HRESULT hr2 = SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluMinutes, m,
2592+
SIMCONNECT_GROUP_PRIORITY_STANDARD,
2593+
SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
2594+
const HRESULT hr3 = SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluYear, y,
2595+
SIMCONNECT_GROUP_PRIORITY_STANDARD,
2596+
SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
2597+
const HRESULT hr4 =
2598+
SimConnect_TransmitClientEvent(m_hSimConnect, 0, EventSetTimeZuluDay, d, SIMCONNECT_GROUP_PRIORITY_STANDARD,
2599+
SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
2600+
2601+
if (isFailure(hr1, hr2, hr3, hr4)) { CLogMessage(this).warning(u"Sending time sync failed!"); }
2602+
else
2603+
{
2604+
m_syncTimeDeferredCounter = 5; // allow some time to sync
2605+
CLogMessage(this).info(u"Synchronized time to '%1' UTC") << currentDateTime.toString();
2606+
}
2607+
}
2608+
25142609
bool CSimulatorFsxCommon::requestPositionDataForSimObject(const CSimConnectObject &simObject,
25152610
SIMCONNECT_PERIOD period)
25162611
{
@@ -2630,6 +2725,7 @@ namespace swift::simplugin::fsxcommon
26302725
m_simConnected = false;
26312726
m_simSimulating = false;
26322727
m_sbDataReceived = 0;
2728+
m_syncTimeDeferredCounter = 0;
26332729
m_requestIdSimObjAircraft = static_cast<SIMCONNECT_DATA_REQUEST_ID>(RequestSimObjAircraftStart);
26342730
m_dispatchErrors = 0;
26352731
m_receiveExceptionCount = 0;
@@ -3013,6 +3109,16 @@ namespace swift::simplugin::fsxcommon
30133109
return connectedSimName.contains("fsx") || connectedSimName.contains("microsoft") ||
30143110
connectedSimName.contains("simulator x");
30153111
}
3112+
else if (pluginSim.isMSFS())
3113+
{
3114+
// MSFS 2020 drivers only works with MSFS
3115+
return connectedSimName.contains("kittyhawk");
3116+
}
3117+
else if (pluginSim.isMSFS2024())
3118+
{
3119+
// MSFS2024 drivers only works with MSFS2024
3120+
return connectedSimName.contains("sunrise");
3121+
}
30163122
return false;
30173123
}
30183124

src/plugins/simulator/fsxcommon/simulatorfsxcommon.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,12 @@ namespace swift::simplugin::fsxcommon
461461
bool updateRemoteAircraftParts(const CSimConnectObject &simObject,
462462
const swift::misc::simulation::CInterpolationResult &result, bool forcedUpdate);
463463

464+
//! Calling CSimulatorFsxCommon::updateAirports
465+
void triggerUpdateAirports(const swift::misc::aviation::CAirportList &airports);
466+
467+
//! Update airports from simulator
468+
void updateAirports(const swift::misc::aviation::CAirportList &airports);
469+
464470
//! Send parts to simulator
465471
//! \remark does not send if there is no change
466472
bool sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObject,
@@ -543,6 +549,9 @@ namespace swift::simplugin::fsxcommon
543549
//! The SimConnect object for idxs
544550
CSimConnectObject getSimObjectForObjectId(DWORD objectId) const;
545551

552+
//! Sync time with user's computer
553+
void synchronizeTime(const DataDefinitionSimEnvironment *simEnv);
554+
546555
//! Request data for a CSimConnectObject (aka remote aircraft)
547556
bool requestPositionDataForSimObject(const CSimConnectObject &simObject,
548557
SIMCONNECT_PERIOD period = SIMCONNECT_PERIOD_SECOND);
@@ -642,6 +651,7 @@ namespace swift::simplugin::fsxcommon
642651
qint64 m_traceAutoUntilTs = -1; //!< allows to automatically trace for some time
643652
qint64 m_simulatingChangedTs = -1; //!< timestamp, when simulating changed (used to avoid jitter)
644653
int m_sbDataReceived = 0; //!< SB3 area data received
654+
int m_syncTimeDeferredCounter = 0; //!< Set when synchronized, used to wait some time
645655

646656
// tracing dispatch performance
647657
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa dispatch

src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,13 @@ namespace swift::simplugin::fsxcommon
260260
simulatorFsxP3D->reverseLookupAndUpdateOwnAircraftModel(model);
261261
break;
262262
}
263+
case CSimConnectDefinitions::RequestSimEnvironment:
264+
{
265+
const DataDefinitionSimEnvironment *simEnv =
266+
reinterpret_cast<const DataDefinitionSimEnvironment *>(&pObjData->dwData);
267+
simulatorFsxP3D->synchronizeTime(simEnv);
268+
break;
269+
}
263270
case CSimConnectDefinitions::RequestMSFSTransponder:
264271
{
265272
const DataDefinitionMSFSTransponderMode *transponderMode =
@@ -368,6 +375,32 @@ namespace swift::simplugin::fsxcommon
368375
}
369376
break; // SIMCONNECT_RECV_ID_SIMOBJECT_DATA
370377
}
378+
case SIMCONNECT_RECV_ID_AIRPORT_LIST:
379+
{
380+
const SIMCONNECT_RECV_AIRPORT_LIST *pAirportList = static_cast<SIMCONNECT_RECV_AIRPORT_LIST *>(pData);
381+
CAirportList simAirports;
382+
for (unsigned i = 0; i < pAirportList->dwArraySize; ++i)
383+
{
384+
const SIMCONNECT_DATA_FACILITY_AIRPORT *pFacilityAirport = pAirportList->rgData + i;
385+
if (!pFacilityAirport) { break; }
386+
const QString icao(pFacilityAirport->Icao);
387+
if (icao.isEmpty()) { continue; } // airfield without ICAO code
388+
if (!CAirportIcaoCode::isValidIcaoDesignator(icao, true))
389+
{
390+
continue;
391+
} // tiny airfields/strips in simulator
392+
if (CAirportIcaoCode::containsNumbers(icao)) { continue; } // tiny airfields/strips in simulator
393+
const CCoordinateGeodetic pos(pFacilityAirport->Latitude, pFacilityAirport->Longitude,
394+
pFacilityAirport->Altitude);
395+
const CAirport airport(CAirportIcaoCode(icao), pos);
396+
simAirports.push_back(airport);
397+
}
398+
if (!simAirports.isEmpty())
399+
{
400+
// simulatorFsxP3D->triggerUpdateAirports(simAirports); // real "work" outside SimConnectProc
401+
}
402+
break; // SIMCONNECT_RECV_ID_AIRPORT_LIST
403+
}
371404
case SIMCONNECT_RECV_ID_CLIENT_DATA:
372405
{
373406
if (!simulatorFsxP3D->m_useSbOffsets) { break; }

src/plugins/simulator/msfs2024/simconnectdatadefinitionmsfs2024.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ namespace swift::simplugin::msfs2024common
310310
RequestOwnAircraft,
311311
RequestOwnAircraftTitle,
312312
RequestOwnAircraftLivery,
313+
RequestSimEnvironment,
313314
RequestSbData, //!< SB client area / XPDR mode
314315
RequestMSFSTransponder, //!< MSFS XPDR mode/ident
315316
RequestFacility,

src/plugins/simulator/msfs2024/simulatormsfs2024common.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,12 @@ namespace swift::simplugin::msfs2024common
759759
SIMCONNECT_SIMOBJECT_TYPE_USER),
760760
"Cannot request title and livery", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObjectType");
761761

762+
hr += this->logAndTraceSendId(
763+
SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestSimEnvironment,
764+
CSimConnectDefinitions::DataSimEnvironment, SIMCONNECT_OBJECT_ID_USER,
765+
SIMCONNECT_PERIOD_SECOND, SIMCONNECT_DATA_REQUEST_FLAG_CHANGED),
766+
"Cannot request sim.env.", Q_FUNC_INFO, "SimConnect_RequestDataOnSimObject");
767+
762768
hr += this->logAndTraceSendId(SimConnect_RequestDataOnSimObject(
763769
m_hSimConnect, CSimConnectDefinitions::RequestMSFSTransponder,
764770
CSimConnectDefinitions::DataTransponderModeMSFS, SIMCONNECT_OBJECT_ID_USER,

0 commit comments

Comments
 (0)