diff --git a/samples/fsd/main.cpp b/samples/fsd/main.cpp index 16de8117c..6ed2b2812 100644 --- a/samples/fsd/main.cpp +++ b/samples/fsd/main.cpp @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) CServer server("fsd.swift-project.org", 6809, user); server.setServerType(CServer::FSDServerVatsim); client.setServer(server); - client.setSimType(SimType::XPLANE10); + client.setSimType(CSimulatorInfo::xplane()); client.setPilotRating(PilotRating::Student); client.printToConsole(true); diff --git a/src/blackcore/context/contextnetworkimpl.cpp b/src/blackcore/context/contextnetworkimpl.cpp index 5611440b2..f16fcca19 100644 --- a/src/blackcore/context/contextnetworkimpl.cpp +++ b/src/blackcore/context/contextnetworkimpl.cpp @@ -251,12 +251,24 @@ namespace BlackCore mode.setLoginMode(CLoginMode::Observer); } - const QString l = extraLiveryString.isEmpty() ? ownAircraft.getModel().getSwiftLiveryString() : extraLiveryString; + const CSimulatorInfo sim = this->getIContextSimulator() ? this->getIContextSimulator()->getSimulatorPluginInfo().getSimulatorInfo() : CSimulatorInfo(); + const QString l = extraLiveryString.isEmpty() ? ownAircraft.getModel().getSwiftLiveryString(sim) : extraLiveryString; const QString m = extraModelString.isEmpty() ? ownAircraft.getModelString() : extraModelString; + // FG fix, do not send livery and model ids for FlightGear + // https://discordapp.com/channels/539048679160676382/567091362030419981/698124094482415616 + if (sim.isFG() && extraModelString.isEmpty()) + { + sendModelString = false; + } + m_currentMode = mode; m_fsdClient->setLoginMode(mode); m_fsdClient->setCallsign(ownAircraft.getCallsign()); + + // set this BEFORE model string as FG has different handling + m_fsdClient->setSimType(sim); + m_fsdClient->setIcaoCodes(ownAircraft); m_fsdClient->setLiveryAndModelString(l, sendLivery, m, sendModelString); m_fsdClient->setClientName(sApp->swiftVersionChar()); @@ -266,7 +278,7 @@ namespace BlackCore QString clientKey; if (!getCmdLineClientIdAndKey(clientId, clientKey)) { - clientId = CBuildConfig::vatsimClientId(); + clientId = CBuildConfig::vatsimClientId(); clientKey = CBuildConfig::vatsimPrivateKey(); } @@ -274,8 +286,6 @@ namespace BlackCore m_fsdClient->setClientCapabilities(Capabilities::AircraftInfo | Capabilities::FastPos | Capabilities::AtcInfo | Capabilities::AircraftConfig); m_fsdClient->setServer(server); - const CSimulatorPluginInfo sim = this->getIContextSimulator() ? this->getIContextSimulator()->getSimulatorPluginInfo() : CSimulatorPluginInfo(); - m_fsdClient->setSimType(sim); m_fsdClient->setPilotRating(PilotRating::Student); m_fsdClient->setAtcRating(AtcRating::Observer); @@ -693,8 +703,12 @@ namespace BlackCore const ISimulator::SimulatorStatus simStatus = static_cast(status); if (ISimulator::isAnyConnectedStatus(simStatus)) { - const CContextSimulator *sim = this->getRuntime()->getCContextSimulator(); + const QPointer sim = this->getRuntime()->getCContextSimulator(); this->setSimulationEnvironmentProvider(sim ? sim->simulator() : nullptr); + const CSimulatorInfo simInfo = sim ? sim->getSimulatorPluginInfo().getSimulatorInfo() : CSimulatorInfo(); + + m_simulatorConnected++; + m_lastConnectedSim = simInfo; } else { @@ -803,10 +817,11 @@ namespace BlackCore emit this->textMessageSent(message); } - const CSimulatedAircraft CContextNetwork::ownAircraft() const + CSimulatedAircraft CContextNetwork::ownAircraft() const { - Q_ASSERT(this->getRuntime()); - Q_ASSERT(this->getRuntime()->getCContextOwnAircraft()); + Q_ASSERT(this->getRuntime()); // must never be null + + if (!this->getRuntime()->getIContextOwnAircraft()) { return {}; } return this->getRuntime()->getCContextOwnAircraft()->getOwnAircraft(); } diff --git a/src/blackcore/context/contextnetworkimpl.h b/src/blackcore/context/contextnetworkimpl.h index 3f68de7af..3b3eec55e 100644 --- a/src/blackcore/context/contextnetworkimpl.h +++ b/src/blackcore/context/contextnetworkimpl.h @@ -304,6 +304,8 @@ namespace BlackCore QTimer *m_requestAircraftDataTimer = nullptr; //!< general updates such as frequencies, see requestAircraftDataUpdates() QTimer *m_requestAtisTimer = nullptr; //!< general updates such as ATIS QTimer *m_staggeredMatchingTimer = nullptr; //!< staggered update + int m_simulatorConnected = 0; //!< how often a simulator has been connected + BlackMisc::Simulation::CSimulatorInfo m_lastConnectedSim; //!< last connected sim. // Digest signals, only sending after some time BlackMisc::CDigestSignal m_dsAtcStationsBookedChanged { this, &IContextNetwork::changedAtcStationsBooked, &IContextNetwork::changedAtcStationsBookedDigest, 1000, 2 }; @@ -313,7 +315,7 @@ namespace BlackCore QQueue m_readyForModelMatching; //!< ready for matching //! Own aircraft from \sa CContextOwnAircraft - const BlackMisc::Simulation::CSimulatedAircraft ownAircraft() const; + BlackMisc::Simulation::CSimulatedAircraft ownAircraft() const; //! Check if a callsign is a valid partner callsign bool isValidPartnerCallsign(const BlackMisc::Aviation::CCallsign &ownCallsign, const BlackMisc::Aviation::CCallsign &partnerCallsign); diff --git a/src/blackcore/fsd/fsdclient.cpp b/src/blackcore/fsd/fsdclient.cpp index 8f84b5824..3fc863d2b 100644 --- a/src/blackcore/fsd/fsdclient.cpp +++ b/src/blackcore/fsd/fsdclient.cpp @@ -151,14 +151,6 @@ namespace BlackCore m_fsdTextCodec = textCodec; } - void CFSDClient::setSimulatorInfo(const CSimulatorPluginInfo &simInfo) - { - Q_ASSERT_X(this->getConnectionStatus().isDisconnected(), Q_FUNC_INFO, "Can't change server details while still connected"); - - QWriteLocker l(&m_lockUserClientBuffered); - m_simulatorInfo = simInfo; - } - void CFSDClient::setCallsign(const CCallsign &callsign) { Q_ASSERT_X(this->getConnectionStatus().isDisconnected(), Q_FUNC_INFO, "Can't change callsign while still connected"); @@ -176,10 +168,13 @@ namespace BlackCore QWriteLocker l(&m_lockUserClientBuffered); m_ownAircraftIcaoCode = ownAircraft.getAircraftIcaoCode(); m_ownAirlineIcaoCode = ownAircraft.getAirlineIcaoCode(); - m_ownLivery = ownAircraft.getModel().getSwiftLiveryString(); + + /* use setLiveryAndModelString + m_ownLivery = ownAircraft.getModel().getSwiftLiveryString(m_simTypeInfo); m_ownModelString = ownAircraft.getModelString(); m_sendLiveryString = true; - m_sendMModelString = true; + m_sendModelString = true; + */ } void CFSDClient::setLiveryAndModelString(const QString &livery, bool sendLiveryString, const QString &modelString, bool sendModelString) @@ -188,16 +183,18 @@ namespace BlackCore m_ownLivery = livery; m_ownModelString = modelString; m_sendLiveryString = sendLiveryString; - m_sendMModelString = sendModelString; + m_sendModelString = sendModelString; } - void CFSDClient::setSimType(const CSimulatorPluginInfo &simInfo) + void CFSDClient::setSimType(const CSimulatorInfo &simInfo) { - //! \fixme Define recognized simulators somewhere */ - const CSimulatorInfo::Simulator sim = simInfo.getSimulatorInfo().getSimulator(); + this->setSimType(simInfo.getSimulator()); + } + void CFSDClient::setSimType(const CSimulatorInfo::Simulator simulator) + { QWriteLocker l(&m_lockUserClientBuffered); - switch (sim) + switch (simulator) { case CSimulatorInfo::FSX: m_simType = SimType::MSFSX; break; case CSimulatorInfo::P3D: m_simType = SimType::P3Dv4; break; @@ -206,6 +203,7 @@ namespace BlackCore case CSimulatorInfo::XPLANE: m_simType = SimType::XPLANE11; break; default: m_simType = SimType::Unknown; break; } + m_simTypeInfo = CSimulatorInfo(simulator); } QStringList CFSDClient::getPresetValues() const @@ -284,11 +282,13 @@ namespace BlackCore { const AddPilot pilotLogin(callsign, cid, password, m_pilotRating, m_protocolRevision, m_simType, name); sendQueudedMessage(pilotLogin); + CStatusMessage(this).info(u"Sending login as '%1' '%2' '%3' '%4' '%5' '%6'") << callsign << cid << toQString(m_pilotRating) << m_protocolRevision << toQString(m_simType) << name; } else if (m_loginMode.isObserver()) { const AddAtc addAtc(callsign, name, cid, password, m_atcRating, m_protocolRevision); sendQueudedMessage(addAtc); + CStatusMessage(this).info(u"Sending OBS login as '%1' '%2' '%3' '%4' '%5'") << callsign << cid << toQString(m_atcRating) << m_protocolRevision << name; } } @@ -627,18 +627,12 @@ namespace BlackCore if (!connected) { return; } const CSimulatedAircraft myAircraft(getOwnAircraft()); - QString modelString; - { - QReadLocker l(&m_lockUserClientBuffered); - modelString = m_ownModelString.isEmpty() ? myAircraft.getModelString() : m_ownModelString; - } - if (modelString.isEmpty()) { modelString = noModelString(); } - + const QString modelString = this->getConfiguredModelString(myAircraft); const PlaneInfoRequestFsinn planeInfoRequestFsinn(getOwnCallsignAsString(), callsign.toQString(), myAircraft.getAirlineIcaoCodeDesignator(), myAircraft.getAircraftIcaoCodeDesignator(), myAircraft.getAircraftIcaoCombinedType(), - m_sendMModelString ? modelString : QString()); + modelString); sendQueudedMessage(planeInfoRequestFsinn); increaseStatisticsValue(QStringLiteral("sendPlaneInfoRequestFsinn")); } @@ -654,13 +648,12 @@ namespace BlackCore { if (this->getConnectionStatus().isDisconnected() && ! m_unitTestMode) { return; } const CSimulatedAircraft myAircraft(getOwnAircraft()); - QString modelString = m_ownModelString.isEmpty() ? myAircraft.getModelString() : m_ownModelString; - if (modelString.isEmpty()) { modelString = noModelString(); } + const QString modelString = this->getConfiguredModelString(myAircraft); const PlaneInformationFsinn planeInformationFsinn(getOwnCallsignAsString(), callsign.toQString(), myAircraft.getAirlineIcaoCodeDesignator(), myAircraft.getAircraftIcaoCodeDesignator(), myAircraft.getAircraftIcaoCombinedType(), - m_sendMModelString ? modelString : QString()); + modelString); sendQueudedMessage(planeInformationFsinn); increaseStatisticsValue(QStringLiteral("sendPlaneInformationFsinn")); } @@ -718,6 +711,22 @@ namespace BlackCore parseMessage(message); } + QString CFSDClient::getConfiguredModelString(const CSimulatedAircraft &myAircraft) const + { + if (!m_sendModelString) { return noModelString(); } + QReadLocker l(&m_lockUserClientBuffered); + const QString ms = m_ownModelString.isEmpty() ? myAircraft.getModelString() : m_ownModelString; + return ms.isEmpty() ? noModelString() : ms; + } + + QString CFSDClient::getConfiguredLiveryString(const CSimulatedAircraft &myAircraft) const + { + if (!m_sendLiveryString) { return QString(); } + QReadLocker l(&m_lockUserClientBuffered); + const QString livery = m_ownLivery.isEmpty() ? myAircraft.getModel().getSwiftLiveryString() : m_ownLivery; + return livery; + } + void CFSDClient::sendAuthChallenge(const QString &challenge) { const AuthChallenge pduAuthChallenge(getOwnCallsignAsString(), "SERVER", challenge); @@ -1348,10 +1357,11 @@ namespace BlackCore { PlaneInfoRequest planeInfoRequest = PlaneInfoRequest::fromTokens(tokens); - const QString airlineIcao = m_server.getFsdSetup().force3LetterAirlineCodes() ? getOwnAircraft().getAirlineIcaoCode().getDesignator() - : getOwnAircraft().getAirlineIcaoCode().getVDesignator(); - const QString acTypeICAO = getOwnAircraft().getAircraftIcaoCode().getDesignator(); - const QString livery = getOwnAircraft().getModel().getSwiftLiveryString(); + const CSimulatedAircraft myAircraft = this->getOwnAircraft(); + const QString airlineIcao = m_server.getFsdSetup().force3LetterAirlineCodes() ? myAircraft.getAirlineIcaoCode().getDesignator() + : myAircraft.getAirlineIcaoCode().getVDesignator(); + const QString acTypeICAO = myAircraft.getAircraftIcaoCode().getDesignator(); + const QString livery = this->getConfiguredLiveryString(myAircraft); sendPlaneInformation(planeInfoRequest.sender(), acTypeICAO, airlineIcao, livery); } diff --git a/src/blackcore/fsd/fsdclient.h b/src/blackcore/fsd/fsdclient.h index d36dc61d0..b2ae36af3 100644 --- a/src/blackcore/fsd/fsdclient.h +++ b/src/blackcore/fsd/fsdclient.h @@ -101,14 +101,14 @@ namespace BlackCore void setClientIdAndKey(quint16 id, const QByteArray &key); void setClientCapabilities(Capabilities capabilities) { QWriteLocker l(&m_lockUserClientBuffered); m_capabilities = capabilities; } void setServer(const BlackMisc::Network::CServer &server); - void setSimulatorInfo(const BlackMisc::Simulation::CSimulatorPluginInfo &simInfo); void setLoginMode(const BlackMisc::Network::CLoginMode &mode) { QWriteLocker l(&m_lockUserClientBuffered); m_loginMode = mode; } void setCallsign(const BlackMisc::Aviation::CCallsign &callsign); void setPartnerCallsign(const BlackMisc::Aviation::CCallsign &callsign) { QWriteLocker l(&m_lockUserClientBuffered); m_partnerCallsign = callsign; } void setIcaoCodes(const BlackMisc::Simulation::CSimulatedAircraft &ownAircraft); void setLiveryAndModelString(const QString &livery, bool sendLiveryString, const QString &modelString, bool sendModelString); - void setSimType(SimType type) { QWriteLocker l(&m_lockUserClientBuffered); m_simType = type; } void setSimType(const BlackMisc::Simulation::CSimulatorPluginInfo &simInfo); + void setSimType(const BlackMisc::Simulation::CSimulatorInfo &simInfo); + void setSimType(const BlackMisc::Simulation::CSimulatorInfo::Simulator simulator); void setPilotRating(PilotRating rating) { QWriteLocker l(&m_lockUserClientBuffered); m_pilotRating = rating; } void setAtcRating(AtcRating rating) { QWriteLocker l(&m_lockUserClientBuffered); m_atcRating = rating; } //! @} @@ -301,6 +301,12 @@ namespace BlackCore return noms; } + //! Model string as configured, also dependent from simulator + QString getConfiguredModelString(const BlackMisc::Simulation::CSimulatedAircraft &myAircraft) const; + + //! Livery string, also dependent from simulator + QString getConfiguredLiveryString(const BlackMisc::Simulation::CSimulatedAircraft &myAircraft) const; + //! JSON packets struct JsonPackets { @@ -474,12 +480,12 @@ namespace BlackCore std::atomic_bool m_filterPasswordFromLogin { false }; // timer parents are needed as we move to thread - QTimer m_scheduledConfigUpdate { this }; //!< config updates - QTimer m_positionUpdateTimer { this }; //!< sending positions + QTimer m_scheduledConfigUpdate { this }; //!< config updates + QTimer m_positionUpdateTimer { this }; //!< sending positions QTimer m_interimPositionUpdateTimer { this }; //!< sending interim positions QTimer m_fsdSendMessageTimer { this }; //!< FSD message sending - qint64 m_additionalOffsetTime = 0; //!< additional offset time + qint64 m_additionalOffsetTime = 0; //!< additional offset time std::atomic_bool m_statistics { false }; QMap m_callStatistics; //!< how many calls? @@ -493,6 +499,7 @@ namespace BlackCore SimType m_simType = SimType::Unknown; PilotRating m_pilotRating = PilotRating::Unknown; AtcRating m_atcRating = AtcRating::Unknown; + BlackMisc::Simulation::CSimulatorInfo m_simTypeInfo; // same as m_simType // Client data QString m_clientName; @@ -504,7 +511,6 @@ namespace BlackCore Capabilities m_capabilities = Capabilities::None; // buffered data for FSD - BlackMisc::Simulation::CSimulatorPluginInfo m_simulatorInfo; //!< used simulator BlackMisc::Aviation::CCallsign m_ownCallsign; //!< "buffered callsign", as this must not change when connected BlackMisc::Aviation::CCallsign m_partnerCallsign; //!< "buffered"callsign", of partner flying in shared cockpit BlackMisc::Aviation::CAircraftIcaoCode m_ownAircraftIcaoCode; //!< "buffered icao", as this must not change when connected @@ -512,7 +518,7 @@ namespace BlackCore QString m_ownLivery; //!< "buffered livery", as this must not change when connected QString m_ownModelString; //!< "buffered model string", as this must not change when connected std::atomic_bool m_sendLiveryString { true }; - std::atomic_bool m_sendMModelString { true }; + std::atomic_bool m_sendModelString { true }; mutable QReadWriteLock m_lockUserClientBuffered { QReadWriteLock::Recursive }; //!< for user, client and buffered data QString getOwnCallsignAsString() const { QReadLocker l(&m_lockUserClientBuffered); return m_ownCallsign.asString(); } diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index afff3a803..291acdc55 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -586,16 +586,24 @@ namespace BlackMisc return (liveryString.length() > liveryStringPrefix().length() && liveryString.startsWith(liveryStringPrefix(), Qt::CaseInsensitive)); } - QString CAircraftModel::getSwiftLiveryString() const + QString CAircraftModel::getSwiftLiveryString(bool aircraftIcao, bool livery, bool model) const { + if (!aircraftIcao && !livery && !model) { return QString(); } const QString l = - (this->getLivery().hasValidDbKey() ? u'l' % this->getLivery().getDbKeyAsString() : QString()) % - (this->getAircraftIcaoCode().hasValidDbKey() ? QStringLiteral("a") % this->getAircraftIcaoCode().getDbKeyAsString() : QString()) % - (this->hasValidDbKey() ? u'm' % this->getDbKeyAsString() : QString()); + (livery && this->getLivery().hasValidDbKey() ? u'l' % this->getLivery().getDbKeyAsString() : QString()) % + (aircraftIcao && this->getAircraftIcaoCode().hasValidDbKey() ? QStringLiteral("a") % this->getAircraftIcaoCode().getDbKeyAsString() : QString()) % + (model && this->hasValidDbKey() ? u'm' % this->getDbKeyAsString() : QString()); return l.isEmpty() ? QString() : liveryStringPrefix() % l; } + QString CAircraftModel::getSwiftLiveryString(const CSimulatorInfo &sim) const + { + return (sim.isFG()) ? + this->getSwiftLiveryString(true, false, false) : + this->getSwiftLiveryString(); + } + DBTripleIds CAircraftModel::parseNetworkLiveryString(const QString &liveryString) { // "swift_m22l33a11" diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index 04a555500..918320b86 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -367,7 +367,10 @@ namespace BlackMisc //! swift livery string (to be sent via network) //! \sa parseNetworkLiveryString - QString getSwiftLiveryString() const; + QString getSwiftLiveryString(bool aircraftIcao = true, bool livery = true, bool model = true) const; + + //! swift livery string (to be sent via network) for simulator + QString getSwiftLiveryString(const CSimulatorInfo &sim) const; //! Update missing parts from another model void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority = true); diff --git a/src/blackmisc/simulation/simulatorplugininfo.cpp b/src/blackmisc/simulation/simulatorplugininfo.cpp index 0342cdaea..50e6cd395 100644 --- a/src/blackmisc/simulation/simulatorplugininfo.cpp +++ b/src/blackmisc/simulation/simulatorplugininfo.cpp @@ -43,7 +43,10 @@ namespace BlackMisc // set info if it wasn't set already if (m_info.isNoSimulator() && !m_simulator.isEmpty()) { - m_info = CSimulatorInfo(m_simulator); + if (!this->isEmulatedPlugin()) + { + m_info = CSimulatorInfo(m_simulator); + } } } diff --git a/tests/blackcore/fsd/testfsdclient/testfsdclient.cpp b/tests/blackcore/fsd/testfsdclient/testfsdclient.cpp index 131f697a5..2e2fa0ffd 100644 --- a/tests/blackcore/fsd/testfsdclient/testfsdclient.cpp +++ b/tests/blackcore/fsd/testfsdclient/testfsdclient.cpp @@ -143,7 +143,7 @@ namespace BlackFsdTest client->setLoginMode(BlackMisc::Network::CLoginMode::Pilot); client->setServer(server); client->setPilotRating(PilotRating::Student); - client->setSimType(SimType::XPLANE10); + client->setSimType(CSimulatorInfo::xplane()); client->setPilotRating(PilotRating::Student); QString key("727d1efd5cb9f8d2c28372469d922bb4"); client->setClientIdAndKey(0xb9ba, key.toLocal8Bit());