18 using namespace swift::config;
20 using namespace swift::misc::simulation;
21 using namespace swift::misc::aviation;
22 using namespace swift::misc::physical_quantities;
23 using namespace swift::misc::geo;
24 using namespace swift::misc::network;
25 using namespace swift::misc::simulation;
26 using namespace swift::misc::simulation::fscommon;
27 using namespace swift::misc::simulation::fsx;
29 namespace swift::simplugin::fsxcommon
31 void CALLBACK CSimulatorFsxCommon::SimConnectProc(SIMCONNECT_RECV *pData,
DWORD cbData,
void *pContext)
37 const qint64 procTimeStart = QDateTime::currentMSecsSinceEpoch();
39 const SIMCONNECT_RECV_ID recvId =
static_cast<SIMCONNECT_RECV_ID
>(pData->dwID);
40 simulatorFsxP3D->m_dispatchReceiveIdLast = recvId;
41 simulatorFsxP3D->m_dispatchProcCount++;
44 case SIMCONNECT_RECV_ID_OPEN:
46 SIMCONNECT_RECV_OPEN *
event =
static_cast<SIMCONNECT_RECV_OPEN *
>(pData);
47 const QString simConnectVersion = QStringLiteral(
"%1.%2.%3.%4")
48 .arg(event->dwSimConnectVersionMajor)
49 .arg(event->dwSimConnectVersionMinor)
50 .arg(event->dwSimConnectBuildMajor)
51 .arg(event->dwSimConnectBuildMinor);
52 const QString version = QStringLiteral(
"%1.%2.%3.%4")
53 .arg(event->dwApplicationVersionMajor)
54 .arg(event->dwApplicationVersionMinor)
55 .arg(event->dwApplicationBuildMajor)
56 .arg(event->dwApplicationBuildMinor);
57 const QString name = CSimulatorFsxCommon::fsxCharToQString(event->szApplicationName);
58 const QString details =
59 QStringLiteral(
"Name: '%1' Version: %2 SimConnect: %3").arg(name, version, simConnectVersion);
61 simulatorFsxP3D->m_simConnectVersion = simConnectVersion;
64 simulatorFsxP3D->setSimConnected();
67 case SIMCONNECT_RECV_ID_EXCEPTION:
69 if (!simulatorFsxP3D->stillDisplayReceiveExceptions()) {
break; }
72 SIMCONNECT_RECV_EXCEPTION *exception =
static_cast<SIMCONNECT_RECV_EXCEPTION *
>(pData);
73 const DWORD exceptionId = exception->dwException;
74 const DWORD sendId = exception->dwSendID;
75 const DWORD index = exception->dwIndex;
77 const DWORD data = cbData;
78 const TraceFsxSendId trace = simulatorFsxP3D->getSendIdTrace(sendId);
79 bool logGenericExceptionInfo =
true;
83 case SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE:
break;
84 case SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID:
87 case SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED:
98 simulatorFsxP3D->addingAircraftFailed(simObject);
99 logGenericExceptionInfo =
false;
112 logGenericExceptionInfo =
false;
122 if (logGenericExceptionInfo)
124 QString ex = QString::asprintf(
"Exception=%lu | SendID=%lu | Index=%lu | cbData=%lu", exceptionId,
125 sendId, index, data);
126 const QString exceptionString(
127 CSimConnectUtilities::simConnectExceptionToString(
static_cast<DWORD>(exception->dwException)));
128 const QString sendIdDetails = simulatorFsxP3D->getSendIdTraceDetails(sendId);
129 CLogMessage(simulatorFsxP3D).
warning(u
"Caught simConnect exception: '%1' '%2' | send details: '%3'")
130 << exceptionString << ex << (sendIdDetails.isEmpty() ?
"N/A" : sendIdDetails);
134 case SIMCONNECT_RECV_ID_QUIT:
136 simulatorFsxP3D->onSimExit();
139 case SIMCONNECT_RECV_ID_EVENT:
141 const SIMCONNECT_RECV_EVENT *
event =
static_cast<SIMCONNECT_RECV_EVENT *
>(pData);
142 switch (event->uEventID)
144 case SystemEventSimStatus:
146 const bool running =
event->dwData ? true :
false;
147 if (running) { simulatorFsxP3D->onSimRunning(); }
148 else { simulatorFsxP3D->onSimStopped(); }
151 case SystemEventPause:
153 const bool paused =
event->dwData ? true :
false;
165 case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE:
167 const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *
event =
168 static_cast<SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *
>(pData);
169 const DWORD objectId =
event->dwData;
170 const SIMCONNECT_SIMOBJECT_TYPE objectType =
event->eObjType;
171 if (objectType != SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT && objectType != SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER)
180 switch (event->uEventID)
182 case SystemEventObjectRemoved: simulatorFsxP3D->simulatorReportedObjectRemoved(objectId);
break;
183 case SystemEventObjectAdded:
192 case SIMCONNECT_RECV_ID_EVENT_FRAME:
194 const SIMCONNECT_RECV_EVENT_FRAME *
event =
static_cast<SIMCONNECT_RECV_EVENT_FRAME *
>(pData);
195 switch (event->uEventID)
197 case SystemEventFrame:
199 simulatorFsxP3D->onSimFrame();
205 case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID:
207 const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *
event =
static_cast<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *
>(pData);
208 const DWORD requestId =
event->dwRequestID;
209 const DWORD objectId =
event->dwObjectID;
210 simulatorFsxP3D->m_dispatchRequestIdLast = requestId;
212 if (CSimulatorFsxCommon::isRequestForSimConnectObject(requestId))
214 bool success = simulatorFsxP3D->setSimConnectObjectId(requestId, objectId);
215 if (!success) {
break; }
216 success = simulatorFsxP3D->simulatorReportedObjectAdded(
222 const CSimConnectObject simObject = simulatorFsxP3D->getSimObjectForObjectId(objectId);
233 case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE:
238 case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
240 const SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData =
static_cast<SIMCONNECT_RECV_SIMOBJECT_DATA *
>(pData);
241 const DWORD requestId = pObjData->dwRequestID;
242 simulatorFsxP3D->m_dispatchRequestIdLast = requestId;
246 case CSimConnectDefinitions::RequestOwnAircraft:
249 "DataDefinitionOwnAircraft has an incorrect size.");
252 simulatorFsxP3D->updateOwnAircraftFromSimulator(*ownAircaft);
255 case CSimConnectDefinitions::RequestOwnAircraftTitle:
263 case CSimConnectDefinitions::RequestMSFSTransponder:
267 simulatorFsxP3D->updateMSFSTransponderMode(*transponderMode);
272 const DWORD objectId = pObjData->dwObjectID;
273 if (CSimulatorFsxCommon::isRequestForSimObjAircraft(requestId))
275 const CSimConnectObject simObject = simulatorFsxP3D->getSimObjectForObjectId(objectId);
278 CSimulatorFsxCommon::requestToSimObjectRequest(requestId);
280 if (subRequest == CSimConnectDefinitions::SimObjectPositionData)
283 "DataDefinitionPosData has an incorrect size.");
289 simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject,
290 *remoteAircraftSimData);
293 else if (subRequest == CSimConnectDefinitions::SimObjectModel)
296 "DataDefinitionRemoteAircraftModel has an incorrect size.");
302 simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject, *remoteAircraftModel);
305 else if (subRequest == CSimConnectDefinitions::SimObjectLights)
308 "DataDefinitionRemoteAircraftLights has an incorrect size.");
316 simulatorFsxP3D->setCurrentLights(callsign, lights);
320 simulatorFsxP3D->setLightsAsSent(callsign, lights);
327 if (CBuildConfig::isLocalDeveloperDebugBuild())
329 CLogMessage(simulatorFsxP3D).
error(u
"Unknown subrequest (aircraft): '%1' %2")
330 << CSimConnectDefinitions::simObjectRequestToString(subRequest)
335 else if (CSimulatorFsxCommon::isRequestForSimObjTerrainProbe(requestId))
337 const CSimConnectObject probeObj = simulatorFsxP3D->getSimObjectForObjectId(objectId);
341 CSimulatorFsxCommon::requestToSimObjectRequest(requestId);
343 if (subRequest == CSimConnectDefinitions::SimObjectPositionData)
346 "DataDefinitionRemoteAircraftSimData has an incorrect size.");
354 simulatorFsxP3D->updateProbeFromSimulator(cs, *probeSimData);
359 if (CBuildConfig::isLocalDeveloperDebugBuild())
362 << CSimConnectDefinitions::simObjectRequestToString(subRequest) << probeObj.
toQString();
371 case SIMCONNECT_RECV_ID_CLIENT_DATA:
373 if (!simulatorFsxP3D->m_useSbOffsets) {
break; }
374 simulatorFsxP3D->m_sbDataReceived++;
375 const SIMCONNECT_RECV_CLIENT_DATA *clientData =
static_cast<SIMCONNECT_RECV_CLIENT_DATA *
>(pData);
376 if (clientData->dwRequestID == CSimConnectDefinitions::RequestSbData)
381 std::memcpy(&sbData.
data, &clientData->dwData, 128);
382 simulatorFsxP3D->updateOwnAircraftFromSimulator(sbData);
386 case SIMCONNECT_RECV_ID_EVENT_FILENAME:
388 const SIMCONNECT_RECV_EVENT_FILENAME *
event =
static_cast<SIMCONNECT_RECV_EVENT_FILENAME *
>(pData);
389 switch (event->uEventID)
391 case SystemEventFlightLoaded:
break;
396 default: simulatorFsxP3D->m_dispatchProcEmptyCount++;
break;
400 const qint64 procTimeEnd = QDateTime::currentMSecsSinceEpoch();
401 simulatorFsxP3D->m_dispatchProcTimeMs = procTimeEnd - procTimeStart;
402 if (simulatorFsxP3D->m_dispatchProcTimeMs > simulatorFsxP3D->m_dispatchProcMaxTimeMs)
404 simulatorFsxP3D->m_dispatchProcMaxTimeMs = simulatorFsxP3D->m_dispatchProcTimeMs;
void physicallyAddingRemoteModelFailed(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft, bool disabled, bool requestFailover, const swift::misc::CStatusMessage &message)
Adding the remote model failed.
void reverseLookupAndUpdateOwnAircraftModel(const swift::misc::simulation::CAircraftModel &model)
Set own model.
void emitSimulatorCombinedStatus(SimulatorStatus oldStatus=Unspecified)
Emit the combined status.
Class for emitting a log message.
static void preformatted(const CStatusMessage &statusMessage)
Sends a verbatim, preformatted message to the log.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Streamable status message, e.g.
Value object encapsulating information about aircraft's lights.
Value object encapsulating information of a callsign.
const QString & asString() const
Get callsign (normalized)
bool isEmpty() const
Is empty?
Aircraft model (used by another pilot, my models on disk)
@ TypeOwnSimulatorModel
represents own simulator model (AI model, model on disk)
Comprehensive information of an aircraft.
QString getCallsignAsString() const
Get callsign.
const QString & getModelString() const
Get model string.
const QString & getIdentifier() const
Identifier.
void setSimulatorDetails(const QString &name, const QString &details, const QString &version)
Set version and simulator details from running simulator.
CSimulatorPluginInfo getSimulatorPluginInfo() const
Get the represented plugin.
bool m_simPaused
simulator paused?
SimObjectRequest
SimObject requests used for AI aircraft and probes.
Class representing a SimConnect object.
bool isInvalid() const
Invalid?
DWORD getObjectId() const
Get SimConnect object id.
QString toQString() const
SimObject as string.
bool hasValidRequestAndObjectId() const
Was the object really added to simulator.
const swift::misc::aviation::CAircraftLights & getLightsAsSent() const
Lights as sent to simulator.
const swift::misc::simulation::CSimulatedAircraft & getAircraft() const
Simulated aircraft (as added)
bool isValid() const
Valid?
const swift::misc::aviation::CCallsign & getCallsign() const
Get callsign.
const QString & getAircraftModelString() const
Simulated aircraft model string.
bool isTerrainProbe() const
Probe?
bool isAircraft() const
Aircraft?
bool isKnownSimObjectId(DWORD objectId) const
Is the object id one of our AI objects?
FSX Simulator Implementation.
bool isUsingFsxTerrainProbe() const
FSX Terrain probe.
CSimConnectObjects m_simConnectObjects
AI objects and their object and request ids.
QMap< DWORD, swift::misc::aviation::CCallsign > m_pendingProbeRequests
pending elevation requests: requestId/aircraft callsign
void setUsingFsxTerrainProbe(bool use)
FSX terrain probe.
bool triggerAutoTraceSendId(qint64 traceTimeMs=AutoTraceOffsetMs)
Trigger tracing ids for some while.
CSimConnectObject getSimObjectForTrace(const TraceFsxSendId &trace) const
CSimConnectObject for trace.
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
unsigned long DWORD
Fake Windows DWORD.
byte data[128]
128 bytes of data, offsets
Data structure for MSFS transponder mode information.
Data struct of our own aircraft.
Data struct of aircraft position.
char title[256]
Aircraft model string.
Data for AI object and probe sent back from simulator.
swift::misc::aviation::CAircraftLights toLights() const
Convert to lights.
Data struct of aircraft model data.
Struct to trace send ids.
bool isValid() const
Valid trace?
CSimConnectObject simObject
CSimConnectObject at the time of the trace.