4 #include "directplaypeer.h"
8 #include <QScopedPointer>
19 using namespace swift::misc::aviation;
21 namespace swift::simplugin::fs9
23 const QStringList &CDirectPlayPeer::getLogCategories()
29 CDirectPlayPeer::CDirectPlayPeer(
const CCallsign &callsign, QObject *parent)
30 : QObject(parent), m_callsign(callsign), m_callbackWrapper(this, &
CDirectPlayPeer::directPlayMessageHandler)
42 if (m_coInitializeSucceeded) { CoUninitialize(); }
49 case DPN_MSGID_CREATE_PLAYER:
51 DPNMSG_CREATE_PLAYER *pCreatePlayerMsg =
static_cast<DPNMSG_CREATE_PLAYER *
>(msgBuffer);
55 DPN_PLAYER_INFO *pdpPlayerInfo =
nullptr;
56 HRESULT hr = DPNERR_CONNECTING;
60 while (hr == DPNERR_CONNECTING)
62 hr =
m_directPlayPeer->GetPeerInfo(pCreatePlayerMsg->dpnidPlayer, pdpPlayerInfo, &dwSize, 0);
65 if (hr == DPNERR_BUFFERTOOSMALL)
67 QScopedArrayPointer<unsigned char> memPtr(
new unsigned char[dwSize]);
68 pdpPlayerInfo =
reinterpret_cast<DPN_PLAYER_INFO *
>(memPtr.data());
69 if (pdpPlayerInfo ==
nullptr) {
break; }
71 ZeroMemory(pdpPlayerInfo, dwSize);
72 pdpPlayerInfo->dwSize =
sizeof(DPN_PLAYER_INFO);
74 hr =
m_directPlayPeer->GetPeerInfo(pCreatePlayerMsg->dpnidPlayer, pdpPlayerInfo, &dwSize, 0);
77 if (pdpPlayerInfo->dwPlayerFlags & DPNPLAYER_LOCAL)
91 case DPN_MSGID_RECEIVE:
93 PDPNMSG_RECEIVE pReceiveMsg =
static_cast<PDPNMSG_RECEIVE
>(msgBuffer);
98 const QByteArray messageData =
99 QByteArray((
char *)pReceiveMsg->pReceiveData, pReceiveMsg->dwReceiveDataSize);
105 case DPN_MSGID_ENUM_HOSTS_RESPONSE:
107 PDPNMSG_ENUM_HOSTS_RESPONSE enumHostsResponseMsg =
static_cast<PDPNMSG_ENUM_HOSTS_RESPONSE
>(msgBuffer);
108 const DPN_APPLICATION_DESC *applicationDescription = enumHostsResponseMsg->pApplicationDescription;
111 return applicationDescription->guidInstance == hostNode.getApplicationDesc().guidInstance;
122 if (FAILED(hr = enumHostsResponseMsg->pAddressSender->Duplicate(hostNode.
getHostAddressPtr())))
128 DPN_APPLICATION_DESC appDesc;
130 ZeroMemory(&appDesc,
sizeof(DPN_APPLICATION_DESC));
131 memcpy(&appDesc, applicationDescription,
sizeof(DPN_APPLICATION_DESC));
134 appDesc.pwszSessionName =
nullptr;
135 appDesc.pwszPassword =
nullptr;
136 appDesc.pvReservedData =
nullptr;
137 appDesc.dwReservedDataSize = 0;
138 appDesc.pvApplicationReservedData =
nullptr;
139 appDesc.dwApplicationReservedDataSize = 0;
142 hostNode.
setSessionName(QString::fromWCharArray(applicationDescription->pwszSessionName));
147 case DPN_MSGID_CONNECT_COMPLETE:
149 const PDPNMSG_CONNECT_COMPLETE connectCompleteMsg =
static_cast<PDPNMSG_CONNECT_COMPLETE
>(msgBuffer);
153 CLogMessage(
this).
warning(u
"DirectPlay connection returned: %1") << connectCompleteMsg->hResultCode;
167 HRESULT hr = CoInitializeEx(
nullptr, COINIT_MULTITHREADED);
170 if (hr == RPC_E_CHANGED_MODE)
172 CLogMessage(
this).
debug(u
"CoInitializeEx was already called with a different mode. Trying again.");
173 hr = CoInitializeEx(
nullptr, COINIT_APARTMENTTHREADED);
180 if (hr == S_OK || hr == S_FALSE) { m_coInitializeSucceeded =
true; }
188 if (FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Peer,
nullptr, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Peer,
219 HRESULT hr =
m_directPlayPeer->EnumServiceProviders(&CLSID_DP8SP_TCPIP,
nullptr,
nullptr, &dwSize, &dwItems, 0);
221 if (hr != DPNERR_BUFFERTOOSMALL)
229 QScopedArrayPointer<unsigned char> memPtr(
new unsigned char[dwSize]);
230 DPN_SERVICE_PROVIDER_INFO *dpnSPInfo =
reinterpret_cast<DPN_SERVICE_PROVIDER_INFO *
>(memPtr.data());
232 if (FAILED(hr =
m_directPlayPeer->EnumServiceProviders(&CLSID_DP8SP_TCPIP,
nullptr, dpnSPInfo, &dwSize,
240 if (dwItems == 0) { hr = E_FAIL; }
242 if (SUCCEEDED(hr)) {
return true; }
243 else {
return false; }
251 if (FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Address,
nullptr, CLSCTX_INPROC_SERVER,
252 IID_IDirectPlay8Address,
reinterpret_cast<void **
>(&
m_deviceAddress))))
273 if (FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Address,
nullptr, CLSCTX_INPROC_SERVER,
274 IID_IDirectPlay8Address,
reinterpret_cast<void **
>(&
m_deviceAddress))))
275 return logDirectPlayError(hr);
278 if (FAILED(hr =
m_deviceAddress->SetSP(&CLSID_DP8SP_TCPIP))) {
return logDirectPlayError(hr); }
286 DPN_BUFFER_DESC dpBufferDesc;
288 if ((dpBufferDesc.dwBufferSize = message.size()) == 0) {
return S_FALSE; }
291 dpBufferDesc.pBufferData = (BYTE *)message.data();
293 DPNHANDLE asyncHandle;
296 DPNSEND_GUARANTEED)))
298 const QString m(message);
299 CLogMessage(
this).
warning(u
"DirectPlay: Failed to send message! Return value: %1 ") << hr;
static const QString & driver()
Driver.
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & debug()
Set the severity to debug.
Value object encapsulating information of a callsign.
DirectPlay peer implementation More information can be found in the DirectX9 SDK documentation http:/...
HRESULT directPlayMessageHandler(DWORD messageId, void *msgBuffer)
DirectPlay message handler.
std::atomic< DPNID > m_playerLocal
Local player Id.
bool isServiceProviderValid(const GUID *pGuidSP)
Returns true of the service provider is a valid on this machine.
HRESULT createHostAddress()
Creates a new DirectPlay device address.
QList< CHostNode > m_hostNodeList
List of enumerated hosts.
std::atomic< DPNID > m_playerUser
User player Id.
IDirectPlay8Peer * m_directPlayPeer
DirectPlay peer address.
HRESULT initDirectPlay()
Initialize DirectPlay.
virtual ~CDirectPlayPeer()
Destructor.
IDirectPlay8Address * m_deviceAddress
DirectPlay device address.
void connectionComplete()
Async operatione complete.
HRESULT sendMessage(const QByteArray &data)
Send a custom DirectPlay message.
TCallbackWrapper m_callbackWrapper
Callback wrapper.
void customPacketReceived(const QByteArray &data)
Received custom FS9 packet.
HRESULT createDeviceAddress()
Creates a new DirectPlay device address.
void SafeRelease(T *&pT)
Safely release a COM allocated object.
Free functions in swift::misc.
unsigned long DWORD
Fake Windows DWORD.
Class representing a enumerated host node.
IDirectPlay8Address ** getHostAddressPtr()
Returns a pointer to the hosts address.
void setApplicationDesc(const DPN_APPLICATION_DESC &appDesc)
Set the hosts application description.
void setSessionName(const QString &name)
Set the session name.
static ReturnType WINAPI messageHandler(void *userContext, Argument1 arg1, Argument2 arg2)
FS9 message handler callback.