mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 20:15:35 +08:00
170 lines
6.0 KiB
C++
170 lines
6.0 KiB
C++
/* Copyright (C) 2014
|
|
* swift project community / contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
|
* contained in the LICENSE file.
|
|
*/
|
|
|
|
#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;
|
|
|
|
namespace BlackSimPlugin
|
|
{
|
|
namespace Fs9
|
|
{
|
|
CFs9Host::CFs9Host(QObject *owner) :
|
|
CDirectPlayPeer(owner, CProject::systemNameAndVersion())
|
|
{
|
|
}
|
|
|
|
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::sendTextMessage(const QString &textMessage)
|
|
{
|
|
MPChatText mpChatText;
|
|
mpChatText.chat_data = textMessage;
|
|
QByteArray message;
|
|
MultiPlayerPacketParser::writeType(message, CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND);
|
|
MultiPlayerPacketParser::writeSize(message, mpChatText.chat_data.size() + 1);
|
|
message = MultiPlayerPacketParser::writeMessage(message, mpChatText);
|
|
sendMessage(message);
|
|
}
|
|
|
|
void CFs9Host::initialize()
|
|
{
|
|
initDirectPlay();
|
|
createHostAddress();
|
|
startHosting(CProject::systemNameAndVersion(), m_callsign);
|
|
}
|
|
|
|
void CFs9Host::cleanup()
|
|
{
|
|
stopHosting();
|
|
}
|
|
|
|
|
|
HRESULT CFs9Host::startHosting(const QString &session, const QString &callsign)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_hostStatus == Hosting) return hr;
|
|
|
|
DPN_APPLICATION_DESC dpAppDesc;
|
|
|
|
QScopedArrayPointer<wchar_t> wszSession(new wchar_t[session.size() + 1]);
|
|
QScopedArrayPointer<wchar_t> wszPlayername(new wchar_t[callsign.size() + 1]);
|
|
|
|
session.toWCharArray(wszSession.data());
|
|
wszSession[session.size()] = 0;
|
|
callsign.toWCharArray(wszPlayername.data());
|
|
wszPlayername[callsign.size()] = 0;
|
|
|
|
PLAYER_INFO_STRUCT playerInfo;
|
|
ZeroMemory(&playerInfo, sizeof(PLAYER_INFO_STRUCT));
|
|
strcpy(playerInfo.szAircraft, "Boeing 737-400");
|
|
|
|
|
|
playerInfo.dwFlags = PLAYER_INFO_STRUCT::PARAMS_RECV | PLAYER_INFO_STRUCT::PARAMS_SEND;
|
|
|
|
// Prepare and set the player information structure.
|
|
DPN_PLAYER_INFO player;
|
|
ZeroMemory(&player, sizeof(DPN_PLAYER_INFO));
|
|
player.dwSize = sizeof(DPN_PLAYER_INFO);
|
|
player.pvData = &playerInfo;
|
|
player.dwDataSize = sizeof(PLAYER_INFO_STRUCT);
|
|
player.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
|
|
player.pwszName = wszPlayername.data();
|
|
if (FAILED(hr = m_directPlayPeer->SetPeerInfo(&player, nullptr, nullptr, DPNSETPEERINFO_SYNC)))
|
|
{
|
|
qWarning() << "Failed to set peer info!";
|
|
return hr;
|
|
}
|
|
|
|
// Now set up the Application Description
|
|
ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
|
|
dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
|
|
dpAppDesc.guidApplication = CFs9Sdk::guid();
|
|
dpAppDesc.pwszSessionName = wszSession.data();
|
|
|
|
// We are now ready to host the app
|
|
if (FAILED(hr = m_directPlayPeer->Host(&dpAppDesc, // AppDesc
|
|
&m_deviceAddress, 1, // Device Address
|
|
nullptr,
|
|
nullptr, // Reserved
|
|
nullptr, // Player Context
|
|
0))) // dwFlags
|
|
{
|
|
qWarning() << "Failed to start hosting!";
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
qDebug() << "Host successfully started";
|
|
m_hostStatus = Hosting;
|
|
}
|
|
|
|
emit statusChanged(m_hostStatus);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFs9Host::stopHosting()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_hostStatus == Terminated) return hr;
|
|
|
|
qDebug() << "Terminating host";
|
|
hr = m_directPlayPeer->TerminateSession(nullptr, 0, 0);
|
|
hr = m_directPlayPeer->Close(0);
|
|
m_hostStatus = Terminated;
|
|
|
|
emit statusChanged(m_hostStatus);
|
|
return hr;
|
|
}
|
|
}
|
|
}
|