Compare commits
No commits in common. "396aa8d80792f93f7a948fcbbab99d85e333b2ce" and "42acea35bb18d9f03da8be0c5b4dba8ab1f2889e" have entirely different histories.
396aa8d807
...
42acea35bb
6
TODO.md
6
TODO.md
@ -16,9 +16,3 @@
|
|||||||
- hash: Hash of file at path
|
- hash: Hash of file at path
|
||||||
- Requires mapping akin to C#
|
- Requires mapping akin to C#
|
||||||
- Try to be fast
|
- Try to be fast
|
||||||
- Define Protocoll
|
|
||||||
- Login Master Slave
|
|
||||||
- Commands
|
|
||||||
- Text
|
|
||||||
- Port
|
|
||||||
- Time
|
|
||||||
@ -100,7 +100,7 @@ class SimConnect
|
|||||||
bool pausedMenu;
|
bool pausedMenu;
|
||||||
bool paused;
|
bool paused;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
struct germanairlinesva::gaconnector::websocket::data simData;
|
struct germanairlinesva::websocket::data simData;
|
||||||
std::shared_ptr<germanairlinesva::file::config::Config> configuration;
|
std::shared_ptr<germanairlinesva::file::config::Config> configuration;
|
||||||
std::function<void(const std::string)> toLog;
|
std::function<void(const std::string)> toLog;
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ class SimConnect
|
|||||||
~SimConnect();
|
~SimConnect();
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
const std::string getVersion() const;
|
const std::string getVersion() const;
|
||||||
void getData(struct germanairlinesva::gaconnector::websocket::data *data);
|
void getData(struct germanairlinesva::websocket::data *data);
|
||||||
void getStates() const;
|
void getStates() const;
|
||||||
void handleMessage();
|
void handleMessage();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,11 +16,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "_simconnect.h"
|
|
||||||
#include "config/config.hpp"
|
#include "config/config.hpp"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "logbook/logbook.hpp"
|
#include "logbook/logbook.hpp"
|
||||||
#include "recording/recording.hpp"
|
#include "recording/recording.hpp"
|
||||||
|
#include "_simconnect.h"
|
||||||
#include "simdata/simDatabase.hpp"
|
#include "simdata/simDatabase.hpp"
|
||||||
|
|
||||||
WINBOOL addNotifyIcon(HWND hWnd);
|
WINBOOL addNotifyIcon(HWND hWnd);
|
||||||
|
|||||||
22
esp/main.cpp
22
esp/main.cpp
@ -12,10 +12,10 @@ std::atomic<bool> wantsExit;
|
|||||||
|
|
||||||
std::shared_ptr<germanairlinesva::file::config::Config> configuration;
|
std::shared_ptr<germanairlinesva::file::config::Config> configuration;
|
||||||
std::unique_ptr<germanairlinesva::file::simdata::SimDatabase> database;
|
std::unique_ptr<germanairlinesva::file::simdata::SimDatabase> database;
|
||||||
std::unique_ptr<germanairlinesva::gaconnector::websocket::Websocket> connector;
|
std::unique_ptr<germanairlinesva::websocket::Websocket> connector;
|
||||||
std::unique_ptr<SimConnect> simConnect;
|
std::unique_ptr<SimConnect> simConnect;
|
||||||
|
|
||||||
struct germanairlinesva::gaconnector::websocket::data toSend;
|
struct germanairlinesva::websocket::data toSend;
|
||||||
germanairlinesva::file::recording::Recording p;
|
germanairlinesva::file::recording::Recording p;
|
||||||
|
|
||||||
// The Window Procedure
|
// The Window Procedure
|
||||||
@ -127,8 +127,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
configuration = std::make_unique<germanairlinesva::file::config::Config>();
|
configuration = std::make_unique<germanairlinesva::file::config::Config>();
|
||||||
toLog("Config loaded");
|
toLog("Config loaded");
|
||||||
|
|
||||||
connector =
|
connector = std::make_unique<germanairlinesva::websocket::Websocket>(
|
||||||
std::make_unique<germanairlinesva::gaconnector::websocket::Websocket>(
|
|
||||||
"wss://ws.hofmannnet.myhome-server.de:8000",
|
"wss://ws.hofmannnet.myhome-server.de:8000",
|
||||||
configuration->getUser(),
|
configuration->getUser(),
|
||||||
toLog);
|
toLog);
|
||||||
@ -154,8 +153,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
CoTaskMemFree(folder);
|
CoTaskMemFree(folder);
|
||||||
|
|
||||||
char hash[2 * MD5LEN + 1] = "";
|
char hash[2 * MD5LEN + 1] = "";
|
||||||
if (germanairlinesva::utilities::generateMD5(path.c_str(), hash, toLog) ==
|
if (germanairlinesva::util::generateMD5(path.c_str(), hash, toLog) == 0) {
|
||||||
0) {
|
|
||||||
database = std::make_unique<germanairlinesva::file::simdata::SimDatabase>(
|
database = std::make_unique<germanairlinesva::file::simdata::SimDatabase>(
|
||||||
FSX_VERSION,
|
FSX_VERSION,
|
||||||
hash,
|
hash,
|
||||||
@ -326,13 +324,13 @@ void end(HWND hWnd)
|
|||||||
|
|
||||||
void serverWorker()
|
void serverWorker()
|
||||||
{
|
{
|
||||||
germanairlinesva::utilities::setThreadName("GAServerWorker");
|
germanairlinesva::util::setThreadName("GAServerWorker");
|
||||||
|
|
||||||
while (!wantsExit) {
|
while (!wantsExit) {
|
||||||
simConnect->getStates();
|
simConnect->getStates();
|
||||||
|
|
||||||
struct germanairlinesva::gaconnector::websocket::data *copy =
|
struct germanairlinesva::websocket::data *copy =
|
||||||
new germanairlinesva::gaconnector::websocket::data();
|
new germanairlinesva::websocket::data();
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
@ -349,7 +347,7 @@ void serverWorker()
|
|||||||
|
|
||||||
void recordingWorker()
|
void recordingWorker()
|
||||||
{
|
{
|
||||||
germanairlinesva::utilities::setThreadName("GARecordingWorker");
|
germanairlinesva::util::setThreadName("GARecordingWorker");
|
||||||
|
|
||||||
germanairlinesva::file::recording::RecordingEntry lastPath;
|
germanairlinesva::file::recording::RecordingEntry lastPath;
|
||||||
std::uint32_t segment = 0;
|
std::uint32_t segment = 0;
|
||||||
@ -358,8 +356,8 @@ void recordingWorker()
|
|||||||
auto rwys = ap.second;
|
auto rwys = ap.second;
|
||||||
|
|
||||||
while (!wantsExit) {
|
while (!wantsExit) {
|
||||||
struct germanairlinesva::gaconnector::websocket::data *copy =
|
struct germanairlinesva::websocket::data *copy =
|
||||||
new germanairlinesva::gaconnector::websocket::data();
|
new germanairlinesva::websocket::data();
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
|
|||||||
@ -323,8 +323,7 @@ const std::string SimConnect::getVersion() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimConnect::getData(
|
void SimConnect::getData(struct germanairlinesva::websocket::data *data)
|
||||||
struct germanairlinesva::gaconnector::websocket::data *data)
|
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(this->mutex);
|
const std::lock_guard<std::mutex> lock(this->mutex);
|
||||||
memcpy(data, &this->simData, sizeof(this->simData));
|
memcpy(data, &this->simData, sizeof(this->simData));
|
||||||
|
|||||||
@ -51,10 +51,10 @@ namespace file
|
|||||||
std::ifstream in(BASE_DIRECTORY CONFIG);
|
std::ifstream in(BASE_DIRECTORY CONFIG);
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(in, line)) {
|
while (std::getline(in, line)) {
|
||||||
std::vector<std::string> fields = utilities::split(line, '=');
|
std::vector<std::string> fields = util::split(line, '=');
|
||||||
if (fields.size() >= 2) {
|
if (fields.size() >= 2) {
|
||||||
utilities::trim(fields[0]);
|
util::trim(fields[0]);
|
||||||
utilities::trim(fields[1]);
|
util::trim(fields[1]);
|
||||||
if (fields[0] == "scenery") {
|
if (fields[0] == "scenery") {
|
||||||
this->scenery = fields[1];
|
this->scenery = fields[1];
|
||||||
} else if (fields[0] == "user") {
|
} else if (fields[0] == "user") {
|
||||||
|
|||||||
@ -117,7 +117,7 @@ namespace file
|
|||||||
public:
|
public:
|
||||||
inline Logbook()
|
inline Logbook()
|
||||||
{
|
{
|
||||||
if (utilities::fileExists(BASE_DIRECTORY LOGBOOK)) {
|
if (util::fileExists(BASE_DIRECTORY LOGBOOK)) {
|
||||||
this->fromFile();
|
this->fromFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_FILE_RECORDING_RECORDINGENTRY_H
|
#ifndef GERMANAIRLINESVA_FILE_RECORDINGENTRY_H
|
||||||
#define GERMANAIRLINESVA_FILE_RECORDING_RECORDINGENTRY_H
|
#define GERMANAIRLINESVA_FILE_RECORDINGENTRY_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -26,14 +26,14 @@ namespace file
|
|||||||
std::uint32_t time;
|
std::uint32_t time;
|
||||||
std::uint16_t altitude = 0;
|
std::uint16_t altitude = 0;
|
||||||
std::uint16_t groundSpeed = 0;
|
std::uint16_t groundSpeed = 0;
|
||||||
struct utilities::geodata::point coordinates = {NAN, NAN};
|
struct geodata::point coordinates = {NAN, NAN};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline RecordingEntry() = default;
|
inline RecordingEntry() = default;
|
||||||
inline RecordingEntry(std::uint32_t time,
|
inline RecordingEntry(std::uint32_t time,
|
||||||
std::uint16_t altitude,
|
std::uint16_t altitude,
|
||||||
std::uint16_t groundSpeed,
|
std::uint16_t groundSpeed,
|
||||||
struct utilities::geodata::point coordinates)
|
struct geodata::point coordinates)
|
||||||
: time(time), altitude(altitude), groundSpeed(groundSpeed),
|
: time(time), altitude(altitude), groundSpeed(groundSpeed),
|
||||||
coordinates(coordinates)
|
coordinates(coordinates)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -32,7 +32,7 @@ namespace file
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string designator;
|
std::string designator;
|
||||||
struct utilities::geodata::point center;
|
struct geodata::point center;
|
||||||
std::uint8_t radius;
|
std::uint8_t radius;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -45,7 +45,7 @@ namespace file
|
|||||||
radius(radius){};
|
radius(radius){};
|
||||||
// From Database
|
// From Database
|
||||||
inline Gate(std::string designator,
|
inline Gate(std::string designator,
|
||||||
struct utilities::geodata::point center,
|
struct geodata::point center,
|
||||||
std::uint8_t radius)
|
std::uint8_t radius)
|
||||||
: designator(designator), center(center), radius(radius){};
|
: designator(designator), center(center), radius(radius){};
|
||||||
|
|
||||||
@ -56,9 +56,9 @@ namespace file
|
|||||||
write<decltype(this->radius)>(out, this->radius);
|
write<decltype(this->radius)>(out, this->radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool contains(utilities::geodata::point coordinates) const
|
inline bool contains(geodata::point coordinates) const
|
||||||
{
|
{
|
||||||
return utilities::geodata::distanceEarthP(this->center, coordinates);
|
return geodata::distanceEarthP(this->center, coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::string to_string() const
|
inline const std::string to_string() const
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace file
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string designator;
|
std::string designator;
|
||||||
struct utilities::geodata::box bounds;
|
struct geodata::box bounds;
|
||||||
std::uint8_t width;
|
std::uint8_t width;
|
||||||
std::uint16_t length;
|
std::uint16_t length;
|
||||||
double trueHeading;
|
double trueHeading;
|
||||||
@ -49,51 +49,49 @@ namespace file
|
|||||||
double width)
|
double width)
|
||||||
: designator(designator), width(width)
|
: designator(designator), width(width)
|
||||||
{
|
{
|
||||||
this->length = utilities::geodata::distanceEarthD(latitudeStart,
|
this->length = geodata::distanceEarthD(latitudeStart,
|
||||||
longitudeStart,
|
longitudeStart,
|
||||||
latitudeEnd,
|
latitudeEnd,
|
||||||
longitudeEnd);
|
longitudeEnd);
|
||||||
this->trueHeading = utilities::geodata::bearingDD(latitudeStart,
|
this->trueHeading = geodata::bearingDD(latitudeStart,
|
||||||
longitudeStart,
|
longitudeStart,
|
||||||
latitudeEnd,
|
latitudeEnd,
|
||||||
longitudeEnd);
|
longitudeEnd);
|
||||||
this->bounds = utilities::geodata::calculateBoxDD(
|
this->bounds =
|
||||||
{latitudeStart, longitudeStart},
|
geodata::calculateBoxDD({latitudeStart, longitudeStart},
|
||||||
{latitudeEnd, longitudeEnd},
|
{latitudeEnd, longitudeEnd},
|
||||||
this->trueHeading,
|
this->trueHeading,
|
||||||
this->width);
|
this->width);
|
||||||
};
|
};
|
||||||
// From MakeRwys
|
// From MakeRwys
|
||||||
inline Runway(std::string designator,
|
inline Runway(std::string designator,
|
||||||
struct utilities::geodata::point start,
|
struct geodata::point start,
|
||||||
double width,
|
double width,
|
||||||
double length,
|
double length,
|
||||||
double trueHeading)
|
double trueHeading)
|
||||||
: designator(designator), width(width), length(length),
|
: designator(designator), width(width), length(length),
|
||||||
trueHeading(trueHeading)
|
trueHeading(trueHeading)
|
||||||
{
|
{
|
||||||
utilities::geodata::point end =
|
geodata::point end =
|
||||||
utilities::geodata::calculatePointDD(start, trueHeading, length);
|
geodata::calculatePointDD(start, trueHeading, length);
|
||||||
|
|
||||||
this->bounds = utilities::geodata::calculateBoxDD(start,
|
this->bounds =
|
||||||
end,
|
geodata::calculateBoxDD(start, end, trueHeading, width);
|
||||||
trueHeading,
|
|
||||||
width);
|
|
||||||
};
|
};
|
||||||
// From database
|
// From database
|
||||||
inline Runway(std::string designator,
|
inline Runway(std::string designator,
|
||||||
struct utilities::geodata::box bounds,
|
struct geodata::box bounds,
|
||||||
std::uint8_t width,
|
std::uint8_t width,
|
||||||
std::uint16_t length,
|
std::uint16_t length,
|
||||||
double trueHeading)
|
double trueHeading)
|
||||||
: designator(designator), bounds(bounds), width(width),
|
: designator(designator), bounds(bounds), width(width),
|
||||||
length(length), trueHeading(trueHeading){};
|
length(length), trueHeading(trueHeading){};
|
||||||
|
|
||||||
inline bool containsPoint(const utilities::geodata::point point) const
|
inline bool containsPoint(const geodata::point point) const
|
||||||
{
|
{
|
||||||
size_t j = 3;
|
size_t j = 3;
|
||||||
bool c = false;
|
bool c = false;
|
||||||
std::vector<utilities::geodata::point> poly{this->bounds.topLeft,
|
std::vector<geodata::point> poly{this->bounds.topLeft,
|
||||||
this->bounds.topRight,
|
this->bounds.topRight,
|
||||||
this->bounds.bottomRight,
|
this->bounds.bottomRight,
|
||||||
this->bounds.bottomLeft};
|
this->bounds.bottomLeft};
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
#ifdef XP
|
#ifdef XP
|
||||||
#include "simdata/simdataXP.hpp"
|
#include "simdata/simdataXP.hpp"
|
||||||
#endif
|
#endif
|
||||||
#if not defined(XP) && not defined(MSFS)
|
#ifndef MSFS
|
||||||
#include "simdata/simdataESP.hpp"
|
#include "simdata/simdataESP.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -61,8 +61,7 @@ namespace file
|
|||||||
std::uint16_t numGates = read<std::uint16_t>(in);
|
std::uint16_t numGates = read<std::uint16_t>(in);
|
||||||
for (int j = 0; j < numGates; j++) {
|
for (int j = 0; j < numGates; j++) {
|
||||||
std::string designator = readString(in);
|
std::string designator = readString(in);
|
||||||
struct utilities::geodata::point center =
|
struct geodata::point center = read<struct geodata::point>(in);
|
||||||
read<struct utilities::geodata::point>(in);
|
|
||||||
std::uint8_t radius = read<std::uint8_t>(in);
|
std::uint8_t radius = read<std::uint8_t>(in);
|
||||||
|
|
||||||
this->airports[icao].first.emplace_back(designator,
|
this->airports[icao].first.emplace_back(designator,
|
||||||
@ -74,8 +73,7 @@ namespace file
|
|||||||
for (int j = 0; j < numRunways; j++) {
|
for (int j = 0; j < numRunways; j++) {
|
||||||
std::string designator = readString(in);
|
std::string designator = readString(in);
|
||||||
// Center
|
// Center
|
||||||
struct utilities::geodata::box bounds =
|
struct geodata::box bounds = read<struct geodata::box>(in);
|
||||||
read<struct utilities::geodata::box>(in);
|
|
||||||
std::uint8_t width = read<std::uint8_t>(in);
|
std::uint8_t width = read<std::uint8_t>(in);
|
||||||
std::uint16_t length = read<std::uint16_t>(in);
|
std::uint16_t length = read<std::uint16_t>(in);
|
||||||
double trueHeading = read<double>(in);
|
double trueHeading = read<double>(in);
|
||||||
@ -115,7 +113,7 @@ namespace file
|
|||||||
std::function<void(const std::string)> toLog)
|
std::function<void(const std::string)> toLog)
|
||||||
{
|
{
|
||||||
if (strcmp(configuration->getScenery().c_str(), hash) != 0 ||
|
if (strcmp(configuration->getScenery().c_str(), hash) != 0 ||
|
||||||
!utilities::fileExists(BASE_DIRECTORY SIMDATABASE)) {
|
!util::fileExists(BASE_DIRECTORY SIMDATABASE)) {
|
||||||
#ifdef XP
|
#ifdef XP
|
||||||
scan(simVersion < 12000 ? XPLANE11_BASE_SCENERY
|
scan(simVersion < 12000 ? XPLANE11_BASE_SCENERY
|
||||||
: XPLANE12_BASE_SCENERY,
|
: XPLANE12_BASE_SCENERY,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_FILE_SIMDATA_SIMDATAESP_H
|
#ifndef GERMANAIRLINESVA_FILE_SIMDATA_SIMDATAXP_H
|
||||||
#define GERMANAIRLINESVA_FILE_SIMDATA_SIMDATAESP_H
|
#define GERMANAIRLINESVA_FILE_SIMDATA_SIMDATAXP_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -55,7 +55,7 @@ namespace file
|
|||||||
log << "<FILE> " << runwaysFile << std::endl;
|
log << "<FILE> " << runwaysFile << std::endl;
|
||||||
|
|
||||||
while (std::getline(runways, line)) {
|
while (std::getline(runways, line)) {
|
||||||
std::vector<std::string> fields = utilities::split(line, ',');
|
std::vector<std::string> fields = util::split(line, ',');
|
||||||
// New ICAO
|
// New ICAO
|
||||||
if (currentIcao != nullptr && *currentIcao != fields[0]) {
|
if (currentIcao != nullptr && *currentIcao != fields[0]) {
|
||||||
tmpAirportRunways[*currentIcao] = tmpRunways;
|
tmpAirportRunways[*currentIcao] = tmpRunways;
|
||||||
@ -85,13 +85,12 @@ namespace file
|
|||||||
designator = "0" + designator;
|
designator = "0" + designator;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct utilities::geodata::point start = {std::stod(fields[2]),
|
struct geodata::point start = {std::stod(fields[2]),
|
||||||
std::stod(fields[3])};
|
std::stod(fields[3])};
|
||||||
tmpRunways.emplace_back(
|
tmpRunways.emplace_back(designator,
|
||||||
designator,
|
|
||||||
start,
|
start,
|
||||||
utilities::geodata::toMetre(std::stod(fields[8])),
|
geodata::toMetre(std::stod(fields[8])),
|
||||||
utilities::geodata::toMetre(std::stod(fields[6])),
|
geodata::toMetre(std::stod(fields[6])),
|
||||||
std::stod(fields[5]) + std::stod(fields[9]));
|
std::stod(fields[5]) + std::stod(fields[9]));
|
||||||
|
|
||||||
log << "\t<RUNWAY> " << line << std::endl;
|
log << "\t<RUNWAY> " << line << std::endl;
|
||||||
@ -99,7 +98,7 @@ namespace file
|
|||||||
|
|
||||||
currentIcao = nullptr;
|
currentIcao = nullptr;
|
||||||
while (std::getline(gates, line)) {
|
while (std::getline(gates, line)) {
|
||||||
std::vector<std::string> fields = utilities::split(line, ',');
|
std::vector<std::string> fields = util::split(line, ',');
|
||||||
// New ICAO
|
// New ICAO
|
||||||
if (currentIcao != nullptr && *currentIcao != fields[0]) {
|
if (currentIcao != nullptr && *currentIcao != fields[0]) {
|
||||||
tmpAirportGates[*currentIcao] = tmpGates;
|
tmpAirportGates[*currentIcao] = tmpGates;
|
||||||
|
|||||||
@ -79,9 +79,8 @@ namespace file
|
|||||||
int validCount = 0;
|
int validCount = 0;
|
||||||
|
|
||||||
while (std::getline(infile, line)) {
|
while (std::getline(infile, line)) {
|
||||||
std::vector<std::string> fields = utilities::split(line, ' ');
|
std::vector<std::string> fields = util::split(line, ' ');
|
||||||
fields =
|
fields = util::select_T<std::string>(fields, [](const std::string &s) {
|
||||||
utilities::select_T<std::string>(fields, [](const std::string &s) {
|
|
||||||
return s.length() > 0;
|
return s.length() > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -174,7 +173,7 @@ namespace file
|
|||||||
std::vector<std::string> packs;
|
std::vector<std::string> packs;
|
||||||
while (std::getline(custom, line)) {
|
while (std::getline(custom, line)) {
|
||||||
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
||||||
std::string path = utilities::rtrim_copy(line.substr(pos + 13)) +
|
std::string path = util::rtrim_copy(line.substr(pos + 13)) +
|
||||||
"Earth nav data/apt.dat";
|
"Earth nav data/apt.dat";
|
||||||
packs.emplace_back(path);
|
packs.emplace_back(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
shopt -s globstar
|
shopt -s globstar
|
||||||
|
|
||||||
GLOBIGNORE='**/XPLM/**:XPLM/**:**/XPLM:**/ixwebsocket/**:ixwebsocket/**:**/ixwebsocket:**/nlohmann/**:nlohmann/**:**/nlohmann:**/XPSDK/**:XPSDK/**:**/XPSDK:**/build*/**:build*/**:**/build*:**/openSSL/**:openSSL/**:**/openSSL:**/SimConnect/**:SimConnect/**:**/SimConnect'
|
GLOBIGNORE='**/XPLM/**:XPLM/**:**/XPLM:**/ixwebsocket/**:ixwebsocket/**:**/ixwebsocket:**/nlohmann/**:nlohmann/**:**/nlohmann:**/XPSDK/**:XPSDK/**:**/XPSDK:**/build*/**:build*/**:**/build*:**/openSSL/**:openSSL/**:**/openSSL'
|
||||||
|
|
||||||
clang-format -verbose -i **/*.cpp
|
clang-format -verbose -i **/*.cpp
|
||||||
clang-format -verbose -i **/*.h
|
clang-format -verbose -i **/*.h
|
||||||
|
|||||||
@ -1,62 +0,0 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_RECORDER_RECORDER_H
|
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_RECORDER_RECORDER_H
|
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <functional>
|
|
||||||
#include <mutex>
|
|
||||||
#include <queue>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "websocket.h"
|
|
||||||
|
|
||||||
#include "config/config.hpp"
|
|
||||||
#include "logbook/logbook.hpp"
|
|
||||||
#include "recording/recording.hpp"
|
|
||||||
#include "simdata/simDatabase.hpp"
|
|
||||||
|
|
||||||
namespace germanairlinesva
|
|
||||||
{
|
|
||||||
namespace gaconnector
|
|
||||||
{
|
|
||||||
namespace recorder
|
|
||||||
{
|
|
||||||
class Recorder
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::function<void(const std::string)> toLog;
|
|
||||||
|
|
||||||
std::mutex mutex;
|
|
||||||
std::thread serverThread;
|
|
||||||
std::thread recordingThread;
|
|
||||||
std::atomic<bool> wantsExit{false};
|
|
||||||
|
|
||||||
std::shared_ptr<file::config::Config> configuration;
|
|
||||||
std::unique_ptr<file::simdata::SimDatabase> database;
|
|
||||||
std::unique_ptr<websocket::Websocket> connector;
|
|
||||||
|
|
||||||
websocket::data toSend;
|
|
||||||
|
|
||||||
std::queue<std::function<void()>> &messageQueue()
|
|
||||||
{
|
|
||||||
static std::queue<std::function<void()>> _messageQueue;
|
|
||||||
return _messageQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void serverWorker();
|
|
||||||
void recordingWorker();
|
|
||||||
|
|
||||||
// For Testing
|
|
||||||
void test() const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Recorder(int simVersion, std::function<void(const std::string)> toLog);
|
|
||||||
~Recorder();
|
|
||||||
|
|
||||||
void setData(websocket::data &data);
|
|
||||||
void handleMessages();
|
|
||||||
};
|
|
||||||
} // namespace recorder
|
|
||||||
} // namespace gaconnector
|
|
||||||
} // namespace germanairlinesva
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,180 +0,0 @@
|
|||||||
#include "include/recorder.h"
|
|
||||||
|
|
||||||
namespace germanairlinesva
|
|
||||||
{
|
|
||||||
namespace gaconnector
|
|
||||||
{
|
|
||||||
namespace recorder
|
|
||||||
{
|
|
||||||
Recorder::Recorder(int simVersion,
|
|
||||||
std::function<void(const std::string)> toLog)
|
|
||||||
: toLog(std::move(toLog))
|
|
||||||
{
|
|
||||||
// Configuration
|
|
||||||
this->configuration = std::make_shared<file::config::Config>();
|
|
||||||
this->toLog("Configuration loaded");
|
|
||||||
|
|
||||||
// Database
|
|
||||||
#ifdef XP
|
|
||||||
char hash[2 * MD5LEN + 1] = "";
|
|
||||||
if (utilities::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) == 0) {
|
|
||||||
this->database =
|
|
||||||
std::make_unique<file::simdata::SimDatabase>(simVersion,
|
|
||||||
hash,
|
|
||||||
this->configuration,
|
|
||||||
this->toLog);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef MSFS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// WebSocket
|
|
||||||
this->connector = std::make_unique<websocket::Websocket>(
|
|
||||||
"wss://ws.hofmannnet.myhome-server.de:8000",
|
|
||||||
this->configuration->getUser(),
|
|
||||||
this->toLog);
|
|
||||||
this->toLog("WebSocket started");
|
|
||||||
|
|
||||||
// For Testing
|
|
||||||
this->test();
|
|
||||||
|
|
||||||
// Thread for sending data to websocket
|
|
||||||
this->serverThread = std::thread(&Recorder::serverWorker, this);
|
|
||||||
this->recordingThread = std::thread(&Recorder::recordingWorker, this);
|
|
||||||
this->toLog("Workers started");
|
|
||||||
}
|
|
||||||
|
|
||||||
Recorder::~Recorder()
|
|
||||||
{
|
|
||||||
wantsExit = true;
|
|
||||||
serverThread.join();
|
|
||||||
recordingThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::setData(websocket::data &data)
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
std::memcpy(&this->toSend, &data, sizeof(websocket::data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::handleMessages()
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
if (!messageQueue().empty()) {
|
|
||||||
auto op = std::move(messageQueue().front());
|
|
||||||
messageQueue().pop();
|
|
||||||
op();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::serverWorker()
|
|
||||||
{
|
|
||||||
utilities::setThreadName("GAServerWorker");
|
|
||||||
|
|
||||||
while (!wantsExit) {
|
|
||||||
struct websocket::data copy;
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
std::memcpy(©, &toSend, sizeof(websocket::data));
|
|
||||||
}
|
|
||||||
|
|
||||||
connector->sendData(copy);
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
|
||||||
}
|
|
||||||
|
|
||||||
toLog("Server thread stopped");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::recordingWorker()
|
|
||||||
{
|
|
||||||
utilities::setThreadName("GARecordingWorker");
|
|
||||||
|
|
||||||
file::recording::Recording path;
|
|
||||||
file::recording::RecordingEntry lastPath;
|
|
||||||
std::uint32_t segment = 0;
|
|
||||||
|
|
||||||
while (!wantsExit) {
|
|
||||||
struct websocket::data copy;
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
std::memcpy(©, &toSend, sizeof(websocket::data));
|
|
||||||
}
|
|
||||||
|
|
||||||
file::recording::RecordingEntry currentPath(
|
|
||||||
segment,
|
|
||||||
static_cast<std::uint16_t>(copy.alt),
|
|
||||||
static_cast<std::uint16_t>(copy.gs),
|
|
||||||
{copy.lat, copy.lon});
|
|
||||||
|
|
||||||
if (strcmp(copy.path, "") != 0 && copy.pause &&
|
|
||||||
lastPath != currentPath) {
|
|
||||||
path.addEntry(currentPath);
|
|
||||||
lastPath = currentPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
segment++;
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
path.toFile("flight.rec");
|
|
||||||
toLog("Recording thread stopped");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::test() const
|
|
||||||
{
|
|
||||||
#ifndef MSFS
|
|
||||||
this->toLog("Readback test of sim database using EDDF");
|
|
||||||
auto ap = (*this->database)["EDDF"];
|
|
||||||
for (const auto &it : ap.first) {
|
|
||||||
this->toLog(" " + it.to_string());
|
|
||||||
}
|
|
||||||
for (const auto &it : ap.second) {
|
|
||||||
this->toLog(" " + it.to_string());
|
|
||||||
}
|
|
||||||
this->toLog("Readback test of sim database using XXXX");
|
|
||||||
auto ap2 = (*database)["XXXX"];
|
|
||||||
ap2.first.size() == 0 ? this->toLog(" SUCCESS") : this->toLog(" ERROR");
|
|
||||||
#endif
|
|
||||||
toLog("Logbook Test");
|
|
||||||
germanairlinesva::file::logbook::Logbook logbook;
|
|
||||||
logbook.addEntry("08.09.2022",
|
|
||||||
"F",
|
|
||||||
"1000",
|
|
||||||
"L049",
|
|
||||||
"D-ALFA",
|
|
||||||
"John F. Kennedy International Aiport / EDDF",
|
|
||||||
"A1",
|
|
||||||
"14L",
|
|
||||||
"Gander International Airport / CYQX",
|
|
||||||
"10",
|
|
||||||
"03",
|
|
||||||
"10:00",
|
|
||||||
"10:20",
|
|
||||||
"13:20",
|
|
||||||
"13:30",
|
|
||||||
210.5,
|
|
||||||
20.1,
|
|
||||||
5012.4156,
|
|
||||||
8.87,
|
|
||||||
5041.3856,
|
|
||||||
7.1,
|
|
||||||
971.14,
|
|
||||||
2.41,
|
|
||||||
980.65,
|
|
||||||
-165.23,
|
|
||||||
1,
|
|
||||||
1.2012,
|
|
||||||
"2022-09-08_VGA1000",
|
|
||||||
5.5,
|
|
||||||
1);
|
|
||||||
logbook.toFile();
|
|
||||||
}
|
|
||||||
} // namespace recorder
|
|
||||||
} // namespace gaconnector
|
|
||||||
} // namespace germanairlinesva
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_UTILITIES_CONSTANTS_H
|
#ifndef GERMANAIRLINESVA_GACONNECTOR_CONSTANTS_H
|
||||||
#define GERMANAIRLINESVA_UTILITIES_CONSTANTS_H
|
#define GERMANAIRLINESVA_GACONNECTOR_CONSTANTS_H
|
||||||
|
|
||||||
#ifdef XP
|
#ifdef XP
|
||||||
#define BASE_DIRECTORY "Resources/plugins/GAConnector/"
|
#define BASE_DIRECTORY "Resources/plugins/GAConnector/"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_UTILITIES_GEODATA_H
|
#ifndef GERMANAIRLINESVA_GACONNECTOR_GEODATA_H
|
||||||
#define GERMANAIRLINESVA_UTILITIES_GEODATA_H
|
#define GERMANAIRLINESVA_GACONNECTOR_GEODATA_H
|
||||||
|
|
||||||
#define M_PI 3.14159265358979323846
|
#define M_PI 3.14159265358979323846
|
||||||
#define BUFSIZE 1024
|
#define BUFSIZE 1024
|
||||||
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
namespace utilities
|
namespace geodata
|
||||||
{
|
{
|
||||||
namespace geodata
|
|
||||||
{
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct point {
|
struct point {
|
||||||
@ -93,8 +91,7 @@ namespace utilities
|
|||||||
lon2r = toRadians(toLongitude);
|
lon2r = toRadians(toLongitude);
|
||||||
u = sin((lat2r - lat1r) / 2);
|
u = sin((lat2r - lat1r) / 2);
|
||||||
v = sin((lon2r - lon1r) / 2);
|
v = sin((lon2r - lon1r) / 2);
|
||||||
return 2.0 * EARTH_M *
|
return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
|
||||||
asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input in degrees, Output in metres
|
// Input in degrees, Output in metres
|
||||||
@ -107,8 +104,7 @@ namespace utilities
|
|||||||
lon2r = toRadians(to.longitude);
|
lon2r = toRadians(to.longitude);
|
||||||
u = sin((lat2r - lat1r) / 2);
|
u = sin((lat2r - lat1r) / 2);
|
||||||
v = sin((lon2r - lon1r) / 2);
|
v = sin((lon2r - lon1r) / 2);
|
||||||
return 2.0 * EARTH_M *
|
return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
|
||||||
asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input and Output in degrees
|
// Input and Output in degrees
|
||||||
@ -173,8 +169,7 @@ namespace utilities
|
|||||||
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
|
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
|
||||||
std::cos(coordinates.latitude),
|
std::cos(coordinates.latitude),
|
||||||
std::cos(distance / EARTH_M) -
|
std::cos(distance / EARTH_M) -
|
||||||
std::sin(coordinates.latitude) *
|
std::sin(coordinates.latitude) * std::sin(newLatitude));
|
||||||
std::sin(newLatitude));
|
|
||||||
|
|
||||||
return {toDegrees(newLatitude), toDegrees(newLongitude)};
|
return {toDegrees(newLatitude), toDegrees(newLongitude)};
|
||||||
}
|
}
|
||||||
@ -195,8 +190,7 @@ namespace utilities
|
|||||||
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
|
std::atan2(std::sin(r_bearing) * std::sin(distance / EARTH_M) *
|
||||||
std::cos(coordinates.latitude),
|
std::cos(coordinates.latitude),
|
||||||
std::cos(distance / EARTH_M) -
|
std::cos(distance / EARTH_M) -
|
||||||
std::sin(coordinates.latitude) *
|
std::sin(coordinates.latitude) * std::sin(newLatitude));
|
||||||
std::sin(newLatitude));
|
|
||||||
|
|
||||||
return {newLatitude, newLongitude};
|
return {newLatitude, newLongitude};
|
||||||
}
|
}
|
||||||
@ -207,8 +201,7 @@ namespace utilities
|
|||||||
double length,
|
double length,
|
||||||
double width)
|
double width)
|
||||||
{
|
{
|
||||||
struct point primaryCenter =
|
struct point primaryCenter = calculatePointDR(center, bearing, -length / 2);
|
||||||
calculatePointDR(center, bearing, -length / 2);
|
|
||||||
struct point secondaryCenter =
|
struct point secondaryCenter =
|
||||||
calculatePointDR(center, bearing, length / 2);
|
calculatePointDR(center, bearing, length / 2);
|
||||||
double offsetHeadingNorth =
|
double offsetHeadingNorth =
|
||||||
@ -244,8 +237,8 @@ namespace utilities
|
|||||||
|
|
||||||
return {primaryTop, secondaryTop, secondaryBottom, primaryBottom};
|
return {primaryTop, secondaryTop, secondaryBottom, primaryBottom};
|
||||||
}
|
}
|
||||||
} // namespace geodata
|
|
||||||
} // namespace utilities
|
} // namespace geodata
|
||||||
} // namespace germanairlinesva
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_UTILITIES_UTIL_H
|
#ifndef GERMANAIRLINESVA_GACONNECTOR_UTIL_H
|
||||||
#define GERMANAIRLINESVA_UTILITIES_UTIL_H
|
#define GERMANAIRLINESVA_GACONNECTOR_UTIL_H
|
||||||
|
|
||||||
#define BUFSIZE 1024
|
#define BUFSIZE 1024
|
||||||
#define MD5LEN 16
|
#define MD5LEN 16
|
||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
namespace utilities
|
namespace util
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline std::vector<T>
|
static inline std::vector<T>
|
||||||
@ -294,7 +294,7 @@ namespace utilities
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} // namespace utilities
|
} // namespace util
|
||||||
} // namespace germanairlinesva
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_WEBSOCKET_TYPES_H
|
#ifndef GERMANAIRLINESVA_GACONNECTOR_SOCKET_TYPES_H
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_WEBSOCKET_TYPES_H
|
#define GERMANAIRLINESVA_GACONNECTOR_SOCKET_TYPES_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
namespace gaconnector
|
namespace websocket
|
||||||
{
|
{
|
||||||
namespace websocket
|
|
||||||
{
|
|
||||||
#pragma pack(push) /* push current alignment to stack */
|
#pragma pack(push) /* push current alignment to stack */
|
||||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||||
|
|
||||||
@ -34,17 +32,7 @@ namespace gaconnector
|
|||||||
float totalWeightKg = 0;
|
float totalWeightKg = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum commands {
|
enum commands { PROCESS, SAVE, LOAD, TEXT, TIME, UNPAUSE, PAUSE, PORT, END };
|
||||||
PROCESS,
|
|
||||||
SAVE,
|
|
||||||
LOAD,
|
|
||||||
TEXT,
|
|
||||||
TIME,
|
|
||||||
UNPAUSE,
|
|
||||||
PAUSE,
|
|
||||||
PORT,
|
|
||||||
END
|
|
||||||
};
|
|
||||||
|
|
||||||
struct command_base {
|
struct command_base {
|
||||||
enum commands type;
|
enum commands type;
|
||||||
@ -57,8 +45,7 @@ namespace gaconnector
|
|||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop) /* restore original alignment from stack */
|
#pragma pack(pop) /* restore original alignment from stack */
|
||||||
} // namespace websocket
|
} // namespace websocket
|
||||||
} // namespace gaconnector
|
|
||||||
} // namespace germanairlinesva
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_WEBSOCKET_WEBSOCKET_H
|
#ifndef GERMANAIRLINESVA_GACONNECTOR_WEBSOCKET_H
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_WEBSOCKET_WEBSOCKET_H
|
#define GERMANAIRLINESVA_GACONNECTOR_WEBSOCKET_H
|
||||||
|
|
||||||
#define BUFSIZE 1024
|
#define BUFSIZE 1024
|
||||||
#define MD5LEN 16
|
#define MD5LEN 16
|
||||||
@ -20,10 +20,8 @@
|
|||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
namespace gaconnector
|
namespace websocket
|
||||||
{
|
{
|
||||||
namespace websocket
|
|
||||||
{
|
|
||||||
class Websocket
|
class Websocket
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -42,8 +40,7 @@ namespace gaconnector
|
|||||||
void onClientMessageCallback(const ix::WebSocketMessagePtr &msg);
|
void onClientMessageCallback(const ix::WebSocketMessagePtr &msg);
|
||||||
void sendData(data &d);
|
void sendData(data &d);
|
||||||
};
|
};
|
||||||
} // namespace websocket
|
} // namespace websocket
|
||||||
} // namespace gaconnector
|
|
||||||
} // namespace germanairlinesva
|
} // namespace germanairlinesva
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -2,10 +2,8 @@
|
|||||||
|
|
||||||
namespace germanairlinesva
|
namespace germanairlinesva
|
||||||
{
|
{
|
||||||
namespace gaconnector
|
namespace websocket
|
||||||
{
|
{
|
||||||
namespace websocket
|
|
||||||
{
|
|
||||||
Websocket::Websocket(std::string host,
|
Websocket::Websocket(std::string host,
|
||||||
std::string user,
|
std::string user,
|
||||||
std::function<void(const std::string)> toLog)
|
std::function<void(const std::string)> toLog)
|
||||||
@ -90,8 +88,8 @@ namespace gaconnector
|
|||||||
{
|
{
|
||||||
if (strcmp(d.path, this->lastPath) != 0) {
|
if (strcmp(d.path, this->lastPath) != 0) {
|
||||||
strcpy(this->lastPath, d.path);
|
strcpy(this->lastPath, d.path);
|
||||||
if (utilities::generateMD5(d.path, this->lastHash, this->toLog)) {
|
if (util::generateMD5(d.path, this->lastHash, this->toLog)) {
|
||||||
strcpy(this->lastHash, "NO HASH");
|
strcpy(this->lastHash, "NOT SET");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +110,5 @@ namespace gaconnector
|
|||||||
this->webSocket->send(msg.str(), false);
|
this->webSocket->send(msg.str(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace websocket
|
} // namespace websocket
|
||||||
} // namespace gaconnector
|
|
||||||
} // namespace germanairlinesva
|
} // namespace germanairlinesva
|
||||||
@ -1,15 +1,12 @@
|
|||||||
file(GLOB socket CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/websocket/*.cpp)
|
file(GLOB socket CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/websocket/*.cpp)
|
||||||
file(GLOB recorder CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/recorder/*.cpp)
|
|
||||||
|
|
||||||
add_library(germanairlinesva_xplugin SHARED
|
add_library(germanairlinesva_xplugin SHARED
|
||||||
${socket}
|
${socket}
|
||||||
${recorder}
|
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(germanairlinesva_xplugin PRIVATE
|
target_include_directories(germanairlinesva_xplugin PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/file/include
|
${CMAKE_SOURCE_DIR}/file/include
|
||||||
${CMAKE_SOURCE_DIR}/recorder/include
|
|
||||||
${CMAKE_SOURCE_DIR}/simdata/include
|
${CMAKE_SOURCE_DIR}/simdata/include
|
||||||
${CMAKE_SOURCE_DIR}/websocket/include
|
${CMAKE_SOURCE_DIR}/websocket/include
|
||||||
${CMAKE_SOURCE_DIR}/utilities/include
|
${CMAKE_SOURCE_DIR}/utilities/include
|
||||||
|
|||||||
@ -1,13 +1,24 @@
|
|||||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAIN_H
|
#ifndef GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAIN_H
|
||||||
#define GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAIN_H
|
#define GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAIN_H
|
||||||
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "recorder.h"
|
#include "websocket.h"
|
||||||
|
|
||||||
|
#include "config/config.hpp"
|
||||||
|
#include "constants.h"
|
||||||
|
#include "logbook/logbook.hpp"
|
||||||
|
#include "recording/recording.hpp"
|
||||||
|
#include "simdata/simDatabase.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
#include "XPLM/XPLMDataAccess.h"
|
#include "XPLM/XPLMDataAccess.h"
|
||||||
#include "XPLM/XPLMGraphics.h"
|
#include "XPLM/XPLMGraphics.h"
|
||||||
|
|||||||
179
xplugin/main.cpp
179
xplugin/main.cpp
@ -1,5 +1,20 @@
|
|||||||
#include "include/main.h"
|
#include "include/main.h"
|
||||||
|
|
||||||
|
std::mutex mutex;
|
||||||
|
std::queue<std::function<void()>> &messageQueue()
|
||||||
|
{
|
||||||
|
static std::queue<std::function<void()>> _messageQueue;
|
||||||
|
return _messageQueue;
|
||||||
|
}
|
||||||
|
std::thread serverThread;
|
||||||
|
std::thread recordingThread;
|
||||||
|
std::atomic<bool> wantsExit;
|
||||||
|
|
||||||
|
std::shared_ptr<germanairlinesva::file::config::Config> configuration;
|
||||||
|
std::unique_ptr<germanairlinesva::file::simdata::SimDatabase> database;
|
||||||
|
std::unique_ptr<germanairlinesva::websocket::Websocket> connector;
|
||||||
|
int xplaneVersion;
|
||||||
|
|
||||||
/* Datarefs */
|
/* Datarefs */
|
||||||
XPLMDataRef pauseIndicator;
|
XPLMDataRef pauseIndicator;
|
||||||
XPLMDataRef parkingBrake;
|
XPLMDataRef parkingBrake;
|
||||||
@ -28,21 +43,22 @@ XPLMDataRef pitch;
|
|||||||
XPLMDataRef roll;
|
XPLMDataRef roll;
|
||||||
XPLMDataRef quaternion;
|
XPLMDataRef quaternion;
|
||||||
|
|
||||||
struct germanairlinesva::gaconnector::websocket::data toSend;
|
struct germanairlinesva::websocket::data toSend;
|
||||||
germanairlinesva::gaconnector::recorder::Recorder *recorder;
|
germanairlinesva::file::recording::Recording p;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callbacks
|
* Callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
||||||
{
|
{
|
||||||
int xplaneVersion;
|
|
||||||
|
|
||||||
XPLMEnableFeature("XPLM_USE_NATIVE_PATHS", 1);
|
XPLMEnableFeature("XPLM_USE_NATIVE_PATHS", 1);
|
||||||
XPLMGetVersions(&xplaneVersion, NULL, NULL);
|
XPLMGetVersions(&xplaneVersion, NULL, NULL);
|
||||||
|
|
||||||
toLog("Plugin using X-Plane Version " + std::to_string(xplaneVersion));
|
toLog("Plugin using X-Plane Version " + std::to_string(xplaneVersion));
|
||||||
|
|
||||||
|
wantsExit.store(false);
|
||||||
|
|
||||||
/* First we must fill in the passed-in buffers to describe our
|
/* First we must fill in the passed-in buffers to describe our
|
||||||
* plugin to the plugin-system. */
|
* plugin to the plugin-system. */
|
||||||
|
|
||||||
@ -95,10 +111,75 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
|||||||
roll = XPLMFindDataRef("sim/flightmodel/position/phi"); // FLOAT
|
roll = XPLMFindDataRef("sim/flightmodel/position/phi"); // FLOAT
|
||||||
quaternion = XPLMFindDataRef("sim/flightmodel/position/q"); // FLOAT[4]
|
quaternion = XPLMFindDataRef("sim/flightmodel/position/q"); // FLOAT[4]
|
||||||
|
|
||||||
// Recorder
|
configuration = std::make_unique<germanairlinesva::file::config::Config>();
|
||||||
recorder =
|
toLog("Config loaded");
|
||||||
new germanairlinesva::gaconnector::recorder::Recorder(xplaneVersion,
|
|
||||||
|
connector = std::make_unique<germanairlinesva::websocket::Websocket>(
|
||||||
|
"wss://ws.hofmannnet.myhome-server.de:8000",
|
||||||
|
configuration->getUser(),
|
||||||
toLog);
|
toLog);
|
||||||
|
toLog("WebSocket started");
|
||||||
|
|
||||||
|
char hash[2 * MD5LEN + 1] = "";
|
||||||
|
if (germanairlinesva::util::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) ==
|
||||||
|
0) {
|
||||||
|
database = std::make_unique<germanairlinesva::file::simdata::SimDatabase>(
|
||||||
|
xplaneVersion,
|
||||||
|
hash,
|
||||||
|
configuration,
|
||||||
|
toLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
toLog("Readback test of sim database using EDDF");
|
||||||
|
auto ap = (*database)["EDDF"];
|
||||||
|
for (const auto &it : ap.first) {
|
||||||
|
toLog(" " + it.to_string());
|
||||||
|
}
|
||||||
|
for (const auto &it : ap.second) {
|
||||||
|
toLog(" " + it.to_string());
|
||||||
|
}
|
||||||
|
toLog("Readback test of sim database using XXXX");
|
||||||
|
auto ap2 = (*database)["XXXX"];
|
||||||
|
ap2.first.size() == 0 ? toLog(" SUCCESS") : toLog(" ERROR");
|
||||||
|
|
||||||
|
// Thread for sending data to websocket
|
||||||
|
serverThread = std::thread(&serverWorker);
|
||||||
|
recordingThread = std::thread(&recordingWorker);
|
||||||
|
toLog("Workers started");
|
||||||
|
|
||||||
|
toLog("Logbook Test");
|
||||||
|
germanairlinesva::file::logbook::Logbook logbook;
|
||||||
|
logbook.addEntry("08.09.2022",
|
||||||
|
"F",
|
||||||
|
"1000",
|
||||||
|
"L049",
|
||||||
|
"D-ALFA",
|
||||||
|
"John F. Kennedy International Aiport / EDDF",
|
||||||
|
"A1",
|
||||||
|
"14L",
|
||||||
|
"Gander International Airport / CYQX",
|
||||||
|
"10",
|
||||||
|
"03",
|
||||||
|
"10:00",
|
||||||
|
"10:20",
|
||||||
|
"13:20",
|
||||||
|
"13:30",
|
||||||
|
210.5,
|
||||||
|
20.1,
|
||||||
|
5012.4156,
|
||||||
|
8.87,
|
||||||
|
5041.3856,
|
||||||
|
7.1,
|
||||||
|
971.14,
|
||||||
|
2.41,
|
||||||
|
980.65,
|
||||||
|
-165.23,
|
||||||
|
1,
|
||||||
|
1.2012,
|
||||||
|
"2022-09-08_VGA1000",
|
||||||
|
5.5,
|
||||||
|
1);
|
||||||
|
logbook.toFile();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -107,9 +188,12 @@ PLUGIN_API void XPluginStop(void)
|
|||||||
{
|
{
|
||||||
/* Flight Loop */
|
/* Flight Loop */
|
||||||
XPLMUnregisterFlightLoopCallback(flightLoop, nullptr);
|
XPLMUnregisterFlightLoopCallback(flightLoop, nullptr);
|
||||||
|
|
||||||
/* End threads */
|
/* End threads */
|
||||||
recorder->~Recorder();
|
wantsExit = true;
|
||||||
|
serverThread.join();
|
||||||
|
recordingThread.join();
|
||||||
|
|
||||||
|
p.toFile("flight.rec");
|
||||||
|
|
||||||
toLog("Plugin stopped");
|
toLog("Plugin stopped");
|
||||||
}
|
}
|
||||||
@ -130,9 +214,9 @@ PLUGIN_API void
|
|||||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||||
float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
||||||
{
|
{
|
||||||
std::memset(&toSend,
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
0,
|
|
||||||
sizeof(germanairlinesva::gaconnector::websocket::data));
|
std::memset(&toSend, 0, sizeof(germanairlinesva::websocket::data));
|
||||||
|
|
||||||
toSend.pause = XPLMGetDatai(pauseIndicator);
|
toSend.pause = XPLMGetDatai(pauseIndicator);
|
||||||
toSend.pBrake = XPLMGetDataf(parkingBrake);
|
toSend.pBrake = XPLMGetDataf(parkingBrake);
|
||||||
@ -158,14 +242,79 @@ float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
|||||||
toSend.payloadKg = XPLMGetDataf(payloadKgs);
|
toSend.payloadKg = XPLMGetDataf(payloadKgs);
|
||||||
toSend.totalWeightKg = XPLMGetDataf(totalWeightKgs);
|
toSend.totalWeightKg = XPLMGetDataf(totalWeightKgs);
|
||||||
|
|
||||||
recorder->setData(toSend);
|
if (!messageQueue().empty()) {
|
||||||
|
auto op = std::move(messageQueue().front());
|
||||||
recorder->handleMessages();
|
messageQueue().pop();
|
||||||
|
op();
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
void serverWorker()
|
||||||
|
{
|
||||||
|
germanairlinesva::util::setThreadName("GAServerWorker");
|
||||||
|
|
||||||
|
while (!wantsExit) {
|
||||||
|
struct germanairlinesva::websocket::data copy;
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
|
std::memcpy(©, &toSend, sizeof(germanairlinesva::websocket::data));
|
||||||
|
}
|
||||||
|
|
||||||
|
connector->sendData(copy);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||||
|
}
|
||||||
|
|
||||||
|
toLog("Server thread stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
void recordingWorker()
|
||||||
|
{
|
||||||
|
germanairlinesva::util::setThreadName("GARecordingWorker");
|
||||||
|
|
||||||
|
germanairlinesva::file::recording::RecordingEntry lastPath;
|
||||||
|
std::uint32_t segment = 0;
|
||||||
|
|
||||||
|
auto ap = (*database)["EDDF"];
|
||||||
|
auto rwys = ap.second;
|
||||||
|
|
||||||
|
while (!wantsExit) {
|
||||||
|
struct germanairlinesva::websocket::data copy;
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
|
std::memcpy(©, &toSend, sizeof(germanairlinesva::websocket::data));
|
||||||
|
}
|
||||||
|
|
||||||
|
germanairlinesva::file::recording::RecordingEntry currentPath(
|
||||||
|
segment,
|
||||||
|
static_cast<std::uint16_t>(copy.alt),
|
||||||
|
static_cast<std::uint16_t>(copy.gs),
|
||||||
|
{copy.lat, copy.lon});
|
||||||
|
|
||||||
|
if (strcmp(copy.path, "") != 0 && copy.pause && lastPath != currentPath) {
|
||||||
|
p.addEntry(currentPath);
|
||||||
|
lastPath = currentPath;
|
||||||
|
|
||||||
|
for (const auto &it : rwys) {
|
||||||
|
if (it.containsPoint({copy.lat, copy.lon})) {
|
||||||
|
toLog("On Runway: " + it.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
segment++;
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
toLog("Recording thread stopped");
|
||||||
|
}
|
||||||
|
|
||||||
void toLog(const std::string &message)
|
void toLog(const std::string &message)
|
||||||
{
|
{
|
||||||
std::time_t utc = std::time(nullptr);
|
std::time_t utc = std::time(nullptr);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user