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 "multiplayer_packet_parser.h"
#include "blacksimplugin_freefunctions.h"
#include <QDebug>
#include <QTimer>
#include <QFile>
@@ -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<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 hr = S_OK;

View File

@@ -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

View File

@@ -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<void **>(&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<wchar_t> 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,

View File

@@ -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);

View File

@@ -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 <QScopedArrayPointer>
#include <QVector>
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()
{
initDirectPlay();
createDeviceAddress();
createHostAddress();
startHosting(CProject::systemNameAndVersion(), m_callsign);
}

View File

@@ -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

View File

@@ -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);