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

View File

@@ -262,7 +262,7 @@ namespace BlackCore::Fsd
void sendDeleteAtc(); void sendDeleteAtc();
void sendPilotDataUpdate(); void sendPilotDataUpdate();
void sendInterimPilotDataUpdate(); void sendInterimPilotDataUpdate();
void sendVisualPilotDataUpdate(); void sendVisualPilotDataUpdate(bool slowUpdate = false);
void sendAtcDataUpdate(double latitude, double longitude); void sendAtcDataUpdate(double latitude, double longitude);
void sendPing(const QString &receiver); void sendPing(const QString &receiver);
// //
@@ -366,6 +366,7 @@ namespace BlackCore::Fsd
void handleTextMessage(const QStringList &tokens); void handleTextMessage(const QStringList &tokens);
void handlePilotDataUpdate(const QStringList &tokens); void handlePilotDataUpdate(const QStringList &tokens);
void handleVisualPilotDataUpdate(const QStringList &tokens); void handleVisualPilotDataUpdate(const QStringList &tokens);
void handleVisualPilotDataToggle(const QStringList &tokens);
void handleEuroscopeSimData(const QStringList &tokens); void handleEuroscopeSimData(const QStringList &tokens);
void handlePing(const QStringList &tokens); void handlePing(const QStringList &tokens);
void handlePong(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_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 static int constexpr c_sendFsdMsgIntervalMsec = 10; //!< interval for FSD send messages
bool m_stoppedSendingVisualPositions = false; //!< for when velocity drops to zero bool m_stoppedSendingVisualPositions = false; //!< for when velocity drops to zero
bool m_serverWantsVisualPositions = false; //!< there are interested clients in range
}; };
} // ns } // ns

View File

@@ -40,6 +40,7 @@ enum class MessageType
KillRequest, KillRequest,
PilotDataUpdate, PilotDataUpdate,
VisualPilotDataUpdate, VisualPilotDataUpdate,
VisualPilotDataToggle,
Ping, Ping,
Pong, Pong,
ServerError, 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(); m_client->sendPilotDataUpdate();
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 2);
const QList<QVariant> arguments = spy.takeFirst(); const QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 1); QCOMPARE(arguments.size(), 1);
const CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>(); const CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
@@ -476,7 +476,7 @@ namespace BlackFsdTest
m_client->sendPilotDataUpdate(); m_client->sendPilotDataUpdate();
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 2);
QList<QVariant> arguments = spy.takeFirst(); QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 1); QCOMPARE(arguments.size(), 1);
CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>(); CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();
@@ -509,7 +509,7 @@ namespace BlackFsdTest
m_client->sendPilotDataUpdate(); m_client->sendPilotDataUpdate();
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 2);
QList<QVariant> arguments = spy.takeFirst(); QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 1); QCOMPARE(arguments.size(), 1);
CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>(); CRawFsdMessage fsdMessage = arguments.at(0).value<CRawFsdMessage>();

View File

@@ -38,6 +38,7 @@
#include "blackcore/fsd/servererror.h" #include "blackcore/fsd/servererror.h"
#include "blackcore/fsd/interimpilotdataupdate.h" #include "blackcore/fsd/interimpilotdataupdate.h"
#include "blackcore/fsd/visualpilotdataupdate.h" #include "blackcore/fsd/visualpilotdataupdate.h"
#include "blackcore/fsd/visualpilotdatatoggle.h"
#include "blackcore/fsd/planeinforequest.h" #include "blackcore/fsd/planeinforequest.h"
#include "blackcore/fsd/planeinformation.h" #include "blackcore/fsd/planeinformation.h"
#include "blackcore/fsd/planeinforequestfsinn.h" #include "blackcore/fsd/planeinforequestfsinn.h"
@@ -86,6 +87,7 @@ namespace BlackMiscTest
void testPBH(); void testPBH();
void testPilotDataUpdate(); void testPilotDataUpdate();
void testVisualPilotDataUpdate(); void testVisualPilotDataUpdate();
void testVisualPilotDataToggle();
void testPing(); void testPing();
void testPlaneInfoRequest(); void testPlaneInfoRequest();
void testPlaneInformation(); void testPlaneInformation();
@@ -543,6 +545,25 @@ namespace BlackMiscTest
QCOMPARE(0.0, messageFromTokens.m_noseGearAngle); 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() void CTestFsdMessages::testPing()
{ {
const Ping message("ABCD", "SERVER", "85275222"); const Ping message("ABCD", "SERVER", "85275222");