diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cc78e7..7a0dbf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ else() endif() project(LiveTraffic - VERSION 3.4.1 + VERSION 3.4.2 DESCRIPTION "LiveTraffic X-Plane plugin") # Provide compile macros from the above project version definition diff --git a/Include/DataRefs.h b/Include/DataRefs.h index 4c3ac5d..e5ca6da 100644 --- a/Include/DataRefs.h +++ b/Include/DataRefs.h @@ -54,8 +54,8 @@ const bool DEF_SND_FMOD_INST = false; ///< Enforce using our own FMOD const bool DEF_SND_FMOD_INST = true; ///< Enforce using our own FMOD instance instead of X-Plane's? #endif const int DEF_SUI_TRANSP = 0; ///< Settings UI: transaprent background? -const int MIN_NETW_TIMEOUT = 5; ///< [s] minimum network request timeout -const int DEF_NETW_TIMEOUT = 90; ///< [s] of network request timeout +const int DEF_MIN_NETW_TIMEOUT = 5; ///< [s] default minimum network request timeout +const int DEF_MAX_NETW_TIMEOUT = 5; ///< [s] default maximum network request timeout constexpr int DEF_UI_FONT_SCALE = 100; ///< [%] Default font scaling @@ -382,7 +382,8 @@ enum dataRefsLT { DR_CFG_FD_LONG_REFRESH_INTVL, DR_CFG_FD_BUF_PERIOD, DR_CFG_FD_REDUCE_HEIGHT, - DR_CFG_NETW_TIMEOUT, + DR_CFG_MIN_NETW_TIMEOUT, + DR_CFG_MAX_NETW_TIMEOUT, DR_CFG_LND_LIGHTS_TAXI, DR_CFG_HIDE_BELOW_AGL, DR_CFG_HIDE_TAXIING, @@ -685,7 +686,8 @@ class DataRefs int fdCurrRefrIntvl = DEF_FD_REFRESH_INTVL; ///< current value of how often to fetch new flight data int fdBufPeriod = DEF_FD_BUF_PERIOD; ///< seconds to buffer before simulating aircraft int fdReduceHeight = DEF_FD_REDUCE_HEIGHT; ///< [ft] reduce flight data usage when user aircraft is flying above this altitude - int netwTimeout = DEF_NETW_TIMEOUT; ///< [s] of network request timeout + int netwTimeoutMin = DEF_MIN_NETW_TIMEOUT; ///< [s] of min network request timeout + int netwTimeoutMax = DEF_MAX_NETW_TIMEOUT; ///< [s] of max network request timeout int bLndLightsTaxi = false; // keep landing lights on while taxiing? (to be able to see the a/c as there is no taxi light functionality) int hideBelowAGL = 0; // if positive: a/c visible only above this height AGL int hideTaxiing = 0; // hide a/c while taxiing? @@ -922,7 +924,8 @@ class DataRefs inline int GetFdRefreshIntvl() const { return fdCurrRefrIntvl; } inline int GetFdBufPeriod() const { return fdBufPeriod; } inline int GetAcOutdatedIntvl() const { return 2 * GetFdBufPeriod(); } - inline int GetNetwTimeout() const { return netwTimeout; } + inline int GetNetwTimeoutMin() const { return netwTimeoutMin; } + inline int GetNetwTimeoutMax() const { return netwTimeoutMax; } inline bool GetLndLightsTaxi() const { return bLndLightsTaxi != 0; } inline int GetHideBelowAGL() const { return hideBelowAGL; } inline bool GetHideTaxiing() const { return hideTaxiing != 0; } diff --git a/Include/LTWeather.h b/Include/LTWeather.h index 79a5969..6d65c66 100644 --- a/Include/LTWeather.h +++ b/Include/LTWeather.h @@ -1,8 +1,8 @@ /// @file LTWeather.h /// @brief Fetch real weather information from AWC -/// @see https://www.aviationweather.gov/dataserver/example?datatype=metar +/// @see https://aviationweather.gov/data/api/#/Dataserver/dataserverMetars /// @author Birger Hoppe -/// @copyright (c) 2018-2020 Birger Hoppe +/// @copyright (c) 2018-2023 Birger Hoppe /// @copyright Permission is hereby granted, free of charge, to any person obtaining a /// copy of this software and associated documentation files (the "Software"), /// to deal in the Software without restriction, including without limitation diff --git a/Lib/XPMP2 b/Lib/XPMP2 index 0a65b95..5d990be 160000 --- a/Lib/XPMP2 +++ b/Lib/XPMP2 @@ -1 +1 @@ -Subproject commit 0a65b9520f622710b31bb0f2908416c2db7da6a5 +Subproject commit 5d990be4401698ef88fc1b10dbab7f7040c54ff8 diff --git a/LiveTraffic.xcodeproj/project.pbxproj b/LiveTraffic.xcodeproj/project.pbxproj index ceb0c20..116424f 100755 --- a/LiveTraffic.xcodeproj/project.pbxproj +++ b/LiveTraffic.xcodeproj/project.pbxproj @@ -585,7 +585,7 @@ KnownAssetTags = ( New, ); - LastUpgradeCheck = 1410; + LastUpgradeCheck = 1420; }; buildConfigurationList = D607B16209A5563100699BC3 /* Build configuration list for PBXProject "LiveTraffic" */; compatibilityVersion = "Xcode 12.0"; @@ -790,7 +790,7 @@ LIVETRAFFIC_VERSION_BETA = 0; LIVETRAFFIC_VER_MAJOR = 3; LIVETRAFFIC_VER_MINOR = 4; - LIVETRAFFIC_VER_PATCH = 1; + LIVETRAFFIC_VER_PATCH = 2; LLVM_LTO = NO; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.15; @@ -896,7 +896,7 @@ LIVETRAFFIC_VERSION_BETA = 0; LIVETRAFFIC_VER_MAJOR = 3; LIVETRAFFIC_VER_MINOR = 4; - LIVETRAFFIC_VER_PATCH = 1; + LIVETRAFFIC_VER_PATCH = 2; LLVM_LTO = YES; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.15; diff --git a/LiveTraffic.xcodeproj/xcuserdata/birger.xcuserdatad/xcschemes/LiveTraffic.xcscheme b/LiveTraffic.xcodeproj/xcuserdata/birger.xcuserdatad/xcschemes/LiveTraffic.xcscheme index 4566633..e4a1112 100644 --- a/LiveTraffic.xcodeproj/xcuserdata/birger.xcuserdatad/xcschemes/LiveTraffic.xcscheme +++ b/LiveTraffic.xcodeproj/xcuserdata/birger.xcuserdatad/xcschemes/LiveTraffic.xcscheme @@ -1,6 +1,6 @@ 180 || fdReduceHeight < 1000 || fdReduceHeight > 100000|| fdSnapTaxiDist < 0 || fdSnapTaxiDist > 50 || - netwTimeout < 10 || + netwTimeoutMax < 5 || netwTimeoutMin > netwTimeoutMax || hideBelowAGL < 0 || hideBelowAGL > MDL_ALT_MAX || hideNearbyGnd < 0 || hideNearbyGnd > 500 || hideNearbyAir < 0 || hideNearbyAir > 5000 || @@ -1776,7 +1778,8 @@ void DataRefs::ResetAdvCfgToDefaults () fdLongRefrIntvl = DEF_FD_LONG_REFR_INTVL; fdBufPeriod = DEF_FD_BUF_PERIOD; fdReduceHeight = DEF_FD_REDUCE_HEIGHT; - netwTimeout = DEF_NETW_TIMEOUT; + netwTimeoutMin = DEF_MIN_NETW_TIMEOUT; + netwTimeoutMax = DEF_MAX_NETW_TIMEOUT; contrailAltMin_ft = DEF_CONTR_ALT_MIN; contrailAltMax_ft = DEF_CONTR_ALT_MAX; contrailLifeTime = DEF_CONTR_LIFETIME; @@ -2010,7 +2013,7 @@ bool DataRefs::LoadConfigFile() // which conversion to do with the (older) version of the config file? unsigned long cfgFileVer = 0; - enum cfgFileConvE { CFG_NO_CONV=0, CFG_V3, CFG_V31, CFG_V331 } conv = CFG_NO_CONV; + enum cfgFileConvE { CFG_NO_CONV=0, CFG_V3, CFG_V31, CFG_V331, CFG_V342 } conv = CFG_NO_CONV; // open a config file std::string sFileName (LTCalcFullPath(PATH_CONFIG_FILE)); @@ -2072,8 +2075,10 @@ bool DataRefs::LoadConfigFile() // any conversions required? if (cfgFileVer < 30100) // < 3.1.0 conv = CFG_V31; - else if (cfgFileVer < 30301) // < 3.3.1 + if (cfgFileVer < 30301) // < 3.3.1 conv = CFG_V331; + if (cfgFileVer < 30402) // < 3.4.2: Reset Force FMOD instance = 0, set network timeout to 5s + conv = CFG_V342; } } @@ -2122,9 +2127,9 @@ bool DataRefs::LoadConfigFile() switch (conv) { case CFG_NO_CONV: break; - case CFG_V331: - case CFG_V31: case CFG_V3: + case CFG_V31: + case CFG_V331: // We "forgot" to change the default to 49005 for fresh installations, // so we need to convert the port all the way up to v3.3.1: if (*i == DATA_REFS_LT[DR_CFG_RT_TRAFFIC_PORT]) { @@ -2132,6 +2137,14 @@ bool DataRefs::LoadConfigFile() if (sVal == "49003") sVal = "49005"; } + [[fallthrough]]; + case CFG_V342: + // Re-implemented XP Sound, so we reset the "Force own FMOD Instance flag" because we believe in the XP implementation now ;-) + if (*i == DATA_REFS_LT[DR_CFG_SND_FORCE_FMOD_INSTANCE]) + sVal = "0"; + // With OpenSky API timeouts we set the max timeout to just 5s so we try more often + if (*i == DATA_REFS_LT[DR_CFG_MAX_NETW_TIMEOUT]) + sVal = "5"; break; } diff --git a/Src/LTADSBEx.cpp b/Src/LTADSBEx.cpp index ec3493b..76bfea3 100644 --- a/Src/LTADSBEx.cpp +++ b/Src/LTADSBEx.cpp @@ -643,7 +643,7 @@ bool ADSBExchangeConnection::DoTestADSBExAPIKey (const std::string newKey) // prepare the handle with the right options readBuf.reserve(CURL_MAX_WRITE_SIZE); curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeout()); + curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeoutMax()); curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, curl_errtxt); curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, testKeyTy == ADSBEX_KEY_RAPIDAPI ? ReceiveHeader : NULL); curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, DoTestADSBExAPIKeyCB); diff --git a/Src/LTADSBHub.cpp b/Src/LTADSBHub.cpp index f8b5c92..f8be7ae 100644 --- a/Src/LTADSBHub.cpp +++ b/Src/LTADSBHub.cpp @@ -122,7 +122,6 @@ void ADSBHubConnection::StreamMain () #endif // *** Main Loop *** - struct timeval timeout = { ADSBHUB_TIMEOUT_S, 0 }; while (!bStopThr && tcpStream.isOpen()) { // wait for some signal on either socket (Stream or self-pipe) @@ -132,6 +131,7 @@ void ADSBHubConnection::StreamMain () #if APL == 1 || LIN == 1 FD_SET(streamPipe[0], &sRead); // check the self-pipe #endif + struct timeval timeout = { ADSBHUB_TIMEOUT_S, 0 }; int retval = select(maxSock, &sRead, NULL, NULL, &timeout); // short-cut if we are to shut down (return from 'select' due to closed socket) diff --git a/Src/LTChannel.cpp b/Src/LTChannel.cpp index 9002708..3d5e228 100644 --- a/Src/LTChannel.cpp +++ b/Src/LTChannel.cpp @@ -345,7 +345,7 @@ std::ofstream LTOnlineChannel::outRaw; LTOnlineChannel::LTOnlineChannel () : pCurl(NULL), -nTimeout(dataRefs.GetNetwTimeout()), +nTimeout(dataRefs.GetNetwTimeoutMax()), netData((char*)malloc(CURL_MAX_WRITE_SIZE)), // initial buffer allocation netDataPos(0), netDataSize(CURL_MAX_WRITE_SIZE), curl_errtxt{0}, httpResponse(HTTP_OK) @@ -575,10 +575,20 @@ bool LTOnlineChannel::FetchAllData (const positionTy& pos) // In case of timeout increase the channel's timeout and don't count it as an error if (cc == CURLE_OPERATION_TIMEDOUT) { - LOG_MSG(logWARN, ERR_CURL_PERFORM, ChName(), cc, curl_errtxt); - nTimeout = std::min (nTimeout * 2, - dataRefs.GetNetwTimeout()); - LOG_MSG(logWARN, "%s: Timeout increased to %ds", ChName(), nTimeout); + // But bother the user only with messages once every 3 minutes (this is due to OpenSky having been plagued with slow API responses running into timeouts) + static float tLastMsg = 0.0f; // time last message was logged + const float now = dataRefs.GetMiscNetwTime(); + if (tLastMsg + 180.0f < now) { + LOG_MSG(logWARN, ERR_CURL_PERFORM, ChName(), cc, curl_errtxt); + tLastMsg = now; + } + // Increase the timeout + const int prevTimeout = nTimeout; + nTimeout = std::min (nTimeout * 2, // double the timeout + dataRefs.GetNetwTimeoutMax()); + if (nTimeout > prevTimeout) { + LOG_MSG(logWARN, "%s: Timeout increased to %ds", ChName(), nTimeout); + } } else { SHOW_MSG(logERR, ERR_CURL_PERFORM, ChName(), cc, curl_errtxt); IncErrCnt(); @@ -594,9 +604,11 @@ bool LTOnlineChannel::FetchAllData (const positionTy& pos) // Based on actual time take set a new network timeout as twice the response time { const std::chrono::seconds d = std::chrono::duration_cast(tEnd - tStart); + // In case of a reduction we reduce to no less than half the previous value, + // keep value between min/max network timeout nTimeout = std::clamp ((int)d.count() * 2, - std::max(MIN_NETW_TIMEOUT,nTimeout/2), // this means the in case of a reduction we reduce to now less than half the previous value - dataRefs.GetNetwTimeout()); + std::max(dataRefs.GetNetwTimeoutMin(),nTimeout/2), + dataRefs.GetNetwTimeoutMax()); // LOG_MSG(logWARN, "%s: Timeout set to %ds", ChName(), nTimeout); break; } diff --git a/Src/LTOpenGlider.cpp b/Src/LTOpenGlider.cpp index 522dfb1..d2fca8c 100644 --- a/Src/LTOpenGlider.cpp +++ b/Src/LTOpenGlider.cpp @@ -19,7 +19,7 @@ /// @details Also downloads and performs searches in the aircraft list /// @see http://ddb.glidernet.org/download/ /// @author Birger Hoppe -/// @copyright (c) 2018-2020 Birger Hoppe +/// @copyright (c) 2018-2023 Birger Hoppe /// @copyright Permission is hereby granted, free of charge, to any person obtaining a /// copy of this software and associated documentation files (the "Software"), /// to deal in the Software without restriction, including without limitation @@ -355,7 +355,6 @@ void OpenGliderConnection::APRSMain (const positionTy& pos, unsigned dist_km) } // *** Main Loop *** - struct timeval timeout = { OGN_APRS_TIMEOUT_S, 0 }; while (!bStopAprs && tcpAprs.isOpen()) { // wait for some signal on either socket (APRS or self-pipe) @@ -365,6 +364,7 @@ void OpenGliderConnection::APRSMain (const positionTy& pos, unsigned dist_km) #if APL == 1 || LIN == 1 FD_SET(aprsPipe[0], &sRead); // check the self-pipe #endif + struct timeval timeout = { OGN_APRS_TIMEOUT_S, 0 }; int retval = select(maxSock, &sRead, NULL, NULL, &timeout); // short-cut if we are to shut down (return from 'select' due to closed socket) @@ -546,8 +546,15 @@ bool OpenGliderConnection::APRSProcessLine (const std::string& ln) // We expect 16 matches, 17 if fpm is given. Size is one more because element 0 is the complete matched string: if (m.size() < 17) { // didn't match. But if we think this _could_ be a valid message then we should warn, maybe there's still a flaw in the regex above - if (ln.find("! id") != std::string::npos) { - LOG_MSG(logWARN, WARN_OGN_APRS_NOT_MATCHED, ln.c_str()); + if (ln.find("! id") != std::string::npos && // seems to include an id + ln.find("/A=") != std::string::npos) // as well as an altitude (there are messages out there without altitude, which we rightfully and silently discard this way) + { + static float lastWarn = -300.0f; + const float now = dataRefs.GetMiscNetwTime(); + if (lastWarn < now - 300.0f) { // only issue warning if last such warning is more than 5 minutes ago + lastWarn = now; + LOG_MSG(logWARN, WARN_OGN_APRS_NOT_MATCHED, ln.c_str()); + } } // but otherwise no issue...there are some message in the stream that we just don't need return true; @@ -919,7 +926,7 @@ static bool OGNAcListDoDownload () // prepare the handle with the right options ho.readBuf.reserve(CURL_MAX_WRITE_SIZE); curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeout()); + curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeoutMax()); curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, curl_errtxt); curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, OGNAcListNetwCB); curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &ho); diff --git a/Src/LTOpenSky.cpp b/Src/LTOpenSky.cpp index a09e2b9..0894c9d 100644 --- a/Src/LTOpenSky.cpp +++ b/Src/LTOpenSky.cpp @@ -503,7 +503,6 @@ bool OpenSkyAcMasterdata::FetchAllData (const positionTy& /*pos*/) if (!info.empty()) vecAc.push_back(std::move(info)); - IncErrCnt(); return !listMd.empty(); // return `true` if there is data to process, otherwise we wouldn't process what had been received before the error } diff --git a/Src/LTVersion.cpp b/Src/LTVersion.cpp index 246b647..5645dd7 100644 --- a/Src/LTVersion.cpp +++ b/Src/LTVersion.cpp @@ -200,7 +200,7 @@ bool FetchXPlaneOrgVersion () verXPlaneOrg = 0; readBuf.reserve(CURL_MAX_WRITE_SIZE); curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeout()); + curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeoutMax()); curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, curl_errtxt); curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, FetchVersionCB); curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &readBuf); diff --git a/Src/LTWeather.cpp b/Src/LTWeather.cpp index 70cd4b5..b55d234 100644 --- a/Src/LTWeather.cpp +++ b/Src/LTWeather.cpp @@ -1,8 +1,8 @@ /// @file LTWeather.cpp /// @brief Fetch real weather information from AWC -/// @see https://www.aviationweather.gov/dataserver/example?datatype=metar -/// @see Example request: Latest weather 25 statute miles around EDLE, limited to the fields we are interested in: -/// https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&radialDistance=100;-118.9385,33.4036&hoursBeforeNow=2&mostRecent=true&fields=raw_text,station_id,latitude,longitude,altim_in_hg +/// @see https://aviationweather.gov/data/api/#/Dataserver/dataserverMetars +/// @see Example request: Latest weather somewhere around EDDL, limited to the fields we are interested in: +/// https://aviationweather.gov//cgi-bin/data/dataserver.php?requestType=retrieve&dataSource=metars&format=xml&boundingBox=45.5,0.5,54.5,9,5&hoursBeforeNow=2&mostRecent=true&fields=raw_text,station_id,latitude,longitude,altim_in_hg /// @details Example response: /// @code{.xml} /// @@ -52,7 +52,7 @@ /// @endcode /// /// @author Birger Hoppe -/// @copyright (c) 2018-2020 Birger Hoppe +/// @copyright (c) 2018-2023 Birger Hoppe /// @copyright Permission is hereby granted, free of charge, to any person obtaining a /// copy of this software and associated documentation files (the "Software"), /// to deal in the Software without restriction, including without limitation @@ -76,7 +76,7 @@ // /// The request URL, parameters are in this order: radius, longitude, latitude -const char* WEATHER_URL="https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&minLat=%.2f&minLon=%.2f&maxLat=%.2f&maxLon=%.2f&hoursBeforeNow=2&mostRecent=true&fields=raw_text,station_id,latitude,longitude,altim_in_hg"; +const char* WEATHER_URL="https://aviationweather.gov/cgi-bin/data/dataserver.php?requestType=retrieve&dataSource=metars&format=xml&hoursBeforeNow=2&mostRecent=true&boundingBox=%.2f,%.2f,%.2f,%.2f&fields=raw_text,station_id,latitude,longitude,altim_in_hg"; /// Weather search radius (increment) to use if the initial weather request came back empty constexpr float ADD_WEATHER_RADIUS_NM = 100.0f; @@ -219,7 +219,7 @@ bool WeatherFetch (float _lat, float _lon, float _radius_nm) // prepare the handle with the right options readBuf.reserve(CURL_MAX_WRITE_SIZE); curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeout()); + curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, dataRefs.GetNetwTimeoutMax()); curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, curl_errtxt); curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, WeatherFetchCB); curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &readBuf); diff --git a/Src/SettingsUI.cpp b/Src/SettingsUI.cpp index 18738d1..01f0d12 100644 --- a/Src/SettingsUI.cpp +++ b/Src/SettingsUI.cpp @@ -791,8 +791,9 @@ void LTSettingsUI::buildInterface() ImGui::FilteredCfgNumber("Above height AGL of", sFilter, DR_CFG_FD_REDUCE_HEIGHT, 1000, 100000, 1000, "%d ft"); ImGui::FilteredCfgNumber("increase refresh to", sFilter, DR_CFG_FD_LONG_REFRESH_INTVL, 10, 180, 5, "%d s"); ImGui::FilteredCfgNumber("Buffering period", sFilter, DR_CFG_FD_BUF_PERIOD, 10, 180, 5, "%d s"); - ImGui::FilteredCfgNumber("Max. Network timeout", sFilter, DR_CFG_NETW_TIMEOUT, 10, 180, 5, "%d s"); - + ImGui::FilteredCfgNumber("Min. Network timeout", sFilter, DR_CFG_MIN_NETW_TIMEOUT, 5, 180, 5, "%d s"); + ImGui::FilteredCfgNumber("Max. Network timeout", sFilter, DR_CFG_MAX_NETW_TIMEOUT, 5, 180, 5, "%d s"); + if (!*sFilter) ImGui::TreePop(); } diff --git a/docs/readme.html b/docs/readme.html index de00aaa..c21e303 100755 --- a/docs/readme.html +++ b/docs/readme.html @@ -128,13 +128,55 @@

Release Notes

v3

-

v3.4.1

+

v3.4.2

Update: In case of doubt you can always just copy all files from the archive over the files of your existing installation.

+

At least copy the following files, which have changed compared to v3.4.1:

+
    +
  • lin|mac|win_x64/LiveTraffic.xpl
  • +
+ +

Change log:

+ +
    +
  • + In light of OpenSky's API timeout issues, some network error handling + is reworked. Introduced a new + Advanced Setting + for Min. Network Timeout. + With this version, both Min. and Max. Network timeout are set to 5s. + This way LiveTraffic won't wait long for OpenSky not responding + but instead will retry again sooner. + See here for recommendations. +
  • +
  • + Reimplemented usage of XP's sound system when running in X-Plane 12.04 and later. + As I believe in this implementation, the + setting "Own FMOD Instance" + is reset to inactive, but is still available and can be + activated again in case there are still issues. +
  • +
  • + Fixed #257 + weather download to updated API endpoints so that proper atmospheric pressure + can again be applied to altitudes conversion. +
  • +
  • + Fixed #258 + extensive logging of ignored OGN messages. +
  • +
  • + Linux: Fixed ADSBHub and OGN disconnects + due to "'select' ran into a timeout" +
  • +
+ +

v3.4.1

+

At least copy the following files, which have changed compared to v3.4.0:

  • lin|mac|win_x64/LiveTraffic.xpl