[FSD] Add rehost packet ($XX) for VATSIM

This commit is contained in:
Mat Sutcliffe
2022-02-16 21:40:46 +00:00
parent 5106859ed9
commit d2fadccf4e
5 changed files with 138 additions and 0 deletions

View File

@@ -39,6 +39,7 @@
#include "blackcore/fsd/planeinforequestfsinn.h"
#include "blackcore/fsd/planeinformationfsinn.h"
#include "blackcore/fsd/revbclientparts.h"
#include "blackcore/fsd/rehost.h"
#include "blackmisc/aviation/flightplan.h"
#include "blackmisc/network/rawfsdmessage.h"
@@ -1097,6 +1098,7 @@ namespace BlackCore::Fsd
m_messageTypeMapping["#DL"] = MessageType::ServerHeartbeat;
m_messageTypeMapping["#TM"] = MessageType::TextMessage;
m_messageTypeMapping["#SB"] = MessageType::PilotClientCom;
m_messageTypeMapping["$XX"] = MessageType::Rehost;
// Euroscope
m_messageTypeMapping["SIMDATA"] = MessageType::EuroscopeSimData;
@@ -1642,6 +1644,34 @@ namespace BlackCore::Fsd
CLogMessage(this).debug(u"Set Config at %1 ") << offsetTimeMs ;
}
void CFSDClient::handleRehost(const QStringList &tokens)
{
const Rehost rehost = Rehost::fromTokens(tokens);
CLogMessage(this).info(u"Server requested we switch server to %1") << rehost.m_hostname;
m_rehosting = true;
auto newSocket = new QTcpSocket(this);
connect(newSocket, &QTcpSocket::connected, this, [this, newSocket]
{
readDataFromSocket();
CLogMessage(this).debug(u"Successfully switched server");
QObject::disconnect(newSocket);
m_socket.reset(newSocket);
m_rehosting = false;
connectSocketSignals();
readDataFromSocket();
});
connect(newSocket, &QTcpSocket::errorOccurred, this, [this, newSocket]
{
CLogMessage(this).warning(u"Failed to switch server: %1") << newSocket->errorString();
m_rehosting = false;
delete newSocket;
if (m_socket->state() != QAbstractSocket::ConnectedState) { updateConnectionStatus(CConnectionStatus::Disconnected); }
});
newSocket->connectToHost(rehost.m_hostname, m_socket->peerPort());
}
void CFSDClient::handleCustomPilotPacket(const QStringList &tokens)
{
const QString subType = tokens.at(2);
@@ -1757,11 +1787,15 @@ namespace BlackCore::Fsd
void CFSDClient::printSocketError(QAbstractSocket::SocketError socketError)
{
if (m_rehosting) { return; }
CLogMessage(this).error(u"FSD socket error: %1") << this->socketErrorString(socketError);
}
void CFSDClient::handleSocketError(QAbstractSocket::SocketError socketError)
{
if (m_rehosting) { return; }
const QString error = this->socketErrorString(socketError);
switch (socketError)
{
@@ -1893,6 +1927,7 @@ namespace BlackCore::Fsd
void CFSDClient::clearState()
{
m_rehosting = false;
m_stoppedSendingVisualPositions = false;
m_serverWantsVisualPositions = false;
m_visualPositionUpdateSentCount = 0;
@@ -2252,6 +2287,7 @@ namespace BlackCore::Fsd
case MessageType::VisualPilotDataStopped: handleVisualPilotDataUpdate(tokens, messageType); break;
case MessageType::VisualPilotDataToggle: handleVisualPilotDataToggle(tokens); break;
case MessageType::EuroscopeSimData: handleEuroscopeSimData(tokens); break;
case MessageType::Rehost: handleRehost(tokens); break;
// normally we should not get here
default:

View File

@@ -379,6 +379,7 @@ namespace BlackCore::Fsd
void handleCustomPilotPacket(const QStringList &tokens);
void handleFsdIdentification(const QStringList &tokens);
void handleRevBClientPartsPacket(const QStringList &tokens);
void handleRehost(const QStringList &tokens);
//
void handleUnknownPacket(const QString &line);
@@ -475,6 +476,7 @@ namespace BlackCore::Fsd
std::unique_ptr<QTcpSocket> m_socket = std::make_unique<QTcpSocket>(this); //!< used TCP socket, parent needed as it runs in worker thread
void connectSocketSignals();
bool m_rehosting = false;
std::atomic_bool m_unitTestMode { false };
std::atomic_bool m_printToConsole { false };

View File

@@ -52,6 +52,7 @@ enum class MessageType
PilotClientCom,
RevBClientParts, // IVAO only
RevBPilotDescription, // -PD IVAO only not handled in swift
Rehost,
};
namespace BlackCore::Fsd

View File

@@ -0,0 +1,42 @@
/* Copyright (C) 2019
* 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 "rehost.h"
#include "serializer.h"
#include "blackmisc/logmessage.h"
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
namespace BlackCore::Fsd
{
Rehost::Rehost() : MessageBase()
{ }
Rehost::Rehost(const QString &sender, const QString &hostname)
: MessageBase(sender, {}),
m_hostname(hostname)
{ }
QStringList Rehost::toTokens() const
{
return { m_sender, m_hostname };
}
Rehost Rehost::fromTokens(const QStringList &tokens)
{
if (tokens.size() < 2)
{
CLogMessage(static_cast<Rehost *>(nullptr)).debug(u"Wrong number of arguments.");
return {};
}
return Rehost(tokens[0], tokens[1]);
}
}

View File

@@ -0,0 +1,57 @@
/* Copyright (C) 2019
* 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_REHOST_H
#define BLACKCORE_FSD_REHOST_H
#include "messagebase.h"
#include "enums.h"
namespace BlackCore::Fsd
{
//! The server requests us to connect to a different server.
class BLACKCORE_EXPORT Rehost : public MessageBase
{
public:
//! Constructor
Rehost(const QString &sender, const QString &hostname);
//! Message converted to tokens
QStringList toTokens() const;
//! Construct from tokens
static Rehost fromTokens(const QStringList &tokens);
//! PDU identifier
static QString pdu() { return "$XX"; }
//! Properties
//! @{
QString m_hostname;
//! @}
private:
Rehost();
};
//! Equal to operator
inline bool operator==(const Rehost &lhs, const Rehost &rhs)
{
return lhs.m_hostname == rhs.m_hostname;
}
//! Not equal to operator
inline bool operator!=(const Rehost &lhs, const Rehost &rhs)
{
return !(lhs == rhs);
}
}
#endif // guard