From 53b257fa3d1e827aed8801cc7a1418378a99b075 Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Tue, 2 Sep 2014 20:32:44 +0200 Subject: [PATCH] refs #308 Instead of enumerating hosts, use the well known host url Since we are hosting in the same process, we can get the URL from the host object and pass it to new clients. --- src/plugins/simulator/fs9/directplay_peer.cpp | 19 ++++++++ src/plugins/simulator/fs9/directplay_peer.h | 3 ++ src/plugins/simulator/fs9/fs9_client.cpp | 45 ++++++++++--------- src/plugins/simulator/fs9/fs9_client.h | 3 ++ src/plugins/simulator/fs9/fs9_host.cpp | 39 +++++++++++++++- src/plugins/simulator/fs9/fs9_host.h | 3 ++ src/plugins/simulator/fs9/simulator_fs9.cpp | 1 + 7 files changed, 90 insertions(+), 23 deletions(-) diff --git a/src/plugins/simulator/fs9/directplay_peer.cpp b/src/plugins/simulator/fs9/directplay_peer.cpp index af434bd12..1200cea3e 100644 --- a/src/plugins/simulator/fs9/directplay_peer.cpp +++ b/src/plugins/simulator/fs9/directplay_peer.cpp @@ -9,6 +9,7 @@ #include "directplay_peer.h" #include "multiplayer_packet_parser.h" +#include "blacksimplugin_freefunctions.h" #include #include #include @@ -253,6 +254,24 @@ namespace BlackSimPlugin return hr; } + HRESULT CDirectPlayPeer::createHostAddress() + { + HRESULT hr = S_OK; + + // Create our IDirectPlay8Address Device Address + if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Address, nullptr, + CLSCTX_INPROC_SERVER, + IID_IDirectPlay8Address, + reinterpret_cast(&m_deviceAddress) ) ) ) + return printDirectPlayError(hr); + + // Set the SP for our Device Address + if( FAILED( hr = m_deviceAddress->SetSP( &CLSID_DP8SP_TCPIP ) ) ) + return printDirectPlayError(hr); + + return S_OK; + } + HRESULT CDirectPlayPeer::sendMessage( const QByteArray &message) { HRESULT hr = S_OK; diff --git a/src/plugins/simulator/fs9/directplay_peer.h b/src/plugins/simulator/fs9/directplay_peer.h index c9c90444f..d8d59e27f 100644 --- a/src/plugins/simulator/fs9/directplay_peer.h +++ b/src/plugins/simulator/fs9/directplay_peer.h @@ -71,6 +71,9 @@ namespace BlackSimPlugin //! Creates a new DirectPlay device address HRESULT createDeviceAddress(); + //! Creates a new DirectPlay device address + HRESULT createHostAddress(); + QString m_callsign; //!< Peer callsign IDirectPlay8Peer *m_directPlayPeer = nullptr; //!< DirectPlay peer address diff --git a/src/plugins/simulator/fs9/fs9_client.cpp b/src/plugins/simulator/fs9/fs9_client.cpp index 80d61b07f..918e3846f 100644 --- a/src/plugins/simulator/fs9/fs9_client.cpp +++ b/src/plugins/simulator/fs9/fs9_client.cpp @@ -41,7 +41,7 @@ namespace BlackSimPlugin { initDirectPlay(); createDeviceAddress(); - enumDirectPlayHosts(); + //enumDirectPlayHosts(); connectToSession(m_callsign); } @@ -63,6 +63,27 @@ namespace BlackSimPlugin closeConnection(); } + void CFs9Client::setHostAddress(const QString &hostAddress) + { + HRESULT hr = S_OK; + + // Create our IDirectPlay8Address Host Address + if( FAILED( hr = CoCreateInstance(CLSID_DirectPlay8Address, nullptr, + CLSCTX_INPROC_SERVER, + IID_IDirectPlay8Address, + reinterpret_cast(&m_hostAddress) ) ) ) + { + printDirectPlayError(hr); + return; + } + + if (FAILED (hr = m_hostAddress->BuildFromURLA(hostAddress.toLatin1().data()))) + { + printDirectPlayError(hr); + return; + } + } + void CFs9Client::addAircraftSituation(const CAircraftSituation &situation) { QMutexLocker locker(&m_mutexInterpolator); @@ -181,20 +202,6 @@ namespace BlackSimPlugin QMutexLocker locker(&m_mutexHostList); - if (m_hostNodeList.size() == 0) - { - qWarning() << "Host node list is empty!"; - return E_FAIL; - } - - CHostNode hostNode = m_hostNodeList.first(); - - if (!hostNode.getHostAddress()) - { - qWarning() << "Host address is invalid!"; - return E_FAIL; - } - QScopedArrayPointer wszPlayername(new wchar_t[callsign.size() + 1]); callsign.toWCharArray(wszPlayername.data()); @@ -224,16 +231,10 @@ namespace BlackSimPlugin dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC); dpAppDesc.guidApplication = CFs9Sdk::guid(); - IDirectPlay8Address *hostAddress = nullptr; - if FAILED( hr = hostNode.getHostAddress()->Duplicate(&hostAddress)) - { - qWarning() << "Failed to duplocate host address!"; - return hr; - } // We are now ready to host the app if( FAILED( hr = m_directPlayPeer->Connect( &dpAppDesc, // AppDesc - hostAddress, + m_hostAddress, m_deviceAddress, nullptr, nullptr, diff --git a/src/plugins/simulator/fs9/fs9_client.h b/src/plugins/simulator/fs9/fs9_client.h index c929bf5d4..0a45e2284 100644 --- a/src/plugins/simulator/fs9/fs9_client.h +++ b/src/plugins/simulator/fs9/fs9_client.h @@ -46,6 +46,9 @@ namespace BlackSimPlugin //! Destructor virtual ~CFs9Client(); + //! Set DirectPlay host address + void setHostAddress(const QString &hostAddress); + //! Add new aircraft situation void addAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation); diff --git a/src/plugins/simulator/fs9/fs9_host.cpp b/src/plugins/simulator/fs9/fs9_host.cpp index 83b4205aa..4cf1d666f 100644 --- a/src/plugins/simulator/fs9/fs9_host.cpp +++ b/src/plugins/simulator/fs9/fs9_host.cpp @@ -9,11 +9,13 @@ #define _CRT_SECURE_NO_WARNINGS +#include "blacksimplugin_freefunctions.h" #include "fs9_host.h" #include "multiplayer_packet_parser.h" #include "multiplayer_packets.h" #include "blackmisc/project.h" #include +#include using namespace BlackMisc; @@ -26,10 +28,45 @@ namespace BlackSimPlugin { } + QString CFs9Host::getHostAddress() + { + QString address; + if (m_hostStatus == Hosting) + { + DWORD dwNumAddresses = 0; + + HRESULT hr; + QVector addresses(dwNumAddresses); + m_directPlayPeer->GetLocalHostAddresses(addresses.data(), &dwNumAddresses, 0); + addresses.resize(dwNumAddresses); + ZeroMemory( addresses.data(), dwNumAddresses * sizeof(LPDIRECTPLAY8ADDRESS) ); + if (FAILED (hr = m_directPlayPeer->GetLocalHostAddresses(addresses.data(), &dwNumAddresses, 0))) + { + printDirectPlayError(hr); + return address; + } + + char url[250]; + DWORD size = 250; + addresses[0]->GetURLA(url, &size); + address = QString(url); + + for (uint ii = 0; ii < dwNumAddresses; ++ii) + { + LPDIRECTPLAY8ADDRESS pAddress = addresses[ii]; + if (pAddress) + { + pAddress->Release(); + } + } + } + return address; + } + void CFs9Host::init() { initDirectPlay(); - createDeviceAddress(); + createHostAddress(); startHosting(CProject::systemNameAndVersion(), m_callsign); } diff --git a/src/plugins/simulator/fs9/fs9_host.h b/src/plugins/simulator/fs9/fs9_host.h index 9f1b00ac9..b0c586b7e 100644 --- a/src/plugins/simulator/fs9/fs9_host.h +++ b/src/plugins/simulator/fs9/fs9_host.h @@ -38,6 +38,9 @@ namespace BlackSimPlugin //! Returns true if the users simulator is connected bool isConnected() const { return m_playerUser != 0; } + //! Get DirectPlay host url + QString getHostAddress(); + public slots: //! \copydoc CDirectPlayPeer::init diff --git a/src/plugins/simulator/fs9/simulator_fs9.cpp b/src/plugins/simulator/fs9/simulator_fs9.cpp index ee7c8e47f..90a8f2d33 100644 --- a/src/plugins/simulator/fs9/simulator_fs9.cpp +++ b/src/plugins/simulator/fs9/simulator_fs9.cpp @@ -112,6 +112,7 @@ namespace BlackSimPlugin // Create a new client thread, set update frequency to 25 ms and start it QThread *clientThread = new QThread(this); CFs9Client *client = new CFs9Client(callsign.toQString(), CTime(25, CTimeUnit::ms())); + client->setHostAddress(m_fs9Host->getHostAddress()); client->setPlayerUserId(m_fs9Host->getPlayerUserId()); client->moveToThread(clientThread);