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.
This commit is contained in:
Roland Winklmeier
2014-09-02 20:32:44 +02:00
parent 7a02aff7b9
commit 53b257fa3d
7 changed files with 90 additions and 23 deletions

View File

@@ -9,6 +9,7 @@
#include "directplay_peer.h" #include "directplay_peer.h"
#include "multiplayer_packet_parser.h" #include "multiplayer_packet_parser.h"
#include "blacksimplugin_freefunctions.h"
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QTimer>
#include <QFile> #include <QFile>
@@ -253,6 +254,24 @@ namespace BlackSimPlugin
return hr; 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<void**>(&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 CDirectPlayPeer::sendMessage( const QByteArray &message)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;

View File

@@ -71,6 +71,9 @@ namespace BlackSimPlugin
//! Creates a new DirectPlay device address //! Creates a new DirectPlay device address
HRESULT createDeviceAddress(); HRESULT createDeviceAddress();
//! Creates a new DirectPlay device address
HRESULT createHostAddress();
QString m_callsign; //!< Peer callsign QString m_callsign; //!< Peer callsign
IDirectPlay8Peer *m_directPlayPeer = nullptr; //!< DirectPlay peer address IDirectPlay8Peer *m_directPlayPeer = nullptr; //!< DirectPlay peer address

View File

@@ -41,7 +41,7 @@ namespace BlackSimPlugin
{ {
initDirectPlay(); initDirectPlay();
createDeviceAddress(); createDeviceAddress();
enumDirectPlayHosts(); //enumDirectPlayHosts();
connectToSession(m_callsign); connectToSession(m_callsign);
} }
@@ -63,6 +63,27 @@ namespace BlackSimPlugin
closeConnection(); 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<void **>(&m_hostAddress) ) ) )
{
printDirectPlayError(hr);
return;
}
if (FAILED (hr = m_hostAddress->BuildFromURLA(hostAddress.toLatin1().data())))
{
printDirectPlayError(hr);
return;
}
}
void CFs9Client::addAircraftSituation(const CAircraftSituation &situation) void CFs9Client::addAircraftSituation(const CAircraftSituation &situation)
{ {
QMutexLocker locker(&m_mutexInterpolator); QMutexLocker locker(&m_mutexInterpolator);
@@ -181,20 +202,6 @@ namespace BlackSimPlugin
QMutexLocker locker(&m_mutexHostList); 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<wchar_t> wszPlayername(new wchar_t[callsign.size() + 1]); QScopedArrayPointer<wchar_t> wszPlayername(new wchar_t[callsign.size() + 1]);
callsign.toWCharArray(wszPlayername.data()); callsign.toWCharArray(wszPlayername.data());
@@ -224,16 +231,10 @@ namespace BlackSimPlugin
dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC); dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
dpAppDesc.guidApplication = CFs9Sdk::guid(); 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 // We are now ready to host the app
if( FAILED( hr = m_directPlayPeer->Connect( &dpAppDesc, // AppDesc if( FAILED( hr = m_directPlayPeer->Connect( &dpAppDesc, // AppDesc
hostAddress, m_hostAddress,
m_deviceAddress, m_deviceAddress,
nullptr, nullptr,
nullptr, nullptr,

View File

@@ -46,6 +46,9 @@ namespace BlackSimPlugin
//! Destructor //! Destructor
virtual ~CFs9Client(); virtual ~CFs9Client();
//! Set DirectPlay host address
void setHostAddress(const QString &hostAddress);
//! Add new aircraft situation //! Add new aircraft situation
void addAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation); void addAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation);

View File

@@ -9,11 +9,13 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include "blacksimplugin_freefunctions.h"
#include "fs9_host.h" #include "fs9_host.h"
#include "multiplayer_packet_parser.h" #include "multiplayer_packet_parser.h"
#include "multiplayer_packets.h" #include "multiplayer_packets.h"
#include "blackmisc/project.h" #include "blackmisc/project.h"
#include <QScopedArrayPointer> #include <QScopedArrayPointer>
#include <QVector>
using namespace BlackMisc; using namespace BlackMisc;
@@ -26,10 +28,45 @@ namespace BlackSimPlugin
{ {
} }
QString CFs9Host::getHostAddress()
{
QString address;
if (m_hostStatus == Hosting)
{
DWORD dwNumAddresses = 0;
HRESULT hr;
QVector<LPDIRECTPLAY8ADDRESS> 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() void CFs9Host::init()
{ {
initDirectPlay(); initDirectPlay();
createDeviceAddress(); createHostAddress();
startHosting(CProject::systemNameAndVersion(), m_callsign); startHosting(CProject::systemNameAndVersion(), m_callsign);
} }

View File

@@ -38,6 +38,9 @@ namespace BlackSimPlugin
//! Returns true if the users simulator is connected //! Returns true if the users simulator is connected
bool isConnected() const { return m_playerUser != 0; } bool isConnected() const { return m_playerUser != 0; }
//! Get DirectPlay host url
QString getHostAddress();
public slots: public slots:
//! \copydoc CDirectPlayPeer::init //! \copydoc CDirectPlayPeer::init

View File

@@ -112,6 +112,7 @@ namespace BlackSimPlugin
// Create a new client thread, set update frequency to 25 ms and start it // Create a new client thread, set update frequency to 25 ms and start it
QThread *clientThread = new QThread(this); QThread *clientThread = new QThread(this);
CFs9Client *client = new CFs9Client(callsign.toQString(), CTime(25, CTimeUnit::ms())); CFs9Client *client = new CFs9Client(callsign.toQString(), CTime(25, CTimeUnit::ms()));
client->setHostAddress(m_fs9Host->getHostAddress());
client->setPlayerUserId(m_fs9Host->getPlayerUserId()); client->setPlayerUserId(m_fs9Host->getPlayerUserId());
client->moveToThread(clientThread); client->moveToThread(clientThread);