Issue #94 Implement $SF packet to toggle visual pilot data sending

Still send a visual pilot data update at the slow rate of
every 5 seconds when visual pilot data update is disabled.
This commit is contained in:
Mat Sutcliffe
2022-01-23 19:33:09 +00:00
parent 872f546881
commit a4448dddc6
7 changed files with 173 additions and 20 deletions

View File

@@ -31,6 +31,7 @@
#include "blackcore/fsd/servererror.h"
#include "blackcore/fsd/interimpilotdataupdate.h"
#include "blackcore/fsd/visualpilotdataupdate.h"
#include "blackcore/fsd/visualpilotdatatoggle.h"
#include "blackcore/fsd/planeinforequest.h"
#include "blackcore/fsd/planeinformation.h"
#include "blackcore/fsd/planeinforequestfsinn.h"
@@ -50,6 +51,7 @@
#include <QHostAddress>
#include <QStringBuilder>
#include <QStringView>
#include <QNetworkReply>
using namespace BlackConfig;
using namespace BlackCore::Vatsim;
@@ -116,7 +118,7 @@ namespace BlackCore::Fsd
connect(&m_interimPositionUpdateTimer, &QTimer::timeout, this, &CFSDClient::sendInterimPilotDataUpdate);
m_visualPositionUpdateTimer.setObjectName(this->objectName().append(":m_visualPositionUpdateTimer"));
connect(&m_visualPositionUpdateTimer, &QTimer::timeout, this, &CFSDClient::sendVisualPilotDataUpdate);
connect(&m_visualPositionUpdateTimer, &QTimer::timeout, this, [this] { sendVisualPilotDataUpdate(); });
m_scheduledConfigUpdate.setObjectName(this->objectName().append(":m_scheduledConfigUpdate"));
connect(&m_scheduledConfigUpdate, &QTimer::timeout, this, &CFSDClient::sendIncrementalAircraftConfig);
@@ -361,6 +363,11 @@ namespace BlackCore::Fsd
myAircraft.getParts().isOnGround());
sendQueudedMessage(pilotDataUpdate);
}
if (this->isVisualPositionSendingEnabledForServer())
{
sendVisualPilotDataUpdate(true);
}
}
void CFSDClient::sendInterimPilotDataUpdate()
@@ -386,28 +393,35 @@ namespace BlackCore::Fsd
}
}
void CFSDClient::sendVisualPilotDataUpdate()
void CFSDClient::sendVisualPilotDataUpdate(bool slowUpdate)
{
if (this->getConnectionStatus().isDisconnected() && ! m_unitTestMode) { return; }
if (m_loginMode == CLoginMode::Observer || !isVisualPositionSendingEnabledForServer()) { return; }
const CSimulatedAircraft myAircraft(getOwnAircraft());
static constexpr double minVelocity = 0.00005;
if (std::abs(myAircraft.getVelocity().getVelocityX(CSpeedUnit::m_s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getVelocityY(CSpeedUnit::m_s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getVelocityZ(CSpeedUnit::m_s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getPitchVelocity(CAngleUnit::rad(), CTimeUnit::s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getRollVelocity(CAngleUnit::rad(), CTimeUnit::s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getHeadingVelocity(CAngleUnit::rad(), CTimeUnit::s())) < minVelocity)
if (!slowUpdate)
{
if (m_stoppedSendingVisualPositions) { return; }
m_stoppedSendingVisualPositions = true;
}
else
{
m_stoppedSendingVisualPositions = false;
}
static constexpr double minVelocity = 0.00005;
if (std::abs(myAircraft.getVelocity().getVelocityX(CSpeedUnit::m_s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getVelocityY(CSpeedUnit::m_s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getVelocityZ(CSpeedUnit::m_s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getPitchVelocity(CAngleUnit::rad(), CTimeUnit::s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getRollVelocity(CAngleUnit::rad(), CTimeUnit::s())) < minVelocity &&
std::abs(myAircraft.getVelocity().getHeadingVelocity(CAngleUnit::rad(), CTimeUnit::s())) < minVelocity)
{
if (m_stoppedSendingVisualPositions) { return; }
m_stoppedSendingVisualPositions = true;
}
else
{
m_stoppedSendingVisualPositions = false;
}
if (!m_serverWantsVisualPositions)
{
return;
}
}
VisualPilotDataUpdate visualPilotDataUpdate(getOwnCallsignAsString(),
myAircraft.latitude().value(CAngleUnit::deg()),
myAircraft.longitude().value(CAngleUnit::deg()),
@@ -1062,6 +1076,7 @@ namespace BlackCore::Fsd
m_messageTypeMapping["$!!"] = MessageType::KillRequest;
m_messageTypeMapping["@"] = MessageType::PilotDataUpdate;
m_messageTypeMapping["^"] = MessageType::VisualPilotDataUpdate;
m_messageTypeMapping["$SF"] = MessageType::VisualPilotDataToggle;
m_messageTypeMapping["$PI"] = MessageType::Ping;
m_messageTypeMapping["$PO"] = MessageType::Pong;
m_messageTypeMapping["$ER"] = MessageType::ServerError;
@@ -1286,6 +1301,12 @@ namespace BlackCore::Fsd
emit visualPilotDataUpdateReceived(situation);
}
void CFSDClient::handleVisualPilotDataToggle(const QStringList& tokens)
{
const VisualPilotDataToggle toggle = VisualPilotDataToggle::fromTokens(tokens);
m_serverWantsVisualPositions = toggle.m_active;
}
void CFSDClient::handlePing(const QStringList &tokens)
{
const Ping ping = Ping::fromTokens(tokens);
@@ -1852,6 +1873,7 @@ namespace BlackCore::Fsd
void CFSDClient::clearState()
{
m_stoppedSendingVisualPositions = false;
m_serverWantsVisualPositions = false;
m_textMessagesToConsolidate.clear();
m_pendingAtisQueries.clear();
m_lastPositionUpdate.clear();
@@ -2204,6 +2226,7 @@ namespace BlackCore::Fsd
case MessageType::PilotClientCom: handleCustomPilotPacket(tokens); break;
case MessageType::RevBClientParts: handleRevBClientPartsPacket(tokens); break;
case MessageType::VisualPilotDataUpdate: handleVisualPilotDataUpdate(tokens); break;
case MessageType::VisualPilotDataToggle: handleVisualPilotDataToggle(tokens); break;
case MessageType::EuroscopeSimData: handleEuroscopeSimData(tokens); break;
// normally we should not get here

View File

@@ -262,7 +262,7 @@ namespace BlackCore::Fsd
void sendDeleteAtc();
void sendPilotDataUpdate();
void sendInterimPilotDataUpdate();
void sendVisualPilotDataUpdate();
void sendVisualPilotDataUpdate(bool slowUpdate = false);
void sendAtcDataUpdate(double latitude, double longitude);
void sendPing(const QString &receiver);
//
@@ -366,6 +366,7 @@ namespace BlackCore::Fsd
void handleTextMessage(const QStringList &tokens);
void handlePilotDataUpdate(const QStringList &tokens);
void handleVisualPilotDataUpdate(const QStringList &tokens);
void handleVisualPilotDataToggle(const QStringList &tokens);
void handleEuroscopeSimData(const QStringList &tokens);
void handlePing(const QStringList &tokens);
void handlePong(const QStringList &tokens);
@@ -568,6 +569,7 @@ namespace BlackCore::Fsd
static int constexpr c_updateVisualPositionIntervalMsec = 200; //!< interval for the VATSIM visual position updates (send our position and 6DOF velocity)
static int constexpr c_sendFsdMsgIntervalMsec = 10; //!< interval for FSD send messages
bool m_stoppedSendingVisualPositions = false; //!< for when velocity drops to zero
bool m_serverWantsVisualPositions = false; //!< there are interested clients in range
};
} // ns

View File

@@ -40,6 +40,7 @@ enum class MessageType
KillRequest,
PilotDataUpdate,
VisualPilotDataUpdate,
VisualPilotDataToggle,
Ping,
Pong,
ServerError,

View File

@@ -0,0 +1,48 @@
/* Copyright (C) 2022
* 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. 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.
*/
#include "visualpilotdatatoggle.h"
#include "pbh.h"
#include "serializer.h"
#include "blackmisc/logmessage.h"
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
namespace BlackCore::Fsd
{
VisualPilotDataToggle::VisualPilotDataToggle() : MessageBase()
{ }
VisualPilotDataToggle::VisualPilotDataToggle(const QString &sender, const QString &client, bool active)
: MessageBase(sender, {}),
m_client(client),
m_active(active)
{ }
QStringList VisualPilotDataToggle::toTokens() const
{
QStringList tokens;
tokens.push_back(m_sender);
tokens.push_back(m_client);
tokens.push_back(QString::number(m_active ? 1 : 0));
return tokens;
}
VisualPilotDataToggle VisualPilotDataToggle::fromTokens(const QStringList &tokens)
{
if (tokens.size() < 3)
{
CLogMessage(static_cast<VisualPilotDataToggle *>(nullptr)).debug(u"Wrong number of arguments.");
return {};
}
return VisualPilotDataToggle(tokens[0], tokens[1], tokens[2] == QStringLiteral("1"));
}
}

View File

@@ -0,0 +1,58 @@
/* Copyright (C) 2022
* 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. 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.
*/
//! \file
#ifndef BLACKCORE_FSD_VISUALPILOTDATATOGGLE_H
#define BLACKCORE_FSD_VISUALPILOTDATATOGGLE_H
#include "messagebase.h"
#include "enums.h"
namespace BlackCore::Fsd
{
//! Message from server to start or stop sending visual pilot data updates.
class BLACKCORE_EXPORT VisualPilotDataToggle : public MessageBase
{
public:
//! Constructor
VisualPilotDataToggle(const QString &sender, const QString &client, bool active);
//! Message converted to tokens
QStringList toTokens() const;
//! Construct from tokens
static VisualPilotDataToggle fromTokens(const QStringList &tokens);
//! PDU identifier
static QString pdu() { return "$SF"; }
//! Properties
//! @{
QString m_client;
bool m_active = false;
//! @}
private:
VisualPilotDataToggle();
};
//! Equal to operator
inline bool operator==(const VisualPilotDataToggle &lhs, const VisualPilotDataToggle &rhs)
{
return lhs.m_client == rhs.m_client && lhs.m_active == rhs.m_active;
}
//! Not equal to operator
inline bool operator!=(const VisualPilotDataToggle &lhs, const VisualPilotDataToggle &rhs)
{
return !(lhs == rhs);
}
}
#endif // guard

View File

@@ -444,7 +444,7 @@ namespace BlackFsdTest
m_client->sendPilotDataUpdate();
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.count(), 2);
const QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 1);
const CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
@@ -476,7 +476,7 @@ namespace BlackFsdTest
m_client->sendPilotDataUpdate();
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.count(), 2);
QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 1);
CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
@@ -509,7 +509,7 @@ namespace BlackFsdTest
m_client->sendPilotDataUpdate();
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.count(), 2);
QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 1);
CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();

View File

@@ -38,6 +38,7 @@
#include "blackcore/fsd/servererror.h"
#include "blackcore/fsd/interimpilotdataupdate.h"
#include "blackcore/fsd/visualpilotdataupdate.h"
#include "blackcore/fsd/visualpilotdatatoggle.h"
#include "blackcore/fsd/planeinforequest.h"
#include "blackcore/fsd/planeinformation.h"
#include "blackcore/fsd/planeinforequestfsinn.h"
@@ -86,6 +87,7 @@ namespace BlackMiscTest
void testPBH();
void testPilotDataUpdate();
void testVisualPilotDataUpdate();
void testVisualPilotDataToggle();
void testPing();
void testPlaneInfoRequest();
void testPlaneInformation();
@@ -543,6 +545,25 @@ namespace BlackMiscTest
QCOMPARE(0.0, messageFromTokens.m_noseGearAngle);
}
void CTestFsdMessages::testVisualPilotDataToggle()
{
const VisualPilotDataToggle message("SERVER", "ABCD", true);
QCOMPARE(QString("SERVER"), message.sender());
QCOMPARE(QString("ABCD"), message.m_client);
QCOMPARE(true, message.m_active);
QString stringRef("SERVER:ABCD:1");
QString str = message.toTokens().join(":");
QCOMPARE(str, stringRef);
QStringList tokens = QString("SERVER:ABCD:1").split(':');
auto messageFromTokens = VisualPilotDataToggle::fromTokens(tokens);
QCOMPARE(QString("SERVER"), messageFromTokens.sender());
QCOMPARE(QString("ABCD"), messageFromTokens.m_client);
QCOMPARE(true, messageFromTokens.m_active);
}
void CTestFsdMessages::testPing()
{
const Ping message("ABCD", "SERVER", "85275222");