diff --git a/src/plugins/simulator/fs9/directplaypeer.cpp b/src/plugins/simulator/fs9/directplaypeer.cpp index 56b76b315..8c0c797fa 100644 --- a/src/plugins/simulator/fs9/directplaypeer.cpp +++ b/src/plugins/simulator/fs9/directplaypeer.cpp @@ -150,11 +150,23 @@ namespace BlackSimPlugin } break; } + case DPN_MSGID_CONNECT_COMPLETE: + { + const PDPNMSG_CONNECT_COMPLETE connectCompleteMsg = static_cast(msgBuffer); + if (connectCompleteMsg->hResultCode == DPN_OK) + { + emit connectionComplete(); + } + else + { + CLogMessage(this).warning(u"DirectPlay connection returned: %1") << connectCompleteMsg->hResultCode; + } + } } // Directx9 SDK: Unless otherwise noted, this function should return S_OK. // http://doc.51windows.net/Directx9_SDK/play/ref/callbacks/pfndpnmessagehandler.htm - return S_OK; + return DPN_OK; } HRESULT CDirectPlayPeer::initDirectPlay() diff --git a/src/plugins/simulator/fs9/directplaypeer.h b/src/plugins/simulator/fs9/directplaypeer.h index 5ce6e7f2d..d732e2f4a 100644 --- a/src/plugins/simulator/fs9/directplaypeer.h +++ b/src/plugins/simulator/fs9/directplaypeer.h @@ -26,6 +26,9 @@ namespace BlackSimPlugin { namespace Fs9 { + HRESULT inline s_success_pending() { return DPNSUCCESS_PENDING; } + bool inline isPending(HRESULT hr) { return hr == s_success_pending(); } + //! DirectPlay peer implementation //! More information can be found in the DirectX9 SDK documentation //! http://doc.51windows.net/Directx9_SDK/?url=/Directx9_SDK/play/dplay.htm @@ -49,6 +52,8 @@ namespace BlackSimPlugin //! Log categories static const BlackMisc::CLogCategoryList &getLogCategories(); + + public slots: //! Send a custom DirectPlay message HRESULT sendMessage(const QByteArray &data); @@ -60,6 +65,9 @@ namespace BlackSimPlugin //! Received custom FS9 packet void customPacketReceived(const QByteArray &data); + //! Async operatione complete + void connectionComplete(); + protected: //! DirectPlay message handler HRESULT directPlayMessageHandler(DWORD messageId, void *msgBuffer); diff --git a/src/plugins/simulator/fs9/fs9client.cpp b/src/plugins/simulator/fs9/fs9client.cpp index 7c091f65d..31d1badb2 100644 --- a/src/plugins/simulator/fs9/fs9client.cpp +++ b/src/plugins/simulator/fs9/fs9client.cpp @@ -32,16 +32,19 @@ namespace BlackSimPlugin { namespace Fs9 { - CFs9Client::CFs9Client(const CCallsign &callsign, const QString &modelName, + CFs9Client::CFs9Client(const CSimulatedAircraft &remoteAircraft, const CTime &updateInterval, CInterpolationLogger *logger, ISimulator *simulator) : - CDirectPlayPeer(simulator, callsign), + CDirectPlayPeer(simulator, remoteAircraft.getCallsign()), + m_remoteAircraft(remoteAircraft), m_updateInterval(updateInterval), - m_interpolator(callsign, simulator, simulator, simulator->getRemoteAircraftProvider(), logger), - m_modelName(modelName) + m_interpolator(remoteAircraft.getCallsign(), simulator, simulator, simulator->getRemoteAircraftProvider(), logger), + m_modelName(remoteAircraft.getModelString()) { m_interpolator.attachLogger(logger); Q_ASSERT_X(this->simulator(), Q_FUNC_INFO, "Wrong owner, expect simulator object"); + + connect(this, &CFs9Client::connectionComplete, this, &CFs9Client::handleConnectionCompleted); } MPPositionVelocity aircraftSituationToFS9(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, double updateInterval) @@ -282,10 +285,8 @@ namespace BlackSimPlugin m_player.dwDataSize = sizeof(PLAYER_INFO_STRUCT); m_player.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA; m_player.pwszName = wszPlayername.data(); - if (isFailure(hr = m_directPlayPeer->SetPeerInfo(&m_player, nullptr, nullptr, DPNSETPEERINFO_SYNC))) - { - return logDirectPlayError(hr); - } + hr = m_directPlayPeer->SetPeerInfo(&m_player, nullptr, nullptr, DPNSETPEERINFO_SYNC); + if (isFailure(hr)) { return logDirectPlayError(hr); } // Now set up the Application Description DPN_APPLICATION_DESC dpAppDesc; @@ -293,8 +294,8 @@ namespace BlackSimPlugin dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC); dpAppDesc.guidApplication = CFs9Sdk::guid(); - // We are now ready to host the app - if (isFailure(hr = m_directPlayPeer->Connect(&dpAppDesc, // AppDesc + DPNHANDLE asyncOpHandle; + hr = m_directPlayPeer->Connect(&dpAppDesc, m_hostAddress, m_deviceAddress, nullptr, @@ -302,21 +303,9 @@ namespace BlackSimPlugin nullptr, 0, nullptr, nullptr, - nullptr, - DPNCONNECT_SYNC))) - { - return logDirectPlayError(hr); - } - - CLogMessage(this).info(u"Callsign '%1' connected to session.") << m_callsign; - sendMultiplayerChangePlayerPlane(); - sendMultiplayerPosition(); - sendMultiplayerParamaters(); - m_timerId = startTimer(m_updateInterval.valueInteger(CTimeUnit::ms())); - - m_clientStatus = Connected; - emit statusChanged(m_callsign, m_clientStatus); - + &asyncOpHandle, + 0); + if (!isPending(hr) && isFailure(hr)) { return logDirectPlayError(hr); } return hr; } @@ -332,7 +321,7 @@ namespace BlackSimPlugin } m_clientStatus = Disconnected; - emit statusChanged(m_callsign, m_clientStatus); + emit statusChanged(m_remoteAircraft, m_clientStatus); return hr; } @@ -387,6 +376,18 @@ namespace BlackSimPlugin sendMessage(message); } + void CFs9Client::handleConnectionCompleted() + { + CLogMessage(this).info(u"Callsign '%1' connected to session.") << m_callsign; + sendMultiplayerChangePlayerPlane(); + sendMultiplayerPosition(); + sendMultiplayerParamaters(); + m_timerId = startTimer(m_updateInterval.valueInteger(CTimeUnit::ms())); + + m_clientStatus = Connected; + emit statusChanged(m_remoteAircraft, m_clientStatus); + } + const ISimulator *CFs9Client::simulator() const { return qobject_cast(this->parent()); diff --git a/src/plugins/simulator/fs9/fs9client.h b/src/plugins/simulator/fs9/fs9client.h index d460137f8..b5d44e614 100644 --- a/src/plugins/simulator/fs9/fs9client.h +++ b/src/plugins/simulator/fs9/fs9client.h @@ -38,8 +38,7 @@ namespace BlackSimPlugin }; //! Constructor - CFs9Client(const BlackMisc::Aviation::CCallsign &callsign, - const QString &modelName, + CFs9Client(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft, const BlackMisc::PhysicalQuantities::CTime &updateInterval, BlackMisc::Simulation::CInterpolationLogger *logger, BlackCore::ISimulator *simulator); @@ -69,7 +68,7 @@ namespace BlackSimPlugin signals: //! Client status changed - void statusChanged(const BlackMisc::Aviation::CCallsign &callsign, BlackSimPlugin::Fs9::CFs9Client::ClientStatus); + void statusChanged(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft, BlackSimPlugin::Fs9::CFs9Client::ClientStatus); protected: //! \copydoc QObject::timerEvent @@ -95,9 +94,12 @@ namespace BlackSimPlugin void sendMultiplayerChangePlayerPlane(); //! @} + void handleConnectionCompleted(); + //! Simulator interface const BlackCore::ISimulator *simulator() const; + BlackMisc::Simulation::CSimulatedAircraft m_remoteAircraft; BlackMisc::PhysicalQuantities::CTime m_updateInterval; BlackMisc::Simulation::CInterpolatorMulti m_interpolator; QString m_modelName; diff --git a/src/plugins/simulator/fs9/simulatorfs9.cpp b/src/plugins/simulator/fs9/simulatorfs9.cpp index 4e09ec8d9..e401c9f3d 100644 --- a/src/plugins/simulator/fs9/simulatorfs9.cpp +++ b/src/plugins/simulator/fs9/simulatorfs9.cpp @@ -174,22 +174,13 @@ namespace BlackSimPlugin this->physicallyRemoveRemoteAircraft(callsign); } - bool rendered = true; - updateAircraftRendered(callsign, rendered); - CFs9Client *client = new CFs9Client(callsign, newRemoteAircraft.getModelString(), CTime(25, CTimeUnit::ms()), &m_interpolationLogger, this); + CFs9Client *client = new CFs9Client(newRemoteAircraft, CTime(25, CTimeUnit::ms()), &m_interpolationLogger, this); client->setHostAddress(m_fs9Host->getHostAddress()); client->setPlayerUserId(m_fs9Host->getPlayerUserId()); + connect(client, &CFs9Client::statusChanged, this, &CSimulatorFs9::updateRenderStatus); client->start(); m_hashFs9Clients.insert(callsign, client); - const bool updated = updateAircraftRendered(callsign, rendered); - CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft); - remoteAircraftCopy.setRendered(rendered); - if (updated) - { - emit aircraftRenderingChanged(remoteAircraftCopy); - } - CLogMessage(this).info(u"FS9: Added aircraft '%1'") << callsign.toQString(); return true; } @@ -428,6 +419,18 @@ namespace BlackSimPlugin m_ownAircraftUpdateCycles++; } + void CSimulatorFs9::updateRenderStatus(const CSimulatedAircraft &remoteAircraft, CFs9Client::ClientStatus) + { + const bool updated = updateAircraftRendered(remoteAircraft.getCallsign(), true); + CSimulatedAircraft remoteAircraftCopy(remoteAircraft); + remoteAircraftCopy.setRendered(true); + if (updated) + { + emit aircraftRenderingChanged(remoteAircraftCopy); + } + CLogMessage(this).info(u"FS9: Added aircraft '%1'") << remoteAircraft.getCallsignAsString(); + } + void CSimulatorFs9::disconnectAllClients() { // Stop all FS9 client tasks diff --git a/src/plugins/simulator/fs9/simulatorfs9.h b/src/plugins/simulator/fs9/simulatorfs9.h index df63546ab..5ec25657a 100644 --- a/src/plugins/simulator/fs9/simulatorfs9.h +++ b/src/plugins/simulator/fs9/simulatorfs9.h @@ -98,6 +98,8 @@ namespace BlackSimPlugin //! Called when data about our own aircraft are received void updateOwnAircraftFromSimulator(const BlackMisc::Simulation::CSimulatedAircraft &ownAircraft); + void updateRenderStatus(const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft, BlackSimPlugin::Fs9::CFs9Client::ClientStatus); + //! Disconnect all clients void disconnectAllClients();