Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v4.1.0 SayIntentions channel, Fixes #276

Merged
merged 8 commits into from
Nov 17, 2024
Merged
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ else()
endif()

project(LiveTraffic
VERSION 4.0.0
VERSION 4.1.0
DESCRIPTION "LiveTraffic X-Plane plugin")
set(VERSION_BETA 0)

Expand Down Expand Up @@ -166,6 +166,7 @@ set(Header_Files
Include/LTOpenGlider.h
Include/LTOpenSky.h
Include/LTRealTraffic.h
Include/LTSayIntentions.h
Include/LTSynthetic.h
Include/LTWeather.h
Include/SettingsUI.h
Expand Down Expand Up @@ -213,6 +214,7 @@ set(Source_Files
Src/LTOpenSky.cpp
Src/LTRealTraffic.cpp
Src/LTSynthetic.cpp
Src/LTSayIntentions.cpp
Src/LTVersion.cpp
Src/LTWeather.cpp
Src/SettingsUI.cpp
Expand Down
4,682 changes: 4,682 additions & 0 deletions Data/SayIntentions/SI_Tracker_Map.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Include/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ constexpr const char* REMOTE_SIGNATURE = "TwinFan.plugin.XPMP2.Remote";
#define CFG_RT_LICENSE "RealTraffic_License"
#define CFG_FSC_USER "FSC_User"
#define CFG_FSC_PWD "FSC_Pwd"
#define CFG_SI_DISPLAYNAME "SI_DisplayName"

//MARK: Menu Items
#define MENU_INFO_LIST_WND "Status / Information..."
Expand Down Expand Up @@ -268,6 +269,7 @@ constexpr const char* REMOTE_SIGNATURE = "TwinFan.plugin.XPMP2.Remote";
#define HELP_SET_CH_OPENGLIDER "setup/installation/ogn"
#define HELP_SET_CH_REALTRAFFIC "setup/installation/realtraffic-connectivity"
#define HELP_SET_CH_FSCHARTER "setup/installation/fscharter"
#define HELP_SET_CH_SI "setup/installation/sayintentions"
#define HELP_SET_OUTPUT_CH "setup/installation/foreflight" // currently the same as ForeFlight, which is the only output channel
#define HELP_SET_CH_FOREFLIGHT "setup/installation/foreflight"
#define HELP_SET_ACLABELS "setup/configuration/settings-a-c-labels"
Expand Down Expand Up @@ -372,7 +374,7 @@ constexpr int SERR_LEN = 100; // size of buffer for IO error t
#define ERR_CFG_FILE_VER "Config file '%s' first line: Unsupported format or version: '%s'"
#define ERR_CFG_FILE_VER_UNEXP "Config file '%s' first line: Unexpected version %s, expected %s...trying to continue"
#define ERR_CFG_FILE_IGNORE "Ignoring unkown entry '%s' from config file '%s'"
#define ERR_CFG_FILE_WORDS "Expected two words (key, value) in config file '%s', line '%s': ignored"
#define ERR_CFG_FILE_WORDS "Expected two words (key, value) separated by a space in config file '%s', line '%s': ignored"
#define ERR_CFG_FILE_READ "Could not read from '%s': %s"
#define ERR_CFG_LINE_READ "Could not read from file '%s', line %d: %s"
#define ERR_CFG_FILE_TOOMANY "Too many warnings"
Expand Down
5 changes: 5 additions & 0 deletions Include/DataRefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ enum dataRefsLT {
DR_CHANNEL_FUTUREDATACHN_ONLINE, // placeholder, first channel
DR_CHANNEL_FORE_FLIGHT_SENDER,
DR_CHANNEL_SYNTHETIC,
DR_CHANNEL_SAYINTENTIONS,
DR_CHANNEL_FSCHARTER,
DR_CHANNEL_OPEN_GLIDER_NET,
DR_CHANNEL_ADSB_HUB,
Expand Down Expand Up @@ -755,6 +756,7 @@ class DataRefs
std::string sRTLicense; ///< RealTraffic License
std::string sFSCUser; ///< FSCharter login user
std::string sFSCPwd; ///< FSCharter login password
std::string sSIDisplayName; ///< SayIntentions own display name

// live values
bool bReInitAll = false; // shall all a/c be re-initiaized (e.g. time jumped)?
Expand Down Expand Up @@ -1023,6 +1025,9 @@ class DataRefs
void SetFSCharterUser (const std::string& user) { sFSCUser = user; }
void SetFSCharterPwd (const std::string& pwd) { sFSCPwd = pwd; }

const std::string& GetSIDisplayName () const { return sSIDisplayName; }
void SetSIDisplayName (const std::string& dn) { sSIDisplayName = dn; }

// timestamp offset network vs. system clock
inline void ChTsOffsetReset() { chTsOffset = 0.0f; chTsOffsetCnt = 0; }
inline double GetChTsOffset () const { return chTsOffset; }
Expand Down
2 changes: 1 addition & 1 deletion Include/LTFlightData.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class LTFlightData
// KEY (protected, can be set only once, no mutex-control)
public:
// in ascending order of priority
enum FDKeyType { KEY_UNKNOWN=0, KEY_OGN, KEY_RT, KEY_FLARM, KEY_ICAO, KEY_FSC, KEY_ADSBEX };
enum FDKeyType { KEY_UNKNOWN=0, KEY_OGN, KEY_RT, KEY_FLARM, KEY_ICAO, KEY_FSC, KEY_ADSBEX, KEY_SAYINTENTIONS };
struct FDKeyTy {
FDKeyType eKeyType = KEY_UNKNOWN;
std::string key; // the primary key in use
Expand Down
71 changes: 71 additions & 0 deletions Include/LTSayIntentions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/// @file LTSayIntentions.h
/// @brief Channel to SayIntentions traffic map
/// @see https://tracker.sayintentions.ai/
/// @details Defines SayIntentionsConnection:\n
/// Takes traffic from https://lambda.sayintentions.ai/tracker/map
/// @author Birger Hoppe
/// @copyright (c) 2024 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
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:\n
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.\n
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.

#ifndef LTSayIntentions_h
#define LTSayIntentions_h

#include "LTChannel.h"

//
//MARK: SayIntentions Constants
//
#define SI_CHECK_NAME "SayIntentions Flight Tracker"
#define SI_CHECK_URL "https://tracker.sayintentions.ai"
#define SI_CHECK_POPUP "See who's flying with SayIntentions just now"

#define SI_NAME "SayIntentions"
#define SI_URL_ALL "https://lambda.sayintentions.ai/tracker/map"

#define SI_KEY "flight_id"
#define SI_LAT "lat"
#define SI_LON "lon"
#define SI_ALT "altitude"
#define SI_ALT_AGL "altitude_agl"
#define SI_DISPLAYNAME "displayname"
#define SI_ORIGIN "origin"
#define SI_DEST "final_destination"
#define SI_CALL "callsign"
#define SI_REG "tail_number"
#define SI_HEADING "heading"
#define SI_AC_TYPE "aircraft_icao"
#define SI_SPD "airspeed"

//
// MARK: SayIntentions connection class
//

/// Connection to SayIntentions
class SayIntentionsConnection : public LTFlightDataChannel
{
protected:
double tsRequest = NAN; ///< when did we send the last request?
public:
SayIntentionsConnection (); ///< Constructor
std::string GetURL (const positionTy& pos) override; ///< returns the constant URL to SayIntentions traffic
bool ProcessFetchedData () override; ///< Process response, selecting traffic around us and forwarding to the processing queues
protected:
void Main () override; ///< virtual thread main function
std::string UnprocessCallSign (std::string cs); ///< Converts "Piper-two-Five-Seven-papa" back to "Piper 257P"
};

#endif /* LTSayIntentions_h */
5 changes: 5 additions & 0 deletions Include/LiveTraffic.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ extern DataRefs dataRefs;
#include "LTADSBHub.h"
#include "LTOpenGlider.h"
#include "LTFSCharter.h"
#include "LTSayIntentions.h"
#include "LTSynthetic.h"

//MARK: Global Control functions
Expand Down Expand Up @@ -222,6 +223,10 @@ bool RemoteFileDownload (const std::string& url, const std::string& path);
std::string& str_toupper(std::string& s);
/// return a std::string copy converted to uppercase
std::string str_toupper_c(const std::string& s);
// change a std::string to lowercase
std::string& str_tolower(std::string& s);
/// return a std::string copy converted to lowercase
std::string str_tolower_c(const std::string& s);
/// Case-insensitive equal
bool striequal (const std::string& a, const std::string& b);
/// Case-insensitive begins with
Expand Down
3 changes: 3 additions & 0 deletions Include/SettingsUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class LTSettingsUI : public LTImgWindow
std::string sFSCPwd; ///< FSC password
bool bFSCPwdClearText = false; ///< Is FSC pwd displayed clear text?

// Channel: SayIntentions
std::string sSIDisplayName; ///< SayIntentions own display name

// Weather
std::string txtManualMETAR; ///< manually set METAR for fixed weather

Expand Down
14 changes: 11 additions & 3 deletions LiveTraffic.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
258117B4291AF22F00D05428 /* libfmod.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 258117B3291AF22F00D05428 /* libfmod.dylib */; };
258117B6291AF24D00D05428 /* FMOD_Logo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 258117B5291AF24D00D05428 /* FMOD_Logo.cpp */; };
259EC47A2505959A009B86F3 /* LTOpenGlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 259EC47925057815009B86F3 /* LTOpenGlider.cpp */; };
25A5D97A2CE3F9E2004F507C /* LTSayIntentions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25A5D9792CE3F9E2004F507C /* LTSayIntentions.cpp */; };
25ABEEFE219A1C2100F61413 /* LTVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25ABEEFD219A1C2100F61413 /* LTVersion.cpp */; };
25AE00D9213887AF00908E65 /* SettingsUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25AE00D8213887AF00908E65 /* SettingsUI.cpp */; };
25BFBB9320DEE2DC00D52B6C /* LTChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25BFBB9220DEE2DC00D52B6C /* LTChannel.cpp */; };
Expand Down Expand Up @@ -151,6 +152,8 @@
25A095C72203B01300658AA8 /* DataRefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataRefs.h; sourceTree = "<group>"; };
25A095C82203B01300658AA8 /* LiveTraffic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveTraffic.h; sourceTree = "<group>"; };
25A095C92203B01300658AA8 /* LTAircraft.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTAircraft.h; sourceTree = "<group>"; };
25A5D9792CE3F9E2004F507C /* LTSayIntentions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LTSayIntentions.cpp; sourceTree = "<group>"; };
25A5D97D2CE3FC0F004F507C /* LTSayIntentions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTSayIntentions.h; sourceTree = "<group>"; };
25A70295241D911200D2E7EE /* Apt.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Apt.md; sourceTree = "<group>"; };
25AACA2F217A99ED0035DC20 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; wrapsLines = 1; };
25AACA30217B2FCA0035DC20 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
Expand Down Expand Up @@ -308,6 +311,7 @@
259EC47925057815009B86F3 /* LTOpenGlider.cpp */,
2573631F22233CDA005210C5 /* LTOpenSky.cpp */,
2573631922233008005210C5 /* LTRealTraffic.cpp */,
25A5D9792CE3F9E2004F507C /* LTSayIntentions.cpp */,
25EF90032B497C6100D7C805 /* LTSynthetic.cpp */,
25ABEEFD219A1C2100F61413 /* LTVersion.cpp */,
254F278824EF230400CACCDA /* LTWeather.cpp */,
Expand Down Expand Up @@ -441,6 +445,7 @@
259EC47825057802009B86F3 /* LTOpenGlider.h */,
2573631C22233CCA005210C5 /* LTOpenSky.h */,
2573631B22233041005210C5 /* LTRealTraffic.h */,
25A5D97D2CE3FC0F004F507C /* LTSayIntentions.h */,
25EF90052B497C7900D7C805 /* LTSynthetic.h */,
254F278724EF22FE00CACCDA /* LTWeather.h */,
25A095C32203B01300658AA8 /* SettingsUI.h */,
Expand Down Expand Up @@ -588,7 +593,7 @@
KnownAssetTags = (
New,
);
LastUpgradeCheck = 1540;
LastUpgradeCheck = 1610;
};
buildConfigurationList = D607B16209A5563100699BC3 /* Build configuration list for PBXProject "LiveTraffic" */;
compatibilityVersion = "Xcode 12.0";
Expand Down Expand Up @@ -683,6 +688,7 @@
25EF90042B497C6100D7C805 /* LTSynthetic.cpp in Sources */,
25AE00D9213887AF00908E65 /* SettingsUI.cpp in Sources */,
25C59458207A296500E52073 /* TextIO.cpp in Sources */,
25A5D97A2CE3F9E2004F507C /* LTSayIntentions.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -795,7 +801,7 @@
LIBRARY_SEARCH_PATHS = Lib/fmod;
LIVETRAFFIC_VERSION_BETA = 0;
LIVETRAFFIC_VER_MAJOR = 4;
LIVETRAFFIC_VER_MINOR = 0;
LIVETRAFFIC_VER_MINOR = 1;
LIVETRAFFIC_VER_PATCH = 0;
LLVM_LTO = NO;
MACH_O_TYPE = mh_dylib;
Expand Down Expand Up @@ -904,7 +910,7 @@
LIBRARY_SEARCH_PATHS = Lib/fmod;
LIVETRAFFIC_VERSION_BETA = 0;
LIVETRAFFIC_VER_MAJOR = 4;
LIVETRAFFIC_VER_MINOR = 0;
LIVETRAFFIC_VER_MINOR = 1;
LIVETRAFFIC_VER_PATCH = 0;
LLVM_LTO = YES;
MACH_O_TYPE = mh_dylib;
Expand Down Expand Up @@ -949,6 +955,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Lib/fmod",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
OTHER_LDFLAGS = (
"$(OTHER_LDFLAGS)",
"-Wl,-exported_symbol",
Expand Down Expand Up @@ -1001,6 +1008,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Lib/fmod",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
OTHER_LDFLAGS = (
"$(OTHER_LDFLAGS)",
"-Wl,-exported_symbol",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
LastUpgradeVersion = "1610"
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
22 changes: 13 additions & 9 deletions Src/DataRefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ DataRefs::dataRefDefinitionT DATA_REFS_LT[CNT_DATAREFS_LT] = {
{"livetraffic/channel/futuredatachn/online", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, false },
{"livetraffic/channel/fore_flight/sender", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, true, true },
{"livetraffic/channel/synthetic/intern", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, true, true },
{"livetraffic/channel/sayintentions/online", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, true, true },
{"livetraffic/channel/fscharter/online", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, true, true },
{"livetraffic/channel/open_glider/online", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, true, true },
{"livetraffic/channel/adsbhub/online", DataRefs::LTGetInt, DataRefs::LTSetBool, GET_VAR, true, true },
Expand Down Expand Up @@ -1162,8 +1163,8 @@ void DataRefs::UpdateUsersPlanePos ()
XPLMGetDatai(adrXP[DR_PLANE_ONGRND]) ? GND_ON : GND_OFF
);

// make invalid pos invalid
if (pos.lat() < -75 || pos.lat() > 75)
// make invalid pos invalid (but why?)
if (pos.lat() < -85 || pos.lat() > 85)
pos.lat() = NAN;

// cache the position
Expand Down Expand Up @@ -2123,18 +2124,18 @@ bool DataRefs::LoadConfigFile()
// break out of loop if reading the start of another section indicated by [ ]
if (lnBuf.front() == '[' && lnBuf.back() == ']') break;

// otherwise should be 2 tokens
ln = str_tokenize(lnBuf, " ");
if (ln.size() != 2) {
// otherwise should be 2 tokens, separated by the (first) space character
const std::string::size_type posSpc = lnBuf.find(' ');
if (posSpc == std::string::npos) {
// wrong number of words in that line
LOG_MSG(logWARN,ERR_CFG_FILE_WORDS, sFileName.c_str(), lnBuf.c_str());
errCnt++;
continue;
}

const std::string sDataRef = lnBuf.substr(0, posSpc);
std::string sVal = posSpc+1 < lnBuf.length() ? lnBuf.substr(posSpc+1) : "";

// did read a name and a value?
const std::string& sDataRef = ln[0];
std::string& sVal = ln[1];
if (!sDataRef.empty() && !sVal.empty()) {
// verify that we know that name
dataRefDefinitionT* i = std::find_if(std::begin(DATA_REFS_LT),
Expand Down Expand Up @@ -2206,6 +2207,8 @@ bool DataRefs::LoadConfigFile()
SetFSCharterUser(sVal);
else if (sDataRef == CFG_FSC_PWD)
SetFSCharterPwd(Cleartext(sVal));
else if (sDataRef == CFG_SI_DISPLAYNAME)
SetSIDisplayName(sVal);
else
{
// unknown config entry, ignore
Expand All @@ -2214,7 +2217,6 @@ bool DataRefs::LoadConfigFile()
errCnt++;
}
}

}

// *** [FlarmAcTypes] ***
Expand Down Expand Up @@ -2352,6 +2354,8 @@ bool DataRefs::SaveConfigFile()
fOut << CFG_FSC_USER << ' ' << sFSCUser << '\n';
if (!sFSCPwd.empty())
fOut << CFG_FSC_PWD << ' ' << Obfuscate(sFSCPwd) << '\n';
if (!sSIDisplayName.empty())
fOut << CFG_SI_DISPLAYNAME << ' ' << sSIDisplayName << '\n';

// *** [FlarmAcTypes] ***
fOut << '\n' << CFG_FLARM_ACTY_SECTION << '\n';
Expand Down
1 change: 1 addition & 0 deletions Src/LTChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ bool LTFlightDataEnable()
listFDC.emplace_back(new ADSBHubConnection());
listFDC.emplace_back(new OpenGliderConnection);
listFDC.emplace_back(new FSCConnection);
listFDC.emplace_back(new SayIntentionsConnection);
listFDC.emplace_back(new SyntheticConnection);
// load online master data connections
listFDC.emplace_back(new OpenSkyAcMasterFile);
Expand Down
4 changes: 4 additions & 0 deletions Src/LTFlightData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ std::string LTFlightData::FDKeyTy::SetKey (FDKeyType _eType, unsigned long _num)
case KEY_RT:
snprintf(buf, sizeof(buf), "%08lX", _num);
break;
case KEY_SAYINTENTIONS:
snprintf(buf, sizeof(buf), "%lu", _num);
break;
case KEY_UNKNOWN:
// must not happen
LOG_ASSERT(eKeyType!=KEY_UNKNOWN);
Expand Down Expand Up @@ -301,6 +304,7 @@ const char* LTFlightData::FDKeyTy::GetKeyTypeText () const
case KEY_ICAO: return "ICAO";
case KEY_FSC: return "FSCharter";
case KEY_ADSBEX: return "ADSBEx";
case KEY_SAYINTENTIONS: return "SI";
}
return "unknown";
}
Expand Down
Loading
Loading