4 #define _CRT_SECURE_NO_WARNINGS
8 #include <QScopedArrayPointer>
21 namespace swift::simplugin::fs9
35 if (m_hostStatus == Hosting)
37 DWORD dwNumAddresses = 0;
40 QVector<LPDIRECTPLAY8ADDRESS> addresses(
static_cast<int>(dwNumAddresses));
41 m_directPlayPeer->GetLocalHostAddresses(addresses.data(), &dwNumAddresses, 0);
42 addresses.resize(
static_cast<int>(dwNumAddresses));
43 ZeroMemory(addresses.data(), dwNumAddresses *
sizeof(LPDIRECTPLAY8ADDRESS));
44 if (FAILED(hr =
m_directPlayPeer->GetLocalHostAddresses(addresses.data(), &dwNumAddresses, 0)))
46 logDirectPlayError(hr);
50 if (dwNumAddresses < 1) {
return {}; }
60 for (uint ii = 0; ii < dwNumAddresses; ++ii)
63 addresses[
static_cast<int>(ii)]->GetURLA(url, &size);
64 address = QString(url);
65 if (!address.isEmpty()) {
break; }
68 for (uint ii = 0; ii < dwNumAddresses; ++ii)
70 LPDIRECTPLAY8ADDRESS pAddress = addresses[
static_cast<int>(ii)];
85 qDebug() <<
"Message:" << textMessage;
89 HRESULT CFs9Host::startHosting(
const QString &session,
const QString &callsign)
93 if (m_hostStatus == Hosting) {
return hr; }
96 DPN_APPLICATION_DESC dpAppDesc;
98 QScopedArrayPointer<wchar_t> wszSession(
new wchar_t[
static_cast<unsigned>(session.size()) + 1]);
99 QScopedArrayPointer<wchar_t> wszPlayername(
new wchar_t[
static_cast<unsigned>(callsign.size()) + 1]);
101 session.toWCharArray(wszSession.data());
102 wszSession[session.size()] = 0;
103 callsign.toWCharArray(wszPlayername.data());
104 wszPlayername[callsign.size()] = 0;
106 PLAYER_INFO_STRUCT playerInfo;
107 ZeroMemory(&playerInfo,
sizeof(PLAYER_INFO_STRUCT));
108 strcpy(playerInfo.szAircraft,
"Boeing 737-400");
110 playerInfo.dwFlags = PLAYER_INFO_STRUCT::PARAMS_RECV | PLAYER_INFO_STRUCT::PARAMS_SEND;
113 DPN_PLAYER_INFO player;
114 ZeroMemory(&player,
sizeof(DPN_PLAYER_INFO));
115 player.dwSize =
sizeof(DPN_PLAYER_INFO);
116 player.pvData = &playerInfo;
117 player.dwDataSize =
sizeof(PLAYER_INFO_STRUCT);
118 player.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
119 player.pwszName = wszPlayername.data();
120 if (FAILED(hr =
m_directPlayPeer->SetPeerInfo(&player,
nullptr,
nullptr, DPNSETPEERINFO_SYNC)))
122 logDirectPlayError(hr);
127 ZeroMemory(&dpAppDesc,
sizeof(DPN_APPLICATION_DESC));
128 dpAppDesc.dwSize =
sizeof(DPN_APPLICATION_DESC);
130 dpAppDesc.pwszSessionName = wszSession.data();
140 logDirectPlayError(hr);
146 m_hostStatus = Hosting;
150 DWORD dwNumPlayers = 0;
151 hr =
m_directPlayPeer->EnumPlayersAndGroups(
nullptr, &dwNumPlayers, DPNENUM_PLAYERS);
153 if (hr == DPNERR_BUFFERTOOSMALL)
155 QScopedArrayPointer<DPNID> stalledPeers(
new DPNID[dwNumPlayers]);
156 hr =
m_directPlayPeer->EnumPlayersAndGroups(stalledPeers.data(), &dwNumPlayers, DPNENUM_PLAYERS);
159 for (
DWORD i = 0; i < dwNumPlayers; ++i)
161 m_directPlayPeer->DestroyPeer(stalledPeers[
static_cast<int>(i)],
nullptr, 0, 0);
169 HRESULT CFs9Host::stopHosting()
173 if (m_hostStatus == Terminated)
return hr;
176 if (FAILED(hr =
m_directPlayPeer->TerminateSession(
nullptr, 0, 0))) {
return logDirectPlayError(hr); }
178 if (FAILED(hr =
m_directPlayPeer->Close(0))) {
return logDirectPlayError(hr); }
180 m_hostStatus = Terminated;
183 DWORD dwNumPlayers = 0;
184 hr =
m_directPlayPeer->EnumPlayersAndGroups(
nullptr, &dwNumPlayers, DPNENUM_PLAYERS);
186 if (hr == DPNERR_BUFFERTOOSMALL)
188 QScopedArrayPointer<DPNID> stalledPeers(
new DPNID[dwNumPlayers]);
189 hr =
m_directPlayPeer->EnumPlayersAndGroups(stalledPeers.data(), &dwNumPlayers, DPNENUM_PLAYERS);
192 for (
DWORD i = 0; i < dwNumPlayers; ++i)
194 m_directPlayPeer->DestroyPeer(stalledPeers[
static_cast<int>(i)],
nullptr, 0, 0);
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
const QString & swiftVersionString() const
swift info string
Class for emitting a log message.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
QString toQString(bool i18n=false) const
Cast as QString.
DirectPlay peer implementation More information can be found in the DirectX9 SDK documentation http:/...
HRESULT createHostAddress()
Creates a new DirectPlay device address.
IDirectPlay8Peer * m_directPlayPeer
DirectPlay peer address.
HRESULT initDirectPlay()
Initialize DirectPlay.
IDirectPlay8Address * m_deviceAddress
DirectPlay device address.
HRESULT sendMessage(const QByteArray &data)
Send a custom DirectPlay message.
const swift::misc::aviation::CCallsign m_callsign
Peer callsign.
void sendTextMessage(const QString &textMessage)
Send new text message.
QString getHostAddress()
Get DirectPlay host url.
void statusChanged(swift::simplugin::fs9::CFs9Host::HostStatus)
Hosting status changed.
virtual ~CFs9Host()
Destructor.
static GUID guid()
Get FS9 application GUID.
static void writeSize(QByteArray &data, qint32 size)
Write the multiplayer packet size.
static QByteArray writeMessage(QByteArray &data, const Message &message)
Write message to byte stream.
static void writeType(QByteArray &data, CFs9Sdk::MULTIPLAYER_PACKET_ID type)
Write the multiplayer packet type.
void SafeRelease(T *&pT)
Safely release a COM allocated object.
Free functions in swift::misc.
unsigned long DWORD
Fake Windows DWORD.
Multiplayer packet - chat text.
QString chat_data
Chat message.