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

v1.3.2 #45

Merged
merged 6 commits into from
Apr 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)

PROJECT(vACDM VERSION "1.3.1")
PROJECT(vACDM VERSION "1.3.2")
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
SET(CMAKE_CXX_STANDARD 20)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
96 changes: 96 additions & 0 deletions src/core/CompileCommands.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include <algorithm>
#include <string>

#pragma warning(push, 0)
#include "EuroScopePlugIn.h"
#pragma warning(pop)

#include "core/DataManager.h"
#include "core/Server.h"
#include "log/Logger.h"
#include "utils/Number.h"
#include "utils/String.h"
#include "vACDM.h"

using namespace vacdm;
using namespace vacdm::logging;
using namespace vacdm::core;
using namespace vacdm::utils;

namespace vacdm {
bool vACDM::OnCompileCommand(const char *sCommandLine) {
std::string command(sCommandLine);

#pragma warning(push)
#pragma warning(disable : 4244)
std::transform(command.begin(), command.end(), command.begin(), ::toupper);
#pragma warning(pop)

// only handle commands containing ".vacdm"
if (0 != command.find(".VACDM")) return false;

// master command
if (std::string::npos != command.find("MASTER")) {
bool userIsConnected = this->GetConnectionType() != EuroScopePlugIn::CONNECTION_TYPE_NO;
bool userIsInSweatbox = this->GetConnectionType() == EuroScopePlugIn::CONNECTION_TYPE_SWEATBOX;
bool userIsObserver = std::string_view(this->ControllerMyself().GetCallsign()).ends_with("_OBS") == true ||
this->ControllerMyself().GetFacility() == 0;
bool serverAllowsObsAsMaster = com::Server::instance().getServerConfig().allowMasterAsObserver;
bool serverAllowsSweatboxAsMaster = com::Server::instance().getServerConfig().allowMasterInSweatbox;

std::string userIsNotEligibleMessage;

if (!userIsConnected) {
userIsNotEligibleMessage = "You are not logged in to the VATSIM network";
} else if (userIsObserver && !serverAllowsObsAsMaster) {
userIsNotEligibleMessage = "You are logged in as Observer and Server does not allow Observers to be Master";
} else if (userIsInSweatbox && !serverAllowsSweatboxAsMaster) {
userIsNotEligibleMessage =
"You are logged in on a Sweatbox Server and Server does not allow Sweatbox connections";
} else {
DisplayMessage("Executing vACDM as the MASTER");
Logger::instance().log(Logger::LogSender::vACDM, "Switched to MASTER", Logger::LogLevel::Info);
com::Server::instance().setMaster(true);

return true;
}

DisplayMessage("Cannot upgrade to Master");
DisplayMessage(userIsNotEligibleMessage);
return true;
} else if (std::string::npos != command.find("SLAVE")) {
DisplayMessage("Executing vACDM as the SLAVE");
Logger::instance().log(Logger::LogSender::vACDM, "Switched to SLAVE", Logger::LogLevel::Info);
com::Server::instance().setMaster(false);
return true;
} else if (std::string::npos != command.find("RELOAD")) {
this->reloadConfiguration();
return true;
} else if (std::string::npos != command.find("LOG")) {
if (std::string::npos != command.find("LOGLEVEL")) {
DisplayMessage(Logger::instance().handleLogLevelCommand(command));
} else {
DisplayMessage(Logger::instance().handleLogCommand(command));
}
return true;
} else if (std::string::npos != command.find("UPDATERATE")) {
const auto elements = vacdm::utils::String::splitString(command, " ");
if (elements.size() != 3) {
DisplayMessage("Usage: .vacdm UPDATERATE value");
return true;
}
if (false == isNumber(elements[2]) ||
std::stoi(elements[2]) < minUpdateCycleSeconds && std::stoi(elements[2]) > maxUpdateCycleSeconds) {
DisplayMessage("Usage: .vacdm UPDATERATE value");
DisplayMessage("Value must be number between " + std::to_string(minUpdateCycleSeconds) + " and " +
std::to_string(maxUpdateCycleSeconds));
return true;
}

DisplayMessage(DataManager::instance().setUpdateCycleSeconds(std::stoi(elements[2])));

return true;
}
return false;
}
} // namespace vacdm
29 changes: 16 additions & 13 deletions src/core/DataManager.cpp
Original file line number Diff line number Diff line change
@@ -347,9 +347,14 @@ void DataManager::setActiveAirports(const std::list<std::string> activeAirports)
}

void DataManager::queueFlightplanUpdate(EuroScopePlugIn::CFlightPlan flightplan) {
if (false == flightplan.IsValid()) return;
if (false == flightplan.IsValid() || nullptr == flightplan.GetFlightPlanData().GetPlanType() ||
nullptr == flightplan.GetFlightPlanData().GetOrigin())
return;

auto pilot = this->CFlightPlanToPilot(flightplan);

std::lock_guard guard(this->m_euroscopeUpdatesLock);
this->m_euroscopeFlightplanUpdates.push_back({std::chrono::utc_clock::now(), flightplan});
this->m_euroscopeFlightplanUpdates.push_back({std::chrono::utc_clock::now(), pilot});
}

void DataManager::consolidateWithBackend(std::map<std::string, std::array<types::Pilot, 3U>>& pilots) {
@@ -436,7 +441,7 @@ void DataManager::processEuroScopeUpdates(std::map<std::string, std::array<types
for (auto& update : flightplanUpdates) {
bool found = false;

auto pilot = DataManager::CFlightPlanToPilot(update.data);
const auto pilot = update.data;

// find pilot in list
for (auto& pair : pilots) {
@@ -461,20 +466,20 @@ void DataManager::consolidateFlightplanUpdates(std::list<EuroscopeFlightplanUpda
std::list<DataManager::EuroscopeFlightplanUpdate> resultList;

for (const auto& currentUpdate : inputList) {
auto& flightplan = currentUpdate.data;
auto pilot = currentUpdate.data;

// only handle updates for active airports
{
std::lock_guard guard(this->m_airportLock);
bool flightDepartsFromActiveAirport =
std::find(m_activeAirports.begin(), m_activeAirports.end(),
std::string(flightplan.GetFlightPlanData().GetOrigin())) != m_activeAirports.end();
bool flightDepartsFromActiveAirport = std::find(m_activeAirports.begin(), m_activeAirports.end(),
std::string(pilot.origin)) != m_activeAirports.end();
if (false == flightDepartsFromActiveAirport) continue;
}

// Check if the flight plan already exists in the result list
auto it = std::find_if(resultList.begin(), resultList.end(),
[&currentUpdate](const EuroscopeFlightplanUpdate& existingUpdate) {
return existingUpdate.data.GetCallsign() == currentUpdate.data.GetCallsign();
return existingUpdate.data.callsign == currentUpdate.data.callsign;
});

if (it != resultList.end()) {
@@ -484,20 +489,18 @@ void DataManager::consolidateFlightplanUpdates(std::list<EuroscopeFlightplanUpda
// Update with the newer data
*it = currentUpdate;
Logger::instance().log(Logger::LogSender::DataManager,
"Updated: " + std::string(currentUpdate.data.GetCallsign()),
Logger::LogLevel::Info);
"Updated: " + std::string(currentUpdate.data.callsign), Logger::LogLevel::Info);
} else {
// Existing data is already newer, no update needed
Logger::instance().log(Logger::LogSender::DataManager,
"Skipped old update for: " + std::string(currentUpdate.data.GetCallsign()),
"Skipped old update for: " + std::string(currentUpdate.data.callsign),
Logger::LogLevel::Info);
}
} else {
// Flight plan with the callsign doesn't exist, add it to the result list
resultList.push_back(currentUpdate);
Logger::instance().log(Logger::LogSender::DataManager,
"Update added: " + std::string(currentUpdate.data.GetCallsign()),
Logger::LogLevel::Info);
"Update added: " + std::string(currentUpdate.data.callsign), Logger::LogLevel::Info);
}
}

2 changes: 1 addition & 1 deletion src/core/DataManager.h
Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ class DataManager {

struct EuroscopeFlightplanUpdate {
std::chrono::utc_clock::time_point timeIssued;
EuroScopePlugIn::CFlightPlan data;
types::Pilot data;
};

std::mutex m_euroscopeUpdatesLock;
87 changes: 44 additions & 43 deletions src/core/TagFunctions.h
Original file line number Diff line number Diff line change
@@ -9,12 +9,13 @@
#include "types/Pilot.h"
#include "utils/Date.h"
#include "utils/Number.h"
#include "vACDM.h"

using namespace vacdm;
using namespace vacdm::core;
using namespace vacdm::com;

namespace vacdm::tagfunctions {
namespace vacdm {

enum itemFunction {
EXOT_MODIFY = 1,
@@ -39,34 +40,34 @@ enum itemFunction {
RESET_PILOT,
};

void RegisterTagItemFuntions(vACDM *plugin) {
plugin->RegisterTagItemFunction("Modify EXOT", EXOT_MODIFY);
plugin->RegisterTagItemFunction("TOBT now", TOBT_NOW);
plugin->RegisterTagItemFunction("Set TOBT", TOBT_MANUAL);
plugin->RegisterTagItemFunction("TOBT confirm", TOBT_CONFIRM);
plugin->RegisterTagItemFunction("Tobt menu", TOBT_MENU);
plugin->RegisterTagItemFunction("ASAT now", ASAT_NOW);
plugin->RegisterTagItemFunction("ASAT now and startup state", ASAT_NOW_AND_STARTUP);
plugin->RegisterTagItemFunction("Startup Request", STARTUP_REQUEST);
plugin->RegisterTagItemFunction("Request Offblock", OFFBLOCK_REQUEST);
plugin->RegisterTagItemFunction("Set AOBT and Groundstate", AOBT_NOW_AND_STATE);
void vACDM::RegisterTagItemFuntions() {
RegisterTagItemFunction("Modify EXOT", EXOT_MODIFY);
RegisterTagItemFunction("TOBT now", TOBT_NOW);
RegisterTagItemFunction("Set TOBT", TOBT_MANUAL);
RegisterTagItemFunction("TOBT confirm", TOBT_CONFIRM);
RegisterTagItemFunction("Tobt menu", TOBT_MENU);
RegisterTagItemFunction("ASAT now", ASAT_NOW);
RegisterTagItemFunction("ASAT now and startup state", ASAT_NOW_AND_STARTUP);
RegisterTagItemFunction("Startup Request", STARTUP_REQUEST);
RegisterTagItemFunction("Request Offblock", OFFBLOCK_REQUEST);
RegisterTagItemFunction("Set AOBT and Groundstate", AOBT_NOW_AND_STATE);
// Reset Functions
plugin->RegisterTagItemFunction("Reset TOBT", RESET_TOBT);
plugin->RegisterTagItemFunction("Reset ASAT", RESET_ASAT);
plugin->RegisterTagItemFunction("Reset confirmed TOBT", RESET_TOBT_CONFIRM);
plugin->RegisterTagItemFunction("Reset Offblock Request", RESET_AORT);
plugin->RegisterTagItemFunction("Reset AOBT", RESET_AOBT_AND_STATE);
plugin->RegisterTagItemFunction("Reset Menu", RESET_MENU);
plugin->RegisterTagItemFunction("Reset pilot", RESET_PILOT);
RegisterTagItemFunction("Reset TOBT", RESET_TOBT);
RegisterTagItemFunction("Reset ASAT", RESET_ASAT);
RegisterTagItemFunction("Reset confirmed TOBT", RESET_TOBT_CONFIRM);
RegisterTagItemFunction("Reset Offblock Request", RESET_AORT);
RegisterTagItemFunction("Reset AOBT", RESET_AOBT_AND_STATE);
RegisterTagItemFunction("Reset Menu", RESET_MENU);
RegisterTagItemFunction("Reset pilot", RESET_PILOT);
}

void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, POINT pt, RECT area) {
void vACDM::OnFunctionCall(int functionId, const char *itemString, POINT pt, RECT area) {
std::ignore = pt;

// do not handle functions if client is not master
if (false == Server::instance().getMaster()) return;

auto flightplan = plugin->FlightPlanSelectASEL();
auto flightplan = FlightPlanSelectASEL();
std::string callsign(flightplan.GetCallsign());

if (false == DataManager::instance().checkPilotExists(callsign)) return;
@@ -75,7 +76,7 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO

switch (static_cast<itemFunction>(functionId)) {
case EXOT_MODIFY:
plugin->OpenPopupEdit(area, static_cast<int>(itemFunction::EXOT_NEW_VALUE), itemString);
OpenPopupEdit(area, static_cast<int>(itemFunction::EXOT_NEW_VALUE), itemString);
break;
case EXOT_NEW_VALUE:
if (true == isNumber(itemString)) {
@@ -90,7 +91,7 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
std::chrono::utc_clock::now());
break;
case TOBT_MANUAL:
plugin->OpenPopupEdit(area, TOBT_MANUAL_EDIT, "");
OpenPopupEdit(area, TOBT_MANUAL_EDIT, "");
break;
case TOBT_MANUAL_EDIT: {
std::string clock(itemString);
@@ -102,9 +103,9 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
pilot.callsign,
utils::Date::convertStringToTimePoint(clock));
else
plugin->DisplayMessage("Invalid time format. Expected: HHMM (24 hours)");
DisplayMessage("Invalid time format. Expected: HHMM (24 hours)");
} else if (clock.length() != 0) {
plugin->DisplayMessage("Invalid time format. Expected: HHMM (24 hours)");
DisplayMessage("Invalid time format. Expected: HHMM (24 hours)");
}
break;
}
@@ -128,7 +129,7 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
std::chrono::utc_clock::now());
}

plugin->SetGroundState(flightplan, "ST-UP");
SetGroundState(flightplan, "ST-UP");

break;
}
@@ -148,9 +149,9 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO

// set status depending on if the aircraft is positioned at a taxi-out position
if (pilot.taxizoneIsTaxiout) {
plugin->SetGroundState(flightplan, "TAXI");
SetGroundState(flightplan, "TAXI");
} else {
plugin->SetGroundState(flightplan, "PUSH");
SetGroundState(flightplan, "PUSH");
}
break;
}
@@ -165,10 +166,10 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
break;
}
case TOBT_MENU: {
plugin->OpenPopupList(area, "TOBT menu", 1);
plugin->AddPopupListElement("TOBT now", NULL, TOBT_NOW, false, 2, false, false);
plugin->AddPopupListElement("TOBT edit", NULL, TOBT_MANUAL, false, 2, false, false);
plugin->AddPopupListElement("TOBT confirm", NULL, TOBT_CONFIRM, false, 2, false, false);
OpenPopupList(area, "TOBT menu", 1);
AddPopupListElement("TOBT now", NULL, TOBT_NOW, false, 2, false, false);
AddPopupListElement("TOBT edit", NULL, TOBT_MANUAL, false, 2, false, false);
AddPopupListElement("TOBT confirm", NULL, TOBT_CONFIRM, false, 2, false, false);
break;
}
case RESET_TOBT:
@@ -178,7 +179,7 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
case RESET_ASAT:
DataManager::instance().handleTagFunction(DataManager::MessageType::ResetASAT, pilot.callsign,
types::defaultTime);
plugin->SetGroundState(flightplan, "NSTS");
SetGroundState(flightplan, "NSTS");
break;
case RESET_ASRT:
DataManager::instance().handleTagFunction(DataManager::MessageType::ResetASRT, pilot.callsign,
@@ -195,17 +196,17 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
case RESET_AOBT_AND_STATE:
DataManager::instance().handleTagFunction(DataManager::MessageType::ResetAOBT, pilot.callsign,
types::defaultTime);
plugin->SetGroundState(flightplan, "NSTS");
SetGroundState(flightplan, "NSTS");
break;
case RESET_MENU:
plugin->OpenPopupList(area, "RESET menu", 1);
plugin->AddPopupListElement("Reset TOBT", NULL, RESET_TOBT, false, 2, false, false);
plugin->AddPopupListElement("Reset ASAT", NULL, RESET_ASAT, false, 2, false, false);
plugin->AddPopupListElement("Reset ASRT", NULL, RESET_ASRT, false, 2, false, false);
plugin->AddPopupListElement("Reset confirmed TOBT", NULL, RESET_TOBT_CONFIRM, false, 2, false, false);
plugin->AddPopupListElement("Reset AORT", NULL, RESET_AORT, false, 2, false, false);
plugin->AddPopupListElement("Reset AOBT", NULL, RESET_AOBT_AND_STATE, false, 2, false, false);
plugin->AddPopupListElement("Reset Pilot", NULL, RESET_PILOT, false, 2, false, false);
OpenPopupList(area, "RESET menu", 1);
AddPopupListElement("Reset TOBT", NULL, RESET_TOBT, false, 2, false, false);
AddPopupListElement("Reset ASAT", NULL, RESET_ASAT, false, 2, false, false);
AddPopupListElement("Reset ASRT", NULL, RESET_ASRT, false, 2, false, false);
AddPopupListElement("Reset confirmed TOBT", NULL, RESET_TOBT_CONFIRM, false, 2, false, false);
AddPopupListElement("Reset AORT", NULL, RESET_AORT, false, 2, false, false);
AddPopupListElement("Reset AOBT", NULL, RESET_AOBT_AND_STATE, false, 2, false, false);
AddPopupListElement("Reset Pilot", NULL, RESET_PILOT, false, 2, false, false);
break;
case RESET_PILOT:
DataManager::instance().handleTagFunction(DataManager::MessageType::ResetPilot, pilot.callsign,
@@ -215,4 +216,4 @@ void handleTagFunction(vACDM *plugin, int functionId, const char *itemString, PO
break;
}
}
} // namespace vacdm::tagfunctions
} // namespace vacdm
Loading
Loading