Use nested namespaces (C++17 feature)

This commit is contained in:
Mat Sutcliffe
2021-09-15 21:44:54 +01:00
parent 3f2e5b0b69
commit 57d32da826
1345 changed files with 146075 additions and 150376 deletions

View File

@@ -54,334 +54,331 @@ using namespace BlackMisc::Simulation;
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackCore::Data;
namespace BlackCore
namespace BlackCore::Vatsim
{
namespace Vatsim
CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner) :
CThreadedReader(owner, "CVatsimDataFileReader"),
CEcosystemAware(CEcosystemAware::providerIfPossible(owner))
{
CVatsimDataFileReader::CVatsimDataFileReader(QObject *owner) :
CThreadedReader(owner, "CVatsimDataFileReader"),
CEcosystemAware(CEcosystemAware::providerIfPossible(owner))
this->reloadSettings();
}
CSimulatedAircraftList CVatsimDataFileReader::getAircraft() const
{
QReadLocker rl(&m_lock);
return m_aircraft;
}
CAtcStationList CVatsimDataFileReader::getAtcStations() const
{
QReadLocker rl(&m_lock);
return m_atcStations;
}
CAtcStationList CVatsimDataFileReader::getAtcStationsForCallsign(const CCallsign &callsign) const
{
const CCallsignSet cs({callsign});
return this->getAtcStationsForCallsigns(cs);
}
CAtcStationList CVatsimDataFileReader::getAtcStationsForCallsigns(const CCallsignSet &callsigns) const
{
return this->getAtcStations().findByCallsigns(callsigns);
}
CServerList CVatsimDataFileReader::getVoiceServers() const
{
return m_lastGoodSetup.get().getVoiceServers();
}
CServerList CVatsimDataFileReader::getFsdServers() const
{
return m_lastGoodSetup.get().getFsdServers();
}
CUserList CVatsimDataFileReader::getPilotsForCallsigns(const CCallsignSet &callsigns) const
{
return this->getAircraft().findByCallsigns(callsigns).transform(Predicates::MemberTransform(&CSimulatedAircraft::getPilot));
}
CUserList CVatsimDataFileReader::getPilotsForCallsign(const CCallsign &callsign) const
{
const CCallsignSet callsigns({callsign});
return this->getPilotsForCallsigns(callsigns);
}
CAirlineIcaoCode CVatsimDataFileReader::getAirlineIcaoCode(const CCallsign &callsign) const
{
const CSimulatedAircraft aircraft = this->getAircraft().findFirstByCallsign(callsign);
return aircraft.getAirlineIcaoCode();
}
CAircraftIcaoCode CVatsimDataFileReader::getAircraftIcaoCode(const CCallsign &callsign) const
{
const CSimulatedAircraft aircraft = this->getAircraft().findFirstByCallsign(callsign);
return aircraft.getAircraftIcaoCode();
}
CVoiceCapabilities CVatsimDataFileReader::getVoiceCapabilityForCallsign(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return CVoiceCapabilities(); }
QReadLocker rl(&m_lock);
return m_flightPlanRemarks.value(callsign).getVoiceCapabilities();
}
CFlightPlanRemarks CVatsimDataFileReader::getFlightPlanRemarksForCallsign(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return QString(); }
QReadLocker rl(&m_lock);
return m_flightPlanRemarks.value(callsign);
}
void CVatsimDataFileReader::updateWithVatsimDataFileData(CSimulatedAircraft &aircraftToBeUdpated) const
{
this->getAircraft().updateWithVatsimDataFileData(aircraftToBeUdpated);
}
CUserList CVatsimDataFileReader::getControllersForCallsign(const CCallsign &callsign) const
{
const CCallsignSet cs({callsign});
return this->getControllersForCallsigns(cs);
}
CUserList CVatsimDataFileReader::getControllersForCallsigns(const CCallsignSet &callsigns) const
{
return this->getAtcStations().findByCallsigns(callsigns).transform(Predicates::MemberTransform(&CAtcStation::getController));
}
CUserList CVatsimDataFileReader::getUsersForCallsign(const CCallsign &callsign) const
{
const CCallsignSet callsigns({callsign});
return this->getUsersForCallsigns(callsigns);
}
CUserList CVatsimDataFileReader::getUsersForCallsigns(const CCallsignSet &callsigns) const
{
CUserList users;
if (callsigns.isEmpty()) { return users; }
for (const CCallsign &callsign : callsigns)
{
this->reloadSettings();
users.push_back(this->getPilotsForCallsign(callsign));
users.push_back(this->getControllersForCallsign(callsign));
}
return users;
}
void CVatsimDataFileReader::readInBackgroundThread()
{
QPointer<CVatsimDataFileReader> myself(this);
QTimer::singleShot(0, this, [ = ]
{
if (!myself) { return; }
myself->read();
});
}
void CVatsimDataFileReader::doWorkImpl()
{
this->read();
}
void CVatsimDataFileReader::read()
{
this->threadAssertCheck();
if (!this->doWorkCheck()) { return; }
if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM data file")) { return; }
if (this->isNotVATSIMEcosystem()) { return; }
// round robin for load balancing
// remark: Don't use QThread to run network operations in the background
// see http://qt-project.org/doc/qt-4.7/qnetworkaccessmanager.html
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing application");
CFailoverUrlList urls(sApp->getVatsimDataFileUrls());
const QUrl url(urls.obtainNextWorkingUrl(true));
if (url.isEmpty()) { return; }
this->getFromNetworkAndLog(url, { this, &CVatsimDataFileReader::parseVatsimFile});
}
void CVatsimDataFileReader::parseVatsimFile(QNetworkReply *nwReplyPtr)
{
// wrap pointer, make sure any exit cleans up reply
// required to use delete later as object is created in a different thread
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
this->threadAssertCheck();
if (this->isNotVATSIMEcosystem()) { return; }
// Worker thread, make sure to write only synced here!
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return; // stop, terminate straight away, ending thread
}
CSimulatedAircraftList CVatsimDataFileReader::getAircraft() const
{
QReadLocker rl(&m_lock);
return m_aircraft;
}
this->logNetworkReplyReceived(nwReplyPtr);
QStringList illegalEquipmentCodes;
const QUrl url = nwReply->url();
const QString urlString = url.toString();
CAtcStationList CVatsimDataFileReader::getAtcStations() const
if (nwReply->error() == QNetworkReply::NoError)
{
QReadLocker rl(&m_lock);
return m_atcStations;
}
const QString dataFileData = nwReply->readAll();
nwReply->close(); // close asap
CAtcStationList CVatsimDataFileReader::getAtcStationsForCallsign(const CCallsign &callsign) const
{
const CCallsignSet cs({callsign});
return this->getAtcStationsForCallsigns(cs);
}
CAtcStationList CVatsimDataFileReader::getAtcStationsForCallsigns(const CCallsignSet &callsigns) const
{
return this->getAtcStations().findByCallsigns(callsigns);
}
CServerList CVatsimDataFileReader::getVoiceServers() const
{
return m_lastGoodSetup.get().getVoiceServers();
}
CServerList CVatsimDataFileReader::getFsdServers() const
{
return m_lastGoodSetup.get().getFsdServers();
}
CUserList CVatsimDataFileReader::getPilotsForCallsigns(const CCallsignSet &callsigns) const
{
return this->getAircraft().findByCallsigns(callsigns).transform(Predicates::MemberTransform(&CSimulatedAircraft::getPilot));
}
CUserList CVatsimDataFileReader::getPilotsForCallsign(const CCallsign &callsign) const
{
const CCallsignSet callsigns({callsign});
return this->getPilotsForCallsigns(callsigns);
}
CAirlineIcaoCode CVatsimDataFileReader::getAirlineIcaoCode(const CCallsign &callsign) const
{
const CSimulatedAircraft aircraft = this->getAircraft().findFirstByCallsign(callsign);
return aircraft.getAirlineIcaoCode();
}
CAircraftIcaoCode CVatsimDataFileReader::getAircraftIcaoCode(const CCallsign &callsign) const
{
const CSimulatedAircraft aircraft = this->getAircraft().findFirstByCallsign(callsign);
return aircraft.getAircraftIcaoCode();
}
CVoiceCapabilities CVatsimDataFileReader::getVoiceCapabilityForCallsign(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return CVoiceCapabilities(); }
QReadLocker rl(&m_lock);
return m_flightPlanRemarks.value(callsign).getVoiceCapabilities();
}
CFlightPlanRemarks CVatsimDataFileReader::getFlightPlanRemarksForCallsign(const CCallsign &callsign) const
{
if (callsign.isEmpty()) { return QString(); }
QReadLocker rl(&m_lock);
return m_flightPlanRemarks.value(callsign);
}
void CVatsimDataFileReader::updateWithVatsimDataFileData(CSimulatedAircraft &aircraftToBeUdpated) const
{
this->getAircraft().updateWithVatsimDataFileData(aircraftToBeUdpated);
}
CUserList CVatsimDataFileReader::getControllersForCallsign(const CCallsign &callsign) const
{
const CCallsignSet cs({callsign});
return this->getControllersForCallsigns(cs);
}
CUserList CVatsimDataFileReader::getControllersForCallsigns(const CCallsignSet &callsigns) const
{
return this->getAtcStations().findByCallsigns(callsigns).transform(Predicates::MemberTransform(&CAtcStation::getController));
}
CUserList CVatsimDataFileReader::getUsersForCallsign(const CCallsign &callsign) const
{
const CCallsignSet callsigns({callsign});
return this->getUsersForCallsigns(callsigns);
}
CUserList CVatsimDataFileReader::getUsersForCallsigns(const CCallsignSet &callsigns) const
{
CUserList users;
if (callsigns.isEmpty()) { return users; }
for (const CCallsign &callsign : callsigns)
if (dataFileData.isEmpty()) { return; }
if (!this->didContentChange(dataFileData)) // Quick check by hash
{
users.push_back(this->getPilotsForCallsign(callsign));
users.push_back(this->getControllersForCallsign(callsign));
CLogMessage(this).info(u"VATSIM file '%1' has same content, skipped") << urlString;
return;
}
return users;
}
auto jsonDoc = QJsonDocument::fromJson(dataFileData.toUtf8());
if (jsonDoc.isEmpty()) { return; }
void CVatsimDataFileReader::readInBackgroundThread()
{
QPointer<CVatsimDataFileReader> myself(this);
QTimer::singleShot(0, this, [ = ]
// build on local vars for thread safety
CServerList fsdServers;
CAtcStationList atcStations;
CSimulatedAircraftList aircraft;
QMap<CCallsign, CFlightPlanRemarks> flightPlanRemarksMap;
auto updateTimestampFromFile = QDateTime::fromString(jsonDoc["general"]["update_timestamp"].toString(), Qt::ISODateWithMs);
const bool alreadyRead = (updateTimestampFromFile == this->getUpdateTimestamp());
if (alreadyRead)
{
if (!myself) { return; }
myself->read();
});
}
void CVatsimDataFileReader::doWorkImpl()
{
this->read();
}
void CVatsimDataFileReader::read()
{
this->threadAssertCheck();
if (!this->doWorkCheck()) { return; }
if (!this->isInternetAccessible("No network/internet access, cannot read VATSIM data file")) { return; }
if (this->isNotVATSIMEcosystem()) { return; }
// round robin for load balancing
// remark: Don't use QThread to run network operations in the background
// see http://qt-project.org/doc/qt-4.7/qnetworkaccessmanager.html
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing application");
CFailoverUrlList urls(sApp->getVatsimDataFileUrls());
const QUrl url(urls.obtainNextWorkingUrl(true));
if (url.isEmpty()) { return; }
this->getFromNetworkAndLog(url, { this, &CVatsimDataFileReader::parseVatsimFile});
}
void CVatsimDataFileReader::parseVatsimFile(QNetworkReply *nwReplyPtr)
{
// wrap pointer, make sure any exit cleans up reply
// required to use delete later as object is created in a different thread
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
this->threadAssertCheck();
if (this->isNotVATSIMEcosystem()) { return; }
// Worker thread, make sure to write only synced here!
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return; // stop, terminate straight away, ending thread
CLogMessage(this).info(u"VATSIM file has same timestamp, skipped");
return;
}
this->logNetworkReplyReceived(nwReplyPtr);
QStringList illegalEquipmentCodes;
const QUrl url = nwReply->url();
const QString urlString = url.toString();
if (nwReply->error() == QNetworkReply::NoError)
for (QJsonValueRef pilot : jsonDoc["pilots"].toArray())
{
const QString dataFileData = nwReply->readAll();
nwReply->close(); // close asap
if (dataFileData.isEmpty()) { return; }
if (!this->didContentChange(dataFileData)) // Quick check by hash
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"VATSIM file '%1' has same content, skipped") << urlString;
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
auto jsonDoc = QJsonDocument::fromJson(dataFileData.toUtf8());
if (jsonDoc.isEmpty()) { return; }
// build on local vars for thread safety
CServerList fsdServers;
CAtcStationList atcStations;
CSimulatedAircraftList aircraft;
QMap<CCallsign, CFlightPlanRemarks> flightPlanRemarksMap;
auto updateTimestampFromFile = QDateTime::fromString(jsonDoc["general"]["update_timestamp"].toString(), Qt::ISODateWithMs);
const bool alreadyRead = (updateTimestampFromFile == this->getUpdateTimestamp());
if (alreadyRead)
aircraft.push_back(parsePilot(pilot.toObject(), illegalEquipmentCodes));
flightPlanRemarksMap.insert(aircraft.back().getCallsign(), parseFlightPlanRemarks(pilot.toObject()));
}
for (QJsonValueRef controller : jsonDoc["controllers"].toArray())
{
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"VATSIM file has same timestamp, skipped");
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
for (QJsonValueRef pilot : jsonDoc["pilots"].toArray())
{
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
aircraft.push_back(parsePilot(pilot.toObject(), illegalEquipmentCodes));
flightPlanRemarksMap.insert(aircraft.back().getCallsign(), parseFlightPlanRemarks(pilot.toObject()));
}
for (QJsonValueRef controller : jsonDoc["controllers"].toArray())
{
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
atcStations.push_back(parseController(controller.toObject()));
}
for (QJsonValueRef atis : jsonDoc["atis"].toArray())
{
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
atcStations.push_back(parseController(atis.toObject()));
}
for (QJsonValueRef server : jsonDoc["servers"].toArray())
{
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
fsdServers.push_back(parseServer(server.toObject()));
if (!fsdServers.back().hasName()) { fsdServers.pop_back(); }
}
// Setup for VATSIM servers and sorting for comparison
fsdServers.sortBy(&CServer::getName, &CServer::getDescription);
// this part needs to be synchronized
{
QWriteLocker wl(&m_lock);
this->setUpdateTimestamp(updateTimestampFromFile);
m_aircraft = aircraft;
m_atcStations = atcStations;
m_flightPlanRemarks = flightPlanRemarksMap;
}
// update cache itself is thread safe
CVatsimSetup vs(m_lastGoodSetup.get());
const bool changedSetup = vs.setServers(fsdServers, {});
if (changedSetup)
{
vs.setUtcTimestamp(updateTimestampFromFile);
m_lastGoodSetup.set(vs);
}
// warnings, if required
if (!illegalEquipmentCodes.isEmpty())
{
CVatsimDataFileReader::logInconsistentData(
CStatusMessage(this, CStatusMessage::SeverityInfo, u"Illegal / ignored equipment code(s) in VATSIM data file: %1") << illegalEquipmentCodes.join(", ")
);
}
// data read finished
emit this->dataFileRead(dataFileData.size() / 1000);
emit this->dataRead(CEntityFlags::VatsimDataFile, CEntityFlags::ReadFinished, dataFileData.size() / 1000, url);
atcStations.push_back(parseController(controller.toObject()));
}
else
for (QJsonValueRef atis : jsonDoc["atis"].toArray())
{
// network error
CLogMessage(this).warning(u"Reading VATSIM data file failed '%1' '%2'") << nwReply->errorString() << urlString;
nwReply->abort();
emit this->dataRead(CEntityFlags::VatsimDataFile, CEntityFlags::ReadFailed, 0, url);
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
atcStations.push_back(parseController(atis.toObject()));
}
}
CSimulatedAircraft CVatsimDataFileReader::parsePilot(const QJsonObject &pilot, QStringList &o_illegalEquipmentCodes) const
{
const CCallsign callsign(pilot["callsign"].toString());
const CUser user(pilot["cid"].toString(), pilot["name"].toString(), callsign);
const CCoordinateGeodetic position(pilot["latitude"].toDouble(), pilot["longitude"].toDouble(), pilot["altitude"].toInt());
const CHeading heading(pilot["heading"].toInt(), CAngleUnit::deg());
const CSpeed groundspeed(pilot["groundspeed"].toInt(), CSpeedUnit::kts());
const CAircraftSituation situation(callsign, position, heading, {}, {}, groundspeed);
CSimulatedAircraft aircraft(callsign, user, situation);
const QString icaoAndEquipment(pilot["flight_plan"]["aircraft"].toString().trimmed());
const QString icao(CFlightPlan::aircraftIcaoCodeFromEquipmentCode(icaoAndEquipment));
if (CAircraftIcaoCode::isValidDesignator(icao))
for (QJsonValueRef server : jsonDoc["servers"].toArray())
{
aircraft.setAircraftIcaoCode(icao);
if (!this->doWorkCheck())
{
CLogMessage(this).info(u"Terminated VATSIM file parsing process");
return;
}
fsdServers.push_back(parseServer(server.toObject()));
if (!fsdServers.back().hasName()) { fsdServers.pop_back(); }
}
else if (!icaoAndEquipment.isEmpty())
// Setup for VATSIM servers and sorting for comparison
fsdServers.sortBy(&CServer::getName, &CServer::getDescription);
// this part needs to be synchronized
{
o_illegalEquipmentCodes.push_back(icaoAndEquipment);
QWriteLocker wl(&m_lock);
this->setUpdateTimestamp(updateTimestampFromFile);
m_aircraft = aircraft;
m_atcStations = atcStations;
m_flightPlanRemarks = flightPlanRemarksMap;
}
aircraft.setTransponderCode(pilot["transponder"].toString().toInt());
return aircraft;
}
CFlightPlanRemarks CVatsimDataFileReader::parseFlightPlanRemarks(const QJsonObject &pilot) const
{
return CFlightPlanRemarks(pilot["flight_plan"]["remarks"].toString().trimmed());
}
// update cache itself is thread safe
CVatsimSetup vs(m_lastGoodSetup.get());
const bool changedSetup = vs.setServers(fsdServers, {});
if (changedSetup)
{
vs.setUtcTimestamp(updateTimestampFromFile);
m_lastGoodSetup.set(vs);
}
CAtcStation CVatsimDataFileReader::parseController(const QJsonObject &controller) const
{
const CCallsign callsign(controller["callsign"].toString());
const CUser user(controller["cid"].toString(), controller["name"].toString(), callsign);
const CFrequency freq(controller["frequency"].toString().toDouble(), CFrequencyUnit::kHz());
const CLength range(controller["visual_range"].toInt(), CLengthUnit::NM());
const QJsonArray atisLines = controller["text_atis"].toArray();
const auto atisText = makeRange(atisLines).transform([](auto line) { return line.toString(); });
const CInformationMessage atis(CInformationMessage::ATIS, atisText.to<QStringList>().join('\n'));
return CAtcStation(callsign, user, freq, {}, range, true, {}, {}, atis);
}
// warnings, if required
if (!illegalEquipmentCodes.isEmpty())
{
CVatsimDataFileReader::logInconsistentData(
CStatusMessage(this, CStatusMessage::SeverityInfo, u"Illegal / ignored equipment code(s) in VATSIM data file: %1") << illegalEquipmentCodes.join(", ")
);
}
CServer CVatsimDataFileReader::parseServer(const QJsonObject &server) const
{
return CServer(server["name"].toString(), server["location"].toString(),
server["hostname_or_ip"].toString(), 6809, CUser("id", "real name", "email", "password"),
CFsdSetup::vatsimStandard(), CVoiceSetup::vatsimStandard(), CEcosystem::VATSIM,
CServer::FSDServerVatsim, server["clients_connection_allowed"].toInt());
// data read finished
emit this->dataFileRead(dataFileData.size() / 1000);
emit this->dataRead(CEntityFlags::VatsimDataFile, CEntityFlags::ReadFinished, dataFileData.size() / 1000, url);
}
else
{
// network error
CLogMessage(this).warning(u"Reading VATSIM data file failed '%1' '%2'") << nwReply->errorString() << urlString;
nwReply->abort();
emit this->dataRead(CEntityFlags::VatsimDataFile, CEntityFlags::ReadFailed, 0, url);
}
}
void CVatsimDataFileReader::reloadSettings()
CSimulatedAircraft CVatsimDataFileReader::parsePilot(const QJsonObject &pilot, QStringList &o_illegalEquipmentCodes) const
{
const CCallsign callsign(pilot["callsign"].toString());
const CUser user(pilot["cid"].toString(), pilot["name"].toString(), callsign);
const CCoordinateGeodetic position(pilot["latitude"].toDouble(), pilot["longitude"].toDouble(), pilot["altitude"].toInt());
const CHeading heading(pilot["heading"].toInt(), CAngleUnit::deg());
const CSpeed groundspeed(pilot["groundspeed"].toInt(), CSpeedUnit::kts());
const CAircraftSituation situation(callsign, position, heading, {}, {}, groundspeed);
CSimulatedAircraft aircraft(callsign, user, situation);
const QString icaoAndEquipment(pilot["flight_plan"]["aircraft"].toString().trimmed());
const QString icao(CFlightPlan::aircraftIcaoCodeFromEquipmentCode(icaoAndEquipment));
if (CAircraftIcaoCode::isValidDesignator(icao))
{
CReaderSettings s = m_settings.get();
setInitialAndPeriodicTime(s.getInitialTime().toMs(), s.getPeriodicTime().toMs());
aircraft.setAircraftIcaoCode(icao);
}
} // ns
else if (!icaoAndEquipment.isEmpty())
{
o_illegalEquipmentCodes.push_back(icaoAndEquipment);
}
aircraft.setTransponderCode(pilot["transponder"].toString().toInt());
return aircraft;
}
CFlightPlanRemarks CVatsimDataFileReader::parseFlightPlanRemarks(const QJsonObject &pilot) const
{
return CFlightPlanRemarks(pilot["flight_plan"]["remarks"].toString().trimmed());
}
CAtcStation CVatsimDataFileReader::parseController(const QJsonObject &controller) const
{
const CCallsign callsign(controller["callsign"].toString());
const CUser user(controller["cid"].toString(), controller["name"].toString(), callsign);
const CFrequency freq(controller["frequency"].toString().toDouble(), CFrequencyUnit::kHz());
const CLength range(controller["visual_range"].toInt(), CLengthUnit::NM());
const QJsonArray atisLines = controller["text_atis"].toArray();
const auto atisText = makeRange(atisLines).transform([](auto line) { return line.toString(); });
const CInformationMessage atis(CInformationMessage::ATIS, atisText.to<QStringList>().join('\n'));
return CAtcStation(callsign, user, freq, {}, range, true, {}, {}, atis);
}
CServer CVatsimDataFileReader::parseServer(const QJsonObject &server) const
{
return CServer(server["name"].toString(), server["location"].toString(),
server["hostname_or_ip"].toString(), 6809, CUser("id", "real name", "email", "password"),
CFsdSetup::vatsimStandard(), CVoiceSetup::vatsimStandard(), CEcosystem::VATSIM,
CServer::FSDServerVatsim, server["clients_connection_allowed"].toInt());
}
void CVatsimDataFileReader::reloadSettings()
{
CReaderSettings s = m_settings.get();
setInitialAndPeriodicTime(s.getInitialTime().toMs(), s.getPeriodicTime().toMs());
}
} // ns