Simulator database for X-Plane
This commit is contained in:
@@ -7,10 +7,13 @@
|
||||
|
||||
file(GLOB ixwebsocket CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/ixwebsocket/*.cpp)
|
||||
file(GLOB websocket CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/websocket/*.cpp)
|
||||
file(GLOB file CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/file/*.cpp)
|
||||
|
||||
add_library(germanairlinesva_xplugin SHARED
|
||||
${ixwebsocket}
|
||||
${websocket}
|
||||
${file}
|
||||
makeRwysXP.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
@@ -19,6 +22,7 @@ target_include_directories(germanairlinesva_xplugin PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/websocket/include
|
||||
${CMAKE_SOURCE_DIR}/XPSDK/CHeaders
|
||||
${CMAKE_SOURCE_DIR}/nlohmann
|
||||
${CMAKE_SOURCE_DIR}/file/include
|
||||
)
|
||||
|
||||
set_target_properties(germanairlinesva_xplugin PROPERTIES
|
||||
@@ -28,9 +32,11 @@ set_target_properties(germanairlinesva_xplugin PROPERTIES
|
||||
target_compile_definitions(germanairlinesva_xplugin PRIVATE
|
||||
XPLM200
|
||||
XPLM210
|
||||
_USE_MATH_DEFINES
|
||||
)
|
||||
target_compile_options(germanairlinesva_xplugin PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-pedantic
|
||||
-fvisibility=hidden
|
||||
)
|
||||
|
||||
+5
-10
@@ -1,13 +1,5 @@
|
||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_MAIN_H
|
||||
#define GERMANAIRLINESVA_GACONNECTOR_MAIN_H
|
||||
|
||||
#ifdef IBM
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 1024
|
||||
#define MD5LEN 16
|
||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAIN_H
|
||||
#define GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAIN_H
|
||||
|
||||
#include "XPLM/XPLMDataAccess.h"
|
||||
#include "XPLM/XPLMGraphics.h"
|
||||
@@ -16,6 +8,9 @@
|
||||
#include "XPLM/XPLMProcessing.h"
|
||||
#include "XPLM/XPLMUtilities.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "makeRwysXP.h"
|
||||
#include "simulatorDatabase.h"
|
||||
#include "websocket.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAKERWYSXP_H
|
||||
#define GERMANAIRLINESVA_GACONNECTOR_XPLUGIN_MAKERWYSXP_H
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "gate.h"
|
||||
#include "runway.h"
|
||||
#include "stringExtensions.h"
|
||||
#include "util.h"
|
||||
|
||||
int scan(const char *defaultFile,
|
||||
const char *sceneryPack,
|
||||
const char *logFile,
|
||||
std::map<std::string,
|
||||
std::pair<std::vector<Gate>, std::vector<Runway>>> &airports);
|
||||
|
||||
void makeAirport(
|
||||
const std::string &kind,
|
||||
std::ifstream *infile,
|
||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||
*airports,
|
||||
std::ofstream *logfile);
|
||||
void makeGate15(std::vector<Gate> *gates, std::vector<std::string> fields);
|
||||
void makeRunway(std::vector<Runway> *runways, std::vector<std::string> fields);
|
||||
void makeGate1300(std::vector<Gate> *gates, std::vector<std::string> fields);
|
||||
|
||||
#endif
|
||||
+45
-5
@@ -9,6 +9,8 @@ std::queue<std::function<void()>> &messageQueue()
|
||||
std::thread serverThread;
|
||||
std::atomic<bool> wantsExit;
|
||||
|
||||
std::map<std::string, std::string> configuration;
|
||||
|
||||
websocket *connector;
|
||||
|
||||
/* Datarefs */
|
||||
@@ -54,9 +56,9 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
||||
/* First we must fill in the passed-in buffers to describe our
|
||||
* plugin to the plugin-system. */
|
||||
|
||||
strcpy(outName, "WebSocketTestXPlane");
|
||||
strcpy(outSig, "de.german-airlines.WebSocketTestXPlane");
|
||||
strcpy(outDesc, "WebSocketTestXPlane");
|
||||
strcpy(outName, "GAConnector");
|
||||
strcpy(outSig, "de.german-airlines.GAConnector");
|
||||
strcpy(outDesc, "GAConnector");
|
||||
|
||||
/* Flight Loop */
|
||||
XPLMRegisterFlightLoopCallback(flightLoop, -1, nullptr);
|
||||
@@ -111,11 +113,41 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
|
||||
toLog(e.what());
|
||||
return 0;
|
||||
}
|
||||
toLog("WebSocket started");
|
||||
|
||||
configuration =
|
||||
config::readConfig("Resources/plugins/GAConnector/config.cfg");
|
||||
toLog("Config loaded");
|
||||
|
||||
char hash[2 * MD5LEN + 1] = "";
|
||||
if (util::generateMD5("Custom Scenery/scenery_packs.ini", hash, toLog) ==
|
||||
0) {
|
||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||
airports;
|
||||
|
||||
if (strcmp(configuration["scenery"].c_str(), hash) != 0) {
|
||||
scan("Resources/default scenery/default apt dat/Earth nav "
|
||||
"data/apt.dat",
|
||||
"Custom Scenery/scenery_packs.ini",
|
||||
"Resources/plugins/GAConnector/log.txt",
|
||||
airports);
|
||||
simulatorDatabase::toFile(airports,
|
||||
"Resources/plugins/GAConnector/sim.bin");
|
||||
|
||||
configuration["scenery"] = hash;
|
||||
config::writeConfig(configuration,
|
||||
"Resources/plugins/GAConnector/config.cfg");
|
||||
toLog("Sim Database updated");
|
||||
} else {
|
||||
airports = simulatorDatabase::fromFile(
|
||||
"Resources/plugins/GAConnector/sim.bin");
|
||||
toLog("Sim Database loaded");
|
||||
}
|
||||
}
|
||||
|
||||
// Thread for sending data to web socket
|
||||
serverThread = std::thread(&serverWorker);
|
||||
|
||||
toLog("WebSocketTestXPlane initialized and ready");
|
||||
toLog("Worker started");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -134,11 +166,16 @@ PLUGIN_API void XPluginDisable(void) {}
|
||||
|
||||
PLUGIN_API int XPluginEnable(void) { return 1; }
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
PLUGIN_API void
|
||||
XPluginReceiveMessage(XPLMPluginID inFromWho, long inMessage, void *inParam)
|
||||
{
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
@@ -177,9 +214,12 @@ float flightLoop(float elapsedMe, float elapsedSim, int counter, void *refcon)
|
||||
|
||||
return -1;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
void serverWorker()
|
||||
{
|
||||
util::setThreadName("GAWorker");
|
||||
|
||||
while (!wantsExit) {
|
||||
data copy;
|
||||
{
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
#include "include/makeRwysXP.h"
|
||||
|
||||
int scan(const char *defaultFile,
|
||||
const char *sceneryPack,
|
||||
const char *logFile,
|
||||
std::map<std::string,
|
||||
std::pair<std::vector<Gate>, std::vector<Runway>>> &airports)
|
||||
{
|
||||
std::ifstream base(defaultFile);
|
||||
if (!base.good()) {
|
||||
return 1;
|
||||
}
|
||||
std::ifstream custom(sceneryPack);
|
||||
if (!custom.good()) {
|
||||
base.close();
|
||||
return 2;
|
||||
}
|
||||
std::ofstream logfile(logFile, std::ios::out | std::ios::trunc);
|
||||
if (!logfile.good()) {
|
||||
base.close();
|
||||
custom.close();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Default
|
||||
logfile << "<FILE> " << defaultFile << std::endl;
|
||||
makeAirport("DEFAULT", &base, &airports, &logfile);
|
||||
base.close();
|
||||
|
||||
std::string line;
|
||||
size_t pos;
|
||||
std::vector<std::string> packs;
|
||||
while (std::getline(custom, line)) {
|
||||
if ((pos = line.find("SCENERY_PACK")) != std::string::npos) {
|
||||
std::string path =
|
||||
rtrim_copy(line.substr(pos + 13)) + "Earth nav data/apt.dat";
|
||||
packs.push_back(path);
|
||||
}
|
||||
}
|
||||
std::reverse(packs.begin(), packs.end());
|
||||
|
||||
for (std::string const &path : packs) {
|
||||
std::ifstream pack(path);
|
||||
if (pack.good()) {
|
||||
logfile << "<FILE> " << path << std::endl;
|
||||
makeAirport("CUSTOM", &pack, &airports, &logfile);
|
||||
pack.close();
|
||||
} else {
|
||||
pack.close();
|
||||
logfile << "<STATUS>"
|
||||
<< "Could not find " << path << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
custom.close();
|
||||
logfile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void makeAirport(
|
||||
const std::string &kind,
|
||||
std::ifstream *infile,
|
||||
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
|
||||
*airports,
|
||||
std::ofstream *logfile)
|
||||
{
|
||||
std::string line;
|
||||
std::string *currentIcao = nullptr;
|
||||
std::vector<Gate> tmpGates;
|
||||
std::vector<Runway> tmpRunways;
|
||||
|
||||
int apCount = 0;
|
||||
int validCount = 0;
|
||||
|
||||
while (std::getline(*infile, line)) {
|
||||
std::vector<std::string> fields = split(line, ' ');
|
||||
fields = util::select_T<std::string>(fields, [](const std::string &s) {
|
||||
return s.length() > 0;
|
||||
});
|
||||
|
||||
if (fields.empty())
|
||||
continue;
|
||||
if (fields[0] == "1") {
|
||||
// Write to file if ICAO is valid, and we have gates and runways
|
||||
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
||||
!tmpGates.empty()) {
|
||||
(*airports)[*currentIcao] = {tmpGates, tmpRunways};
|
||||
validCount += 1;
|
||||
*logfile << "\t<STATUS> " << *currentIcao << " committed"
|
||||
<< std::endl;
|
||||
} else if (currentIcao != nullptr) {
|
||||
*logfile << "\t<STATUS> " << *currentIcao
|
||||
<< " had no gates or runways" << std::endl;
|
||||
}
|
||||
tmpGates = std::vector<Gate>();
|
||||
tmpRunways = std::vector<Runway>();
|
||||
currentIcao = new std::string(fields[4]);
|
||||
apCount += 1;
|
||||
*logfile << "\t<" << kind << "> " << line << std::endl;
|
||||
} else if (currentIcao != nullptr && fields[0] == "15") {
|
||||
makeGate15(&tmpGates, fields);
|
||||
*logfile << "\t\t<GATE OLD> " << line << std::endl;
|
||||
} else if (fields[0] == "16" || fields[0] == "17") {
|
||||
// Write to file if ICAO is valid, and we have gates and runways
|
||||
if (currentIcao != nullptr && !tmpRunways.empty() &&
|
||||
!tmpGates.empty()) {
|
||||
(*airports)[*currentIcao] = {tmpGates, tmpRunways};
|
||||
validCount += 1;
|
||||
*logfile << "\t<STATUS> " << *currentIcao << " committed"
|
||||
<< std::endl;
|
||||
} else if (currentIcao != nullptr) {
|
||||
*logfile << "\t<STATUS> " << *currentIcao
|
||||
<< " had no gates or runways" << std::endl;
|
||||
}
|
||||
tmpGates = std::vector<Gate>();
|
||||
tmpRunways = std::vector<Runway>();
|
||||
currentIcao = nullptr;
|
||||
*logfile << "\t<" << kind << " SKIPPED> " << line << std::endl;
|
||||
} else if (currentIcao != nullptr && fields[0] == "100") {
|
||||
makeRunway(&tmpRunways, fields);
|
||||
*logfile << "\t\t<RUNWAY> " << line << std::endl;
|
||||
} else if (currentIcao != nullptr && fields[0] == "1300") {
|
||||
makeGate1300(&tmpGates, fields);
|
||||
*logfile << "\t\t<GATE> " << line << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) {
|
||||
(*airports)[*currentIcao] = {tmpGates, tmpRunways};
|
||||
validCount += 1;
|
||||
*logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
|
||||
}
|
||||
*logfile << "<STATUS> " << apCount << " airports found, of which "
|
||||
<< validCount << " are valid" << std::endl;
|
||||
}
|
||||
|
||||
void makeGate15(std::vector<Gate> *gates, std::vector<std::string> fields)
|
||||
{
|
||||
std::string gateName;
|
||||
for (size_t j = 4; j < fields.size() - 1; j++) {
|
||||
gateName += fields[j] + " ";
|
||||
}
|
||||
gateName += fields.back();
|
||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||
|
||||
gates->push_back(
|
||||
Gate{gateName, std::stod(fields[1]), std::stod(fields[2])});
|
||||
}
|
||||
|
||||
void makeRunway(std::vector<Runway> *runways, std::vector<std::string> fields)
|
||||
{
|
||||
runways->push_back(Runway{fields[8],
|
||||
std::stod(fields[9]),
|
||||
std::stod(fields[10]),
|
||||
std::stod(fields[18]),
|
||||
std::stod(fields[19]),
|
||||
std::stod(fields[1])});
|
||||
runways->push_back(Runway{fields[17],
|
||||
std::stod(fields[18]),
|
||||
std::stod(fields[19]),
|
||||
std::stod(fields[9]),
|
||||
std::stod(fields[10]),
|
||||
std::stod(fields[1])});
|
||||
}
|
||||
|
||||
void makeGate1300(std::vector<Gate> *gates, std::vector<std::string> fields)
|
||||
{
|
||||
std::string gateName;
|
||||
for (size_t j = 6; j < fields.size() - 1; j++) {
|
||||
gateName += fields[j] + " ";
|
||||
}
|
||||
gateName += fields.back();
|
||||
gateName = std::regex_replace(gateName, std::regex{","}, "0");
|
||||
|
||||
gates->push_back(
|
||||
Gate{gateName, std::stod(fields[1]), std::stod(fields[2])});
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma warning(suppress : 26440)
|
||||
BOOL APIENTRY DllMain(HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved)
|
||||
@@ -11,7 +10,6 @@ BOOL APIENTRY DllMain(HANDLE hModule,
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user